summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-03-16 23:35:25 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-03-16 23:35:25 +0000
commit1f0090a1eaa1b750a2fc5c99c91b790d5322a1fd (patch)
treec685060f260410e6704c9dfd457ed8c347141f1d /arch/arm/kernel
parent2472f3c8d8fc18b25b2cf1574c036e238187c0ff (diff)
parent10a8c3839810ac9af1aec836d61b92e7a879f5fa (diff)
downloadop-kernel-dev-1f0090a1eaa1b750a2fc5c99c91b790d5322a1fd.zip
op-kernel-dev-1f0090a1eaa1b750a2fc5c99c91b790d5322a1fd.tar.gz
Merge branch 'misc' into devel
Conflicts: arch/arm/Kconfig
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/bios32.c5
-rw-r--r--arch/arm/kernel/head-common.S90
-rw-r--r--arch/arm/kernel/head-nommu.S3
-rw-r--r--arch/arm/kernel/head.S9
-rw-r--r--arch/arm/kernel/irq.c50
-rw-r--r--arch/arm/kernel/module.c27
-rw-r--r--arch/arm/kernel/ptrace.c383
-rw-r--r--arch/arm/kernel/ptrace.h37
-rw-r--r--arch/arm/kernel/return_address.c1
-rw-r--r--arch/arm/kernel/setup.c39
-rw-r--r--arch/arm/kernel/signal.c9
-rw-r--r--arch/arm/kernel/traps.c4
12 files changed, 94 insertions, 563 deletions
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c6273a3..d86fcd4 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -583,6 +583,11 @@ void __init pci_common_init(struct hw_pci *hw)
* Assign resources.
*/
pci_bus_assign_resources(bus);
+
+ /*
+ * Enable bridges
+ */
+ pci_enable_bridges(bus);
}
/*
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 8f57515..c84b57d 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -25,83 +25,6 @@
* machine ID for example).
*/
__HEAD
-__error_a:
-#ifdef CONFIG_DEBUG_LL
- mov r4, r1 @ preserve machine ID
- adr r0, str_a1
- bl printascii
- mov r0, r4
- bl printhex8
- adr r0, str_a2
- bl printascii
- adr r3, __lookup_machine_type_data
- ldmia r3, {r4, r5, r6} @ get machine desc list
- sub r4, r3, r4 @ get offset between virt&phys
- add r5, r5, r4 @ convert virt addresses to
- add r6, r6, r4 @ physical address space
-1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
- bl printhex8
- mov r0, #'\t'
- bl printch
- ldr r0, [r5, #MACHINFO_NAME] @ get machine name
- add r0, r0, r4
- bl printascii
- mov r0, #'\n'
- bl printch
- add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
- cmp r5, r6
- blo 1b
- adr r0, str_a3
- bl printascii
- b __error
-ENDPROC(__error_a)
-
-str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
-str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
-str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
- .align
-#else
- b __error
-#endif
-
-/*
- * Lookup machine architecture in the linker-build list of architectures.
- * Note that we can't use the absolute addresses for the __arch_info
- * lists since we aren't running with the MMU on (and therefore, we are
- * not in the correct address space). We have to calculate the offset.
- *
- * r1 = machine architecture number
- * Returns:
- * r3, r4, r6 corrupted
- * r5 = mach_info pointer in physical address space
- */
-__lookup_machine_type:
- adr r3, __lookup_machine_type_data
- ldmia r3, {r4, r5, r6}
- sub r3, r3, r4 @ get offset between virt&phys
- add r5, r5, r3 @ convert virt addresses to
- add r6, r6, r3 @ physical address space
-1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
- teq r3, r1 @ matches loader number?
- beq 2f @ found
- add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
- cmp r5, r6
- blo 1b
- mov r5, #0 @ unknown machine
-2: mov pc, lr
-ENDPROC(__lookup_machine_type)
-
-/*
- * Look in arch/arm/kernel/arch.[ch] for information about the
- * __arch_info structures.
- */
- .align 2
- .type __lookup_machine_type_data, %object
-__lookup_machine_type_data:
- .long .
- .long __arch_info_begin
- .long __arch_info_end
- .size __lookup_machine_type_data, . - __lookup_machine_type_data
/* Determine validity of the r2 atags pointer. The heuristic requires
* that the pointer be aligned, in the first 16k of physical RAM and
@@ -109,8 +32,6 @@ __lookup_machine_type_data:
* of this function may be more lenient with the physical address and
* may also be able to move the ATAGS block if necessary.
*
- * r8 = machinfo
- *
* Returns:
* r2 either valid atags pointer, or zero
* r5, r6 corrupted
@@ -185,17 +106,6 @@ __mmap_switched_data:
.size __mmap_switched_data, . - __mmap_switched_data
/*
- * This provides a C-API version of __lookup_machine_type
- */
-ENTRY(lookup_machine_type)
- stmfd sp!, {r4 - r6, lr}
- mov r1, r0
- bl __lookup_machine_type
- mov r0, r5
- ldmfd sp!, {r4 - r6, pc}
-ENDPROC(lookup_machine_type)
-
-/*
* This provides a C-API version of __lookup_processor_type
*/
ENTRY(lookup_processor_type)
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 814ce1a..6b1e0ad 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -44,9 +44,6 @@ ENTRY(stext)
bl __lookup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)?
beq __error_p @ yes, error 'p'
- bl __lookup_machine_type @ r5=machinfo
- movs r8, r5 @ invalid machine (r5=0)?
- beq __error_a @ yes, error 'a'
adr lr, BSYM(__after_proc_init) @ return (PIC) address
ARM( add pc, r10, #PROCINFO_INITFUNC )
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f06ff9f..60fe279 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -87,14 +87,10 @@ ENTRY(stext)
movs r10, r5 @ invalid processor (r5=0)?
THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_p @ yes, error 'p'
- bl __lookup_machine_type @ r5=machinfo
- movs r8, r5 @ invalid machine (r5=0)?
- THUMB( it eq ) @ force fixup-able long branch encoding
- beq __error_a @ yes, error 'a'
/*
* r1 = machine no, r2 = atags,
- * r8 = machinfo, r9 = cpuid, r10 = procinfo
+ * r9 = cpuid, r10 = procinfo
*/
bl __vet_atags
#ifdef CONFIG_SMP_ON_UP
@@ -105,7 +101,7 @@ ENTRY(stext)
/*
* The following calls CPU specific code in a position independent
* manner. See arch/arm/mm/proc-*.S for details. r10 = base of
- * xxx_proc_info structure selected by __lookup_machine_type
+ * xxx_proc_info structure selected by __lookup_processor_type
* above. On return, the CPU will be ready for the MMU to be
* turned on, and r0 will hold the CPU control register value.
*/
@@ -124,7 +120,6 @@ ENDPROC(stext)
* amount which are required to get the kernel running, which
* generally means mapping in the kernel code.
*
- * r8 = machinfo
* r9 = cpuid
* r10 = procinfo
*
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 28536e3..3535d37 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -179,14 +179,21 @@ int __init arch_probe_nr_irqs(void)
#ifdef CONFIG_HOTPLUG_CPU
-static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
+static bool migrate_one_irq(struct irq_data *d)
{
- pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->irq_data.node, cpu);
+ unsigned int cpu = cpumask_any_and(d->affinity, cpu_online_mask);
+ bool ret = false;
- raw_spin_lock_irq(&desc->lock);
- desc->irq_data.chip->irq_set_affinity(&desc->irq_data,
- cpumask_of(cpu), false);
- raw_spin_unlock_irq(&desc->lock);
+ if (cpu >= nr_cpu_ids) {
+ cpu = cpumask_any(cpu_online_mask);
+ ret = true;
+ }
+
+ pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu);
+
+ d->chip->irq_set_affinity(d, cpumask_of(cpu), true);
+
+ return ret;
}
/*
@@ -198,25 +205,30 @@ void migrate_irqs(void)
{
unsigned int i, cpu = smp_processor_id();
struct irq_desc *desc;
+ unsigned long flags;
+
+ local_irq_save(flags);
for_each_irq_desc(i, desc) {
struct irq_data *d = &desc->irq_data;
+ bool affinity_broken = false;
- if (d->node == cpu) {
- unsigned int newcpu = cpumask_any_and(d->affinity,
- cpu_online_mask);
- if (newcpu >= nr_cpu_ids) {
- if (printk_ratelimit())
- printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
- i, cpu);
+ raw_spin_lock(&desc->lock);
+ do {
+ if (desc->action == NULL)
+ break;
- cpumask_setall(d->affinity);
- newcpu = cpumask_any_and(d->affinity,
- cpu_online_mask);
- }
+ if (d->node != cpu)
+ break;
- route_irq(desc, i, newcpu);
- }
+ affinity_broken = migrate_one_irq(d);
+ } while (0);
+ raw_spin_unlock(&desc->lock);
+
+ if (affinity_broken && printk_ratelimit())
+ pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu);
}
+
+ local_irq_restore(flags);
}
#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 6d4105e..6fcf22c 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -76,6 +76,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
unsigned long loc;
Elf32_Sym *sym;
+ const char *symname;
s32 offset;
#ifdef CONFIG_THUMB2_KERNEL
u32 upper, lower, sign, j1, j2;
@@ -83,18 +84,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
offset = ELF32_R_SYM(rel->r_info);
if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
- printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n",
+ pr_err("%s: section %u reloc %u: bad relocation sym offset\n",
module->name, relindex, i);
return -ENOEXEC;
}
sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
+ symname = strtab + sym->st_name;
if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
- printk(KERN_ERR "%s: out of bounds relocation, "
- "section %d reloc %d offset %d size %d\n",
- module->name, relindex, i, rel->r_offset,
- dstsec->sh_size);
+ pr_err("%s: section %u reloc %u sym '%s': out of bounds relocation, offset %d size %u\n",
+ module->name, relindex, i, symname,
+ rel->r_offset, dstsec->sh_size);
return -ENOEXEC;
}
@@ -120,10 +121,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
if (offset & 3 ||
offset <= (s32)0xfe000000 ||
offset >= (s32)0x02000000) {
- printk(KERN_ERR
- "%s: relocation out of range, section "
- "%d reloc %d sym '%s'\n", module->name,
- relindex, i, strtab + sym->st_name);
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+ module->name, relindex, i, symname,
+ ELF32_R_TYPE(rel->r_info), loc,
+ sym->st_value);
return -ENOEXEC;
}
@@ -196,10 +197,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
if (!(offset & 1) ||
offset <= (s32)0xff000000 ||
offset >= (s32)0x01000000) {
- printk(KERN_ERR
- "%s: relocation out of range, section "
- "%d reloc %d sym '%s'\n", module->name,
- relindex, i, strtab + sym->st_name);
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+ module->name, relindex, i, symname,
+ ELF32_R_TYPE(rel->r_info), loc,
+ sym->st_value);
return -ENOEXEC;
}
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index b13e70f..2bf27f3 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -26,8 +26,6 @@
#include <asm/system.h>
#include <asm/traps.h>
-#include "ptrace.h"
-
#define REG_PC 15
#define REG_PSR 16
/*
@@ -184,389 +182,12 @@ put_user_reg(struct task_struct *task, int offset, long data)
return ret;
}
-static inline int
-read_u32(struct task_struct *task, unsigned long addr, u32 *res)
-{
- int ret;
-
- ret = access_process_vm(task, addr, res, sizeof(*res), 0);
-
- return ret == sizeof(*res) ? 0 : -EIO;
-}
-
-static inline int
-read_instr(struct task_struct *task, unsigned long addr, u32 *res)
-{
- int ret;
-
- if (addr & 1) {
- u16 val;
- ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0);
- ret = ret == sizeof(val) ? 0 : -EIO;
- *res = val;
- } else {
- u32 val;
- ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0);
- ret = ret == sizeof(val) ? 0 : -EIO;
- *res = val;
- }
- return ret;
-}
-
-/*
- * Get value of register `rn' (in the instruction)
- */
-static unsigned long
-ptrace_getrn(struct task_struct *child, unsigned long insn)
-{
- unsigned int reg = (insn >> 16) & 15;
- unsigned long val;
-
- val = get_user_reg(child, reg);
- if (reg == 15)
- val += 8;
-
- return val;
-}
-
-/*
- * Get value of operand 2 (in an ALU instruction)
- */
-static unsigned long
-ptrace_getaluop2(struct task_struct *child, unsigned long insn)
-{
- unsigned long val;
- int shift;
- int type;
-
- if (insn & 1 << 25) {
- val = insn & 255;
- shift = (insn >> 8) & 15;
- type = 3;
- } else {
- val = get_user_reg (child, insn & 15);
-
- if (insn & (1 << 4))
- shift = (int)get_user_reg (child, (insn >> 8) & 15);
- else
- shift = (insn >> 7) & 31;
-
- type = (insn >> 5) & 3;
- }
-
- switch (type) {
- case 0: val <<= shift; break;
- case 1: val >>= shift; break;
- case 2:
- val = (((signed long)val) >> shift);
- break;
- case 3:
- val = (val >> shift) | (val << (32 - shift));
- break;
- }
- return val;
-}
-
-/*
- * Get value of operand 2 (in a LDR instruction)
- */
-static unsigned long
-ptrace_getldrop2(struct task_struct *child, unsigned long insn)
-{
- unsigned long val;
- int shift;
- int type;
-
- val = get_user_reg(child, insn & 15);
- shift = (insn >> 7) & 31;
- type = (insn >> 5) & 3;
-
- switch (type) {
- case 0: val <<= shift; break;
- case 1: val >>= shift; break;
- case 2:
- val = (((signed long)val) >> shift);
- break;
- case 3:
- val = (val >> shift) | (val << (32 - shift));
- break;
- }
- return val;
-}
-
-#define OP_MASK 0x01e00000
-#define OP_AND 0x00000000
-#define OP_EOR 0x00200000
-#define OP_SUB 0x00400000
-#define OP_RSB 0x00600000
-#define OP_ADD 0x00800000
-#define OP_ADC 0x00a00000
-#define OP_SBC 0x00c00000
-#define OP_RSC 0x00e00000
-#define OP_ORR 0x01800000
-#define OP_MOV 0x01a00000
-#define OP_BIC 0x01c00000
-#define OP_MVN 0x01e00000
-
-static unsigned long
-get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
-{
- u32 alt = 0;
-
- switch (insn & 0x0e000000) {
- case 0x00000000:
- case 0x02000000: {
- /*
- * data processing
- */
- long aluop1, aluop2, ccbit;
-
- if ((insn & 0x0fffffd0) == 0x012fff10) {
- /*
- * bx or blx
- */
- alt = get_user_reg(child, insn & 15);
- break;
- }
-
-
- if ((insn & 0xf000) != 0xf000)
- break;
-
- aluop1 = ptrace_getrn(child, insn);
- aluop2 = ptrace_getaluop2(child, insn);
- ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0;
-
- switch (insn & OP_MASK) {
- case OP_AND: alt = aluop1 & aluop2; break;
- case OP_EOR: alt = aluop1 ^ aluop2; break;
- case OP_SUB: alt = aluop1 - aluop2; break;
- case OP_RSB: alt = aluop2 - aluop1; break;
- case OP_ADD: alt = aluop1 + aluop2; break;
- case OP_ADC: alt = aluop1 + aluop2 + ccbit; break;
- case OP_SBC: alt = aluop1 - aluop2 + ccbit; break;
- case OP_RSC: alt = aluop2 - aluop1 + ccbit; break;
- case OP_ORR: alt = aluop1 | aluop2; break;
- case OP_MOV: alt = aluop2; break;
- case OP_BIC: alt = aluop1 & ~aluop2; break;
- case OP_MVN: alt = ~aluop2; break;
- }
- break;
- }
-
- case 0x04000000:
- case 0x06000000:
- /*
- * ldr
- */
- if ((insn & 0x0010f000) == 0x0010f000) {
- unsigned long base;
-
- base = ptrace_getrn(child, insn);
- if (insn & 1 << 24) {
- long aluop2;
-
- if (insn & 0x02000000)
- aluop2 = ptrace_getldrop2(child, insn);
- else
- aluop2 = insn & 0xfff;
-
- if (insn & 1 << 23)
- base += aluop2;
- else
- base -= aluop2;
- }
- read_u32(child, base, &alt);
- }
- break;
-
- case 0x08000000:
- /*
- * ldm
- */
- if ((insn & 0x00108000) == 0x00108000) {
- unsigned long base;
- unsigned int nr_regs;
-
- if (insn & (1 << 23)) {
- nr_regs = hweight16(insn & 65535) << 2;
-
- if (!(insn & (1 << 24)))
- nr_regs -= 4;
- } else {
- if (insn & (1 << 24))
- nr_regs = -4;
- else
- nr_regs = 0;
- }
-
- base = ptrace_getrn(child, insn);
-
- read_u32(child, base + nr_regs, &alt);
- break;
- }
- break;
-
- case 0x0a000000: {
- /*
- * bl or b
- */
- signed long displ;
- /* It's a branch/branch link: instead of trying to
- * figure out whether the branch will be taken or not,
- * we'll put a breakpoint at both locations. This is
- * simpler, more reliable, and probably not a whole lot
- * slower than the alternative approach of emulating the
- * branch.
- */
- displ = (insn & 0x00ffffff) << 8;
- displ = (displ >> 6) + 8;
- if (displ != 0 && displ != 4)
- alt = pc + displ;
- }
- break;
- }
-
- return alt;
-}
-
-static int
-swap_insn(struct task_struct *task, unsigned long addr,
- void *old_insn, void *new_insn, int size)
-{
- int ret;
-
- ret = access_process_vm(task, addr, old_insn, size, 0);
- if (ret == size)
- ret = access_process_vm(task, addr, new_insn, size, 1);
- return ret;
-}
-
-static void
-add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr)
-{
- int nr = dbg->nsaved;
-
- if (nr < 2) {
- u32 new_insn = BREAKINST_ARM;
- int res;
-
- res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4);
-
- if (res == 4) {
- dbg->bp[nr].address = addr;
- dbg->nsaved += 1;
- }
- } else
- printk(KERN_ERR "ptrace: too many breakpoints\n");
-}
-
-/*
- * Clear one breakpoint in the user program. We copy what the hardware
- * does and use bit 0 of the address to indicate whether this is a Thumb
- * breakpoint or an ARM breakpoint.
- */
-static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
-{
- unsigned long addr = bp->address;
- union debug_insn old_insn;
- int ret;
-
- if (addr & 1) {
- ret = swap_insn(task, addr & ~1, &old_insn.thumb,
- &bp->insn.thumb, 2);
-
- if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
- printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
- "0x%08lx (0x%04x)\n", task->comm,
- task_pid_nr(task), addr, old_insn.thumb);
- } else {
- ret = swap_insn(task, addr & ~3, &old_insn.arm,
- &bp->insn.arm, 4);
-
- if (ret != 4 || old_insn.arm != BREAKINST_ARM)
- printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
- "0x%08lx (0x%08x)\n", task->comm,
- task_pid_nr(task), addr, old_insn.arm);
- }
-}
-
-void ptrace_set_bpt(struct task_struct *child)
-{
- struct pt_regs *regs;
- unsigned long pc;
- u32 insn;
- int res;
-
- regs = task_pt_regs(child);
- pc = instruction_pointer(regs);
-
- if (thumb_mode(regs)) {
- printk(KERN_WARNING "ptrace: can't handle thumb mode\n");
- return;
- }
-
- res = read_instr(child, pc, &insn);
- if (!res) {
- struct debug_info *dbg = &child->thread.debug;
- unsigned long alt;
-
- dbg->nsaved = 0;
-
- alt = get_branch_address(child, pc, insn);
- if (alt)
- add_breakpoint(child, dbg, alt);
-
- /*
- * Note that we ignore the result of setting the above
- * breakpoint since it may fail. When it does, this is
- * not so much an error, but a forewarning that we may
- * be receiving a prefetch abort shortly.
- *
- * If we don't set this breakpoint here, then we can
- * lose control of the thread during single stepping.
- */
- if (!alt || predicate(insn) != PREDICATE_ALWAYS)
- add_breakpoint(child, dbg, pc + 4);
- }
-}
-
-/*
- * Ensure no single-step breakpoint is pending. Returns non-zero
- * value if child was being single-stepped.
- */
-void ptrace_cancel_bpt(struct task_struct *child)
-{
- int i, nsaved = child->thread.debug.nsaved;
-
- child->thread.debug.nsaved = 0;
-
- if (nsaved > 2) {
- printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
- nsaved = 2;
- }
-
- for (i = 0; i < nsaved; i++)
- clear_breakpoint(child, &child->thread.debug.bp[i]);
-}
-
-void user_disable_single_step(struct task_struct *task)
-{
- task->ptrace &= ~PT_SINGLESTEP;
- ptrace_cancel_bpt(task);
-}
-
-void user_enable_single_step(struct task_struct *task)
-{
- task->ptrace |= PT_SINGLESTEP;
-}
-
/*
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
{
- user_disable_single_step(child);
+ /* Nothing to do. */
}
/*
@@ -576,8 +197,6 @@ void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
{
siginfo_t info;
- ptrace_cancel_bpt(tsk);
-
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h
deleted file mode 100644
index 3926605..0000000
--- a/arch/arm/kernel/ptrace.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * linux/arch/arm/kernel/ptrace.h
- *
- * Copyright (C) 2000-2003 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/ptrace.h>
-
-extern void ptrace_cancel_bpt(struct task_struct *);
-extern void ptrace_set_bpt(struct task_struct *);
-extern void ptrace_break(struct task_struct *, struct pt_regs *);
-
-/*
- * Send SIGTRAP if we're single-stepping
- */
-static inline void single_step_trap(struct task_struct *task)
-{
- if (task->ptrace & PT_SINGLESTEP) {
- ptrace_cancel_bpt(task);
- send_sig(SIGTRAP, task, 1);
- }
-}
-
-static inline void single_step_clear(struct task_struct *task)
-{
- if (task->ptrace & PT_SINGLESTEP)
- ptrace_cancel_bpt(task);
-}
-
-static inline void single_step_set(struct task_struct *task)
-{
- if (task->ptrace & PT_SINGLESTEP)
- ptrace_set_bpt(task);
-}
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index df246da..0b13a72 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -9,6 +9,7 @@
* the Free Software Foundation.
*/
#include <linux/module.h>
+#include <linux/ftrace.h>
#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
#include <linux/sched.h>
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 5ea4fb71..db23828 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -308,7 +308,44 @@ static void __init cacheid_init(void)
* already provide the required functionality.
*/
extern struct proc_info_list *lookup_processor_type(unsigned int);
-extern struct machine_desc *lookup_machine_type(unsigned int);
+
+static void __init early_print(const char *str, ...)
+{
+ extern void printascii(const char *);
+ char buf[256];
+ va_list ap;
+
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+
+#ifdef CONFIG_DEBUG_LL
+ printascii(buf);
+#endif
+ printk("%s", buf);
+}
+
+static struct machine_desc * __init lookup_machine_type(unsigned int type)
+{
+ extern struct machine_desc __arch_info_begin[], __arch_info_end[];
+ struct machine_desc *p;
+
+ for (p = __arch_info_begin; p < __arch_info_end; p++)
+ if (type == p->nr)
+ return p;
+
+ early_print("\n"
+ "Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n"
+ "Available machine support:\n\nID (hex)\tNAME\n", type);
+
+ for (p = __arch_info_begin; p < __arch_info_end; p++)
+ early_print("%08x\t%s\n", p->nr, p->name);
+
+ early_print("\nPlease check your kernel config and/or bootloader.\n");
+
+ while (true)
+ /* can't use cpu_relax() here as it may require MMU setup */;
+}
static void __init feat_v6_fixup(void)
{
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index abaf844..cb83983 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -20,7 +20,6 @@
#include <asm/unistd.h>
#include <asm/vfp.h>
-#include "ptrace.h"
#include "signal.h"
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -348,8 +347,6 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
if (restore_sigframe(regs, frame))
goto badframe;
- single_step_trap(current);
-
return regs->ARM_r0;
badframe:
@@ -383,8 +380,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
goto badframe;
- single_step_trap(current);
-
return regs->ARM_r0;
badframe:
@@ -706,8 +701,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
if (try_to_freeze())
goto no_signal;
- single_step_clear(current);
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
sigset_t *oldset;
@@ -726,7 +719,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
- single_step_set(current);
return;
}
@@ -772,7 +764,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
}
}
- single_step_set(current);
}
asmlinkage void
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index ee57640..21ac43f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -23,6 +23,7 @@
#include <linux/kexec.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
@@ -32,7 +33,6 @@
#include <asm/unwind.h>
#include <asm/tls.h>
-#include "ptrace.h"
#include "signal.h"
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
@@ -256,7 +256,7 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
return ret;
}
-DEFINE_SPINLOCK(die_lock);
+static DEFINE_SPINLOCK(die_lock);
/*
* This function is protected against re-entrancy.
OpenPOWER on IntegriCloud