mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-vfio-20250908' of https://github.com/legoater/qemu into staging
vfio queue: * Large refactor of the VFIO code to use QOM casts and follow the current coding style guidelines * Removal of the deprecated vfio-platform, vfio-calxeda-xgmac and vfio-amd-xgbe devices * Fail with error if dma_max_mappings limit is hit * Added 'x-pci-class-code' property to vfio-user-pci device * Added a new helper to retrieve a VFIOPCIDevice from a VFIODevice * Fixed IGD OpRegion detection # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmi/CfMACgkQUaNDx8/7 # 7KFkbhAAmbIxFxqLzRO3vnsSRGMkBnvZiQdz/b/iHHV8Uj6eJ6Vr5YxoR2c4XQqz # kkU1+sBBezIWWWQ1dwRW19oObFp8ZvZKWT5AELqSXu/Svdh/kcJ99JnZa+JoK+r9 # rMTFEyjKOc0p9IDI1EIT6wJSqtUi2nXm3w1M4O1qkC17KriLtNLxtxEPCc6l6Ks4 # 0SEDddcVBhk8T0Jb8bHuRoaXqCER11bH07xzCQWTI7tW3cebX6622+F+H72/GvL9 # Gzs/61xTnoiIyGMs+jKM1hoURF0Fvv24zaHmSImxZX1vvF+ezeaRl2equ/H6AbDl # 0+ShqRIj4XChRe0jf+08UDMor9sjRZYRw7NDSkM7hf9kS2VU/44FutAeOL0qAjb4 # oQqIAA1XBqDUW+5SzuzF2t2idBokLKH+d6qEmTTaMQEMrCDzv6Rx41e+27S3Qmai # Ir+D37S57rrUvQFT6asCu6SOIrUPQHPZHDZkod7VPFTNsJkIaHzlViThzip4+CxO # WbO8j0qXYq6OZ4C99GngkosT750DHoLrH5CKujNS4qHAqjisH145xkChM6LwFpzO # o6SlBJg9mmMAsV7hHONk9x1GyESXHsoECQhjXrR7Yibv5ffPapEm/ruG3/gnZ5jA # AgnQLrbKrla5AX8UsGi/Pz75BqadWBC0uABtYV+A0XTEluMC+0Q= # =8KqI # -----END PGP SIGNATURE----- # gpg: Signature made Mon 08 Sep 2025 17:53:07 BST # gpg: using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1 # gpg: Good signature from "Cédric Le Goater <clg@redhat.com>" [full] # gpg: aka "Cédric Le Goater <clg@kaod.org>" [full] # Primary key fingerprint: A0F6 6548 F048 95EB FE6B 0B60 51A3 43C7 CFFB ECA1 * tag 'pull-vfio-20250908' of https://github.com/legoater/qemu: (31 commits) vfio/pci.h: rename VFIOPCIDevice pdev field to parent_obj s390x/s390-pci-vfio.c: use QOM casts where appropriate vfio-user/pci.c: use QOM casts where appropriate vfio/igd.c: use QOM casts where appropriate vfio/cpr.c: use QOM casts where appropriate vfio/pci-quirks.c: use QOM casts where appropriate vfio/pci.c: use QOM casts where appropriate vfio/pci.h: update VFIOPCIDevice declaration vfio-user/pci.c: rename VFIOUserPCIDevice device field to parent_obj vfio-user/pci.c: use QOM casts where appropriate vfio-user/pci.c: update VFIOUserPCIDevice declaration vfio-user/container.h: rename VFIOUserContainer bcontainer field to parent_obj vfio/container.c: use QOM casts where appropriate vfio-user/container.h: update VFIOUserContainer declaration vfio/vfio-container.h: rename VFIOContainer bcontainer field to parent_obj vfio/spapr.c: use QOM casts where appropriate ppc/spapr_pci_vfio.c: use QOM casts where appropriate hw/vfio/container.c: use QOM casts where appropriate hw/vfio/cpr-legacy.c: use QOM casts where appropriate vfio/vfio-container.h: update VFIOContainer declaration ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -1575,6 +1575,7 @@ F: tests/functional/ppc64/test_tuxrun.py
|
||||
PowerNV (Non-Virtualized)
|
||||
M: Nicholas Piggin <npiggin@gmail.com>
|
||||
R: Aditya Gupta <adityag@linux.ibm.com>
|
||||
R: Glenn Miles <milesg@linux.ibm.com>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: docs/system/ppc/powernv.rst
|
||||
@@ -2781,6 +2782,7 @@ T: git https://github.com/philmd/qemu.git fw_cfg-next
|
||||
|
||||
XIVE
|
||||
R: Gautam Menghani <gautam@linux.ibm.com>
|
||||
R: Glenn Miles <milesg@linux.ibm.com>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/*/*xive*
|
||||
|
||||
@@ -488,31 +488,6 @@ Stream ``reconnect`` (since 9.2)
|
||||
The ``reconnect`` option only allows specifying second granularity timeouts,
|
||||
which is not enough for all types of use cases, use ``reconnect-ms`` instead.
|
||||
|
||||
VFIO device options
|
||||
'''''''''''''''''''
|
||||
|
||||
``-device vfio-calxeda-xgmac`` (since 10.0)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The vfio-calxeda-xgmac device allows to assign a host Calxeda Highbank
|
||||
10Gb XGMAC Ethernet controller device ("calxeda,hb-xgmac" compatibility
|
||||
string) to a guest. Calxeda HW has been ewasted now and there is no point
|
||||
keeping that device.
|
||||
|
||||
``-device vfio-amd-xgbe`` (since 10.0)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The vfio-amd-xgbe device allows to assign a host AMD 10GbE controller
|
||||
to a guest ("amd,xgbe-seattle-v1a" compatibility string). AMD "Seattle"
|
||||
is not supported anymore and there is no point keeping that device.
|
||||
|
||||
``-device vfio-platform`` (since 10.0)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The vfio-platform device allows to assign a host platform device
|
||||
to a guest in a generic manner. Integrating a new device into
|
||||
the vfio-platform infrastructure requires some adaptation at
|
||||
both kernel and qemu level. No such attempt has been done for years
|
||||
and the conclusion is that vfio-platform has not got any traction.
|
||||
PCIe passthrough shall be the mainline solution.
|
||||
|
||||
CPU device properties
|
||||
'''''''''''''''''''''
|
||||
|
||||
|
||||
@@ -1280,6 +1280,31 @@ The corresponding upstream server project is no longer maintained.
|
||||
Users are recommended to switch to an alternative distributed block
|
||||
device driver such as RBD.
|
||||
|
||||
VFIO devices
|
||||
------------
|
||||
|
||||
``-device vfio-calxeda-xgmac`` (since 10.2)
|
||||
'''''''''''''''''''''''''''''''''''''''''''
|
||||
The vfio-calxeda-xgmac device allows to assign a host Calxeda Highbank
|
||||
10Gb XGMAC Ethernet controller device ("calxeda,hb-xgmac" compatibility
|
||||
string) to a guest. Calxeda HW has been ewasted now and there is no point
|
||||
keeping that device.
|
||||
|
||||
``-device vfio-amd-xgbe`` (since 10.2)
|
||||
''''''''''''''''''''''''''''''''''''''
|
||||
The vfio-amd-xgbe device allows to assign a host AMD 10GbE controller
|
||||
to a guest ("amd,xgbe-seattle-v1a" compatibility string). AMD "Seattle"
|
||||
is not supported anymore and there is no point keeping that device.
|
||||
|
||||
``-device vfio-platform`` (since 10.2)
|
||||
''''''''''''''''''''''''''''''''''''''
|
||||
The vfio-platform device allows to assign a host platform device
|
||||
to a guest in a generic manner. Integrating a new device into
|
||||
the vfio-platform infrastructure requires some adaptation at
|
||||
both kernel and qemu level. No such attempt has been done for years
|
||||
and the conclusion is that vfio-platform has not got any traction.
|
||||
PCIe passthrough shall be the mainline solution.
|
||||
|
||||
Tools
|
||||
-----
|
||||
|
||||
|
||||
@@ -59,8 +59,6 @@ stanza like the following::
|
||||
config ARM_VIRT
|
||||
bool
|
||||
imply PCI_DEVICES
|
||||
imply VFIO_AMD_XGBE
|
||||
imply VFIO_XGMAC
|
||||
select A15MPCORE
|
||||
select ACPI
|
||||
select ARM_SMMUV3
|
||||
|
||||
@@ -5,9 +5,6 @@ config ARM_VIRT
|
||||
depends on TCG || KVM || HVF
|
||||
imply PCI_DEVICES
|
||||
imply TEST_DEVICES
|
||||
imply VFIO_AMD_XGBE
|
||||
imply VFIO_PLATFORM
|
||||
imply VFIO_XGMAC
|
||||
imply TPM_TIS_SYSBUS
|
||||
imply TPM_TIS_I2C
|
||||
imply NVDIMM
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
#include "hw/arm/primecell.h"
|
||||
#include "hw/arm/virt.h"
|
||||
#include "hw/block/flash.h"
|
||||
#include "hw/vfio/vfio-calxeda-xgmac.h"
|
||||
#include "hw/vfio/vfio-amd-xgbe.h"
|
||||
#include "hw/display/ramfb.h"
|
||||
#include "net/net.h"
|
||||
#include "system/device_tree.h"
|
||||
@@ -3218,10 +3216,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
|
||||
* configuration of the particular instance.
|
||||
*/
|
||||
mc->max_cpus = 512;
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS);
|
||||
#ifdef CONFIG_TPM
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
|
||||
|
||||
@@ -32,10 +32,6 @@
|
||||
#include "system/device_tree.h"
|
||||
#include "system/tpm.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/vfio/vfio-platform.h"
|
||||
#include "hw/vfio/vfio-calxeda-xgmac.h"
|
||||
#include "hw/vfio/vfio-amd-xgbe.h"
|
||||
#include "hw/vfio/vfio-region.h"
|
||||
#include "hw/display/ramfb.h"
|
||||
#include "hw/uefi/var-service-api.h"
|
||||
#include "hw/arm/fdt.h"
|
||||
@@ -66,380 +62,6 @@ typedef struct HostProperty {
|
||||
bool optional;
|
||||
} HostProperty;
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
|
||||
/**
|
||||
* copy_properties_from_host
|
||||
*
|
||||
* copies properties listed in an array from host device tree to
|
||||
* guest device tree. If a non optional property is not found, the
|
||||
* function asserts. An optional property is ignored if not found
|
||||
* in the host device tree.
|
||||
* @props: array of HostProperty to copy
|
||||
* @nb_props: number of properties in the array
|
||||
* @host_dt: host device tree blob
|
||||
* @guest_dt: guest device tree blob
|
||||
* @node_path: host dt node path where the property is supposed to be
|
||||
found
|
||||
* @nodename: guest node name the properties should be added to
|
||||
*/
|
||||
static void copy_properties_from_host(HostProperty *props, int nb_props,
|
||||
void *host_fdt, void *guest_fdt,
|
||||
char *node_path, char *nodename)
|
||||
{
|
||||
int i, prop_len;
|
||||
const void *r;
|
||||
Error *err = NULL;
|
||||
|
||||
for (i = 0; i < nb_props; i++) {
|
||||
r = qemu_fdt_getprop(host_fdt, node_path,
|
||||
props[i].name,
|
||||
&prop_len,
|
||||
&err);
|
||||
if (r) {
|
||||
qemu_fdt_setprop(guest_fdt, nodename,
|
||||
props[i].name, r, prop_len);
|
||||
} else {
|
||||
if (props[i].optional && prop_len == -FDT_ERR_NOTFOUND) {
|
||||
/* optional property does not exist */
|
||||
error_free(err);
|
||||
} else {
|
||||
error_report_err(err);
|
||||
}
|
||||
if (!props[i].optional) {
|
||||
/* mandatory property not found: bail out */
|
||||
exit(1);
|
||||
}
|
||||
err = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clock properties whose values are copied/pasted from host */
|
||||
static HostProperty clock_copied_properties[] = {
|
||||
{"compatible", false},
|
||||
{"#clock-cells", false},
|
||||
{"clock-frequency", true},
|
||||
{"clock-output-names", true},
|
||||
};
|
||||
|
||||
/**
|
||||
* fdt_build_clock_node
|
||||
*
|
||||
* Build a guest clock node, used as a dependency from a passthrough'ed
|
||||
* device. Most information are retrieved from the host clock node.
|
||||
* Also check the host clock is a fixed one.
|
||||
*
|
||||
* @host_fdt: host device tree blob from which info are retrieved
|
||||
* @guest_fdt: guest device tree blob where the clock node is added
|
||||
* @host_phandle: phandle of the clock in host device tree
|
||||
* @guest_phandle: phandle to assign to the guest node
|
||||
*/
|
||||
static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
|
||||
uint32_t host_phandle,
|
||||
uint32_t guest_phandle)
|
||||
{
|
||||
char *node_path = NULL;
|
||||
char *nodename;
|
||||
const void *r;
|
||||
int ret, node_offset, prop_len, path_len = 16;
|
||||
|
||||
node_offset = fdt_node_offset_by_phandle(host_fdt, host_phandle);
|
||||
if (node_offset <= 0) {
|
||||
error_report("not able to locate clock handle %d in host device tree",
|
||||
host_phandle);
|
||||
exit(1);
|
||||
}
|
||||
node_path = g_malloc(path_len);
|
||||
while ((ret = fdt_get_path(host_fdt, node_offset, node_path, path_len))
|
||||
== -FDT_ERR_NOSPACE) {
|
||||
path_len += 16;
|
||||
node_path = g_realloc(node_path, path_len);
|
||||
}
|
||||
if (ret < 0) {
|
||||
error_report("not able to retrieve node path for clock handle %d",
|
||||
host_phandle);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r = qemu_fdt_getprop(host_fdt, node_path, "compatible", &prop_len,
|
||||
&error_fatal);
|
||||
if (strcmp(r, "fixed-clock")) {
|
||||
error_report("clock handle %d is not a fixed clock", host_phandle);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nodename = strrchr(node_path, '/');
|
||||
qemu_fdt_add_subnode(guest_fdt, nodename);
|
||||
|
||||
copy_properties_from_host(clock_copied_properties,
|
||||
ARRAY_SIZE(clock_copied_properties),
|
||||
host_fdt, guest_fdt,
|
||||
node_path, nodename);
|
||||
|
||||
qemu_fdt_setprop_cell(guest_fdt, nodename, "phandle", guest_phandle);
|
||||
|
||||
g_free(node_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* sysfs_to_dt_name: convert the name found in sysfs into the node name
|
||||
* for instance e0900000.xgmac is converted into xgmac@e0900000
|
||||
* @sysfs_name: directory name in sysfs
|
||||
*
|
||||
* returns the device tree name upon success or NULL in case the sysfs name
|
||||
* does not match the expected format
|
||||
*/
|
||||
static char *sysfs_to_dt_name(const char *sysfs_name)
|
||||
{
|
||||
gchar **substrings = g_strsplit(sysfs_name, ".", 2);
|
||||
char *dt_name = NULL;
|
||||
|
||||
if (!substrings || !substrings[0] || !substrings[1]) {
|
||||
goto out;
|
||||
}
|
||||
dt_name = g_strdup_printf("%s@%s", substrings[1], substrings[0]);
|
||||
out:
|
||||
g_strfreev(substrings);
|
||||
return dt_name;
|
||||
}
|
||||
|
||||
/* Device Specific Code */
|
||||
|
||||
/**
|
||||
* add_calxeda_midway_xgmac_fdt_node
|
||||
*
|
||||
* Generates a simple node with following properties:
|
||||
* compatible string, regs, interrupts, dma-coherent
|
||||
*/
|
||||
static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
PlatformBusFDTData *data = opaque;
|
||||
PlatformBusDevice *pbus = data->pbus;
|
||||
void *fdt = data->fdt;
|
||||
const char *parent_node = data->pbus_node_name;
|
||||
int compat_str_len, i;
|
||||
char *nodename;
|
||||
uint32_t *irq_attr, *reg_attr;
|
||||
uint64_t mmio_base, irq_number;
|
||||
VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
|
||||
VFIODevice *vbasedev = &vdev->vbasedev;
|
||||
|
||||
mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
|
||||
nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
|
||||
vbasedev->name, mmio_base);
|
||||
qemu_fdt_add_subnode(fdt, nodename);
|
||||
|
||||
compat_str_len = strlen(vdev->compat) + 1;
|
||||
qemu_fdt_setprop(fdt, nodename, "compatible",
|
||||
vdev->compat, compat_str_len);
|
||||
|
||||
qemu_fdt_setprop(fdt, nodename, "dma-coherent", "", 0);
|
||||
|
||||
reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
|
||||
for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
|
||||
reg_attr[2 * i] = cpu_to_be32(mmio_base);
|
||||
reg_attr[2 * i + 1] = cpu_to_be32(
|
||||
memory_region_size(vdev->regions[i]->mem));
|
||||
}
|
||||
qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
|
||||
vbasedev->num_regions * 2 * sizeof(uint32_t));
|
||||
|
||||
irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
|
||||
for (i = 0; i < vbasedev->num_irqs; i++) {
|
||||
irq_number = platform_bus_get_irqn(pbus, sbdev , i)
|
||||
+ data->irq_start;
|
||||
irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
|
||||
irq_attr[3 * i + 1] = cpu_to_be32(irq_number);
|
||||
irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI);
|
||||
}
|
||||
qemu_fdt_setprop(fdt, nodename, "interrupts",
|
||||
irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t));
|
||||
g_free(irq_attr);
|
||||
g_free(reg_attr);
|
||||
g_free(nodename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* AMD xgbe properties whose values are copied/pasted from host */
|
||||
static HostProperty amd_xgbe_copied_properties[] = {
|
||||
{"compatible", false},
|
||||
{"dma-coherent", true},
|
||||
{"amd,per-channel-interrupt", true},
|
||||
{"phy-mode", false},
|
||||
{"mac-address", true},
|
||||
{"amd,speed-set", false},
|
||||
{"amd,serdes-blwc", true},
|
||||
{"amd,serdes-cdr-rate", true},
|
||||
{"amd,serdes-pq-skew", true},
|
||||
{"amd,serdes-tx-amp", true},
|
||||
{"amd,serdes-dfe-tap-config", true},
|
||||
{"amd,serdes-dfe-tap-enable", true},
|
||||
{"clock-names", false},
|
||||
};
|
||||
|
||||
/**
|
||||
* add_amd_xgbe_fdt_node
|
||||
*
|
||||
* Generates the combined xgbe/phy node following kernel >=4.2
|
||||
* binding documentation:
|
||||
* Documentation/devicetree/bindings/net/amd-xgbe.txt:
|
||||
* Also 2 clock nodes are created (dma and ptp)
|
||||
*
|
||||
* Asserts in case of error
|
||||
*/
|
||||
static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
PlatformBusFDTData *data = opaque;
|
||||
PlatformBusDevice *pbus = data->pbus;
|
||||
VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
|
||||
VFIODevice *vbasedev = &vdev->vbasedev;
|
||||
VFIOINTp *intp;
|
||||
const char *parent_node = data->pbus_node_name;
|
||||
char **node_path, *nodename, *dt_name;
|
||||
void *guest_fdt = data->fdt, *host_fdt;
|
||||
const void *r;
|
||||
int i, prop_len;
|
||||
uint32_t *irq_attr, *reg_attr;
|
||||
const uint32_t *host_clock_phandles;
|
||||
uint64_t mmio_base, irq_number;
|
||||
uint32_t guest_clock_phandles[2];
|
||||
|
||||
host_fdt = load_device_tree_from_sysfs();
|
||||
|
||||
dt_name = sysfs_to_dt_name(vbasedev->name);
|
||||
if (!dt_name) {
|
||||
error_report("%s incorrect sysfs device name %s",
|
||||
__func__, vbasedev->name);
|
||||
exit(1);
|
||||
}
|
||||
node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
|
||||
&error_fatal);
|
||||
if (!node_path || !node_path[0]) {
|
||||
error_report("%s unable to retrieve node path for %s/%s",
|
||||
__func__, dt_name, vdev->compat);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (node_path[1]) {
|
||||
error_report("%s more than one node matching %s/%s!",
|
||||
__func__, dt_name, vdev->compat);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
g_free(dt_name);
|
||||
|
||||
if (vbasedev->num_regions != 5) {
|
||||
error_report("%s Does the host dt node combine XGBE/PHY?", __func__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* generate nodes for DMA_CLK and PTP_CLK */
|
||||
r = qemu_fdt_getprop(host_fdt, node_path[0], "clocks",
|
||||
&prop_len, &error_fatal);
|
||||
if (prop_len != 8) {
|
||||
error_report("%s clocks property should contain 2 handles", __func__);
|
||||
exit(1);
|
||||
}
|
||||
host_clock_phandles = r;
|
||||
guest_clock_phandles[0] = qemu_fdt_alloc_phandle(guest_fdt);
|
||||
guest_clock_phandles[1] = qemu_fdt_alloc_phandle(guest_fdt);
|
||||
|
||||
/**
|
||||
* clock handles fetched from host dt are in be32 layout whereas
|
||||
* rest of the code uses cpu layout. Also guest clock handles are
|
||||
* in cpu layout.
|
||||
*/
|
||||
fdt_build_clock_node(host_fdt, guest_fdt,
|
||||
be32_to_cpu(host_clock_phandles[0]),
|
||||
guest_clock_phandles[0]);
|
||||
|
||||
fdt_build_clock_node(host_fdt, guest_fdt,
|
||||
be32_to_cpu(host_clock_phandles[1]),
|
||||
guest_clock_phandles[1]);
|
||||
|
||||
/* combined XGBE/PHY node */
|
||||
mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
|
||||
nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
|
||||
vbasedev->name, mmio_base);
|
||||
qemu_fdt_add_subnode(guest_fdt, nodename);
|
||||
|
||||
copy_properties_from_host(amd_xgbe_copied_properties,
|
||||
ARRAY_SIZE(amd_xgbe_copied_properties),
|
||||
host_fdt, guest_fdt,
|
||||
node_path[0], nodename);
|
||||
|
||||
qemu_fdt_setprop_cells(guest_fdt, nodename, "clocks",
|
||||
guest_clock_phandles[0],
|
||||
guest_clock_phandles[1]);
|
||||
|
||||
reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
|
||||
for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
|
||||
reg_attr[2 * i] = cpu_to_be32(mmio_base);
|
||||
reg_attr[2 * i + 1] = cpu_to_be32(
|
||||
memory_region_size(vdev->regions[i]->mem));
|
||||
}
|
||||
qemu_fdt_setprop(guest_fdt, nodename, "reg", reg_attr,
|
||||
vbasedev->num_regions * 2 * sizeof(uint32_t));
|
||||
|
||||
irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
|
||||
for (i = 0; i < vbasedev->num_irqs; i++) {
|
||||
irq_number = platform_bus_get_irqn(pbus, sbdev , i)
|
||||
+ data->irq_start;
|
||||
irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
|
||||
irq_attr[3 * i + 1] = cpu_to_be32(irq_number);
|
||||
/*
|
||||
* General device interrupt and PCS auto-negotiation interrupts are
|
||||
* level-sensitive while the 4 per-channel interrupts are edge
|
||||
* sensitive
|
||||
*/
|
||||
QLIST_FOREACH(intp, &vdev->intp_list, next) {
|
||||
if (intp->pin == i) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (intp->flags & VFIO_IRQ_INFO_AUTOMASKED) {
|
||||
irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI);
|
||||
} else {
|
||||
irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
|
||||
}
|
||||
}
|
||||
qemu_fdt_setprop(guest_fdt, nodename, "interrupts",
|
||||
irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t));
|
||||
|
||||
g_free(host_fdt);
|
||||
g_strfreev(node_path);
|
||||
g_free(irq_attr);
|
||||
g_free(reg_attr);
|
||||
g_free(nodename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* DT compatible matching */
|
||||
static bool vfio_platform_match(SysBusDevice *sbdev,
|
||||
const BindingEntry *entry)
|
||||
{
|
||||
VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
|
||||
const char *compat;
|
||||
unsigned int n;
|
||||
|
||||
for (n = vdev->num_compat, compat = vdev->compat; n > 0;
|
||||
n--, compat += strlen(compat) + 1) {
|
||||
if (!strcmp(entry->compat, compat)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define VFIO_PLATFORM_BINDING(compat, add_fn) \
|
||||
{TYPE_VFIO_PLATFORM, (compat), (add_fn), vfio_platform_match}
|
||||
|
||||
#endif /* CONFIG_LINUX */
|
||||
|
||||
#ifdef CONFIG_TPM
|
||||
/*
|
||||
* add_tpm_tis_fdt_node: Create a DT node for TPM TIS
|
||||
@@ -510,11 +132,6 @@ static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry)
|
||||
|
||||
/* list of supported dynamic sysbus bindings */
|
||||
static const BindingEntry bindings[] = {
|
||||
#ifdef CONFIG_LINUX
|
||||
TYPE_BINDING(TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node),
|
||||
TYPE_BINDING(TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node),
|
||||
VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
|
||||
#endif
|
||||
#ifdef CONFIG_TPM
|
||||
TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node),
|
||||
#endif
|
||||
|
||||
@@ -106,7 +106,7 @@ static VFIOContainer *vfio_eeh_as_container(AddressSpace *as)
|
||||
|
||||
out:
|
||||
vfio_address_space_put(space);
|
||||
return container_of(bcontainer, VFIOContainer, bcontainer);
|
||||
return VFIO_IOMMU_LEGACY(bcontainer);
|
||||
}
|
||||
|
||||
static bool vfio_eeh_as_ok(AddressSpace *as)
|
||||
|
||||
@@ -62,7 +62,7 @@ S390PCIDMACount *s390_pci_start_dma_count(S390pciState *s,
|
||||
{
|
||||
S390PCIDMACount *cnt;
|
||||
uint32_t avail;
|
||||
VFIOPCIDevice *vpdev = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
|
||||
VFIOPCIDevice *vpdev = VFIO_PCI_BASE(pbdev->pdev);
|
||||
int id;
|
||||
|
||||
assert(vpdev);
|
||||
@@ -108,7 +108,7 @@ static void s390_pci_read_base(S390PCIBusDevice *pbdev,
|
||||
{
|
||||
struct vfio_info_cap_header *hdr;
|
||||
struct vfio_device_info_cap_zpci_base *cap;
|
||||
VFIOPCIDevice *vpci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
|
||||
VFIOPCIDevice *vpci = VFIO_PCI_BASE(pbdev->pdev);
|
||||
uint64_t vfio_size;
|
||||
|
||||
hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_ZPCI_BASE);
|
||||
@@ -162,7 +162,7 @@ static bool get_host_fh(S390PCIBusDevice *pbdev, struct vfio_device_info *info,
|
||||
{
|
||||
struct vfio_info_cap_header *hdr;
|
||||
struct vfio_device_info_cap_zpci_base *cap;
|
||||
VFIOPCIDevice *vpci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
|
||||
VFIOPCIDevice *vpci = VFIO_PCI_BASE(pbdev->pdev);
|
||||
|
||||
hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_ZPCI_BASE);
|
||||
|
||||
@@ -185,7 +185,7 @@ static void s390_pci_read_group(S390PCIBusDevice *pbdev,
|
||||
struct vfio_device_info_cap_zpci_group *cap;
|
||||
S390pciState *s = s390_get_phb();
|
||||
ClpRspQueryPciGrp *resgrp;
|
||||
VFIOPCIDevice *vpci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
|
||||
VFIOPCIDevice *vpci = VFIO_PCI_BASE(pbdev->pdev);
|
||||
uint8_t start_gid = pbdev->zpci_fn.pfgid;
|
||||
|
||||
hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_ZPCI_GROUP);
|
||||
@@ -264,7 +264,7 @@ static void s390_pci_read_util(S390PCIBusDevice *pbdev,
|
||||
{
|
||||
struct vfio_info_cap_header *hdr;
|
||||
struct vfio_device_info_cap_zpci_util *cap;
|
||||
VFIOPCIDevice *vpci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
|
||||
VFIOPCIDevice *vpci = VFIO_PCI_BASE(pbdev->pdev);
|
||||
|
||||
hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_ZPCI_UTIL);
|
||||
|
||||
@@ -291,7 +291,7 @@ static void s390_pci_read_pfip(S390PCIBusDevice *pbdev,
|
||||
{
|
||||
struct vfio_info_cap_header *hdr;
|
||||
struct vfio_device_info_cap_zpci_pfip *cap;
|
||||
VFIOPCIDevice *vpci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
|
||||
VFIOPCIDevice *vpci = VFIO_PCI_BASE(pbdev->pdev);
|
||||
|
||||
hdr = vfio_get_device_info_cap(info, VFIO_DEVICE_INFO_CAP_ZPCI_PFIP);
|
||||
|
||||
@@ -314,7 +314,7 @@ static void s390_pci_read_pfip(S390PCIBusDevice *pbdev,
|
||||
|
||||
static struct vfio_device_info *get_device_info(S390PCIBusDevice *pbdev)
|
||||
{
|
||||
VFIOPCIDevice *vfio_pci = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
|
||||
VFIOPCIDevice *vfio_pci = VFIO_PCI_BASE(pbdev->pdev);
|
||||
|
||||
return vfio_get_device_info(vfio_pci->vbasedev.fd);
|
||||
}
|
||||
|
||||
+11
-15
@@ -24,16 +24,14 @@
|
||||
*/
|
||||
static void vfio_user_listener_begin(VFIOContainerBase *bcontainer)
|
||||
{
|
||||
VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
|
||||
bcontainer);
|
||||
VFIOUserContainer *container = VFIO_IOMMU_USER(bcontainer);
|
||||
|
||||
container->proxy->async_ops = true;
|
||||
}
|
||||
|
||||
static void vfio_user_listener_commit(VFIOContainerBase *bcontainer)
|
||||
{
|
||||
VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
|
||||
bcontainer);
|
||||
VFIOUserContainer *container = VFIO_IOMMU_USER(bcontainer);
|
||||
|
||||
/* wait here for any async requests sent during the transaction */
|
||||
container->proxy->async_ops = false;
|
||||
@@ -44,8 +42,8 @@ static int vfio_user_dma_unmap(const VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
IOMMUTLBEntry *iotlb, bool unmap_all)
|
||||
{
|
||||
VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
|
||||
bcontainer);
|
||||
VFIOUserContainer *container = VFIO_IOMMU_USER(bcontainer);
|
||||
|
||||
Error *local_err = NULL;
|
||||
int ret = 0;
|
||||
|
||||
@@ -86,8 +84,8 @@ static int vfio_user_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova,
|
||||
ram_addr_t size, void *vaddr, bool readonly,
|
||||
MemoryRegion *mrp)
|
||||
{
|
||||
VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
|
||||
bcontainer);
|
||||
VFIOUserContainer *container = VFIO_IOMMU_USER(bcontainer);
|
||||
|
||||
int fd = memory_region_get_fd(mrp);
|
||||
Error *local_err = NULL;
|
||||
int ret = 0;
|
||||
@@ -173,8 +171,7 @@ static int vfio_user_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
|
||||
|
||||
static bool vfio_user_setup(VFIOContainerBase *bcontainer, Error **errp)
|
||||
{
|
||||
VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
|
||||
bcontainer);
|
||||
VFIOUserContainer *container = VFIO_IOMMU_USER(bcontainer);
|
||||
|
||||
assert(container->proxy->dma_pgsizes != 0);
|
||||
bcontainer->pgsizes = container->proxy->dma_pgsizes;
|
||||
@@ -218,7 +215,7 @@ vfio_user_container_connect(AddressSpace *as, VFIODevice *vbasedev,
|
||||
goto put_space_exit;
|
||||
}
|
||||
|
||||
bcontainer = &container->bcontainer;
|
||||
bcontainer = VFIO_IOMMU(container);
|
||||
|
||||
ret = ram_block_uncoordinated_discard_disable(true);
|
||||
if (ret) {
|
||||
@@ -263,7 +260,7 @@ put_space_exit:
|
||||
|
||||
static void vfio_user_container_disconnect(VFIOUserContainer *container)
|
||||
{
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
VFIOContainerBase *bcontainer = VFIO_IOMMU(container);
|
||||
VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
|
||||
VFIOAddressSpace *space = bcontainer->space;
|
||||
|
||||
@@ -291,7 +288,7 @@ static bool vfio_user_device_get(VFIOUserContainer *container,
|
||||
|
||||
vbasedev->fd = -1;
|
||||
|
||||
vfio_device_prepare(vbasedev, &container->bcontainer, &info);
|
||||
vfio_device_prepare(vbasedev, VFIO_IOMMU(container), &info);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -315,8 +312,7 @@ static bool vfio_user_device_attach(const char *name, VFIODevice *vbasedev,
|
||||
|
||||
static void vfio_user_device_detach(VFIODevice *vbasedev)
|
||||
{
|
||||
VFIOUserContainer *container = container_of(vbasedev->bcontainer,
|
||||
VFIOUserContainer, bcontainer);
|
||||
VFIOUserContainer *container = VFIO_IOMMU_USER(vbasedev->bcontainer);
|
||||
|
||||
vfio_device_unprepare(vbasedev);
|
||||
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
#include "hw/vfio-user/proxy.h"
|
||||
|
||||
/* MMU container sub-class for vfio-user. */
|
||||
typedef struct VFIOUserContainer {
|
||||
VFIOContainerBase bcontainer;
|
||||
struct VFIOUserContainer {
|
||||
VFIOContainerBase parent_obj;
|
||||
|
||||
VFIOUserProxy *proxy;
|
||||
} VFIOUserContainer;
|
||||
};
|
||||
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VFIOUserContainer, VFIO_IOMMU_USER);
|
||||
|
||||
|
||||
+11
-7
@@ -20,7 +20,8 @@
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VFIOUserPCIDevice, VFIO_USER_PCI)
|
||||
|
||||
struct VFIOUserPCIDevice {
|
||||
VFIOPCIDevice device;
|
||||
VFIOPCIDevice parent_obj;
|
||||
|
||||
SocketAddress *socket;
|
||||
bool send_queued; /* all sends are queued */
|
||||
uint32_t wait_time; /* timeout for message replies */
|
||||
@@ -64,7 +65,7 @@ static void vfio_user_msix_setup(VFIOPCIDevice *vdev)
|
||||
vdev->msix->pba_region = pba_reg;
|
||||
|
||||
vfio_reg = vdev->bars[vdev->msix->pba_bar].mr;
|
||||
msix_reg = &vdev->pdev.msix_pba_mmio;
|
||||
msix_reg = &PCI_DEVICE(vdev)->msix_pba_mmio;
|
||||
memory_region_init_io(pba_reg, OBJECT(vdev), &vfio_user_pba_ops, vdev,
|
||||
"VFIO MSIX PBA", int128_get64(msix_reg->size));
|
||||
memory_region_add_subregion_overlap(vfio_reg, vdev->msix->pba_offset,
|
||||
@@ -85,7 +86,7 @@ static void vfio_user_msix_teardown(VFIOPCIDevice *vdev)
|
||||
|
||||
static void vfio_user_dma_read(VFIOPCIDevice *vdev, VFIOUserDMARW *msg)
|
||||
{
|
||||
PCIDevice *pdev = &vdev->pdev;
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
VFIOUserProxy *proxy = vdev->vbasedev.proxy;
|
||||
VFIOUserDMARW *res;
|
||||
MemTxResult r;
|
||||
@@ -133,7 +134,7 @@ static void vfio_user_dma_read(VFIOPCIDevice *vdev, VFIOUserDMARW *msg)
|
||||
|
||||
static void vfio_user_dma_write(VFIOPCIDevice *vdev, VFIOUserDMARW *msg)
|
||||
{
|
||||
PCIDevice *pdev = &vdev->pdev;
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
VFIOUserProxy *proxy = vdev->vbasedev.proxy;
|
||||
MemTxResult r;
|
||||
|
||||
@@ -213,8 +214,9 @@ static void vfio_user_compute_needs_reset(VFIODevice *vbasedev)
|
||||
|
||||
static Object *vfio_user_pci_get_object(VFIODevice *vbasedev)
|
||||
{
|
||||
VFIOUserPCIDevice *vdev = container_of(vbasedev, VFIOUserPCIDevice,
|
||||
device.vbasedev);
|
||||
VFIOUserPCIDevice *vdev = VFIO_USER_PCI(container_of(vbasedev,
|
||||
VFIOPCIDevice,
|
||||
vbasedev));
|
||||
|
||||
return OBJECT(vdev);
|
||||
}
|
||||
@@ -406,6 +408,8 @@ static const Property vfio_user_pci_dev_properties[] = {
|
||||
sub_vendor_id, PCI_ANY_ID),
|
||||
DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
|
||||
sub_device_id, PCI_ANY_ID),
|
||||
DEFINE_PROP_UINT32("x-pci-class-code", VFIOPCIDevice,
|
||||
class_code, PCI_ANY_ID),
|
||||
DEFINE_PROP_BOOL("x-send-queued", VFIOUserPCIDevice, send_queued, false),
|
||||
DEFINE_PROP_UINT32("x-msg-timeout", VFIOUserPCIDevice, wait_time, 5000),
|
||||
DEFINE_PROP_BOOL("x-no-posted-writes", VFIOUserPCIDevice, no_post, false),
|
||||
@@ -417,7 +421,7 @@ static void vfio_user_pci_set_socket(Object *obj, Visitor *v, const char *name,
|
||||
VFIOUserPCIDevice *udev = VFIO_USER_PCI(obj);
|
||||
bool success;
|
||||
|
||||
if (udev->device.vbasedev.proxy) {
|
||||
if (VFIO_PCI_BASE(udev)->vbasedev.proxy) {
|
||||
error_setg(errp, "Proxy is connected");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,22 +17,6 @@ config VFIO_CCW
|
||||
select VFIO
|
||||
depends on LINUX && S390_CCW_VIRTIO
|
||||
|
||||
config VFIO_PLATFORM
|
||||
bool
|
||||
default y
|
||||
select VFIO
|
||||
depends on LINUX && PLATFORM_BUS
|
||||
|
||||
config VFIO_XGMAC
|
||||
bool
|
||||
default y
|
||||
depends on VFIO_PLATFORM
|
||||
|
||||
config VFIO_AMD_XGBE
|
||||
bool
|
||||
default y
|
||||
depends on VFIO_PLATFORM
|
||||
|
||||
config VFIO_AP
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* AMD XGBE VFIO device
|
||||
*
|
||||
* Copyright Linaro Limited, 2015
|
||||
*
|
||||
* Authors:
|
||||
* Eric Auger <eric.auger@linaro.org>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/vfio/vfio-amd-xgbe.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
static void amd_xgbe_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev);
|
||||
VFIOAmdXgbeDeviceClass *k = VFIO_AMD_XGBE_DEVICE_GET_CLASS(dev);
|
||||
|
||||
warn_report("-device vfio-amd-xgbe is deprecated");
|
||||
vdev->compat = g_strdup("amd,xgbe-seattle-v1a");
|
||||
vdev->num_compat = 1;
|
||||
|
||||
k->parent_realize(dev, errp);
|
||||
}
|
||||
|
||||
static const VMStateDescription vfio_platform_amd_xgbe_vmstate = {
|
||||
.name = "vfio-amd-xgbe",
|
||||
.unmigratable = 1,
|
||||
};
|
||||
|
||||
static void vfio_amd_xgbe_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VFIOAmdXgbeDeviceClass *vcxc =
|
||||
VFIO_AMD_XGBE_DEVICE_CLASS(klass);
|
||||
device_class_set_parent_realize(dc, amd_xgbe_realize,
|
||||
&vcxc->parent_realize);
|
||||
dc->desc = "VFIO AMD XGBE";
|
||||
dc->vmsd = &vfio_platform_amd_xgbe_vmstate;
|
||||
}
|
||||
|
||||
static const TypeInfo vfio_amd_xgbe_dev_info = {
|
||||
.name = TYPE_VFIO_AMD_XGBE,
|
||||
.parent = TYPE_VFIO_PLATFORM,
|
||||
.instance_size = sizeof(VFIOAmdXgbeDevice),
|
||||
.class_init = vfio_amd_xgbe_class_init,
|
||||
.class_size = sizeof(VFIOAmdXgbeDeviceClass),
|
||||
};
|
||||
|
||||
static void register_amd_xgbe_dev_type(void)
|
||||
{
|
||||
type_register_static(&vfio_amd_xgbe_dev_info);
|
||||
}
|
||||
|
||||
type_init(register_amd_xgbe_dev_type)
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* calxeda xgmac VFIO device
|
||||
*
|
||||
* Copyright Linaro Limited, 2014
|
||||
*
|
||||
* Authors:
|
||||
* Eric Auger <eric.auger@linaro.org>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/vfio/vfio-calxeda-xgmac.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
static void calxeda_xgmac_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev);
|
||||
VFIOCalxedaXgmacDeviceClass *k = VFIO_CALXEDA_XGMAC_DEVICE_GET_CLASS(dev);
|
||||
|
||||
warn_report("-device vfio-calxeda-xgmac is deprecated");
|
||||
vdev->compat = g_strdup("calxeda,hb-xgmac");
|
||||
vdev->num_compat = 1;
|
||||
|
||||
k->parent_realize(dev, errp);
|
||||
}
|
||||
|
||||
static const VMStateDescription vfio_platform_calxeda_xgmac_vmstate = {
|
||||
.name = "vfio-calxeda-xgmac",
|
||||
.unmigratable = 1,
|
||||
};
|
||||
|
||||
static void vfio_calxeda_xgmac_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VFIOCalxedaXgmacDeviceClass *vcxc =
|
||||
VFIO_CALXEDA_XGMAC_DEVICE_CLASS(klass);
|
||||
device_class_set_parent_realize(dc, calxeda_xgmac_realize,
|
||||
&vcxc->parent_realize);
|
||||
dc->desc = "VFIO Calxeda XGMAC";
|
||||
dc->vmsd = &vfio_platform_calxeda_xgmac_vmstate;
|
||||
}
|
||||
|
||||
static const TypeInfo vfio_calxeda_xgmac_dev_info = {
|
||||
.name = TYPE_VFIO_CALXEDA_XGMAC,
|
||||
.parent = TYPE_VFIO_PLATFORM,
|
||||
.instance_size = sizeof(VFIOCalxedaXgmacDevice),
|
||||
.class_init = vfio_calxeda_xgmac_class_init,
|
||||
.class_size = sizeof(VFIOCalxedaXgmacDeviceClass),
|
||||
};
|
||||
|
||||
static void register_calxeda_xgmac_dev_type(void)
|
||||
{
|
||||
type_register_static(&vfio_calxeda_xgmac_dev_info);
|
||||
}
|
||||
|
||||
type_init(register_calxeda_xgmac_dev_type)
|
||||
+15
-20
@@ -71,7 +71,7 @@ static int vfio_dma_unmap_bitmap(const VFIOContainer *container,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
IOMMUTLBEntry *iotlb)
|
||||
{
|
||||
const VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
const VFIOContainerBase *bcontainer = VFIO_IOMMU(container);
|
||||
struct vfio_iommu_type1_dma_unmap *unmap;
|
||||
struct vfio_bitmap *bitmap;
|
||||
VFIOBitmap vbmap;
|
||||
@@ -124,8 +124,7 @@ static int vfio_legacy_dma_unmap_one(const VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size,
|
||||
IOMMUTLBEntry *iotlb)
|
||||
{
|
||||
const VFIOContainer *container = container_of(bcontainer, VFIOContainer,
|
||||
bcontainer);
|
||||
const VFIOContainer *container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
struct vfio_iommu_type1_dma_unmap unmap = {
|
||||
.argsz = sizeof(unmap),
|
||||
.flags = 0,
|
||||
@@ -213,8 +212,7 @@ static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova,
|
||||
ram_addr_t size, void *vaddr, bool readonly,
|
||||
MemoryRegion *mr)
|
||||
{
|
||||
const VFIOContainer *container = container_of(bcontainer, VFIOContainer,
|
||||
bcontainer);
|
||||
const VFIOContainer *container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
struct vfio_iommu_type1_dma_map map = {
|
||||
.argsz = sizeof(map),
|
||||
.flags = VFIO_DMA_MAP_FLAG_READ,
|
||||
@@ -246,8 +244,7 @@ static int
|
||||
vfio_legacy_set_dirty_page_tracking(const VFIOContainerBase *bcontainer,
|
||||
bool start, Error **errp)
|
||||
{
|
||||
const VFIOContainer *container = container_of(bcontainer, VFIOContainer,
|
||||
bcontainer);
|
||||
const VFIOContainer *container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
int ret;
|
||||
struct vfio_iommu_type1_dirty_bitmap dirty = {
|
||||
.argsz = sizeof(dirty),
|
||||
@@ -272,8 +269,7 @@ vfio_legacy_set_dirty_page_tracking(const VFIOContainerBase *bcontainer,
|
||||
static int vfio_legacy_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
|
||||
VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp)
|
||||
{
|
||||
const VFIOContainer *container = container_of(bcontainer, VFIOContainer,
|
||||
bcontainer);
|
||||
const VFIOContainer *container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
struct vfio_iommu_type1_dirty_bitmap *dbitmap;
|
||||
struct vfio_iommu_type1_dirty_bitmap_get *range;
|
||||
int ret;
|
||||
@@ -495,7 +491,7 @@ static void vfio_get_iommu_info_migration(VFIOContainer *container,
|
||||
{
|
||||
struct vfio_info_cap_header *hdr;
|
||||
struct vfio_iommu_type1_info_cap_migration *cap_mig;
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
VFIOContainerBase *bcontainer = VFIO_IOMMU(container);
|
||||
|
||||
hdr = vfio_get_iommu_info_cap(info, VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION);
|
||||
if (!hdr) {
|
||||
@@ -518,8 +514,7 @@ static void vfio_get_iommu_info_migration(VFIOContainer *container,
|
||||
|
||||
static bool vfio_legacy_setup(VFIOContainerBase *bcontainer, Error **errp)
|
||||
{
|
||||
VFIOContainer *container = container_of(bcontainer, VFIOContainer,
|
||||
bcontainer);
|
||||
VFIOContainer *container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
g_autofree struct vfio_iommu_type1_info *info = NULL;
|
||||
int ret;
|
||||
|
||||
@@ -634,7 +629,7 @@ static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
|
||||
|
||||
if (!cpr_is_incoming()) {
|
||||
QLIST_FOREACH(bcontainer, &space->containers, next) {
|
||||
container = container_of(bcontainer, VFIOContainer, bcontainer);
|
||||
container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) {
|
||||
return vfio_container_group_add(container, group, errp);
|
||||
}
|
||||
@@ -652,7 +647,7 @@ static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
|
||||
* create the container struct and group list.
|
||||
*/
|
||||
QLIST_FOREACH(bcontainer, &space->containers, next) {
|
||||
container = container_of(bcontainer, VFIOContainer, bcontainer);
|
||||
container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
|
||||
if (vfio_cpr_container_match(container, group, fd)) {
|
||||
return vfio_container_group_add(container, group, errp);
|
||||
@@ -672,7 +667,7 @@ static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
|
||||
goto fail;
|
||||
}
|
||||
new_container = true;
|
||||
bcontainer = &container->bcontainer;
|
||||
bcontainer = VFIO_IOMMU(container);
|
||||
|
||||
if (!vfio_legacy_cpr_register_container(container, errp)) {
|
||||
goto fail;
|
||||
@@ -735,7 +730,7 @@ fail:
|
||||
static void vfio_container_disconnect(VFIOGroup *group)
|
||||
{
|
||||
VFIOContainer *container = group->container;
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
VFIOContainerBase *bcontainer = VFIO_IOMMU(container);
|
||||
VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
|
||||
|
||||
QLIST_REMOVE(group, container_next);
|
||||
@@ -781,7 +776,7 @@ static VFIOGroup *vfio_group_get(int groupid, AddressSpace *as, Error **errp)
|
||||
QLIST_FOREACH(group, &vfio_group_list, next) {
|
||||
if (group->groupid == groupid) {
|
||||
/* Found it. Now is it already in the right context? */
|
||||
if (group->container->bcontainer.space->as == as) {
|
||||
if (VFIO_IOMMU(group->container)->space->as == as) {
|
||||
return group;
|
||||
} else {
|
||||
error_setg(errp, "group %d used in multiple address spaces",
|
||||
@@ -895,7 +890,7 @@ static bool vfio_device_get(VFIOGroup *group, const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
vfio_device_prepare(vbasedev, &group->container->bcontainer, info);
|
||||
vfio_device_prepare(vbasedev, VFIO_IOMMU(group->container), info);
|
||||
|
||||
vbasedev->fd = fd;
|
||||
vbasedev->group = group;
|
||||
@@ -1087,7 +1082,7 @@ static int vfio_legacy_pci_hot_reset(VFIODevice *vbasedev, bool single)
|
||||
/* Prep dependent devices for reset and clear our marker. */
|
||||
QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
|
||||
if (!vbasedev_iter->dev->realized ||
|
||||
vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) {
|
||||
!vfio_pci_from_vfio_device(vbasedev_iter)) {
|
||||
continue;
|
||||
}
|
||||
tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev);
|
||||
@@ -1172,7 +1167,7 @@ out:
|
||||
|
||||
QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
|
||||
if (!vbasedev_iter->dev->realized ||
|
||||
vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) {
|
||||
!vfio_pci_from_vfio_device(vbasedev_iter)) {
|
||||
continue;
|
||||
}
|
||||
tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev);
|
||||
|
||||
@@ -41,8 +41,8 @@ static int vfio_legacy_cpr_dma_map(const VFIOContainerBase *bcontainer,
|
||||
hwaddr iova, ram_addr_t size, void *vaddr,
|
||||
bool readonly, MemoryRegion *mr)
|
||||
{
|
||||
const VFIOContainer *container = container_of(bcontainer, VFIOContainer,
|
||||
bcontainer);
|
||||
const VFIOContainer *container = VFIO_IOMMU_LEGACY(bcontainer);
|
||||
|
||||
struct vfio_iommu_type1_dma_map map = {
|
||||
.argsz = sizeof(map),
|
||||
.flags = VFIO_DMA_MAP_FLAG_VADDR,
|
||||
@@ -65,7 +65,7 @@ static void vfio_region_remap(MemoryListener *listener,
|
||||
{
|
||||
VFIOContainer *container = container_of(listener, VFIOContainer,
|
||||
cpr.remap_listener);
|
||||
vfio_container_region_add(&container->bcontainer, section, true);
|
||||
vfio_container_region_add(VFIO_IOMMU(container), section, true);
|
||||
}
|
||||
|
||||
static bool vfio_cpr_supported(VFIOContainer *container, Error **errp)
|
||||
@@ -98,7 +98,7 @@ static int vfio_container_pre_save(void *opaque)
|
||||
static int vfio_container_post_load(void *opaque, int version_id)
|
||||
{
|
||||
VFIOContainer *container = opaque;
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
VFIOContainerBase *bcontainer = VFIO_IOMMU(container);
|
||||
VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
|
||||
dma_map_fn saved_dma_map = vioc->dma_map;
|
||||
Error *local_err = NULL;
|
||||
@@ -135,7 +135,7 @@ static int vfio_cpr_fail_notifier(NotifierWithReturn *notifier,
|
||||
{
|
||||
VFIOContainer *container =
|
||||
container_of(notifier, VFIOContainer, cpr.transfer_notifier);
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
VFIOContainerBase *bcontainer = VFIO_IOMMU(container);
|
||||
|
||||
if (e->type != MIG_EVENT_PRECOPY_FAILED) {
|
||||
return 0;
|
||||
@@ -167,7 +167,7 @@ static int vfio_cpr_fail_notifier(NotifierWithReturn *notifier,
|
||||
|
||||
bool vfio_legacy_cpr_register_container(VFIOContainer *container, Error **errp)
|
||||
{
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
VFIOContainerBase *bcontainer = VFIO_IOMMU(container);
|
||||
Error **cpr_blocker = &container->cpr.blocker;
|
||||
|
||||
migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier,
|
||||
@@ -191,7 +191,7 @@ bool vfio_legacy_cpr_register_container(VFIOContainer *container, Error **errp)
|
||||
|
||||
void vfio_legacy_cpr_unregister_container(VFIOContainer *container)
|
||||
{
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
VFIOContainerBase *bcontainer = VFIO_IOMMU(container);
|
||||
|
||||
migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
|
||||
migrate_del_blocker(&container->cpr.blocker);
|
||||
|
||||
+6
-6
@@ -56,7 +56,7 @@ static void vfio_cpr_claim_vectors(VFIOPCIDevice *vdev, int nr_vectors,
|
||||
{
|
||||
int i, fd;
|
||||
bool pending = false;
|
||||
PCIDevice *pdev = &vdev->pdev;
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
|
||||
vdev->nr_vectors = nr_vectors;
|
||||
vdev->msi_vectors = g_new0(VFIOMSIVector, nr_vectors);
|
||||
@@ -99,7 +99,7 @@ static void vfio_cpr_claim_vectors(VFIOPCIDevice *vdev, int nr_vectors,
|
||||
static int vfio_cpr_pci_pre_load(void *opaque)
|
||||
{
|
||||
VFIOPCIDevice *vdev = opaque;
|
||||
PCIDevice *pdev = &vdev->pdev;
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
int size = MIN(pci_config_size(pdev), vdev->config_size);
|
||||
int i;
|
||||
|
||||
@@ -113,7 +113,7 @@ static int vfio_cpr_pci_pre_load(void *opaque)
|
||||
static int vfio_cpr_pci_post_load(void *opaque, int version_id)
|
||||
{
|
||||
VFIOPCIDevice *vdev = opaque;
|
||||
PCIDevice *pdev = &vdev->pdev;
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
int nr_vectors;
|
||||
|
||||
vfio_sub_page_bar_update_mappings(vdev);
|
||||
@@ -173,8 +173,8 @@ const VMStateDescription vfio_cpr_pci_vmstate = {
|
||||
.post_load = vfio_cpr_pci_post_load,
|
||||
.needed = cpr_incoming_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(pdev, VFIOPCIDevice),
|
||||
VMSTATE_MSIX_TEST(pdev, VFIOPCIDevice, pci_msix_present),
|
||||
VMSTATE_PCI_DEVICE(parent_obj, VFIOPCIDevice),
|
||||
VMSTATE_MSIX_TEST(parent_obj, VFIOPCIDevice, pci_msix_present),
|
||||
VMSTATE_VFIO_INTX(intx, VFIOPCIDevice),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
@@ -214,7 +214,7 @@ static int set_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
|
||||
static int vfio_cpr_set_msi_virq(VFIOPCIDevice *vdev, Error **errp, bool enable)
|
||||
{
|
||||
const char *op = (enable ? "enable" : "disable");
|
||||
PCIDevice *pdev = &vdev->pdev;
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
int i, nr_vectors, ret = 0;
|
||||
|
||||
if (msix_enabled(pdev)) {
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ static inline const char *action_to_str(int action)
|
||||
|
||||
static const char *index_to_str(VFIODevice *vbasedev, int index)
|
||||
{
|
||||
if (vbasedev->type != VFIO_DEVICE_TYPE_PCI) {
|
||||
if (!vfio_pci_from_vfio_device(vbasedev)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+25
-20
@@ -200,7 +200,7 @@ static bool vfio_pci_igd_opregion_detect(VFIOPCIDevice *vdev,
|
||||
}
|
||||
|
||||
/* Hotplugging is not supported for opregion access */
|
||||
if (vdev->pdev.qdev.hotplugged) {
|
||||
if (DEVICE(vdev)->hotplugged) {
|
||||
warn_report("IGD device detected, but OpRegion is not supported "
|
||||
"on hotplugged device.");
|
||||
return false;
|
||||
@@ -260,11 +260,12 @@ static int vfio_pci_igd_copy(VFIOPCIDevice *vdev, PCIDevice *pdev,
|
||||
static int vfio_pci_igd_host_init(VFIOPCIDevice *vdev,
|
||||
struct vfio_region_info *info)
|
||||
{
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
PCIBus *bus;
|
||||
PCIDevice *host_bridge;
|
||||
int ret;
|
||||
|
||||
bus = pci_device_root_bus(&vdev->pdev);
|
||||
bus = pci_device_root_bus(pdev);
|
||||
host_bridge = pci_find_device(bus, 0, PCI_DEVFN(0, 0));
|
||||
|
||||
if (!host_bridge) {
|
||||
@@ -327,13 +328,14 @@ type_init(vfio_pci_igd_register_types)
|
||||
static int vfio_pci_igd_lpc_init(VFIOPCIDevice *vdev,
|
||||
struct vfio_region_info *info)
|
||||
{
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
PCIDevice *lpc_bridge;
|
||||
int ret;
|
||||
|
||||
lpc_bridge = pci_find_device(pci_device_root_bus(&vdev->pdev),
|
||||
lpc_bridge = pci_find_device(pci_device_root_bus(pdev),
|
||||
0, PCI_DEVFN(0x1f, 0));
|
||||
if (!lpc_bridge) {
|
||||
lpc_bridge = pci_create_simple(pci_device_root_bus(&vdev->pdev),
|
||||
lpc_bridge = pci_create_simple(pci_device_root_bus(pdev),
|
||||
PCI_DEVFN(0x1f, 0), "vfio-pci-igd-lpc-bridge");
|
||||
}
|
||||
|
||||
@@ -350,13 +352,14 @@ static bool vfio_pci_igd_setup_lpc_bridge(VFIOPCIDevice *vdev, Error **errp)
|
||||
{
|
||||
struct vfio_region_info *host = NULL;
|
||||
struct vfio_region_info *lpc = NULL;
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
PCIDevice *lpc_bridge;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Copying IDs or creating new devices are not supported on hotplug
|
||||
*/
|
||||
if (vdev->pdev.qdev.hotplugged) {
|
||||
if (DEVICE(vdev)->hotplugged) {
|
||||
error_setg(errp, "IGD LPC is not supported on hotplugged device");
|
||||
return false;
|
||||
}
|
||||
@@ -366,7 +369,7 @@ static bool vfio_pci_igd_setup_lpc_bridge(VFIOPCIDevice *vdev, Error **errp)
|
||||
* can stuff host values into, so if there's already one there and it's not
|
||||
* one we can hack on, this quirk is no-go. Sorry Q35.
|
||||
*/
|
||||
lpc_bridge = pci_find_device(pci_device_root_bus(&vdev->pdev),
|
||||
lpc_bridge = pci_find_device(pci_device_root_bus(pdev),
|
||||
0, PCI_DEVFN(0x1f, 0));
|
||||
if (lpc_bridge && !object_dynamic_cast(OBJECT(lpc_bridge),
|
||||
"vfio-pci-igd-lpc-bridge")) {
|
||||
@@ -460,7 +463,7 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
|
||||
int gen;
|
||||
|
||||
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
|
||||
!vfio_is_vga(vdev) || nr != 0) {
|
||||
!vfio_is_base_display(vdev) || nr != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -510,6 +513,7 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
|
||||
static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
|
||||
{
|
||||
struct vfio_region_info *opregion = NULL;
|
||||
PCIDevice *pdev = PCI_DEVICE(vdev);
|
||||
int ret, gen;
|
||||
uint64_t gms_size = 0;
|
||||
uint64_t *bdsm_size;
|
||||
@@ -518,7 +522,7 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
|
||||
Error *err = NULL;
|
||||
|
||||
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
|
||||
!vfio_is_vga(vdev)) {
|
||||
!vfio_is_base_display(vdev)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -529,21 +533,22 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
|
||||
info_report("OpRegion detected on Intel display %x.", vdev->device_id);
|
||||
|
||||
gen = igd_gen(vdev);
|
||||
gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
|
||||
gmch = vfio_pci_read_config(pdev, IGD_GMCH, 4);
|
||||
|
||||
/*
|
||||
* For backward compatibility, enable legacy mode when
|
||||
* - Device geneation is 6 to 9 (including both)
|
||||
* - IGD claims VGA cycles on host
|
||||
* - IGD exposes itself as VGA controller and claims VGA cycles on host
|
||||
* - Machine type is i440fx (pc_piix)
|
||||
* - IGD device is at guest BDF 00:02.0
|
||||
* - Not manually disabled by x-igd-legacy-mode=off
|
||||
*/
|
||||
if ((vdev->igd_legacy_mode != ON_OFF_AUTO_OFF) &&
|
||||
vfio_is_vga(vdev) &&
|
||||
(gen >= 6 && gen <= 9) &&
|
||||
!(gmch & IGD_GMCH_VGA_DISABLE) &&
|
||||
!strcmp(MACHINE_GET_CLASS(qdev_get_machine())->family, "pc_piix") &&
|
||||
(&vdev->pdev == pci_find_device(pci_device_root_bus(&vdev->pdev),
|
||||
(pdev == pci_find_device(pci_device_root_bus(pdev),
|
||||
0, PCI_DEVFN(0x2, 0)))) {
|
||||
/*
|
||||
* IGD legacy mode requires:
|
||||
@@ -565,7 +570,7 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
|
||||
*/
|
||||
ret = vfio_device_get_region_info(&vdev->vbasedev,
|
||||
VFIO_PCI_ROM_REGION_INDEX, &rom);
|
||||
if ((ret || !rom->size) && !vdev->pdev.romfile) {
|
||||
if ((ret || !rom->size) && !pdev->romfile) {
|
||||
error_setg(&err, "Device has no ROM");
|
||||
goto error;
|
||||
}
|
||||
@@ -610,8 +615,8 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
|
||||
* ASLS (OpRegion address) is read-only, emulated
|
||||
* It contains HPA, guest firmware need to reprogram it with GPA.
|
||||
*/
|
||||
pci_set_long(vdev->pdev.config + IGD_ASLS, 0);
|
||||
pci_set_long(vdev->pdev.wmask + IGD_ASLS, ~0);
|
||||
pci_set_long(pdev->config + IGD_ASLS, 0);
|
||||
pci_set_long(pdev->wmask + IGD_ASLS, ~0);
|
||||
pci_set_long(vdev->emulated_config_bits + IGD_ASLS, ~0);
|
||||
|
||||
/*
|
||||
@@ -625,8 +630,8 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
|
||||
}
|
||||
|
||||
/* GMCH is read-only, emulated */
|
||||
pci_set_long(vdev->pdev.config + IGD_GMCH, gmch);
|
||||
pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0);
|
||||
pci_set_long(pdev->config + IGD_GMCH, gmch);
|
||||
pci_set_long(pdev->wmask + IGD_GMCH, 0);
|
||||
pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0);
|
||||
}
|
||||
|
||||
@@ -635,12 +640,12 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
|
||||
|
||||
/* BDSM is read-write, emulated. BIOS needs to be able to write it */
|
||||
if (gen < 11) {
|
||||
pci_set_long(vdev->pdev.config + IGD_BDSM, 0);
|
||||
pci_set_long(vdev->pdev.wmask + IGD_BDSM, ~0);
|
||||
pci_set_long(pdev->config + IGD_BDSM, 0);
|
||||
pci_set_long(pdev->wmask + IGD_BDSM, ~0);
|
||||
pci_set_long(vdev->emulated_config_bits + IGD_BDSM, ~0);
|
||||
} else {
|
||||
pci_set_quad(vdev->pdev.config + IGD_BDSM_GEN11, 0);
|
||||
pci_set_quad(vdev->pdev.wmask + IGD_BDSM_GEN11, ~0);
|
||||
pci_set_quad(pdev->config + IGD_BDSM_GEN11, 0);
|
||||
pci_set_quad(pdev->wmask + IGD_BDSM_GEN11, ~0);
|
||||
pci_set_quad(vdev->emulated_config_bits + IGD_BDSM_GEN11, ~0);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user