Skip to content

Commit

Permalink
qdev: Use GList for global properties
Browse files Browse the repository at this point in the history
If the same GlobalProperty struct is registered twice, the list
entry gets corrupted, making tqe_next points to itself, and
qdev_prop_set_globals() gets stuck in a loop. The bug can be
easily reproduced by running:

  $ qemu-system-x86_64 -rtc-td-hack -rtc-td-hack

Change global_props to use GList instead of queue.h, making the
code simpler and able to deal with properties being registered
twice.

Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
  • Loading branch information
ehabkost committed Jun 17, 2016
1 parent 4acc8fd commit f9a8b55
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 8 deletions.
15 changes: 8 additions & 7 deletions hw/core/qdev-properties.c
Expand Up @@ -1020,12 +1020,11 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
*ptr = value;
}

static QTAILQ_HEAD(, GlobalProperty) global_props =
QTAILQ_HEAD_INITIALIZER(global_props);
static GList *global_props;

void qdev_prop_register_global(GlobalProperty *prop)
{
QTAILQ_INSERT_TAIL(&global_props, prop, next);
global_props = g_list_append(global_props, prop);
}

void qdev_prop_register_global_list(GlobalProperty *props)
Expand All @@ -1039,10 +1038,11 @@ void qdev_prop_register_global_list(GlobalProperty *props)

int qdev_prop_check_globals(void)
{
GlobalProperty *prop;
GList *l;
int ret = 0;

QTAILQ_FOREACH(prop, &global_props, next) {
for (l = global_props; l; l = l->next) {
GlobalProperty *prop = l->data;
ObjectClass *oc;
DeviceClass *dc;
if (prop->used) {
Expand Down Expand Up @@ -1073,9 +1073,10 @@ int qdev_prop_check_globals(void)
static void qdev_prop_set_globals_for_type(DeviceState *dev,
const char *typename)
{
GlobalProperty *prop;
GList *l;

QTAILQ_FOREACH(prop, &global_props, next) {
for (l = global_props; l; l = l->next) {
GlobalProperty *prop = l->data;
Error *err = NULL;

if (strcmp(typename, prop->driver) != 0) {
Expand Down
1 change: 0 additions & 1 deletion include/hw/qdev-core.h
Expand Up @@ -266,7 +266,6 @@ typedef struct GlobalProperty {
const char *value;
bool user_provided;
bool used;
QTAILQ_ENTRY(GlobalProperty) next;
} GlobalProperty;

/*** Board API. This should go away once we have a machine config file. ***/
Expand Down

0 comments on commit f9a8b55

Please sign in to comment.