From c75304a13906e2a91752a12ef90e31ab18467453 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 3 Dec 2015 17:37:38 +0100 Subject: spapr_drc: Handle visitor errors properly Since prop_get_fdt() is only used with QmpOutputVisitor, errors shouldn't actually happen, so this is only a latent bug. Signed-off-by: Markus Armbruster Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index f34bc04..4e7a1d3 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -254,6 +254,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj); + Error *err = NULL; int fdt_offset_next, fdt_offset, fdt_depth; void *fdt; @@ -276,24 +277,43 @@ static void prop_get_fdt(Object *obj, Visitor *v, void *opaque, case FDT_BEGIN_NODE: fdt_depth++; name = fdt_get_name(fdt, fdt_offset, &name_len); - visit_start_struct(v, NULL, NULL, name, 0, NULL); + visit_start_struct(v, NULL, NULL, name, 0, &err); + if (err) { + error_propagate(errp, err); + return; + } break; case FDT_END_NODE: /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */ g_assert(fdt_depth > 0); - visit_end_struct(v, NULL); + visit_end_struct(v, &err); + if (err) { + error_propagate(errp, err); + return; + } fdt_depth--; break; case FDT_PROP: { int i; prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len); name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); - visit_start_list(v, name, NULL); + visit_start_list(v, name, &err); + if (err) { + error_propagate(errp, err); + return; + } for (i = 0; i < prop_len; i++) { - visit_type_uint8(v, (uint8_t *)&prop->data[i], NULL, NULL); - + visit_type_uint8(v, (uint8_t *)&prop->data[i], NULL, &err); + if (err) { + error_propagate(errp, err); + return; + } + } + visit_end_list(v, &err); + if (err) { + error_propagate(errp, err); + return; } - visit_end_list(v, NULL); break; } default: -- cgit v1.1 From c401ae8c9cd4e335dca59661f2849e7a26b5eb31 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 3 Dec 2015 17:37:40 +0100 Subject: spapr_drc: Make device "spapr-dr-connector" unavailable with -device It should only be created via spapr_dr_connector_new(). Attempting to create it with -device crashes. Signed-off-by: Markus Armbruster Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 4e7a1d3..404fb3c 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -594,6 +594,10 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data) drck->attach = attach; drck->detach = detach; drck->release_pending = release_pending; + /* + * Reason: it crashes FIXME find and document the real reason + */ + dk->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo spapr_dr_connector_info = { -- cgit v1.1 From ab8bf1d735133df5b5847bef0b0bea496d614a5a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 3 Dec 2015 17:37:39 +0100 Subject: spapr_drc: Change value of property "fdt" from null back to {} prop_get_fdt() misuses the visitor API: when fdt is null, it doesn't visit anything. object_property_get_qobject() happily object_property_get_qobject(). Amazingly, the latter survives the misuse. Turns out we've papered over it long before prop_get_fdt() existed, in commit 1d10b44. However, commit 6c2f9a1 changed how we paper over it, and as a side effect changed qom-get's value from {} to null. Change it right back by fixing the visitor misuse. Signed-off-by: Markus Armbruster Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 404fb3c..8be62c3 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -259,6 +259,11 @@ static void prop_get_fdt(Object *obj, Visitor *v, void *opaque, void *fdt; if (!drc->fdt) { + visit_start_struct(v, NULL, NULL, name, 0, &err); + if (!err) { + visit_end_struct(v, &err); + } + error_propagate(errp, err); return; } -- cgit v1.1