Commit 3ff72be4 authored by Steven J. Hill's avatar Steven J. Hill Committed by Ralf Baechle

MIPS: Octeon: Enable KASLR

This patch enables KASLR for Octeon systems. The SMP startup code is
such that the secondaries monitor the volatile variable
'octeon_processor_relocated_kernel_entry' for any non-zero value.
The 'plat_post_relocation hook' is used to set that value to the
kernel entry point of the relocated kernel. The secondary CPUs will
then jusmp to the new kernel, perform their initialization again
and begin waiting for the boot CPU to start them via the relocated
loop 'octeon_spin_wait_boot'. Inspired by Steven's code from Cavium.
Signed-off-by: default avatarMatt Redfearn <matt.redfearn@imgtec.com>
Signed-off-by: default avatarSteven J. Hill <steven.hill@cavium.com>
Acked-by: default avatarDavid Daney <david.daney@cavium.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/14669/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 126c1113
...@@ -910,6 +910,7 @@ config CAVIUM_OCTEON_SOC ...@@ -910,6 +910,7 @@ config CAVIUM_OCTEON_SOC
select NR_CPUS_DEFAULT_16 select NR_CPUS_DEFAULT_16
select BUILTIN_DTB select BUILTIN_DTB
select MTD_COMPLEX_MAPPINGS select MTD_COMPLEX_MAPPINGS
select SYS_SUPPORTS_RELOCATABLE
help help
This option supports all of the Octeon reference boards from Cavium This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon Networks. It builds a kernel that dynamically determines the Octeon
...@@ -2571,7 +2572,7 @@ config SYS_SUPPORTS_NUMA ...@@ -2571,7 +2572,7 @@ config SYS_SUPPORTS_NUMA
config RELOCATABLE config RELOCATABLE
bool "Relocatable kernel" bool "Relocatable kernel"
depends on SYS_SUPPORTS_RELOCATABLE && (CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_MIPS32_R6 || CPU_MIPS64_R6) depends on SYS_SUPPORTS_RELOCATABLE && (CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_MIPS32_R6 || CPU_MIPS64_R6 || CAVIUM_OCTEON_SOC)
help help
This builds a kernel image that retains relocation information This builds a kernel image that retains relocation information
so it can be loaded someplace besides the default 1MB. so it can be loaded someplace besides the default 1MB.
......
...@@ -24,12 +24,17 @@ ...@@ -24,12 +24,17 @@
volatile unsigned long octeon_processor_boot = 0xff; volatile unsigned long octeon_processor_boot = 0xff;
volatile unsigned long octeon_processor_sp; volatile unsigned long octeon_processor_sp;
volatile unsigned long octeon_processor_gp; volatile unsigned long octeon_processor_gp;
#ifdef CONFIG_RELOCATABLE
volatile unsigned long octeon_processor_relocated_kernel_entry;
#endif /* CONFIG_RELOCATABLE */
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
uint64_t octeon_bootloader_entry_addr; uint64_t octeon_bootloader_entry_addr;
EXPORT_SYMBOL(octeon_bootloader_entry_addr); EXPORT_SYMBOL(octeon_bootloader_entry_addr);
#endif #endif
extern void kernel_entry(unsigned long arg1, ...);
static void octeon_icache_flush(void) static void octeon_icache_flush(void)
{ {
asm volatile ("synci 0($0)\n"); asm volatile ("synci 0($0)\n");
...@@ -180,6 +185,19 @@ static void __init octeon_smp_setup(void) ...@@ -180,6 +185,19 @@ static void __init octeon_smp_setup(void)
octeon_smp_hotplug_setup(); octeon_smp_hotplug_setup();
} }
#ifdef CONFIG_RELOCATABLE
int plat_post_relocation(long offset)
{
unsigned long entry = (unsigned long)kernel_entry;
/* Send secondaries into relocated kernel */
octeon_processor_relocated_kernel_entry = entry + offset;
return 0;
}
#endif /* CONFIG_RELOCATABLE */
/** /**
* Firmware CPU startup hook * Firmware CPU startup hook
* *
...@@ -333,8 +351,6 @@ void play_dead(void) ...@@ -333,8 +351,6 @@ void play_dead(void)
; ;
} }
extern void kernel_entry(unsigned long arg1, ...);
static void start_after_reset(void) static void start_after_reset(void)
{ {
kernel_entry(0, 0, 0); /* set a2 = 0 for secondary core */ kernel_entry(0, 0, 0); /* set a2 = 0 for secondary core */
......
...@@ -99,9 +99,20 @@ ...@@ -99,9 +99,20 @@
# to begin # to begin
# #
# This is the variable where the next core to boot os stored
PTR_LA t0, octeon_processor_boot
octeon_spin_wait_boot: octeon_spin_wait_boot:
#ifdef CONFIG_RELOCATABLE
PTR_LA t0, octeon_processor_relocated_kernel_entry
LONG_L t0, (t0)
beq zero, t0, 1f
nop
jr t0
nop
1:
#endif /* CONFIG_RELOCATABLE */
# This is the variable where the next core to boot is stored
PTR_LA t0, octeon_processor_boot
# Get the core id of the next to be booted # Get the core id of the next to be booted
LONG_L t1, (t0) LONG_L t1, (t0)
# Keep looping if it isn't me # Keep looping if it isn't me
......
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