Skip to contentSkip to conversation

arm64: Random fixes for 3.7

PATCH New Catalin Marinas 3 participants 7 messages Oct 16, 2012 – Nov 9, 2012 arm64

lore
Share & tools
lore

Catalin Marinas

author maintainer
#0 lore raw

cover arm64: Random fixes for 3.7

Hi,

These are a few AArch64 fixes I want to get in 3.7.

Comments welcome. Thanks.

Catalin Marinas (4):
arm64: Select MODULES_USE_ELF_RELA
arm64: Fix the update_vsyscall() prototype
arm64: Ignore memory blocks below PHYS_OFFSET
arm64: No need to set the x0-x2 registers in start_thread()

 arch/arm64/Kconfig                 |  1 +
 arch/arm64/include/asm/processor.h | 10 ----------
 arch/arm64/kernel/setup.c          | 12 ++++++++++++
 arch/arm64/kernel/vdso.c           | 20 ++++++++++----------
 4 files changed, 23 insertions(+), 20 deletions(-)
author maintainer
#1 lore raw

PATCH 1/4 arm64: Select MODULES_USE_ELF_RELA

With commit 786d35d4 (make most arch asm/module.h files use asm-generic/module.h) arm64 needs to enable MODULES_USE_ELF_RELA for loadable modules.

---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm64/Kconfig +1 -0
index 7ff68c9..ef54a59 100644
@@ -22,6 +22,7 @@ config ARM64
 	select HAVE_PERF_EVENTS
 	select HAVE_SPARSE_IRQ
 	select IRQ_DOMAIN
+	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
 	select OF
 	select OF_EARLY_FLATTREE
#2 lore raw

PATCH 1/4 arm64: Select MODULES_USE_ELF_RELA

Quoted 14 lines · Catalin Marinas

With commit 786d35d4 (make most arch asm/module.h files use asm-generic/module.h) arm64 needs to enable MODULES_USE_ELF_RELA for loadable modules.

---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm64/Kconfig +0 -0
index 7ff68c9..ef54a59 100644

arch/arm64/Kconfig config ARM64 · line 28

Quoted 7 lines
arch/arm64/Kconfig +1 -0
@@ -22,6 +22,7 @@ config ARM64
 	select HAVE_PERF_EVENTS
 	select HAVE_SPARSE_IRQ
 	select IRQ_DOMAIN
+	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
 	select OF
 	select OF_EARLY_FLATTREE

Will

author maintainer
#3 lore raw

PATCH 2/4 arm64: Fix the update_vsyscall() prototype

In reply to Catalin Marinas

With commit 576094b7 (time: Introduce new GENERIC_TIME_VSYSCALL) the old update_vsyscall() prototype is no longer available. This patch updates the arm64 port.

---
 arch/arm64/kernel/vdso.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)
arch/arm64/kernel/vdso.c +10 -10
index 17948fc..ba45794 100644
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
+#include <linux/timekeeper_internal.h>
 #include <linux/vmalloc.h>
 
 #include <asm/cacheflush.h>
@@ -222,11 +223,10 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
 /*
  * Update the vDSO data page to keep in sync with kernel timekeeping.
  */
-void update_vsyscall(struct timespec *ts, struct timespec *wtm,
-		     struct clocksource *clock, u32 mult)
+void update_vsyscall(struct timekeeper *tk)
 {
 	struct timespec xtime_coarse;
-	u32 use_syscall = strcmp(clock->name, "arch_sys_counter");
+	u32 use_syscall = strcmp(tk->clock->name, "arch_sys_counter");
 
 	++vdso_data->tb_seq_count;
 	smp_wmb();
@@ -237,13 +237,13 @@ void update_vsyscall(struct timespec *ts, struct timespec *wtm,
 	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
 
 	if (!use_syscall) {
-		vdso_data->cs_cycle_last	= clock->cycle_last;
-		vdso_data->xtime_clock_sec	= ts->tv_sec;
-		vdso_data->xtime_clock_nsec	= ts->tv_nsec;
-		vdso_data->cs_mult		= mult;
-		vdso_data->cs_shift		= clock->shift;
-		vdso_data->wtm_clock_sec	= wtm->tv_sec;
-		vdso_data->wtm_clock_nsec	= wtm->tv_nsec;
+		vdso_data->cs_cycle_last	= tk->clock->cycle_last;
+		vdso_data->xtime_clock_sec	= tk->xtime_sec;
+		vdso_data->xtime_clock_nsec	= tk->xtime_nsec >> tk->shift;
+		vdso_data->cs_mult		= tk->mult;
+		vdso_data->cs_shift		= tk->shift;
+		vdso_data->wtm_clock_sec	= tk->wall_to_monotonic.tv_sec;
+		vdso_data->wtm_clock_nsec	= tk->wall_to_monotonic.tv_nsec;
 	}
 
 	smp_wmb();
#4 lore raw

PATCH 2/4 arm64: Fix the update_vsyscall() prototype

Quoted 41 lines · Catalin Marinas

With commit 576094b7 (time: Introduce new GENERIC_TIME_VSYSCALL) the old update_vsyscall() prototype is no longer available. This patch updates the arm64 port.

---
  arch/arm64/kernel/vdso.c | 20 ++++++++++----------
  1 file changed, 10 insertions(+), 10 deletions(-)
arch/arm64/kernel/vdso.c +3 -3
index 17948fc..ba45794 100644
@@ -28,6 +28,7 @@
  #include <linux/sched.h>
  #include <linux/signal.h>
  #include <linux/slab.h>
+#include <linux/timekeeper_internal.h>
  #include <linux/vmalloc.h>
 
  #include <asm/cacheflush.h>
@@ -222,11 +223,10 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
  /*
   * Update the vDSO data page to keep in sync with kernel timekeeping.
   */
-void update_vsyscall(struct timespec *ts, struct timespec *wtm,
-		     struct clocksource *clock, u32 mult)
+void update_vsyscall(struct timekeeper *tk)
  {
  	struct timespec xtime_coarse;
-	u32 use_syscall = strcmp(clock->name, "arch_sys_counter");
+	u32 use_syscall = strcmp(tk->clock->name, "arch_sys_counter");
 
  	++vdso_data->tb_seq_count;
  	smp_wmb();
@@ -237,13 +237,13 @@ void update_vsyscall(struct timespec *ts, struct timespec *wtm,
  	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
 
  	if (!use_syscall) {

arch/arm64/kernel/vdso.c void update_vsyscall(struct timespec *ts, struct timespec *wtm, · line 242

Quoted 10 lines
arch/arm64/kernel/vdso.c +3 -7
-		vdso_data->cs_cycle_last	= clock->cycle_last;
-		vdso_data->xtime_clock_sec	= ts->tv_sec;
-		vdso_data->xtime_clock_nsec	= ts->tv_nsec;
-		vdso_data->cs_mult		= mult;
-		vdso_data->cs_shift		= clock->shift;
-		vdso_data->wtm_clock_sec	= wtm->tv_sec;
-		vdso_data->wtm_clock_nsec	= wtm->tv_nsec;
+		vdso_data->cs_cycle_last	= tk->clock->cycle_last;
+		vdso_data->xtime_clock_sec	= tk->xtime_sec;
+		vdso_data->xtime_clock_nsec	= tk->xtime_nsec >> tk->shift;

Sorry for the collision here!

One word of warning: Truncating the sub-ns base like this can cause small single ns inconsistencies from the vsyscalls.

So either use GENERIC_TIME_VSYSCALL_OLD to enable the 1ns generic rounding-up code, or rework the vsyscall code to use the sub-ns granularity as done in 650ea02475106e8d6bdf561896d2ffe0d1c0ebb4 for x86_64. I hope to drop the _OLD config eventually, so this will need to be done at some point.

thanks
-john

author maintainer
#5 lore raw

PATCH 3/4 arm64: Ignore memory blocks below PHYS_OFFSET

In reply to Catalin Marinas

According to Documentation/arm64/booting.txt, the kernel image must be loaded at a pre-defined offset from the start of RAM so that the kernel can calculate PHYS_OFFSET based on this address. If the DT contains memory blocks below this PHYS_OFFSET, report them and ignore the corresponding memory range.

---
 arch/arm64/kernel/setup.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/arm64/kernel/setup.c +12 -0
index 48ffb9f..7665a9b 100644
@@ -170,7 +170,19 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
 
 void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 {
+	base &= PAGE_MASK;
 	size &= PAGE_MASK;
+	if (base + size < PHYS_OFFSET) {
+		pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
+			   base, base + size);
+		return;
+	}
+	if (base < PHYS_OFFSET) {
+		pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
+			   base, PHYS_OFFSET);
+		size -= PHYS_OFFSET - base;
+		base = PHYS_OFFSET;
+	}
 	memblock_add(base, size);
 }
 
author maintainer
#6 lore raw

PATCH 4/4 arm64: No need to set the x0-x2 registers in start_thread()

In reply to Catalin Marinas

For historical reasons, ARM used to set r0-r2 in start_thread() to the first values on the user stack when starting a new user application. The same logic has been inherited in AArch64. The x0 register is overridden by the sys_execve() return value so it's always zero on success. The x1 and x2 registers are ignored by AArch64 and EABI AArch32 applications, so we can safely remove the register setting for both native and compat user space.

This also fixes a potential fault with the kernel accessing user space stack directly.

---
 arch/arm64/include/asm/processor.h | 10 ----------
 1 file changed, 10 deletions(-)
arch/arm64/include/asm/processor.h +0 -10
index 39a208a..5d81004 100644
@@ -92,30 +92,20 @@ static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
 static inline void start_thread(struct pt_regs *regs, unsigned long pc,
 				unsigned long sp)
 {
-	unsigned long *stack = (unsigned long *)sp;
-
 	start_thread_common(regs, pc);
 	regs->pstate = PSR_MODE_EL0t;
 	regs->sp = sp;
-	regs->regs[2] = stack[2];	/* x2 (envp) */
-	regs->regs[1] = stack[1];	/* x1 (argv) */
-	regs->regs[0] = stack[0];	/* x0 (argc) */
 }
 
 #ifdef CONFIG_COMPAT
 static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
 				       unsigned long sp)
 {
-	unsigned int *stack = (unsigned int *)sp;
-
 	start_thread_common(regs, pc);
 	regs->pstate = COMPAT_PSR_MODE_USR;
 	if (pc & 1)
 		regs->pstate |= COMPAT_PSR_T_BIT;
 	regs->compat_sp = sp;
-	regs->regs[2] = stack[2];	/* x2 (envp) */
-	regs->regs[1] = stack[1];	/* x1 (argv) */
-	regs->regs[0] = stack[0];	/* x0 (argc) */
 }
 #endif