On Thu, 14 Feb 2019 16:55:28 +0000,
Ard Biesheuvel <[email protected]> wrote:
>
> On Thu, 14 Feb 2019 at 16:48, Marc Zyngier <[email protected]> wrote:
> >
> > Hi Ard,
> >
> > On 13/02/2019 13:27, Ard Biesheuvel wrote:
> > > In the irqchip and EFI code, we have what basically amounts to a quirk
> > > to work around a peculiarity in the GICv3 architecture, which permits
> > > the system memory address of LPI tables to be programmable only once
> > > after a CPU reset. This means kexec kernels must use the same memory
> > > as the first kernel, and thus ensure that this memory has not been
> > > given out for other purposes by the time the ITS init code runs, which
> > > is not very early for secondary CPUs.
> > >
> > > On systems with many CPUs, these reservations could overflow the
> > > memblock reservation table, and this was addressed in commit
> > > eff896288872 ("efi/arm: Defer persistent reservations until after
> > > paging_init()"). However, this turns out to have made things worse,
> > > since the allocation of page tables and heap space for the resized
> > > memblock reservation table itself may overwrite the regions we are
> > > attempting to reserve, which may cause all kinds of corruption,
> > > also considering that the ITS will still be poking bits into that
> > > memory in response to incoming MSIs.
> > >
> > > So instead, let's grow the static memblock reservation table on such
> > > systems so it can accommodate these reservations at an earlier time.
> > > This will permit us to revert the above commit in a subsequent patch.
> > >
> > > Signed-off-by: Ard Biesheuvel <[email protected]>
> > > ---
> > > arch/arm64/include/asm/memory.h | 11 +++++++++++
> > > include/linux/memblock.h | 3 ---
> > > mm/memblock.c | 10 ++++++++--
> > > 3 files changed, 19 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/arch/arm64/include/asm/memory.h
> > > b/arch/arm64/include/asm/memory.h
> > > index e1ec947e7c0c..7e2b13cdd970 100644
> > > --- a/arch/arm64/include/asm/memory.h
> > > +++ b/arch/arm64/include/asm/memory.h
> > > @@ -332,6 +332,17 @@ static inline void *phys_to_virt(phys_addr_t x)
> > > #define virt_addr_valid(kaddr) \
> > > (_virt_addr_is_linear(kaddr) && _virt_addr_valid(kaddr))
> > >
> > > +/*
> > > + * Given that the GIC architecture permits ITS implementations that can
> > > only be
> > > + * configured with a LPI table address once, GICv3 systems with many
> > > CPUs may
> > > + * end up reserving a lot of different regions after a kexec for their
> > > LPI
> > > + * tables, as we are forced to reuse the same memory after kexec (and
> > > thus
> > > + * reserve it persistently with EFI beforehand)
> > > + */
> > > +#if defined(CONFIG_EFI) && defined(CONFIG_ARM_GIC_V3_ITS)
> > > +#define INIT_MEMBLOCK_RESERVED_REGIONS (INIT_MEMBLOCK_REGIONS + 2
> > > * NR_CPUS)
> >
> > Since GICv3 has 1 pending table per CPU, plus one global property table,
> > can we make this 2 * NR_CPUS + 1? Or is that enough already?
> >
>
> Ah, I misread the code then. That would mean we'll only need 1 extra
> slot per CPU.
>
> So I will change this to
>
> > > +#define INIT_MEMBLOCK_RESERVED_REGIONS (INIT_MEMBLOCK_REGIONS +
> > > NR_CPUS)
>
> considering that INIT_MEMBLOCK_REGIONS defaults to 128, so that one
> global table is already accounted for.
Look good to me.
Thanks,
M.
--
Jazz is not dead, it just smell funny.