Commit 3e9a88c3 authored by Markus Armbruster's avatar Markus Armbruster
Browse files

riscv_hart: Fix riscv_harts_realize() error API violations



The Error ** argument must be NULL, &error_abort, &error_fatal, or a
pointer to a variable containing NULL.  Passing an argument of the
latter kind twice without clearing it in between is wrong: if the
first call sets an error, it no longer points to NULL for the second
call.

riscv_harts_realize() is wrong that way: it passes @errp to
riscv_hart_realize() in a loop.  I can't tell offhand whether this can
fail.

Fix by checking for failure in each iteration.

Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: qemu-riscv@nongnu.org
Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Reviewed-by: default avatarAlistair Francis <alistair.francis@wdc.com>
Message-Id: <20200630090351.1247703-19-armbru@redhat.com>
parent cbe3a8c5
Loading
Loading
Loading
Loading
+5 −9
Original line number Diff line number Diff line
@@ -40,19 +40,13 @@ static void riscv_harts_cpu_reset(void *opaque)
    cpu_reset(CPU(cpu));
}

static void riscv_hart_realize(RISCVHartArrayState *s, int idx,
static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
                               char *cpu_type, Error **errp)
{
    Error *err = NULL;

    object_initialize_child(OBJECT(s), "harts[*]", &s->harts[idx], cpu_type);
    s->harts[idx].env.mhartid = s->hartid_base + idx;
    qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
    qdev_realize(DEVICE(&s->harts[idx]), NULL, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp);
}

static void riscv_harts_realize(DeviceState *dev, Error **errp)
@@ -63,7 +57,9 @@ static void riscv_harts_realize(DeviceState *dev, Error **errp)
    s->harts = g_new0(RISCVCPU, s->num_harts);

    for (n = 0; n < s->num_harts; n++) {
        riscv_hart_realize(s, n, s->cpu_type, errp);
        if (!riscv_hart_realize(s, n, s->cpu_type, errp)) {
            return;
        }
    }
}