Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64

Pull arm64 fixes from Catalin Marinas:
 "Main changes:
   - AArch64 Linux compilation fixes following 3.7-rc1 changes
     (MODULES_USE_ELF_RELA, update_vsyscall() prototype)
   - Unnecessary register setting in start_thread() (thanks to Al Viro)
   - ptrace fixes"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64:
  arm64: fix alignment padding in assembly code
  arm64: ptrace: use HW_BREAKPOINT_EMPTY type for disabled breakpoints
  arm64: ptrace: make structure padding explicit for debug registers
  arm64: No need to set the x0-x2 registers in start_thread()
  arm64: Ignore memory blocks below PHYS_OFFSET
  arm64: Fix the update_vsyscall() prototype
  arm64: Select MODULES_USE_ELF_RELA
  arm64: Remove duplicate inclusion of mmu_context.h in smp.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7ff68c9..ef54a59 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -22,6 +22,7 @@
 	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
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index fe77e51..a581a22 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -18,7 +18,6 @@
 generic-y += irq_regs.h
 generic-y += kdebug.h
 generic-y += kmap_types.h
-generic-y += linkage.h
 generic-y += local.h
 generic-y += local64.h
 generic-y += mman.h
diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
new file mode 100644
index 0000000..636c1bc
--- /dev/null
+++ b/arch/arm64/include/asm/linkage.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN		.align 4
+#define __ALIGN_STR	".align 4"
+
+#endif
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 39a208a..5d81004 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -92,30 +92,20 @@
 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
 
diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 9b131b4e..6913643 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -79,13 +79,14 @@
 
 struct user_hwdebug_state {
 	__u32		dbg_info;
+	__u32		pad;
 	struct {
 		__u64	addr;
 		__u32	ctrl;
+		__u32	pad;
 	}		dbg_regs[16];
 };
 
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI__ASM_PTRACE_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 2ea3968..6e1e77f 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -234,28 +234,33 @@
 				     struct arch_hw_breakpoint_ctrl ctrl,
 				     struct perf_event_attr *attr)
 {
-	int err, len, type;
+	int err, len, type, disabled = !ctrl.enabled;
 
-	err = arch_bp_generic_fields(ctrl, &len, &type);
-	if (err)
-		return err;
+	if (disabled) {
+		len = 0;
+		type = HW_BREAKPOINT_EMPTY;
+	} else {
+		err = arch_bp_generic_fields(ctrl, &len, &type);
+		if (err)
+			return err;
 
-	switch (note_type) {
-	case NT_ARM_HW_BREAK:
-		if ((type & HW_BREAKPOINT_X) != type)
+		switch (note_type) {
+		case NT_ARM_HW_BREAK:
+			if ((type & HW_BREAKPOINT_X) != type)
+				return -EINVAL;
+			break;
+		case NT_ARM_HW_WATCH:
+			if ((type & HW_BREAKPOINT_RW) != type)
+				return -EINVAL;
+			break;
+		default:
 			return -EINVAL;
-		break;
-	case NT_ARM_HW_WATCH:
-		if ((type & HW_BREAKPOINT_RW) != type)
-			return -EINVAL;
-		break;
-	default:
-		return -EINVAL;
+		}
 	}
 
 	attr->bp_len	= len;
 	attr->bp_type	= type;
-	attr->disabled	= !ctrl.enabled;
+	attr->disabled	= disabled;
 
 	return 0;
 }
@@ -372,7 +377,7 @@
 
 #define PTRACE_HBP_ADDR_SZ	sizeof(u64)
 #define PTRACE_HBP_CTRL_SZ	sizeof(u32)
-#define PTRACE_HBP_REG_OFF	sizeof(u32)
+#define PTRACE_HBP_PAD_SZ	sizeof(u32)
 
 static int hw_break_get(struct task_struct *target,
 			const struct user_regset *regset,
@@ -380,7 +385,7 @@
 			void *kbuf, void __user *ubuf)
 {
 	unsigned int note_type = regset->core_note_type;
-	int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit;
+	int ret, idx = 0, offset, limit;
 	u32 info, ctrl;
 	u64 addr;
 
@@ -389,11 +394,20 @@
 	if (ret)
 		return ret;
 
-	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, 4);
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0,
+				  sizeof(info));
+	if (ret)
+		return ret;
+
+	/* Pad */
+	offset = offsetof(struct user_hwdebug_state, pad);
+	ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, offset,
+				       offset + PTRACE_HBP_PAD_SZ);
 	if (ret)
 		return ret;
 
 	/* (address, ctrl) registers */
+	offset = offsetof(struct user_hwdebug_state, dbg_regs);
 	limit = regset->n * regset->size;
 	while (count && offset < limit) {
 		ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
@@ -413,6 +427,13 @@
 		if (ret)
 			return ret;
 		offset += PTRACE_HBP_CTRL_SZ;
+
+		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+					       offset,
+					       offset + PTRACE_HBP_PAD_SZ);
+		if (ret)
+			return ret;
+		offset += PTRACE_HBP_PAD_SZ;
 		idx++;
 	}
 
@@ -425,12 +446,13 @@
 			const void *kbuf, const void __user *ubuf)
 {
 	unsigned int note_type = regset->core_note_type;
-	int ret, idx = 0, offset = PTRACE_HBP_REG_OFF, limit;
+	int ret, idx = 0, offset, limit;
 	u32 ctrl;
 	u64 addr;
 
-	/* Resource info */
-	ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4);
+	/* Resource info and pad */
+	offset = offsetof(struct user_hwdebug_state, dbg_regs);
+	ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
 	if (ret)
 		return ret;
 
@@ -454,6 +476,13 @@
 		if (ret)
 			return ret;
 		offset += PTRACE_HBP_CTRL_SZ;
+
+		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+						offset,
+						offset + PTRACE_HBP_PAD_SZ);
+		if (ret)
+			return ret;
+		offset += PTRACE_HBP_PAD_SZ;
 		idx++;
 	}
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 48ffb9f..7665a9b 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -170,7 +170,19 @@
 
 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);
 }
 
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index b711525..226b6bf 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -46,7 +46,6 @@
 #include <asm/sections.h>
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
-#include <asm/mmu_context.h>
 
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 17948fc..ba45794 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -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 @@
 /*
  * 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 @@
 	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();