aboutsummaryrefslogtreecommitdiff
path: root/core/cpu.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-06-24 14:17:28 -0500
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-06-26 14:28:58 +1000
commit1cb276acc130d1dfbd8ce8347d2ee27035178e65 (patch)
tree0bb9234ea5249145fc46d34d3f7fb5b6f4a6570f /core/cpu.c
parent24726a1f5e41e416b1035f2486870def72a2ce8a (diff)
downloadskiboot-1cb276acc130d1dfbd8ce8347d2ee27035178e65.zip
skiboot-1cb276acc130d1dfbd8ce8347d2ee27035178e65.tar.gz
skiboot-1cb276acc130d1dfbd8ce8347d2ee27035178e65.tar.bz2
cpu: Support setting HID[RADIX] and set it by default on P9
This adds new opal_reinit_cpus() flags to setup radix or hash mode in HID[8] on POWER9. By default HID[8] will be set. On P9 DD1.0, Linux will change it as needed. On P9 DD2.0 hash works in radix mode (radix is really "dual" mode) so KVM won't break and existing kernels will work. Newer kernels built for hash will call this to clear the HID bit and thus get the full size of the TLB as an optimization. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/cpu.c')
-rw-r--r--core/cpu.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/core/cpu.c b/core/cpu.c
index 31f5c92..75c7008 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -49,10 +49,12 @@ unsigned int cpu_max_pir;
struct cpu_thread *boot_cpu;
static struct lock reinit_lock = LOCK_UNLOCKED;
static bool hile_supported;
+static bool radix_supported;
static unsigned long hid0_hile;
static unsigned long hid0_attn;
static bool pm_enabled;
static bool current_hile_mode;
+static bool current_radix_mode;
unsigned long cpu_secondary_start __force_data = 0;
@@ -700,6 +702,7 @@ void init_boot_cpu(void)
case PVR_TYPE_P9:
proc_gen = proc_gen_p9;
hile_supported = true;
+ radix_supported = true;
hid0_hile = SPR_HID0_POWER9_HILE;
hid0_attn = SPR_HID0_POWER9_ENABLE_ATTN;
break;
@@ -1060,11 +1063,27 @@ static int64_t cpu_change_all_hid0(struct hid0_change_req *req)
return OPAL_SUCCESS;
}
+void cpu_set_radix_mode(void)
+{
+ struct hid0_change_req req;
+
+ if (!radix_supported)
+ return;
+
+ req.clr_bits = 0;
+ req.set_bits = SPR_HID0_POWER9_RADIX;
+ cleanup_global_tlb();
+ current_radix_mode = true;
+ cpu_change_all_hid0(&req);
+}
+
void cpu_fast_reboot_complete(void)
{
/* Fast reboot will have cleared HID0:HILE */
current_hile_mode = false;
+ /* On P9, restore radix mode */
+ cpu_set_radix_mode();
}
static int64_t opal_reinit_cpus(uint64_t flags)
@@ -1129,6 +1148,25 @@ static int64_t opal_reinit_cpus(uint64_t flags)
}
}
+ /* If MMU mode change is supported */
+ if (radix_supported &&
+ (flags & (OPAL_REINIT_CPUS_MMU_HASH |
+ OPAL_REINIT_CPUS_MMU_RADIX))) {
+ bool radix = !!(flags & OPAL_REINIT_CPUS_MMU_RADIX);
+
+ flags &= ~(OPAL_REINIT_CPUS_MMU_HASH |
+ OPAL_REINIT_CPUS_MMU_RADIX);
+ if (radix != current_radix_mode) {
+ if (radix)
+ req.set_bits |= SPR_HID0_POWER9_RADIX;
+ else
+ req.clr_bits |= SPR_HID0_POWER9_RADIX;
+
+ cleanup_global_tlb();
+ current_radix_mode = radix;
+ }
+ }
+
/* Apply HID bits changes if any */
if (req.set_bits || req.clr_bits)
cpu_change_all_hid0(&req);