VFIO updates 2018-10-15
- ramfb support for vfio-pci via new -nohotplug device variant (Gerd Hoffmann) - Preparation for generic DT pass-through in vfio-platform (Geert Uytterhoeven & Eric Auger) - vfio-pci QOM fixups (Li Qiang) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQIcBAABAgAGBQJbxM3FAAoJECObm247sIsi2F4P/3V2hpE6YEYHpHWCLZ8ZN1Us WTTubHZJHBweQOTpRZxbby3oyi82f3ybGAFIkd/by8Pta0llOI7uZHJPPpGXe89c 88Dq2IynLB6kOkbTwukxqwAChVQ9aPMc/pTWCP8FWJXWpbU+lL5JjrkNS9eo6NPZ /oWucQu7T6WqOJ96r/luGzOepXMcHJbrxqq7gyLHje+29S1UCu/hclhsefj6dSjx HQgIkn+sK4/mhfjEP5/5MmgzJS2yhxNvtGr7/Qr8m4BThkrjCpEF9SvLYg4E0EDO 6DhjuXEPr81IrCT/ZDPk9rj1rxM7+CiYh9Udfu6vyaj67U2nJNdmShRXnDbQiNEB /pGseF+wYR4WAmd+66vkdpw6AdABDjgx/ReyGZjyDXpTM7ct4WtMcwm2mTFGKyc0 /+OVCro/RmiySgrvUI7uGCL9MvBwPmtyK8kPKt+e2GKnhxJCcH4n8GiK3JiDw9qF w8XMTMzHUsOcQdwpsGoo0ojKjA6yxt82/i0zfV81k/7943y7NySyXa3HEsNe1qhN OXOI8tnWVDsxwnVNytqVxPa5iiob1nTiTXa0TiV9Pk1ZnBMpdM3SZCIWfcd9tgry 1J+sxql+pkVU9p1oBV/oUCnmjrNlMJr4Xj6rcG8S10BDREMna+VXZtmc9SJwwJ2Y WQf417NklqVFjBGnxKNZ =j/tw -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20181015.0' into staging VFIO updates 2018-10-15 - ramfb support for vfio-pci via new -nohotplug device variant (Gerd Hoffmann) - Preparation for generic DT pass-through in vfio-platform (Geert Uytterhoeven & Eric Auger) - vfio-pci QOM fixups (Li Qiang) # gpg: Signature made Mon 15 Oct 2018 18:26:29 BST # gpg: using RSA key 239B9B6E3BB08B22 # gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>" # gpg: aka "Alex Williamson <alex@shazbot.org>" # gpg: aka "Alex Williamson <alwillia@redhat.com>" # gpg: aka "Alex Williamson <alex.l.williamson@gmail.com>" # Primary key fingerprint: 42F6 C04E 540B D1A9 9E7B 8A90 239B 9B6E 3BB0 8B22 * remotes/awilliam/tags/vfio-updates-20181015.0: vfio-pci: make vfio-pci device more QOM conventional hw/arm/virt: Allow dynamic vfio-platform devices again hw/arm/sysbus-fdt: Allow device matching with DT compatible value vfio/platform: Make the vfio-platform device non-abstract hw/vfio/display: add ramfb support stubs: add ramfb Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
dddb37495b
@ -50,11 +50,13 @@ typedef struct PlatformBusFDTData {
|
|||||||
PlatformBusDevice *pbus;
|
PlatformBusDevice *pbus;
|
||||||
} PlatformBusFDTData;
|
} PlatformBusFDTData;
|
||||||
|
|
||||||
/* struct that associates a device type name and a node creation function */
|
/* struct that allows to match a device and create its FDT node */
|
||||||
typedef struct NodeCreationPair {
|
typedef struct BindingEntry {
|
||||||
const char *typename;
|
const char *typename;
|
||||||
int (*add_fdt_node_fn)(SysBusDevice *sbdev, void *opaque);
|
const char *compat;
|
||||||
} NodeCreationPair;
|
int (*add_fn)(SysBusDevice *sbdev, void *opaque);
|
||||||
|
bool (*match_fn)(SysBusDevice *sbdev, const struct BindingEntry *combo);
|
||||||
|
} BindingEntry;
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
|
|
||||||
@ -413,6 +415,27 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
|
|||||||
return 0;
|
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 */
|
#endif /* CONFIG_LINUX */
|
||||||
|
|
||||||
static int no_fdt_node(SysBusDevice *sbdev, void *opaque)
|
static int no_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||||
@ -420,14 +443,23 @@ static int no_fdt_node(SysBusDevice *sbdev, void *opaque)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* list of supported dynamic sysbus devices */
|
/* Device type based matching */
|
||||||
static const NodeCreationPair add_fdt_node_functions[] = {
|
static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry)
|
||||||
|
{
|
||||||
|
return !strcmp(object_get_typename(OBJECT(sbdev)), entry->typename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TYPE_BINDING(type, add_fn) {(type), NULL, (add_fn), type_match}
|
||||||
|
|
||||||
|
/* list of supported dynamic sysbus bindings */
|
||||||
|
static const BindingEntry bindings[] = {
|
||||||
#ifdef CONFIG_LINUX
|
#ifdef CONFIG_LINUX
|
||||||
{TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node},
|
TYPE_BINDING(TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node),
|
||||||
{TYPE_VFIO_AMD_XGBE, add_amd_xgbe_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
|
#endif
|
||||||
{TYPE_RAMFB_DEVICE, no_fdt_node},
|
TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
|
||||||
{"", NULL}, /* last element */
|
TYPE_BINDING("", NULL), /* last element */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Generic Code */
|
/* Generic Code */
|
||||||
@ -446,10 +478,11 @@ static void add_fdt_node(SysBusDevice *sbdev, void *opaque)
|
|||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(add_fdt_node_functions); i++) {
|
for (i = 0; i < ARRAY_SIZE(bindings); i++) {
|
||||||
if (!strcmp(object_get_typename(OBJECT(sbdev)),
|
const BindingEntry *iter = &bindings[i];
|
||||||
add_fdt_node_functions[i].typename)) {
|
|
||||||
ret = add_fdt_node_functions[i].add_fdt_node_fn(sbdev, opaque);
|
if (iter->match_fn(sbdev, iter)) {
|
||||||
|
ret = iter->add_fn(sbdev, opaque);
|
||||||
assert(!ret);
|
assert(!ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1758,6 +1758,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
|
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_VFIO_AMD_XGBE);
|
||||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
||||||
|
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
|
||||||
mc->block_default_type = IF_VIRTIO;
|
mc->block_default_type = IF_VIRTIO;
|
||||||
mc->no_cdrom = 1;
|
mc->no_cdrom = 1;
|
||||||
mc->pci_allow_0_address = true;
|
mc->pci_allow_0_address = true;
|
||||||
|
@ -20,6 +20,7 @@ static void amd_xgbe_realize(DeviceState *dev, Error **errp)
|
|||||||
VFIOAmdXgbeDeviceClass *k = VFIO_AMD_XGBE_DEVICE_GET_CLASS(dev);
|
VFIOAmdXgbeDeviceClass *k = VFIO_AMD_XGBE_DEVICE_GET_CLASS(dev);
|
||||||
|
|
||||||
vdev->compat = g_strdup("amd,xgbe-seattle-v1a");
|
vdev->compat = g_strdup("amd,xgbe-seattle-v1a");
|
||||||
|
vdev->num_compat = 1;
|
||||||
|
|
||||||
k->parent_realize(dev, errp);
|
k->parent_realize(dev, errp);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ static void calxeda_xgmac_realize(DeviceState *dev, Error **errp)
|
|||||||
VFIOCalxedaXgmacDeviceClass *k = VFIO_CALXEDA_XGMAC_DEVICE_GET_CLASS(dev);
|
VFIOCalxedaXgmacDeviceClass *k = VFIO_CALXEDA_XGMAC_DEVICE_GET_CLASS(dev);
|
||||||
|
|
||||||
vdev->compat = g_strdup("calxeda,hb-xgmac");
|
vdev->compat = g_strdup("calxeda,hb-xgmac");
|
||||||
|
vdev->num_compat = 1;
|
||||||
|
|
||||||
k->parent_realize(dev, errp);
|
k->parent_realize(dev, errp);
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,9 @@ static void vfio_display_dmabuf_update(void *opaque)
|
|||||||
|
|
||||||
primary = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_PRIMARY);
|
primary = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_PRIMARY);
|
||||||
if (primary == NULL) {
|
if (primary == NULL) {
|
||||||
|
if (dpy->ramfb) {
|
||||||
|
ramfb_display_update(dpy->con, dpy->ramfb);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +184,9 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)
|
|||||||
vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
|
vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
|
||||||
&vfio_display_dmabuf_ops,
|
&vfio_display_dmabuf_ops,
|
||||||
vdev);
|
vdev);
|
||||||
|
if (vdev->enable_ramfb) {
|
||||||
|
vdev->dpy->ramfb = ramfb_setup(errp);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +234,9 @@ static void vfio_display_region_update(void *opaque)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!plane.drm_format || !plane.size) {
|
if (!plane.drm_format || !plane.size) {
|
||||||
|
if (dpy->ramfb) {
|
||||||
|
ramfb_display_update(dpy->con, dpy->ramfb);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
format = qemu_drm_format_to_pixman(plane.drm_format);
|
format = qemu_drm_format_to_pixman(plane.drm_format);
|
||||||
@ -300,6 +309,9 @@ static int vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp)
|
|||||||
vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
|
vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
|
||||||
&vfio_display_region_ops,
|
&vfio_display_region_ops,
|
||||||
vdev);
|
vdev);
|
||||||
|
if (vdev->enable_ramfb) {
|
||||||
|
vdev->dpy->ramfb = ramfb_setup(errp);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,9 @@
|
|||||||
|
|
||||||
#define MSIX_CAP_LENGTH 12
|
#define MSIX_CAP_LENGTH 12
|
||||||
|
|
||||||
|
#define TYPE_VFIO_PCI "vfio-pci"
|
||||||
|
#define PCI_VFIO(obj) OBJECT_CHECK(VFIOPCIDevice, obj, TYPE_VFIO_PCI)
|
||||||
|
|
||||||
static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
|
static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
|
||||||
static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
|
static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
|
||||||
|
|
||||||
@ -222,7 +225,7 @@ static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev)
|
|||||||
|
|
||||||
static void vfio_intx_update(PCIDevice *pdev)
|
static void vfio_intx_update(PCIDevice *pdev)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
|
||||||
PCIINTxRoute route;
|
PCIINTxRoute route;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
@ -477,7 +480,7 @@ static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg,
|
|||||||
static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
||||||
MSIMessage *msg, IOHandler *handler)
|
MSIMessage *msg, IOHandler *handler)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
|
||||||
VFIOMSIVector *vector;
|
VFIOMSIVector *vector;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -574,7 +577,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
|
|||||||
|
|
||||||
static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
|
static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
|
||||||
VFIOMSIVector *vector = &vdev->msi_vectors[nr];
|
VFIOMSIVector *vector = &vdev->msi_vectors[nr];
|
||||||
|
|
||||||
trace_vfio_msix_vector_release(vdev->vbasedev.name, nr);
|
trace_vfio_msix_vector_release(vdev->vbasedev.name, nr);
|
||||||
@ -1086,7 +1089,7 @@ static const MemoryRegionOps vfio_vga_ops = {
|
|||||||
*/
|
*/
|
||||||
static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
|
static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
|
||||||
VFIORegion *region = &vdev->bars[bar].region;
|
VFIORegion *region = &vdev->bars[bar].region;
|
||||||
MemoryRegion *mmap_mr, *region_mr, *base_mr;
|
MemoryRegion *mmap_mr, *region_mr, *base_mr;
|
||||||
PCIIORegion *r;
|
PCIIORegion *r;
|
||||||
@ -1132,7 +1135,7 @@ static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
|
|||||||
*/
|
*/
|
||||||
uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
|
uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
|
||||||
uint32_t emu_bits = 0, emu_val = 0, phys_val = 0, val;
|
uint32_t emu_bits = 0, emu_val = 0, phys_val = 0, val;
|
||||||
|
|
||||||
memcpy(&emu_bits, vdev->emulated_config_bits + addr, len);
|
memcpy(&emu_bits, vdev->emulated_config_bits + addr, len);
|
||||||
@ -1165,7 +1168,7 @@ uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
|
|||||||
void vfio_pci_write_config(PCIDevice *pdev,
|
void vfio_pci_write_config(PCIDevice *pdev,
|
||||||
uint32_t addr, uint32_t val, int len)
|
uint32_t addr, uint32_t val, int len)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
|
||||||
uint32_t val_le = cpu_to_le32(val);
|
uint32_t val_le = cpu_to_le32(val);
|
||||||
|
|
||||||
trace_vfio_pci_write_config(vdev->vbasedev.name, addr, val, len);
|
trace_vfio_pci_write_config(vdev->vbasedev.name, addr, val, len);
|
||||||
@ -2801,7 +2804,7 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev)
|
|||||||
|
|
||||||
static void vfio_realize(PCIDevice *pdev, Error **errp)
|
static void vfio_realize(PCIDevice *pdev, Error **errp)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
|
||||||
VFIODevice *vbasedev_iter;
|
VFIODevice *vbasedev_iter;
|
||||||
VFIOGroup *group;
|
VFIOGroup *group;
|
||||||
char *tmp, *subsys, group_path[PATH_MAX], *group_name;
|
char *tmp, *subsys, group_path[PATH_MAX], *group_name;
|
||||||
@ -3067,6 +3070,10 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
|
|||||||
goto out_teardown;
|
goto out_teardown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (vdev->enable_ramfb && vdev->dpy == NULL) {
|
||||||
|
error_setg(errp, "ramfb=on requires display=on");
|
||||||
|
goto out_teardown;
|
||||||
|
}
|
||||||
|
|
||||||
vfio_register_err_notifier(vdev);
|
vfio_register_err_notifier(vdev);
|
||||||
vfio_register_req_notifier(vdev);
|
vfio_register_req_notifier(vdev);
|
||||||
@ -3084,8 +3091,7 @@ error:
|
|||||||
|
|
||||||
static void vfio_instance_finalize(Object *obj)
|
static void vfio_instance_finalize(Object *obj)
|
||||||
{
|
{
|
||||||
PCIDevice *pci_dev = PCI_DEVICE(obj);
|
VFIOPCIDevice *vdev = PCI_VFIO(obj);
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pci_dev);
|
|
||||||
VFIOGroup *group = vdev->vbasedev.group;
|
VFIOGroup *group = vdev->vbasedev.group;
|
||||||
|
|
||||||
vfio_display_finalize(vdev);
|
vfio_display_finalize(vdev);
|
||||||
@ -3105,7 +3111,7 @@ static void vfio_instance_finalize(Object *obj)
|
|||||||
|
|
||||||
static void vfio_exitfn(PCIDevice *pdev)
|
static void vfio_exitfn(PCIDevice *pdev)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
VFIOPCIDevice *vdev = PCI_VFIO(pdev);
|
||||||
|
|
||||||
vfio_unregister_req_notifier(vdev);
|
vfio_unregister_req_notifier(vdev);
|
||||||
vfio_unregister_err_notifier(vdev);
|
vfio_unregister_err_notifier(vdev);
|
||||||
@ -3120,8 +3126,7 @@ static void vfio_exitfn(PCIDevice *pdev)
|
|||||||
|
|
||||||
static void vfio_pci_reset(DeviceState *dev)
|
static void vfio_pci_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev);
|
VFIOPCIDevice *vdev = PCI_VFIO(dev);
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
|
||||||
|
|
||||||
trace_vfio_pci_reset(vdev->vbasedev.name);
|
trace_vfio_pci_reset(vdev->vbasedev.name);
|
||||||
|
|
||||||
@ -3161,7 +3166,7 @@ post_reset:
|
|||||||
static void vfio_instance_init(Object *obj)
|
static void vfio_instance_init(Object *obj)
|
||||||
{
|
{
|
||||||
PCIDevice *pci_dev = PCI_DEVICE(obj);
|
PCIDevice *pci_dev = PCI_DEVICE(obj);
|
||||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, PCI_DEVICE(obj));
|
VFIOPCIDevice *vdev = PCI_VFIO(obj);
|
||||||
|
|
||||||
device_add_bootindex_property(obj, &vdev->bootindex,
|
device_add_bootindex_property(obj, &vdev->bootindex,
|
||||||
"bootindex", NULL,
|
"bootindex", NULL,
|
||||||
@ -3245,7 +3250,7 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo vfio_pci_dev_info = {
|
static const TypeInfo vfio_pci_dev_info = {
|
||||||
.name = "vfio-pci",
|
.name = TYPE_VFIO_PCI,
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(VFIOPCIDevice),
|
.instance_size = sizeof(VFIOPCIDevice),
|
||||||
.class_init = vfio_pci_dev_class_init,
|
.class_init = vfio_pci_dev_class_init,
|
||||||
@ -3258,9 +3263,30 @@ static const TypeInfo vfio_pci_dev_info = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Property vfio_pci_dev_nohotplug_properties[] = {
|
||||||
|
DEFINE_PROP_BOOL("ramfb", VFIOPCIDevice, enable_ramfb, false),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void vfio_pci_nohotplug_dev_class_init(ObjectClass *klass, void *data)
|
||||||
|
{
|
||||||
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
|
dc->props = vfio_pci_dev_nohotplug_properties;
|
||||||
|
dc->hotpluggable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo vfio_pci_nohotplug_dev_info = {
|
||||||
|
.name = "vfio-pci-nohotplug",
|
||||||
|
.parent = "vfio-pci",
|
||||||
|
.instance_size = sizeof(VFIOPCIDevice),
|
||||||
|
.class_init = vfio_pci_nohotplug_dev_class_init,
|
||||||
|
};
|
||||||
|
|
||||||
static void register_vfio_pci_dev_type(void)
|
static void register_vfio_pci_dev_type(void)
|
||||||
{
|
{
|
||||||
type_register_static(&vfio_pci_dev_info);
|
type_register_static(&vfio_pci_dev_info);
|
||||||
|
type_register_static(&vfio_pci_nohotplug_dev_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
type_init(register_vfio_pci_dev_type)
|
type_init(register_vfio_pci_dev_type)
|
||||||
|
@ -165,6 +165,7 @@ typedef struct VFIOPCIDevice {
|
|||||||
bool no_geforce_quirks;
|
bool no_geforce_quirks;
|
||||||
bool no_kvm_ioeventfd;
|
bool no_kvm_ioeventfd;
|
||||||
bool no_vfio_ioeventfd;
|
bool no_vfio_ioeventfd;
|
||||||
|
bool enable_ramfb;
|
||||||
VFIODisplay *dpy;
|
VFIODisplay *dpy;
|
||||||
} VFIOPCIDevice;
|
} VFIOPCIDevice;
|
||||||
|
|
||||||
|
@ -655,6 +655,28 @@ static void vfio_platform_realize(DeviceState *dev, Error **errp)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!vdev->compat) {
|
||||||
|
GError *gerr = NULL;
|
||||||
|
gchar *contents;
|
||||||
|
gsize length;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
path = g_strdup_printf("%s/of_node/compatible", vbasedev->sysfsdev);
|
||||||
|
if (!g_file_get_contents(path, &contents, &length, &gerr)) {
|
||||||
|
error_setg(errp, "%s", gerr->message);
|
||||||
|
g_error_free(gerr);
|
||||||
|
g_free(path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_free(path);
|
||||||
|
vdev->compat = contents;
|
||||||
|
for (vdev->num_compat = 0; length; vdev->num_compat++) {
|
||||||
|
size_t skip = strlen(contents) + 1;
|
||||||
|
contents += skip;
|
||||||
|
length -= skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < vbasedev->num_regions; i++) {
|
for (i = 0; i < vbasedev->num_regions; i++) {
|
||||||
if (vfio_region_mmap(vdev->regions[i])) {
|
if (vfio_region_mmap(vdev->regions[i])) {
|
||||||
error_report("%s mmap unsupported. Performance may be slow",
|
error_report("%s mmap unsupported. Performance may be slow",
|
||||||
@ -700,6 +722,8 @@ static void vfio_platform_class_init(ObjectClass *klass, void *data)
|
|||||||
dc->desc = "VFIO-based platform device assignment";
|
dc->desc = "VFIO-based platform device assignment";
|
||||||
sbc->connect_irq_notifier = vfio_start_irqfd_injection;
|
sbc->connect_irq_notifier = vfio_start_irqfd_injection;
|
||||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||||
|
/* Supported by TYPE_VIRT_MACHINE */
|
||||||
|
dc->user_creatable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo vfio_platform_dev_info = {
|
static const TypeInfo vfio_platform_dev_info = {
|
||||||
@ -708,7 +732,6 @@ static const TypeInfo vfio_platform_dev_info = {
|
|||||||
.instance_size = sizeof(VFIOPlatformDevice),
|
.instance_size = sizeof(VFIOPlatformDevice),
|
||||||
.class_init = vfio_platform_class_init,
|
.class_init = vfio_platform_class_init,
|
||||||
.class_size = sizeof(VFIOPlatformDeviceClass),
|
.class_size = sizeof(VFIOPlatformDeviceClass),
|
||||||
.abstract = true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void register_vfio_platform_dev_type(void)
|
static void register_vfio_platform_dev_type(void)
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include "qemu/notify.h"
|
#include "qemu/notify.h"
|
||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
|
#include "hw/display/ramfb.h"
|
||||||
#ifdef CONFIG_LINUX
|
#ifdef CONFIG_LINUX
|
||||||
#include <linux/vfio.h>
|
#include <linux/vfio.h>
|
||||||
#endif
|
#endif
|
||||||
@ -147,6 +148,7 @@ typedef struct VFIODMABuf {
|
|||||||
|
|
||||||
typedef struct VFIODisplay {
|
typedef struct VFIODisplay {
|
||||||
QemuConsole *con;
|
QemuConsole *con;
|
||||||
|
RAMFBState *ramfb;
|
||||||
struct {
|
struct {
|
||||||
VFIORegion buffer;
|
VFIORegion buffer;
|
||||||
DisplaySurface *surface;
|
DisplaySurface *surface;
|
||||||
|
@ -54,7 +54,8 @@ typedef struct VFIOPlatformDevice {
|
|||||||
QLIST_HEAD(, VFIOINTp) intp_list; /* list of IRQs */
|
QLIST_HEAD(, VFIOINTp) intp_list; /* list of IRQs */
|
||||||
/* queue of pending IRQs */
|
/* queue of pending IRQs */
|
||||||
QSIMPLEQ_HEAD(pending_intp_queue, VFIOINTp) pending_intp_queue;
|
QSIMPLEQ_HEAD(pending_intp_queue, VFIOINTp) pending_intp_queue;
|
||||||
char *compat; /* compatibility string */
|
char *compat; /* DT compatible values, separated by NUL */
|
||||||
|
unsigned int num_compat; /* number of compatible values */
|
||||||
uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
|
uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
|
||||||
QEMUTimer *mmap_timer; /* allows fast-path resume after IRQ hit */
|
QEMUTimer *mmap_timer; /* allows fast-path resume after IRQ hit */
|
||||||
QemuMutex intp_mutex; /* protect the intp_list IRQ state */
|
QemuMutex intp_mutex; /* protect the intp_list IRQ state */
|
||||||
|
@ -43,3 +43,4 @@ stub-obj-y += xen-common.o
|
|||||||
stub-obj-y += xen-hvm.o
|
stub-obj-y += xen-hvm.o
|
||||||
stub-obj-y += pci-host-piix.o
|
stub-obj-y += pci-host-piix.o
|
||||||
stub-obj-y += ram-block.o
|
stub-obj-y += ram-block.o
|
||||||
|
stub-obj-y += ramfb.o
|
||||||
|
13
stubs/ramfb.c
Normal file
13
stubs/ramfb.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
|
#include "hw/display/ramfb.h"
|
||||||
|
|
||||||
|
void ramfb_display_update(QemuConsole *con, RAMFBState *s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RAMFBState *ramfb_setup(Error **errp)
|
||||||
|
{
|
||||||
|
error_setg(errp, "ramfb support not available");
|
||||||
|
return NULL;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user