提交 198190a1 编写于 作者: L Linus Torvalds

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
...@@ -22,6 +22,7 @@ config ARM64 ...@@ -22,6 +22,7 @@ config ARM64
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
select HAVE_SPARSE_IRQ select HAVE_SPARSE_IRQ
select IRQ_DOMAIN select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select NO_BOOTMEM select NO_BOOTMEM
select OF select OF
select OF_EARLY_FLATTREE select OF_EARLY_FLATTREE
......
...@@ -18,7 +18,6 @@ generic-y += ipcbuf.h ...@@ -18,7 +18,6 @@ generic-y += ipcbuf.h
generic-y += irq_regs.h generic-y += irq_regs.h
generic-y += kdebug.h generic-y += kdebug.h
generic-y += kmap_types.h generic-y += kmap_types.h
generic-y += linkage.h
generic-y += local.h generic-y += local.h
generic-y += local64.h generic-y += local64.h
generic-y += mman.h generic-y += mman.h
......
#ifndef __ASM_LINKAGE_H
#define __ASM_LINKAGE_H
#define __ALIGN .align 4
#define __ALIGN_STR ".align 4"
#endif
...@@ -92,30 +92,20 @@ static inline void start_thread_common(struct pt_regs *regs, unsigned long pc) ...@@ -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, static inline void start_thread(struct pt_regs *regs, unsigned long pc,
unsigned long sp) unsigned long sp)
{ {
unsigned long *stack = (unsigned long *)sp;
start_thread_common(regs, pc); start_thread_common(regs, pc);
regs->pstate = PSR_MODE_EL0t; regs->pstate = PSR_MODE_EL0t;
regs->sp = sp; 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 #ifdef CONFIG_COMPAT
static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
unsigned long sp) unsigned long sp)
{ {
unsigned int *stack = (unsigned int *)sp;
start_thread_common(regs, pc); start_thread_common(regs, pc);
regs->pstate = COMPAT_PSR_MODE_USR; regs->pstate = COMPAT_PSR_MODE_USR;
if (pc & 1) if (pc & 1)
regs->pstate |= COMPAT_PSR_T_BIT; regs->pstate |= COMPAT_PSR_T_BIT;
regs->compat_sp = sp; 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 #endif
......
...@@ -79,13 +79,14 @@ struct user_fpsimd_state { ...@@ -79,13 +79,14 @@ struct user_fpsimd_state {
struct user_hwdebug_state { struct user_hwdebug_state {
__u32 dbg_info; __u32 dbg_info;
__u32 pad;
struct { struct {
__u64 addr; __u64 addr;
__u32 ctrl; __u32 ctrl;
__u32 pad;
} dbg_regs[16]; } dbg_regs[16];
}; };
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* _UAPI__ASM_PTRACE_H */ #endif /* _UAPI__ASM_PTRACE_H */
...@@ -234,8 +234,12 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type, ...@@ -234,8 +234,12 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
struct arch_hw_breakpoint_ctrl ctrl, struct arch_hw_breakpoint_ctrl ctrl,
struct perf_event_attr *attr) struct perf_event_attr *attr)
{ {
int err, len, type; int err, len, type, disabled = !ctrl.enabled;
if (disabled) {
len = 0;
type = HW_BREAKPOINT_EMPTY;
} else {
err = arch_bp_generic_fields(ctrl, &len, &type); err = arch_bp_generic_fields(ctrl, &len, &type);
if (err) if (err)
return err; return err;
...@@ -252,10 +256,11 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type, ...@@ -252,10 +256,11 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
default: default:
return -EINVAL; return -EINVAL;
} }
}
attr->bp_len = len; attr->bp_len = len;
attr->bp_type = type; attr->bp_type = type;
attr->disabled = !ctrl.enabled; attr->disabled = disabled;
return 0; return 0;
} }
...@@ -372,7 +377,7 @@ static int ptrace_hbp_set_addr(unsigned int note_type, ...@@ -372,7 +377,7 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
#define PTRACE_HBP_ADDR_SZ sizeof(u64) #define PTRACE_HBP_ADDR_SZ sizeof(u64)
#define PTRACE_HBP_CTRL_SZ sizeof(u32) #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, static int hw_break_get(struct task_struct *target,
const struct user_regset *regset, const struct user_regset *regset,
...@@ -380,7 +385,7 @@ static int hw_break_get(struct task_struct *target, ...@@ -380,7 +385,7 @@ static int hw_break_get(struct task_struct *target,
void *kbuf, void __user *ubuf) void *kbuf, void __user *ubuf)
{ {
unsigned int note_type = regset->core_note_type; 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; u32 info, ctrl;
u64 addr; u64 addr;
...@@ -389,11 +394,20 @@ static int hw_break_get(struct task_struct *target, ...@@ -389,11 +394,20 @@ static int hw_break_get(struct task_struct *target,
if (ret) if (ret)
return 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) if (ret)
return ret; return ret;
/* (address, ctrl) registers */ /* (address, ctrl) registers */
offset = offsetof(struct user_hwdebug_state, dbg_regs);
limit = regset->n * regset->size; limit = regset->n * regset->size;
while (count && offset < limit) { while (count && offset < limit) {
ret = ptrace_hbp_get_addr(note_type, target, idx, &addr); ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
...@@ -413,6 +427,13 @@ static int hw_break_get(struct task_struct *target, ...@@ -413,6 +427,13 @@ static int hw_break_get(struct task_struct *target,
if (ret) if (ret)
return ret; return ret;
offset += PTRACE_HBP_CTRL_SZ; 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++; idx++;
} }
...@@ -425,12 +446,13 @@ static int hw_break_set(struct task_struct *target, ...@@ -425,12 +446,13 @@ static int hw_break_set(struct task_struct *target,
const void *kbuf, const void __user *ubuf) const void *kbuf, const void __user *ubuf)
{ {
unsigned int note_type = regset->core_note_type; 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; u32 ctrl;
u64 addr; u64 addr;
/* Resource info */ /* Resource info and pad */
ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, 4); offset = offsetof(struct user_hwdebug_state, dbg_regs);
ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
if (ret) if (ret)
return ret; return ret;
...@@ -454,6 +476,13 @@ static int hw_break_set(struct task_struct *target, ...@@ -454,6 +476,13 @@ static int hw_break_set(struct task_struct *target,
if (ret) if (ret)
return ret; return ret;
offset += PTRACE_HBP_CTRL_SZ; 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++; idx++;
} }
......
...@@ -170,7 +170,19 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys) ...@@ -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) void __init early_init_dt_add_memory_arch(u64 base, u64 size)
{ {
base &= PAGE_MASK;
size &= 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); memblock_add(base, size);
} }
......
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/mmu_context.h>
/* /*
* as from 2.5, kernels no longer have an init_tasks structure * as from 2.5, kernels no longer have an init_tasks structure
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/timekeeper_internal.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
...@@ -222,11 +223,10 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm) ...@@ -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. * Update the vDSO data page to keep in sync with kernel timekeeping.
*/ */
void update_vsyscall(struct timespec *ts, struct timespec *wtm, void update_vsyscall(struct timekeeper *tk)
struct clocksource *clock, u32 mult)
{ {
struct timespec xtime_coarse; 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; ++vdso_data->tb_seq_count;
smp_wmb(); smp_wmb();
...@@ -237,13 +237,13 @@ void update_vsyscall(struct timespec *ts, struct timespec *wtm, ...@@ -237,13 +237,13 @@ void update_vsyscall(struct timespec *ts, struct timespec *wtm,
vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec; vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec;
if (!use_syscall) { if (!use_syscall) {
vdso_data->cs_cycle_last = clock->cycle_last; vdso_data->cs_cycle_last = tk->clock->cycle_last;
vdso_data->xtime_clock_sec = ts->tv_sec; vdso_data->xtime_clock_sec = tk->xtime_sec;
vdso_data->xtime_clock_nsec = ts->tv_nsec; vdso_data->xtime_clock_nsec = tk->xtime_nsec >> tk->shift;
vdso_data->cs_mult = mult; vdso_data->cs_mult = tk->mult;
vdso_data->cs_shift = clock->shift; vdso_data->cs_shift = tk->shift;
vdso_data->wtm_clock_sec = wtm->tv_sec; vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec;
vdso_data->wtm_clock_nsec = wtm->tv_nsec; vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
} }
smp_wmb(); smp_wmb();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册