MIPS: Octeon: Enable KASLR
authorSteven J. Hill <steven.hill@cavium.com>
Tue, 13 Dec 2016 20:25:37 +0000 (14:25 -0600)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 3 Jan 2017 15:34:35 +0000 (16:34 +0100)
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: Matt Redfearn <matt.redfearn@imgtec.com>
Signed-off-by: Steven J. Hill <steven.hill@cavium.com>
Acked-by: David Daney <david.daney@cavium.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/14669/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/Kconfig
arch/mips/cavium-octeon/smp.c
arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h

index 80832aa8e4fb81af324a64d5350ae6ca3e37d40d..7cb4b0e5f49a14cc5ffbb6521fbad3a23b458e87 100644 (file)
@@ -910,6 +910,7 @@ config CAVIUM_OCTEON_SOC
        select NR_CPUS_DEFAULT_16
        select BUILTIN_DTB
        select MTD_COMPLEX_MAPPINGS
+       select SYS_SUPPORTS_RELOCATABLE
        help
          This option supports all of the Octeon reference boards from Cavium
          Networks. It builds a kernel that dynamically determines the Octeon
@@ -2571,7 +2572,7 @@ config SYS_SUPPORTS_NUMA
 
 config RELOCATABLE
        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
          This builds a kernel image that retains relocation information
          so it can be loaded someplace besides the default 1MB.
index 256fe6f65cf2dec815777a8ee736431481115e94..889c3f49dbc0e4fb3fe15eae7a7134a009465c17 100644 (file)
 volatile unsigned long octeon_processor_boot = 0xff;
 volatile unsigned long octeon_processor_sp;
 volatile unsigned long octeon_processor_gp;
+#ifdef CONFIG_RELOCATABLE
+volatile unsigned long octeon_processor_relocated_kernel_entry;
+#endif /* CONFIG_RELOCATABLE */
 
 #ifdef CONFIG_HOTPLUG_CPU
 uint64_t octeon_bootloader_entry_addr;
 EXPORT_SYMBOL(octeon_bootloader_entry_addr);
 #endif
 
+extern void kernel_entry(unsigned long arg1, ...);
+
 static void octeon_icache_flush(void)
 {
        asm volatile ("synci 0($0)\n");
@@ -180,6 +185,19 @@ static void __init octeon_smp_setup(void)
        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
  *
@@ -333,8 +351,6 @@ void play_dead(void)
                ;
 }
 
-extern void kernel_entry(unsigned long arg1, ...);
-
 static void start_after_reset(void)
 {
        kernel_entry(0, 0, 0);  /* set a2 = 0 for secondary core */
index c4873e8594ef126aac8257e92b35e4cb1b3d118b..c38b38ce5a3d821a548a8eb973663568b84b2991 100644 (file)
        # to begin
        #
 
-       # This is the variable where the next core to boot os stored
-       PTR_LA  t0, octeon_processor_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
        LONG_L  t1, (t0)
        # Keep looping if it isn't me