Commit 7e71c428 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman

powerpc/64s/pseries: radix flush translations before MMU is enabled at boot

Radix guests are responsible for managing their own translation caches,
so make them match bare metal radix and hash, and make each CPU flush
all its translations right before enabling its MMU.

Radix guests may not flush partition scope translations, so in
tlbiel_all, make these flushes conditional on CPU_FTR_HVMODE. Process
scope translations are the only type visible to the guest.
Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190902152931.17840-5-npiggin@gmail.com
parent fd13daea
...@@ -616,7 +616,6 @@ void __init radix__early_init_mmu(void) ...@@ -616,7 +616,6 @@ void __init radix__early_init_mmu(void)
/* Switch to the guard PID before turning on MMU */ /* Switch to the guard PID before turning on MMU */
radix__switch_mmu_context(NULL, &init_mm); radix__switch_mmu_context(NULL, &init_mm);
if (cpu_has_feature(CPU_FTR_HVMODE))
tlbiel_all(); tlbiel_all();
} }
...@@ -637,7 +636,6 @@ void radix__early_init_mmu_secondary(void) ...@@ -637,7 +636,6 @@ void radix__early_init_mmu_secondary(void)
} }
radix__switch_mmu_context(NULL, &init_mm); radix__switch_mmu_context(NULL, &init_mm);
if (cpu_has_feature(CPU_FTR_HVMODE))
tlbiel_all(); tlbiel_all();
} }
......
...@@ -51,11 +51,15 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is) ...@@ -51,11 +51,15 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is)
* and partition table entries. Then flush the remaining sets of the * and partition table entries. Then flush the remaining sets of the
* TLB. * TLB.
*/ */
if (early_cpu_has_feature(CPU_FTR_HVMODE)) {
/* MSR[HV] should flush partition scope translations first. */
tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 0); tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 0);
for (set = 1; set < num_sets; set++) for (set = 1; set < num_sets; set++)
tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 0); tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 0);
}
/* Do the same for process scoped entries. */ /* Flush process scoped entries. */
tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 1); tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 1);
for (set = 1; set < num_sets; set++) for (set = 1; set < num_sets; set++)
tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 1); tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment