summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/crash.c2
-rw-r--r--arch/powerpc/kernel/crash_dump.c2
-rw-r--r--arch/powerpc/kernel/kprobes.c12
-rw-r--r--arch/powerpc/kernel/machine_kexec.c6
-rw-r--r--arch/powerpc/kernel/pci_64.c3
-rw-r--r--arch/powerpc/kernel/process.c14
-rw-r--r--arch/powerpc/kernel/ptrace-common.h4
-rw-r--r--arch/powerpc/kernel/rtas.c13
-rw-r--r--arch/powerpc/kernel/setup_64.c60
-rw-r--r--arch/powerpc/kernel/smp.c6
-rw-r--r--arch/powerpc/kernel/udbg.c25
-rw-r--r--arch/powerpc/kernel/udbg_16550.c2
-rw-r--r--arch/powerpc/kernel/vdso32/.gitignore1
-rw-r--r--arch/powerpc/kernel/vdso64/.gitignore1
15 files changed, 97 insertions, 58 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 144e284d21d..bbfa1bdceb4 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -61,9 +61,9 @@ obj-$(CONFIG_MODULES) += $(module-y)
pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
pci_direct_iommu.o iomap.o
obj-$(CONFIG_PCI) += $(pci64-y)
-kexec-$(CONFIG_PPC64) := machine_kexec_64.o
+kexec-$(CONFIG_PPC64) := machine_kexec_64.o crash.o
kexec-$(CONFIG_PPC32) := machine_kexec_32.o
-obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
+obj-$(CONFIG_KEXEC) += machine_kexec.o $(kexec-y)
ifeq ($(CONFIG_PPC_ISERIES),y)
$(obj)/head_64.o: $(obj)/lparmap.s
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 4681155121e..5f248e3fdf8 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -18,7 +18,6 @@
#include <linux/kexec.h>
#include <linux/bootmem.h>
#include <linux/crash_dump.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
@@ -30,6 +29,7 @@
#include <asm/kdump.h>
#include <asm/lmb.h>
#include <asm/firmware.h>
+#include <asm/smp.h>
#ifdef DEBUG
#include <asm/udbg.h>
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 87effa3f21a..211d72653ea 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -55,6 +55,7 @@ void __init kdump_setup(void)
DBG(" <- kdump_setup()\n");
}
+#ifdef CONFIG_PROC_VMCORE
static int __init parse_elfcorehdr(char *p)
{
if (p)
@@ -63,6 +64,7 @@ static int __init parse_elfcorehdr(char *p)
return 0;
}
__setup("elfcorehdr=", parse_elfcorehdr);
+#endif
static int __init parse_savemaxmem(char *p)
{
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 27b0c40601f..cfab48566db 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -179,6 +179,18 @@ static inline int kprobe_handler(struct pt_regs *regs)
kcb->kprobe_status = KPROBE_REENTER;
return 1;
} else {
+ if (*addr != BREAKPOINT_INSTRUCTION) {
+ /* If trap variant, then it belongs not to us */
+ kprobe_opcode_t cur_insn = *addr;
+ if (is_trap(cur_insn))
+ goto no_kprobe;
+ /* The breakpoint instruction was removed by
+ * another cpu right after we hit, no further
+ * handling of this interrupt is appropriate
+ */
+ ret = 1;
+ goto no_kprobe;
+ }
p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
goto ss_probe;
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index a91e40c9ae4..a81ca1b841e 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -14,12 +14,6 @@
#include <linux/threads.h>
#include <asm/machdep.h>
-/*
- * Provide a dummy crash_notes definition until crash dump is implemented.
- * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
- */
-note_buf_t crash_notes[NR_CPUS];
-
void machine_crash_shutdown(struct pt_regs *regs)
{
if (ppc_md.machine_crash_shutdown)
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ba21a6c4f46..24fe70f40b6 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -271,6 +271,9 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *b)
list_for_each_entry(child_bus, &b->children, node)
pcibios_claim_one_bus(child_bus);
}
+#ifdef CONFIG_HOTPLUG
+EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
+#endif
#ifndef CONFIG_PPC_ISERIES
static void __init pcibios_claim_of_setup(void)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 105d5609ff5..1f816f0d774 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -424,7 +424,7 @@ void show_regs(struct pt_regs * regs)
if (trap == 0x300 || trap == 0x600)
printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
printk("TASK = %p[%d] '%s' THREAD: %p",
- current, current->pid, current->comm, current->thread_info);
+ current, current->pid, current->comm, task_thread_info(current));
#ifdef CONFIG_SMP
printk(" CPU: %d", smp_processor_id());
@@ -503,7 +503,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
{
struct pt_regs *childregs, *kregs;
extern void ret_from_fork(void);
- unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
+ unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
CHECK_FULL_REGS(regs);
/* Copy registers */
@@ -516,7 +516,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
#ifdef CONFIG_PPC32
childregs->gpr[2] = (unsigned long) p;
#else
- clear_ti_thread_flag(p->thread_info, TIF_32BIT);
+ clear_tsk_thread_flag(p, TIF_32BIT);
#endif
p->thread.regs = NULL; /* no user register state */
} else {
@@ -588,10 +588,8 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
* set. Do it now.
*/
if (!current->thread.regs) {
- unsigned long childregs = (unsigned long)current->thread_info +
- THREAD_SIZE;
- childregs -= sizeof(struct pt_regs);
- current->thread.regs = (struct pt_regs *)childregs;
+ struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE;
+ current->thread.regs = regs - 1;
}
memset(regs->gpr, 0, sizeof(regs->gpr));
@@ -767,7 +765,7 @@ out:
static int validate_sp(unsigned long sp, struct task_struct *p,
unsigned long nbytes)
{
- unsigned long stack_page = (unsigned long)p->thread_info;
+ unsigned long stack_page = (unsigned long)task_stack_page(p);
if (sp >= stack_page + sizeof(struct thread_struct)
&& sp <= stack_page + THREAD_SIZE - nbytes)
diff --git a/arch/powerpc/kernel/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h
index b1babb72967..5ccbdbe0d5c 100644
--- a/arch/powerpc/kernel/ptrace-common.h
+++ b/arch/powerpc/kernel/ptrace-common.h
@@ -62,7 +62,7 @@ static inline void set_single_step(struct task_struct *task)
struct pt_regs *regs = task->thread.regs;
if (regs != NULL)
regs->msr |= MSR_SE;
- set_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
+ set_tsk_thread_flag(task, TIF_SINGLESTEP);
}
static inline void clear_single_step(struct task_struct *task)
@@ -70,7 +70,7 @@ static inline void clear_single_step(struct task_struct *task)
struct pt_regs *regs = task->thread.regs;
if (regs != NULL)
regs->msr &= ~MSR_SE;
- clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
+ clear_tsk_thread_flag(task, TIF_SINGLESTEP);
}
#ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index ae2e2a31a70..4b9cfe4637b 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -17,6 +17,7 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/capability.h>
#include <linux/delay.h>
#include <asm/prom.h>
@@ -29,6 +30,7 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/lmb.h>
+#include <asm/udbg.h>
struct rtas_t rtas = {
.lock = SPIN_LOCK_UNLOCKED
@@ -52,7 +54,7 @@ EXPORT_SYMBOL(rtas_flash_term_hook);
* are designed only for very early low-level debugging, which
* is why the token is hard-coded to 10.
*/
-void call_rtas_display_status(unsigned char c)
+static void call_rtas_display_status(char c)
{
struct rtas_args *args = &rtas.args;
unsigned long s;
@@ -65,14 +67,14 @@ void call_rtas_display_status(unsigned char c)
args->nargs = 1;
args->nret = 1;
args->rets = (rtas_arg_t *)&(args->args[1]);
- args->args[0] = (int)c;
+ args->args[0] = (unsigned char)c;
enter_rtas(__pa(args));
spin_unlock_irqrestore(&rtas.lock, s);
}
-void call_rtas_display_status_delay(unsigned char c)
+static void call_rtas_display_status_delay(char c)
{
static int pending_newline = 0; /* did last write end with unprinted newline? */
static int width = 16;
@@ -96,6 +98,11 @@ void call_rtas_display_status_delay(unsigned char c)
}
}
+void __init udbg_init_rtas(void)
+{
+ udbg_putc = call_rtas_display_status_delay;
+}
+
void rtas_progress(char *s, unsigned short hex)
{
struct device_node *root;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index c4b76961d6d..e29b275e09e 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -33,6 +33,7 @@
#include <linux/unistd.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
+#include <linux/bootmem.h>
#include <asm/io.h>
#include <asm/kdump.h>
#include <asm/prom.h>
@@ -70,33 +71,6 @@
#define DBG(fmt...)
#endif
-/*
- * Here are some early debugging facilities. You can enable one
- * but your kernel will not boot on anything else if you do so
- */
-
-/* This one is for use on LPAR machines that support an HVC console
- * on vterm 0
- */
-extern void udbg_init_debug_lpar(void);
-/* This one is for use on Apple G5 machines
- */
-extern void udbg_init_pmac_realmode(void);
-/* That's RTAS panel debug */
-extern void call_rtas_display_status_delay(unsigned char c);
-/* Here's maple real mode debug */
-extern void udbg_init_maple_realmode(void);
-
-#define EARLY_DEBUG_INIT() do {} while(0)
-
-#if 0
-#define EARLY_DEBUG_INIT() udbg_init_debug_lpar()
-#define EARLY_DEBUG_INIT() udbg_init_maple_realmode()
-#define EARLY_DEBUG_INIT() udbg_init_pmac_realmode()
-#define EARLY_DEBUG_INIT() \
- do { udbg_putc = call_rtas_display_status_delay; } while(0)
-#endif
-
int have_of = 1;
int boot_cpuid = 0;
int boot_cpuid_phys = 0;
@@ -237,11 +211,8 @@ void __init early_setup(unsigned long dt_ptr)
struct paca_struct *lpaca = get_paca();
static struct machdep_calls **mach;
- /*
- * Enable early debugging if any specified (see top of
- * this file)
- */
- EARLY_DEBUG_INIT();
+ /* Enable early debugging if any specified (see udbg.h) */
+ udbg_early_init();
DBG(" -> early_setup()\n");
@@ -684,3 +655,28 @@ void cpu_die(void)
if (ppc_md.cpu_die)
ppc_md.cpu_die();
}
+
+#ifdef CONFIG_SMP
+void __init setup_per_cpu_areas(void)
+{
+ int i;
+ unsigned long size;
+ char *ptr;
+
+ /* Copy section for each CPU (we discard the original) */
+ size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
+#ifdef CONFIG_MODULES
+ if (size < PERCPU_ENOUGH_ROOM)
+ size = PERCPU_ENOUGH_ROOM;
+#endif
+
+ for_each_cpu(i) {
+ ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
+ if (!ptr)
+ panic("Cannot allocate cpu data for CPU %d\n", i);
+
+ paca[i].data_offset = ptr - __per_cpu_start;
+ memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+ }
+}
+#endif
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d381ec90b75..c8458c531b2 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -338,8 +338,8 @@ static void __init smp_create_idle(unsigned int cpu)
#ifdef CONFIG_PPC64
paca[cpu].__current = p;
#endif
- current_set[cpu] = p->thread_info;
- p->thread_info->cpu = cpu;
+ current_set[cpu] = task_thread_info(p);
+ task_thread_info(p)->cpu = cpu;
}
void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -375,7 +375,7 @@ void __devinit smp_prepare_boot_cpu(void)
#ifdef CONFIG_PPC64
paca[boot_cpuid].__current = current;
#endif
- current_set[boot_cpuid] = current->thread_info;
+ current_set[boot_cpuid] = task_thread_info(current);
}
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 558c1ceb2b9..3774e80094f 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -15,11 +15,36 @@
#include <linux/sched.h>
#include <linux/console.h>
#include <asm/processor.h>
+#include <asm/udbg.h>
void (*udbg_putc)(char c);
int (*udbg_getc)(void);
int (*udbg_getc_poll)(void);
+/*
+ * Early debugging facilities. You can enable _one_ of these via .config,
+ * if you do so your kernel _will not boot_ on anything else. Be careful.
+ */
+void __init udbg_early_init(void)
+{
+#if defined(CONFIG_PPC_EARLY_DEBUG_LPAR)
+ /* For LPAR machines that have an HVC console on vterm 0 */
+ udbg_init_debug_lpar();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_G5)
+ /* For use on Apple G5 machines */
+ udbg_init_pmac_realmode();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS)
+ /* RTAS panel debug */
+ udbg_init_rtas();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE)
+ /* Maple real mode debug */
+ udbg_init_maple_realmode();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_ISERIES)
+ /* For iSeries - hit Ctrl-x Ctrl-x to see the output */
+ udbg_init_iseries();
+#endif
+}
+
/* udbg library, used by xmon et al */
void udbg_puts(const char *s)
{
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 7541bf44d2d..2da65a9c93f 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -155,7 +155,7 @@ void udbg_maple_real_putc(unsigned char c)
}
}
-void udbg_init_maple_realmode(void)
+void __init udbg_init_maple_realmode(void)
{
udbg_comport = (volatile struct NS16550 __iomem *)0xf40003f8;
diff --git a/arch/powerpc/kernel/vdso32/.gitignore b/arch/powerpc/kernel/vdso32/.gitignore
new file mode 100644
index 00000000000..e45fba9d0ce
--- /dev/null
+++ b/arch/powerpc/kernel/vdso32/.gitignore
@@ -0,0 +1 @@
+vdso32.lds
diff --git a/arch/powerpc/kernel/vdso64/.gitignore b/arch/powerpc/kernel/vdso64/.gitignore
new file mode 100644
index 00000000000..3fd18cf9fec
--- /dev/null
+++ b/arch/powerpc/kernel/vdso64/.gitignore
@@ -0,0 +1 @@
+vdso64.lds