arm64: Random fixes for 3.7
Catalin Marinas
maintainercover 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(-)
Catalin Marinas
maintainerPATCH 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
@@ -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
PATCH 1/4 arm64: Select MODULES_USE_ELF_RELA
Quoted 14 lines · Catalin Marinas
With commit
786d35d4(make most archasm/module.hfiles useasm-generic/module.h) arm64 needs to enableMODULES_USE_ELF_RELAfor loadable modules.Signed-off-by Catalin Marinas <[email protected]>--- arch/arm64/Kconfig | 1 + 1 file changed, 1 insertion(+)arch/arm64/Kconfig +0
-0
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
Catalin Marinas
maintainerPATCH 2/4 arm64: Fix the update_vsyscall() prototype
In reply to Catalin MarinasWith 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
@@ -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 ();
PATCH 2/4 arm64: Fix the update_vsyscall() prototype
Quoted 41 lines · Catalin Marinas
With commit
576094b7(time: Introduce newGENERIC_TIME_VSYSCALL) the oldupdate_vsyscall()prototype is no longer available. This patch updates the arm64 port.Signed-off-by Catalin Marinas <[email protected]>Acked-by Will Deacon <[email protected]>Cc John Stultz <[email protected]>--- arch/arm64/kernel/vdso.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)arch/arm64/kernel/vdso.c +3
-3@@ -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
Catalin Marinas
maintainerPATCH 3/4 arm64: Ignore memory blocks below PHYS_OFFSET
In reply to Catalin MarinasAccording 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
@@ -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); }
Catalin Marinas
maintainerPATCH 4/4 arm64: No need to set the x0-x2 registers in start_thread()
In reply to Catalin MarinasFor 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
@@ -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