On Mon, Apr 25, 2016 at 02:52:45PM +0800, Shannon Zhao wrote: > > > On 2016/4/25 1:28, Andrew Jones wrote: > > On Sat, Apr 23, 2016 at 06:04:14PM +0800, Shannon Zhao wrote: > >> > From: Shannon Zhao <shannon.z...@linaro.org> > >> > > >> > Add a virtual PMU device for virt machine while use PPI 7 for PMU > >> > overflow interrupt number. > >> > > >> > Signed-off-by: Shannon Zhao <shannon.z...@linaro.org> > >> > --- > >> > hw/arm/virt.c | 31 +++++++++++++++++++++++++++++++ > >> > include/hw/arm/virt.h | 4 ++++ > >> > include/sysemu/kvm.h | 1 + > >> > stubs/kvm.c | 5 +++++ > >> > target-arm/kvm64.c | 39 +++++++++++++++++++++++++++++++++++++++ > >> > 5 files changed, 80 insertions(+) > >> > > >> > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > >> > index 56d35c7..d77b314 100644 > >> > --- a/hw/arm/virt.c > >> > +++ b/hw/arm/virt.c > >> > @@ -428,6 +428,35 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi, > >> > int type) > >> > qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", > >> > vbi->gic_phandle); > >> > } > >> > > >> > +static void fdt_add_pmu_nodes(const VirtBoardInfo *vbi) > >> > +{ > >> > + CPUState *cpu; > >> > + ARMCPU *armcpu; > >> > + uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI; > >> > + > >> > + CPU_FOREACH(cpu) { > >> > + armcpu = ARM_CPU(cpu); > >> > + if (!armcpu->has_pmu) { > >> > + return; > >> > + } > >> > + > >> > + kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ)); > >> > + } > >> > + > >> > + irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START, > >> > + GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << > >> > vbi->smp_cpus) - 1); > > The shift will overflow when configuring a machine to have more than > > 32 cpus. You should confirm smp_cpus is <= GIC_FDT_IRQ_PPI_CPU_WIDTH > > before generating a mask this way, otherwise you can just pass in 0xff. > > > Ah, right. So it could check the gictype like what we do in > fdt_add_timer_nodes.
Oh, now that I look closer we definitely need that condition. Otherwise we're losing the LEVEL_HI flag that irqflags is initialized to for no reason. Thanks, drew