vfio/platform: Make the vfio-platform device non-abstract
Up to now the vfio-platform device has been abstract and could not be instantiated. The integration of a new vfio platform device required creating a dummy derived device which only set the compatible string. Following the few vfio-platform device integrations we have seen the actual requested adaptation happens on device tree node creation (sysbus-fdt). Hence remove the abstract setting, and read the list of compatible values from sysfs if not set by a derived device. Update the amd-xgbe and calxeda-xgmac drivers to fill in the number of compatible values, as there can now be more than one. Note that sysbus-fdt does not support the instantiation of the vfio-platform device yet. Signed-off-by: Eric Auger <eric.auger@redhat.com> [geert: Rebase, set user_creatable=true, use compatible values in sysfs instead of user-supplied manufacturer/model options, reword] Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Eric Auger <eric.auger@redhat.com> Tested-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
b290659fc3
commit
a49531ebd0
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user