hw/arm/allwinner-a10: Do not use nd_table in instance_init function
The instance_init function of a device can be called at any time, even
if the device is not going to be used (i.e. not going to be realized).
So a instance_init function must not do things that could cause QEMU
to exit, like calling qemu_check_nic_model(&nd_table[0], ...) for example.
But this is what the instance_init function of the allwinner-a10 device
is currently doing - and this causes QEMU to quit unexpectedly when
you run the 'device-list-properties' QMP command for example:
$ echo "{'execute':'qmp_capabilities'}"\
       "{'execute':'device-list-properties',"\
       " 'arguments':{'typename':'allwinner-a10'}}" \
       | arm-softmmu/qemu-system-arm -M mps2-an505,accel=qtest -qmp stdio
{"QMP": {"version": {"qemu": {"micro": 91, "minor": 11, "major": 2},
 "package": "build-all"}, "capabilities": []}}
{"return": {}}
Unsupported NIC model: lan9118
... and QEMU quits after printing the last line (which should not happen
just because of running 'device-list-properties' here).
And with the cubieboard, this even causes QEMU to abort():
$ echo "{'execute':'qmp_capabilities'}"\
       "{'execute':'device-list-properties',"\
       " 'arguments':{'typename':'allwinner-a10'}}" \
       | arm-softmmu/qemu-system-arm -M cubieboard,accel=qtest -qmp stdio
{"QMP": {"version": {"qemu": {"micro": 91, "minor": 11, "major": 2},
 "package": "build-all"}, "capabilities": []}}
{"return": {}}
Unexpected error in error_set_from_qdev_prop_error() at hw/core/qdev-properties.c:1095:
Property 'allwinner-emac.netdev' can't take value 'hub0port0', it's in use
Aborted (core dumped)
To fix the problem we've got to move the offending code to the realize
function instead.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-id: 1522862420-7484-1-git-send-email-thuth@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
			
			
This commit is contained in:
		
							parent
							
								
									f3d9fe8f95
								
							
						
					
					
						commit
						8aabc5437b
					
				@ -38,11 +38,6 @@ static void aw_a10_init(Object *obj)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    object_initialize(&s->emac, sizeof(s->emac), TYPE_AW_EMAC);
 | 
					    object_initialize(&s->emac, sizeof(s->emac), TYPE_AW_EMAC);
 | 
				
			||||||
    qdev_set_parent_bus(DEVICE(&s->emac), sysbus_get_default());
 | 
					    qdev_set_parent_bus(DEVICE(&s->emac), sysbus_get_default());
 | 
				
			||||||
    /* FIXME use qdev NIC properties instead of nd_table[] */
 | 
					 | 
				
			||||||
    if (nd_table[0].used) {
 | 
					 | 
				
			||||||
        qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
 | 
					 | 
				
			||||||
        qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object_initialize(&s->sata, sizeof(s->sata), TYPE_ALLWINNER_AHCI);
 | 
					    object_initialize(&s->sata, sizeof(s->sata), TYPE_ALLWINNER_AHCI);
 | 
				
			||||||
    qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
 | 
					    qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
 | 
				
			||||||
@ -91,6 +86,11 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
 | 
				
			|||||||
    sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
 | 
					    sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
 | 
				
			||||||
    sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
 | 
					    sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* FIXME use qdev NIC properties instead of nd_table[] */
 | 
				
			||||||
 | 
					    if (nd_table[0].used) {
 | 
				
			||||||
 | 
					        qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
 | 
				
			||||||
 | 
					        qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    object_property_set_bool(OBJECT(&s->emac), true, "realized", &err);
 | 
					    object_property_set_bool(OBJECT(&s->emac), true, "realized", &err);
 | 
				
			||||||
    if (err != NULL) {
 | 
					    if (err != NULL) {
 | 
				
			||||||
        error_propagate(errp, err);
 | 
					        error_propagate(errp, err);
 | 
				
			||||||
@ -118,7 +118,7 @@ static void aw_a10_class_init(ObjectClass *oc, void *data)
 | 
				
			|||||||
    DeviceClass *dc = DEVICE_CLASS(oc);
 | 
					    DeviceClass *dc = DEVICE_CLASS(oc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dc->realize = aw_a10_realize;
 | 
					    dc->realize = aw_a10_realize;
 | 
				
			||||||
    /* Reason: Uses serial_hds in realize and nd_table in instance_init */
 | 
					    /* Reason: Uses serial_hds and nd_table in realize function */
 | 
				
			||||||
    dc->user_creatable = false;
 | 
					    dc->user_creatable = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user