From: Michael Ellerman Date: Thu, 13 Jun 2019 05:00:34 +0000 (+1000) Subject: Merge branch 'context-id-fix' into fixes X-Git-Tag: v5.2-rc7~28^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=65565a68c582fec2f2a8f5aaa399118ab1209103;p=users%2Fjedix%2Flinux-maple.git Merge branch 'context-id-fix' into fixes This merges a fix for a bug in our context id handling on 64-bit hash CPUs. The fix was written against v5.1 to ease backporting to stable releases. Here we are merging it up to a v5.2-rc2 base, which involves a bit of manual resolution. It also adds a test case for the bug. Signed-off-by: Michael Ellerman --- 65565a68c582fec2f2a8f5aaa399118ab1209103 diff --cc arch/powerpc/mm/book3s64/mmu_context.c index cb2b08635508,8751ae2e2d04..6d8f06b04022 --- a/arch/powerpc/mm/book3s64/mmu_context.c +++ b/arch/powerpc/mm/book3s64/mmu_context.c @@@ -59,17 -97,6 +97,11 @@@ static int hash__init_new_context(struc { int index; - index = hash__alloc_context_id(); - if (index < 0) - return index; - + mm->context.hash_context = kmalloc(sizeof(struct hash_mm_context), + GFP_KERNEL); - if (!mm->context.hash_context) { - ida_free(&mmu_context_ida, index); ++ if (!mm->context.hash_context) + return -ENOMEM; - } + /* * The old code would re-promote on fork, we don't do that when using * slices as it could cause problem promoting slices that have been @@@ -84,26 -111,14 +116,33 @@@ * We should not be calling init_new_context() on init_mm. Hence a * check against 0 is OK. */ - if (mm->context.id == 0) + if (mm->context.id == 0) { + memset(mm->context.hash_context, 0, sizeof(struct hash_mm_context)); slice_init_new_context_exec(mm); + } else { + /* This is fork. Copy hash_context details from current->mm */ + memcpy(mm->context.hash_context, current->mm->context.hash_context, sizeof(struct hash_mm_context)); +#ifdef CONFIG_PPC_SUBPAGE_PROT + /* inherit subpage prot detalis if we have one. */ + if (current->mm->context.hash_context->spt) { + mm->context.hash_context->spt = kmalloc(sizeof(struct subpage_prot_table), + GFP_KERNEL); + if (!mm->context.hash_context->spt) { - ida_free(&mmu_context_ida, index); + kfree(mm->context.hash_context); + return -ENOMEM; + } + } +#endif ++ } + index = realloc_context_ids(&mm->context); - if (index < 0) ++ if (index < 0) { ++#ifdef CONFIG_PPC_SUBPAGE_PROT ++ kfree(mm->context.hash_context->spt); ++#endif ++ kfree(mm->context.hash_context); + return index; - - subpage_prot_init_new_context(mm); + } pkey_mm_init(mm); return index;