{
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
* 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);
- ida_free(&mmu_context_ida, index);
+ } 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) {
+ kfree(mm->context.hash_context);
+ return -ENOMEM;
+ }
+ }
+#endif
++ }
- if (index < 0)
+ index = realloc_context_ids(&mm->context);
-
- subpage_prot_init_new_context(mm);
++ if (index < 0) {
++#ifdef CONFIG_PPC_SUBPAGE_PROT
++ kfree(mm->context.hash_context->spt);
++#endif
++ kfree(mm->context.hash_context);
+ return index;
+ }
pkey_mm_init(mm);
return index;