On Tue, Jan 21, 2025 at 05:37:33PM +0100, Alexander Gordeev wrote: > On Fri, Jan 03, 2025 at 06:44:15PM +0000, Kevin Brodsky wrote: > > Hi Kevin, > ... > > diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h > > index 5fced6d3c36b..b19b6ed2ab53 100644 > > --- a/arch/s390/include/asm/pgalloc.h > > +++ b/arch/s390/include/asm/pgalloc.h > > @@ -130,11 +130,18 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) > > > > static inline pgd_t *pgd_alloc(struct mm_struct *mm) > > { > > - return (pgd_t *) crst_table_alloc(mm); > > + unsigned long *table = crst_table_alloc(mm); > > + > > + if (!table) > > + return NULL; > > I do not know status of this series, but FWIW, this call is missed: > > crst_table_init(table, _REGION1_ENTRY_EMPTY); Why is that missing? A pgd table can be a Region1, Region2, or Region3 table. The only caller of this function is mm_init() via mm_alloc_pgd(); and right after mm_alloc_pgd() there is a call to init_new_context() which will initialize the pgd correctly. I guess what really gets odd, and might be broken (haven't checked yet) is what happens on dynamic upgrade of page table levels (->crst_table_upgrade()). With that a pgd may become a pud, and with that we get an imbalance with the ctor/dtor calls for the various page table levels when they get freed again. Plus, at first glance, it looks also broken that we have open-coded crst_alloc() calls instead of using the "proper" page table allocation API within crst_table_upgrade(), which again would cause an imbalance.