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

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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.
+18 −2
Original line number Diff line number Diff line
@@ -24,12 +24,17 @@
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 */
+13 −2
Original line number Diff line number Diff line
@@ -99,9 +99,20 @@
	# 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