* [PATCH 0/2] arm: Fix two minor coverity issues @ 2023-05-12 17:02 Peter Maydell 2023-05-12 17:02 ` [PATCH 1/2] target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing Peter Maydell 2023-05-12 17:02 ` [PATCH 2/2] hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' Peter Maydell 0 siblings, 2 replies; 6+ messages in thread From: Peter Maydell @ 2023-05-12 17:02 UTC (permalink / raw) To: qemu-arm, qemu-devel This patchset fixes two minor Coverity issues which are entirely unrelated apart from both being in arm target code. thanks -- PMM Peter Maydell (2): target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' hw/arm/vexpress.c | 40 ++++++++++++++++++++-------------------- target/arm/cortex-regs.c | 11 +++++++++-- 2 files changed, 29 insertions(+), 22 deletions(-) -- 2.34.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing 2023-05-12 17:02 [PATCH 0/2] arm: Fix two minor coverity issues Peter Maydell @ 2023-05-12 17:02 ` Peter Maydell 2023-05-14 9:35 ` Richard Henderson 2023-05-12 17:02 ` [PATCH 2/2] hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' Peter Maydell 1 sibling, 1 reply; 6+ messages in thread From: Peter Maydell @ 2023-05-12 17:02 UTC (permalink / raw) To: qemu-arm, qemu-devel The IMPDEF sysreg L2CTLR_EL1 found on the Cortex-A35, A53, A57, A72 and which we (arguably dubiously) also provide in '-cpu max' has a 2 bit field for the number of processors in the cluster. On real hardware this must be sufficient because it can only be configured with up to 4 CPUs in the cluster. However on QEMU if the board code does not explicitly configure the code into clusters with the right CPU count we default to "give the value assuming that all CPUs in the system are in a single cluster", which might be too big to fit in the field. Instead of just overflowing this 2-bit field, saturate to 3 (meaning "4 CPUs", so at least we don't overwrite other fields in the register. It's unlikely that any guest code really cares about the value in this field; at least, if it does it probably also wants the system to be more closely matching real hardware, i.e. not to have more than 4 CPUs. This issue has been present since the L2CTLR was first added in commit 377a44ec8f2fac5b back in 2014. It was only noticed because Coverity complains (CID 1509227) that the shift might overflow 32 bits and inadvertently sign extend into the top half of the 64 bit value. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/cortex-regs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/target/arm/cortex-regs.c b/target/arm/cortex-regs.c index 17708480e75..ae817b08ddf 100644 --- a/target/arm/cortex-regs.c +++ b/target/arm/cortex-regs.c @@ -15,8 +15,15 @@ static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) { ARMCPU *cpu = env_archcpu(env); - /* Number of cores is in [25:24]; otherwise we RAZ */ - return (cpu->core_count - 1) << 24; + /* + * Number of cores is in [25:24]; otherwise we RAZ. + * If the board didn't configure the CPUs into clusters, + * we default to "all CPUs in one cluster", which might be + * more than the 4 that the hardware permits and which is + * all you can report in this two-bit field. Saturate to + * 0b11 (== 4 CPUs) rather than overflowing the field. + */ + return MIN(cpu->core_count - 1, 3) << 24; } static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = { -- 2.34.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing 2023-05-12 17:02 ` [PATCH 1/2] target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing Peter Maydell @ 2023-05-14 9:35 ` Richard Henderson 0 siblings, 0 replies; 6+ messages in thread From: Richard Henderson @ 2023-05-14 9:35 UTC (permalink / raw) To: Peter Maydell, qemu-arm, qemu-devel On 5/12/23 10:02, Peter Maydell wrote: > The IMPDEF sysreg L2CTLR_EL1 found on the Cortex-A35, A53, A57, A72 > and which we (arguably dubiously) also provide in '-cpu max' has a > 2 bit field for the number of processors in the cluster. On real > hardware this must be sufficient because it can only be configured > with up to 4 CPUs in the cluster. However on QEMU if the board code > does not explicitly configure the code into clusters with the right > CPU count we default to "give the value assuming that all CPUs in > the system are in a single cluster", which might be too big to fit > in the field. > > Instead of just overflowing this 2-bit field, saturate to 3 (meaning > "4 CPUs", so at least we don't overwrite other fields in the register. > It's unlikely that any guest code really cares about the value in > this field; at least, if it does it probably also wants the system > to be more closely matching real hardware, i.e. not to have more > than 4 CPUs. > > This issue has been present since the L2CTLR was first added in > commit 377a44ec8f2fac5b back in 2014. It was only noticed because > Coverity complains (CID 1509227) that the shift might overflow 32 bits > and inadvertently sign extend into the top half of the 64 bit value. > > Signed-off-by: Peter Maydell<peter.maydell@linaro.org> > --- > target/arm/cortex-regs.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~ ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' 2023-05-12 17:02 [PATCH 0/2] arm: Fix two minor coverity issues Peter Maydell 2023-05-12 17:02 ` [PATCH 1/2] target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing Peter Maydell @ 2023-05-12 17:02 ` Peter Maydell 2023-05-14 9:38 ` Richard Henderson 2023-05-15 7:09 ` Philippe Mathieu-Daudé 1 sibling, 2 replies; 6+ messages in thread From: Peter Maydell @ 2023-05-12 17:02 UTC (permalink / raw) To: qemu-arm, qemu-devel In the vexpress board code, we allocate a new MemoryRegion at the top of vexpress_common_init() but only set it up and use it inside the "if (map[VE_NORFLASHALIAS] != -1)" conditional, so we leak it if not. This isn't a very interesting leak as it's a tiny amount of memory once at startup, but it's easy to fix. We could silence Coverity simply by moving the g_new() into the if() block, but this use of g_new(MemoryRegion, 1) is a legacy from when this board model was originally written; we wouldn't do that if we wrote it today. The MemoryRegions are conceptually a part of the board and must not go away until the whole board is done with (at the end of the simulation), so they belong in its state struct. This machine already has a VexpressMachineState struct that extends MachineState, so statically put the MemoryRegions in there instead of dynamically allocating them separately at runtime. Spotted by Coverity (CID 1509083). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/vexpress.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 34b012b528b..56abadd9b8b 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -173,6 +173,11 @@ struct VexpressMachineClass { struct VexpressMachineState { MachineState parent; + MemoryRegion vram; + MemoryRegion sram; + MemoryRegion flashalias; + MemoryRegion lowram; + MemoryRegion a15sram; bool secure; bool virt; }; @@ -182,7 +187,7 @@ struct VexpressMachineState { #define TYPE_VEXPRESS_A15_MACHINE MACHINE_TYPE_NAME("vexpress-a15") OBJECT_DECLARE_TYPE(VexpressMachineState, VexpressMachineClass, VEXPRESS_MACHINE) -typedef void DBoardInitFn(const VexpressMachineState *machine, +typedef void DBoardInitFn(VexpressMachineState *machine, ram_addr_t ram_size, const char *cpu_type, qemu_irq *pic); @@ -263,14 +268,13 @@ static void init_cpus(MachineState *ms, const char *cpu_type, } } -static void a9_daughterboard_init(const VexpressMachineState *vms, +static void a9_daughterboard_init(VexpressMachineState *vms, ram_addr_t ram_size, const char *cpu_type, qemu_irq *pic) { MachineState *machine = MACHINE(vms); MemoryRegion *sysmem = get_system_memory(); - MemoryRegion *lowram = g_new(MemoryRegion, 1); ram_addr_t low_ram_size; if (ram_size > 0x40000000) { @@ -287,9 +291,9 @@ static void a9_daughterboard_init(const VexpressMachineState *vms, * address space should in theory be remappable to various * things including ROM or RAM; we always map the RAM there. */ - memory_region_init_alias(lowram, NULL, "vexpress.lowmem", machine->ram, - 0, low_ram_size); - memory_region_add_subregion(sysmem, 0x0, lowram); + memory_region_init_alias(&vms->lowram, NULL, "vexpress.lowmem", + machine->ram, 0, low_ram_size); + memory_region_add_subregion(sysmem, 0x0, &vms->lowram); memory_region_add_subregion(sysmem, 0x60000000, machine->ram); /* 0x1e000000 A9MPCore (SCU) private memory region */ @@ -348,14 +352,13 @@ static VEDBoardInfo a9_daughterboard = { .init = a9_daughterboard_init, }; -static void a15_daughterboard_init(const VexpressMachineState *vms, +static void a15_daughterboard_init(VexpressMachineState *vms, ram_addr_t ram_size, const char *cpu_type, qemu_irq *pic) { MachineState *machine = MACHINE(vms); MemoryRegion *sysmem = get_system_memory(); - MemoryRegion *sram = g_new(MemoryRegion, 1); { /* We have to use a separate 64 bit variable here to avoid the gcc @@ -386,9 +389,9 @@ static void a15_daughterboard_init(const VexpressMachineState *vms, /* 0x2b060000: SP805 watchdog: not modelled */ /* 0x2b0a0000: PL341 dynamic memory controller: not modelled */ /* 0x2e000000: system SRAM */ - memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000, + memory_region_init_ram(&vms->a15sram, NULL, "vexpress.a15sram", 0x10000, &error_fatal); - memory_region_add_subregion(sysmem, 0x2e000000, sram); + memory_region_add_subregion(sysmem, 0x2e000000, &vms->a15sram); /* 0x7ffb0000: DMA330 DMA controller: not modelled */ /* 0x7ffd0000: PL354 static memory controller: not modelled */ @@ -547,10 +550,6 @@ static void vexpress_common_init(MachineState *machine) I2CBus *i2c; ram_addr_t vram_size, sram_size; MemoryRegion *sysmem = get_system_memory(); - MemoryRegion *vram = g_new(MemoryRegion, 1); - MemoryRegion *sram = g_new(MemoryRegion, 1); - MemoryRegion *flashalias = g_new(MemoryRegion, 1); - MemoryRegion *flash0mem; const hwaddr *map = daughterboard->motherboard_map; int i; @@ -662,24 +661,25 @@ static void vexpress_common_init(MachineState *machine) if (map[VE_NORFLASHALIAS] != -1) { /* Map flash 0 as an alias into low memory */ + MemoryRegion *flash0mem; flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0); - memory_region_init_alias(flashalias, NULL, "vexpress.flashalias", + memory_region_init_alias(&vms->flashalias, NULL, "vexpress.flashalias", flash0mem, 0, VEXPRESS_FLASH_SIZE); - memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias); + memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], &vms->flashalias); } dinfo = drive_get(IF_PFLASH, 0, 1); ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo); sram_size = 0x2000000; - memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size, + memory_region_init_ram(&vms->sram, NULL, "vexpress.sram", sram_size, &error_fatal); - memory_region_add_subregion(sysmem, map[VE_SRAM], sram); + memory_region_add_subregion(sysmem, map[VE_SRAM], &vms->sram); vram_size = 0x800000; - memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size, + memory_region_init_ram(&vms->vram, NULL, "vexpress.vram", vram_size, &error_fatal); - memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram); + memory_region_add_subregion(sysmem, map[VE_VIDEORAM], &vms->vram); /* 0x4e000000 LAN9118 Ethernet */ if (nd_table[0].used) { -- 2.34.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' 2023-05-12 17:02 ` [PATCH 2/2] hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' Peter Maydell @ 2023-05-14 9:38 ` Richard Henderson 2023-05-15 7:09 ` Philippe Mathieu-Daudé 1 sibling, 0 replies; 6+ messages in thread From: Richard Henderson @ 2023-05-14 9:38 UTC (permalink / raw) To: Peter Maydell, qemu-arm, qemu-devel On 5/12/23 10:02, Peter Maydell wrote: > In the vexpress board code, we allocate a new MemoryRegion at the top > of vexpress_common_init() but only set it up and use it inside the > "if (map[VE_NORFLASHALIAS] != -1)" conditional, so we leak it if not. > This isn't a very interesting leak as it's a tiny amount of memory > once at startup, but it's easy to fix. > > We could silence Coverity simply by moving the g_new() into the > if() block, but this use of g_new(MemoryRegion, 1) is a legacy from > when this board model was originally written; we wouldn't do that > if we wrote it today. The MemoryRegions are conceptually a part of > the board and must not go away until the whole board is done with > (at the end of the simulation), so they belong in its state struct. > > This machine already has a VexpressMachineState struct that extends > MachineState, so statically put the MemoryRegions in there instead of > dynamically allocating them separately at runtime. > > Spotted by Coverity (CID 1509083). > > Signed-off-by: Peter Maydell<peter.maydell@linaro.org> > --- > hw/arm/vexpress.c | 40 ++++++++++++++++++++-------------------- > 1 file changed, 20 insertions(+), 20 deletions(-) Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' 2023-05-12 17:02 ` [PATCH 2/2] hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' Peter Maydell 2023-05-14 9:38 ` Richard Henderson @ 2023-05-15 7:09 ` Philippe Mathieu-Daudé 1 sibling, 0 replies; 6+ messages in thread From: Philippe Mathieu-Daudé @ 2023-05-15 7:09 UTC (permalink / raw) To: Peter Maydell, qemu-arm, qemu-devel On 12/5/23 19:02, Peter Maydell wrote: > In the vexpress board code, we allocate a new MemoryRegion at the top > of vexpress_common_init() but only set it up and use it inside the > "if (map[VE_NORFLASHALIAS] != -1)" conditional, so we leak it if not. > This isn't a very interesting leak as it's a tiny amount of memory > once at startup, but it's easy to fix. > > We could silence Coverity simply by moving the g_new() into the > if() block, but this use of g_new(MemoryRegion, 1) is a legacy from > when this board model was originally written; we wouldn't do that > if we wrote it today. The MemoryRegions are conceptually a part of > the board and must not go away until the whole board is done with > (at the end of the simulation), so they belong in its state struct. > > This machine already has a VexpressMachineState struct that extends > MachineState, so statically put the MemoryRegions in there instead of > dynamically allocating them separately at runtime. > > Spotted by Coverity (CID 1509083). > > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> > --- > hw/arm/vexpress.c | 40 ++++++++++++++++++++-------------------- > 1 file changed, 20 insertions(+), 20 deletions(-) Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-05-15 7:10 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-05-12 17:02 [PATCH 0/2] arm: Fix two minor coverity issues Peter Maydell 2023-05-12 17:02 ` [PATCH 1/2] target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing Peter Maydell 2023-05-14 9:35 ` Richard Henderson 2023-05-12 17:02 ` [PATCH 2/2] hw/arm/vexpress: Avoid trivial memory leak of 'flashalias' Peter Maydell 2023-05-14 9:38 ` Richard Henderson 2023-05-15 7:09 ` Philippe Mathieu-Daudé
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).