qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

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: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20200630090351.1247703-19-armbru@redhat.com>

+5 -9
+5 -9
hw/riscv/riscv_hart.c
··· 40 40 cpu_reset(CPU(cpu)); 41 41 } 42 42 43 - static void riscv_hart_realize(RISCVHartArrayState *s, int idx, 43 + static bool riscv_hart_realize(RISCVHartArrayState *s, int idx, 44 44 char *cpu_type, Error **errp) 45 45 { 46 - Error *err = NULL; 47 - 48 46 object_initialize_child(OBJECT(s), "harts[*]", &s->harts[idx], cpu_type); 49 47 s->harts[idx].env.mhartid = s->hartid_base + idx; 50 48 qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]); 51 - qdev_realize(DEVICE(&s->harts[idx]), NULL, &err); 52 - if (err) { 53 - error_propagate(errp, err); 54 - return; 55 - } 49 + return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp); 56 50 } 57 51 58 52 static void riscv_harts_realize(DeviceState *dev, Error **errp) ··· 63 57 s->harts = g_new0(RISCVCPU, s->num_harts); 64 58 65 59 for (n = 0; n < s->num_harts; n++) { 66 - riscv_hart_realize(s, n, s->cpu_type, errp); 60 + if (!riscv_hart_realize(s, n, s->cpu_type, errp)) { 61 + return; 62 + } 67 63 } 68 64 } 69 65