Message ID | 20180927115454.31471-3-geert+renesas@glider.be (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | vfio/sysbus-fdt: Prepare for Generic DT Pass-Through | expand |
On 2018-09-27 13:54, Geert Uytterhoeven wrote: > From: Auger Eric <eric.auger@redhat.com> > > Up to now we have relied on the device type to identify a device tree > node creation function. Since we would like the vfio-platform device to > be instantiable with different compatible strings we introduce the > capability to specialize the node creation depending on actual > compatible value. > > NodeCreationPair is renamed into BindingEntry. The struct is enhanced > with compat and match_fn() fields. We introduce a new matching function > adapted to the vfio-platform generic device. > > Soon, the AMD XGBE can be instantiated with either manner, i.e.: > > -device vfio-amd-xgbe,host=e0900000.xgmac > > or using the new option line: > > -device vfio-platform,host=e0900000.xgmac > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > [geert: Match using 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> scripts/device-crash-test reports a new "crash" with current QEMU master branch, where QEMU aborts like this: aarch64-softmmu/qemu-system-aarch64 -S -machine virt-2.9,accel=tcg -device ramfb hw/arm/sysbus-fdt.c:422:vfio_platform_match: Object 0x564cf9ae8f80 is not an instance of type vfio-platform Aborted (core dumped) I think it is likely due to this patch here ... any chance that you could make this a little bit more user friendly instead of aborting the hard way here? Thanks, Thomas
Hi Thomas, On 11/5/18 10:17 AM, Thomas Huth wrote: > On 2018-09-27 13:54, Geert Uytterhoeven wrote: >> From: Auger Eric <eric.auger@redhat.com> >> >> Up to now we have relied on the device type to identify a device tree >> node creation function. Since we would like the vfio-platform device to >> be instantiable with different compatible strings we introduce the >> capability to specialize the node creation depending on actual >> compatible value. >> >> NodeCreationPair is renamed into BindingEntry. The struct is enhanced >> with compat and match_fn() fields. We introduce a new matching function >> adapted to the vfio-platform generic device. >> >> Soon, the AMD XGBE can be instantiated with either manner, i.e.: >> >> -device vfio-amd-xgbe,host=e0900000.xgmac >> >> or using the new option line: >> >> -device vfio-platform,host=e0900000.xgmac >> >> Signed-off-by: Eric Auger <eric.auger@redhat.com> >> [geert: Match using 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> > > scripts/device-crash-test reports a new "crash" with current QEMU master > branch, where QEMU aborts like this: > > aarch64-softmmu/qemu-system-aarch64 -S -machine virt-2.9,accel=tcg > -device ramfb > hw/arm/sysbus-fdt.c:422:vfio_platform_match: Object 0x564cf9ae8f80 is > not an instance of type vfio-platform > Aborted (core dumped) > > I think it is likely due to this patch here ... any chance that you > could make this a little bit more user friendly instead of aborting the > hard way here? thank you for spotting the bug. We should use object_dynamic_cast() to test if the device is a VFIO_PLATFORM one. I will prepare a patch. Thanks Eric > > Thanks, > Thomas >
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c index 43d6a7bb48ddc351..0e24c803a1c2c734 100644 --- a/hw/arm/sysbus-fdt.c +++ b/hw/arm/sysbus-fdt.c @@ -50,11 +50,13 @@ typedef struct PlatformBusFDTData { PlatformBusDevice *pbus; } PlatformBusFDTData; -/* struct that associates a device type name and a node creation function */ -typedef struct NodeCreationPair { +/* struct that allows to match a device and create its FDT node */ +typedef struct BindingEntry { const char *typename; - int (*add_fdt_node_fn)(SysBusDevice *sbdev, void *opaque); -} NodeCreationPair; + const char *compat; + int (*add_fn)(SysBusDevice *sbdev, void *opaque); + bool (*match_fn)(SysBusDevice *sbdev, const struct BindingEntry *combo); +} BindingEntry; /* helpers */ @@ -413,6 +415,27 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque) 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 */ static int no_fdt_node(SysBusDevice *sbdev, void *opaque) @@ -420,14 +443,23 @@ static int no_fdt_node(SysBusDevice *sbdev, void *opaque) return 0; } -/* list of supported dynamic sysbus devices */ -static const NodeCreationPair add_fdt_node_functions[] = { +/* Device type based matching */ +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 - {TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node}, - {TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node}, + 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 - {TYPE_RAMFB_DEVICE, no_fdt_node}, - {"", NULL}, /* last element */ + TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node), + TYPE_BINDING("", NULL), /* last element */ }; /* Generic Code */ @@ -446,10 +478,11 @@ static void add_fdt_node(SysBusDevice *sbdev, void *opaque) { int i, ret; - for (i = 0; i < ARRAY_SIZE(add_fdt_node_functions); i++) { - if (!strcmp(object_get_typename(OBJECT(sbdev)), - add_fdt_node_functions[i].typename)) { - ret = add_fdt_node_functions[i].add_fdt_node_fn(sbdev, opaque); + for (i = 0; i < ARRAY_SIZE(bindings); i++) { + const BindingEntry *iter = &bindings[i]; + + if (iter->match_fn(sbdev, iter)) { + ret = iter->add_fn(sbdev, opaque); assert(!ret); return; }