Re: [PATCH] MIPS: OCTEON: Enable KASLR

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi David,


On 12/12/16 18:52, David Daney wrote:
On 12/12/2016 01:56 AM, Matt Redfearn wrote:
Hi David,


On 09/12/16 18:46, David Daney wrote:
On 12/09/2016 01:35 AM, Steven J. Hill wrote:
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 jumps 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@xxxxxxxxxx>
Signed-off-by: Steven J. Hill <Steven.Hill@xxxxxxxxxx>
---
 arch/mips/Kconfig |  3 ++-
 arch/mips/cavium-octeon/smp.c |  7 +++++--
 .../include/asm/mach-cavium-octeon/kernel-entry-init.h    | 15
++++++++++++++-
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index b3c5bde..65d7e20 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -909,6 +909,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
@@ -2570,7 +2571,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.
diff --git a/arch/mips/cavium-octeon/smp.c
b/arch/mips/cavium-octeon/smp.c
index 256fe6f..65c8369 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -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");
@@ -333,8 +338,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 */
diff --git
a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
index c4873e8..f69611c 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
@@ -99,9 +99,22 @@
     # to begin
     #

+octeon_spin_wait_boot:
+#ifdef CONFIG_RELOCATABLE
+    PTR_LA    t0, octeon_processor_relocated_kernel_entry
+    LONG_L    t0, (t0)
+    beq    zero, t0, 1f
+

This doesn't look correct.

Please explain how this code implements:

   loop here until octeon_processor_relocated_kernel_entry is set.

This part of the loop is checking if
octeon_processor_relocated_kernel_entry becomes set, in which case don't
take the branch and jump to the relocated kernel entry point that has
been stored in octeon_processor_relocated_kernel_entry by the boot CPU
(that part was missing from Stephens v1 post of this patch). Otherwise
the semantics of the loop remain the same as before, checking for
octeon_processor_boot to be non-zero to start a secondary running this
kernel.

This same loop is executed in the relocated kernel and of course in that
case octeon_processor_relocated_kernel_entry will not be set, just
octeon_processor_boot will be set when the boot CPU is starting the
secondary CPUs.

OK, I now understand what is being done.

Is it ever the case that we will have CONFIG_RELOCATABLE, and not do the relocation?

If not, before relocation we never need to poll octeon_processor_boot before relocation. We could branch to a point that polls octeon_processor_boot after we leave the loop that waits for the relocation to complete.

Maybe it is not that big a deal.

There are a few bail-out paths that can be taken if the kernel cannot be relocated, for example if any relocation fails to apply, or if "nokaslr" is passed on the command line, so yes that is possible.






+    /* If kernel has been relocated, jump to it's new entry point */
+    move    a0, zero
+    move    a1, zero
+    move    a2, zero

Why change the values of a*?  Don't these registers already contain
the proper values from the bootloader?

I don't see where the secondaries make use of any arguments passed from
the bootloader in the entry code.


In the line that says:
   bne    a2, zero, octeon_main_processor


But this follows the same semantics as
the CPU hotplug code, which restarts secondaries with their arguments
set to 0.

Yes, for the secondaries the argument registers are set to zero, but that is so that when they pass through the branch shown above that they get to the proper place.

In this code, we are coming from the bootloader, and these registers already have the proper value.

Adding these three MOVE instructions makes it look like you are taking some needed action when in fact it is unneeded code that only serves to confuse.

I would really like that removed as it just clutters things up and will lead people to think that it is necessary.

OK, makes sense, Steven, could you make the changes, test and re-post?

Thanks,
Matt



David.


Thanks,
Matt


+    jr    t0
+1:
+#endif /* CONFIG_RELOCATABLE */
+
     # This is the variable where the next core to boot os stored
     PTR_LA    t0, octeon_processor_boot
-octeon_spin_wait_boot:
     # Get the core id of the next to be booted
     LONG_L    t1, (t0)
     # Keep looping if it isn't me










[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux