From 7ac87abb8166b99584149fcfb2efef5773a078e9 Mon Sep 17 00:00:00 2001 From: Matt Evans Date: Wed, 25 May 2011 18:09:12 +0000 Subject: powerpc: Fix early boot accounting of CPUs smp_release_cpus() waits for all cpus (including the bootcpu) due to an off-by-one count on boot_cpu_count (which is all CPUs). This patch replaces that with spinning_secondaries (which is all secondary CPUs). Signed-off-by: Matt Evans Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_64.S | 2 +- arch/powerpc/kernel/prom.c | 8 ++++++++ arch/powerpc/kernel/setup_32.c | 1 - arch/powerpc/kernel/setup_64.c | 6 +++--- 4 files changed, 12 insertions(+), 5 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index ba504099844a..3564c49c683e 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -255,7 +255,7 @@ generic_secondary_common_init: mtctr r23 bctrl -3: LOAD_REG_ADDR(r3, boot_cpu_count) /* Decrement boot_cpu_count */ +3: LOAD_REG_ADDR(r3, spinning_secondaries) /* Decrement spinning_secondaries */ lwarx r4,0,r3 subi r4,r4,1 stwcx. r4,0,r3 diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index f2c906b1d8d3..534c50359e06 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -69,6 +69,7 @@ unsigned long tce_alloc_start, tce_alloc_end; u64 ppc64_rma_size; #endif static phys_addr_t first_memblock_size; +static int __initdata boot_cpu_count; static int __init early_parse_mem(char *p) { @@ -748,6 +749,13 @@ void __init early_init_devtree(void *params) */ of_scan_flat_dt(early_init_dt_scan_cpus, NULL); +#if defined(CONFIG_SMP) && defined(CONFIG_PPC64) + /* We'll later wait for secondaries to check in; there are + * NCPUS-1 non-boot CPUs :-) + */ + spinning_secondaries = boot_cpu_count - 1; +#endif + DBG(" <- early_init_devtree()\n"); } diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 620d792b52e4..1d2fbc905303 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -48,7 +48,6 @@ extern void bootx_init(unsigned long r4, unsigned long phys); int boot_cpuid = -1; EXPORT_SYMBOL_GPL(boot_cpuid); -int __initdata boot_cpu_count; int boot_cpuid_phys; int smp_hw_index[NR_CPUS]; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index a88bf2713d41..05769190e7f1 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -73,7 +73,7 @@ #endif int boot_cpuid = 0; -int __initdata boot_cpu_count; +int __initdata spinning_secondaries; u64 ppc64_pft_size; /* Pick defaults since we might want to patch instructions @@ -253,11 +253,11 @@ void smp_release_cpus(void) for (i = 0; i < 100000; i++) { mb(); HMT_low(); - if (boot_cpu_count == 0) + if (spinning_secondaries == 0) break; udelay(1); } - DBG("boot_cpu_count = %d\n", boot_cpu_count); + DBG("spinning_secondaries = %d\n", spinning_secondaries); DBG(" <- smp_release_cpus()\n"); } -- cgit v1.2.3 From 9ca980dce523760ce04a798470d36fd5aa596b78 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 25 May 2011 23:34:12 +0000 Subject: powerpc: Avoid extra indirect function call in sending IPIs On many platforms (including pSeries), smp_ops->message_pass is always smp_muxed_ipi_message_pass. This changes arch/powerpc/kernel/smp.c so that if smp_ops->message_pass is NULL, it calls smp_muxed_ipi_message_pass directly. This means that a platform doesn't need to set both .message_pass and .cause_ipi, only one of them. It is a slight performance improvement in that it gets rid of an indirect function call at the expense of a predictable conditional branch. Signed-off-by: Paul Mackerras Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/smp.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 8ebc6700b98d..2975f64cf310 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -238,15 +238,25 @@ irqreturn_t smp_ipi_demux(void) } #endif /* CONFIG_PPC_SMP_MUXED_IPI */ +static inline void do_message_pass(int cpu, int msg) +{ + if (smp_ops->message_pass) + smp_ops->message_pass(cpu, msg); +#ifdef CONFIG_PPC_SMP_MUXED_IPI + else + smp_muxed_ipi_message_pass(cpu, msg); +#endif +} + void smp_send_reschedule(int cpu) { if (likely(smp_ops)) - smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); + do_message_pass(cpu, PPC_MSG_RESCHEDULE); } void arch_send_call_function_single_ipi(int cpu) { - smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNC_SINGLE); + do_message_pass(cpu, PPC_MSG_CALL_FUNC_SINGLE); } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -254,7 +264,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask) unsigned int cpu; for_each_cpu(cpu, mask) - smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION); + do_message_pass(cpu, PPC_MSG_CALL_FUNCTION); } #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) @@ -268,7 +278,7 @@ void smp_send_debugger_break(void) for_each_online_cpu(cpu) if (cpu != me) - smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK); + do_message_pass(cpu, PPC_MSG_DEBUGGER_BREAK); } #endif -- cgit v1.2.3 From 1325a684b553d4b5c41ae0482f8991b43f945746 Mon Sep 17 00:00:00 2001 From: Ashish Kalra Date: Fri, 22 Apr 2011 16:48:27 -0500 Subject: powerpc/85xx: Save scratch registers to thread info instead of using SPRGs. We expect this is actually faster, and we end up needing more space than we can get from the SPRGs in some instances. This is also useful when running as a guest OS - SPRGs4-7 do not have guest versions. 8 slots are allocated in thread_info for this even though we only actually use 4 of them - this allows space for future code to have more scratch space (and we know we'll need it for things like hugetlb). Signed-off-by: Ashish Kalra Signed-off-by: Becky Bruce Signed-off-by: Kumar Gala --- arch/powerpc/kernel/asm-offsets.c | 3 +++ arch/powerpc/kernel/head_booke.h | 42 +++++++++++++++++++------------ arch/powerpc/kernel/head_fsl_booke.S | 49 ++++++++++++++++++++---------------- 3 files changed, 56 insertions(+), 38 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 36e1c8a29be8..c98144f6f04e 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -82,6 +82,9 @@ int main(void) DEFINE(KSP, offsetof(struct thread_struct, ksp)); DEFINE(KSP_LIMIT, offsetof(struct thread_struct, ksp_limit)); DEFINE(PT_REGS, offsetof(struct thread_struct, regs)); +#ifdef CONFIG_BOOKE + DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0])); +#endif DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index a0bf158c8b47..fc921bf62e15 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -20,33 +20,43 @@ addi reg,reg,val@l #endif +/* + * Macro used to get to thread save registers. + * Note that entries 0-3 are used for the prolog code, and the remaining + * entries are available for specific exception use in the event a handler + * requires more than 4 scratch registers. + */ +#define THREAD_NORMSAVE(offset) (THREAD_NORMSAVES + (offset * 4)) + #define NORMAL_EXCEPTION_PROLOG \ - mtspr SPRN_SPRG_WSCRATCH0,r10;/* save two registers to work with */\ - mtspr SPRN_SPRG_WSCRATCH1,r11; \ - mtspr SPRN_SPRG_WSCRATCH2,r1; \ - mfcr r10; /* save CR in r10 for now */\ + mtspr SPRN_SPRG_WSCRATCH0, r10; /* save one register */ \ + mfspr r10, SPRN_SPRG_THREAD; \ + stw r11, THREAD_NORMSAVE(0)(r10); \ + stw r13, THREAD_NORMSAVE(2)(r10); \ + mfcr r13; /* save CR in r13 for now */\ mfspr r11,SPRN_SRR1; /* check whether user or kernel */\ andi. r11,r11,MSR_PR; \ + mr r11, r1; \ beq 1f; \ - mfspr r1,SPRN_SPRG_THREAD; /* if from user, start at top of */\ - lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\ - ALLOC_STACK_FRAME(r1, THREAD_SIZE); \ -1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\ - mr r11,r1; \ - stw r10,_CCR(r11); /* save various registers */\ + /* if from user, start at top of this thread's kernel stack */ \ + lwz r11, THREAD_INFO-THREAD(r10); \ + ALLOC_STACK_FRAME(r11, THREAD_SIZE); \ +1 : subi r11, r11, INT_FRAME_SIZE; /* Allocate exception frame */ \ + stw r13, _CCR(r11); /* save various registers */ \ stw r12,GPR12(r11); \ stw r9,GPR9(r11); \ - mfspr r10,SPRN_SPRG_RSCRATCH0; \ - stw r10,GPR10(r11); \ - mfspr r12,SPRN_SPRG_RSCRATCH1; \ + mfspr r13, SPRN_SPRG_RSCRATCH0; \ + stw r13, GPR10(r11); \ + lwz r12, THREAD_NORMSAVE(0)(r10); \ stw r12,GPR11(r11); \ + lwz r13, THREAD_NORMSAVE(2)(r10); /* restore r13 */ \ mflr r10; \ stw r10,_LINK(r11); \ - mfspr r10,SPRN_SPRG_RSCRATCH2; \ mfspr r12,SPRN_SRR0; \ - stw r10,GPR1(r11); \ + stw r1, GPR1(r11); \ mfspr r9,SPRN_SRR1; \ - stw r10,0(r11); \ + stw r1, 0(r11); \ + mr r1, r11; \ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ stw r0,GPR0(r11); \ lis r10, STACK_FRAME_REGS_MARKER@ha;/* exception frame marker */ \ diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 5ecf54cfa7d4..985638d5f6c4 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -346,11 +346,12 @@ interrupt_base: /* Data TLB Error Interrupt */ START_EXCEPTION(DataTLBError) mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ - mtspr SPRN_SPRG_WSCRATCH1, r11 - mtspr SPRN_SPRG_WSCRATCH2, r12 - mtspr SPRN_SPRG_WSCRATCH3, r13 - mfcr r11 - mtspr SPRN_SPRG_WSCRATCH4, r11 + mfspr r10, SPRN_SPRG_THREAD + stw r11, THREAD_NORMSAVE(0)(r10) + stw r12, THREAD_NORMSAVE(1)(r10) + stw r13, THREAD_NORMSAVE(2)(r10) + mfcr r13 + stw r13, THREAD_NORMSAVE(3)(r10) mfspr r10, SPRN_DEAR /* Get faulting address */ /* If we are faulting a kernel address, we have to use the @@ -416,11 +417,12 @@ interrupt_base: /* The bailout. Restore registers to pre-exception conditions * and call the heavyweights to help us out. */ - mfspr r11, SPRN_SPRG_RSCRATCH4 + mfspr r10, SPRN_SPRG_THREAD + lwz r11, THREAD_NORMSAVE(3)(r10) mtcr r11 - mfspr r13, SPRN_SPRG_RSCRATCH3 - mfspr r12, SPRN_SPRG_RSCRATCH2 - mfspr r11, SPRN_SPRG_RSCRATCH1 + lwz r13, THREAD_NORMSAVE(2)(r10) + lwz r12, THREAD_NORMSAVE(1)(r10) + lwz r11, THREAD_NORMSAVE(0)(r10) mfspr r10, SPRN_SPRG_RSCRATCH0 b DataStorage @@ -432,11 +434,12 @@ interrupt_base: */ START_EXCEPTION(InstructionTLBError) mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ - mtspr SPRN_SPRG_WSCRATCH1, r11 - mtspr SPRN_SPRG_WSCRATCH2, r12 - mtspr SPRN_SPRG_WSCRATCH3, r13 - mfcr r11 - mtspr SPRN_SPRG_WSCRATCH4, r11 + mfspr r10, SPRN_SPRG_THREAD + stw r11, THREAD_NORMSAVE(0)(r10) + stw r12, THREAD_NORMSAVE(1)(r10) + stw r13, THREAD_NORMSAVE(2)(r10) + mfcr r13 + stw r13, THREAD_NORMSAVE(3)(r10) mfspr r10, SPRN_SRR0 /* Get faulting address */ /* If we are faulting a kernel address, we have to use the @@ -496,11 +499,12 @@ interrupt_base: /* The bailout. Restore registers to pre-exception conditions * and call the heavyweights to help us out. */ - mfspr r11, SPRN_SPRG_RSCRATCH4 + mfspr r10, SPRN_SPRG_THREAD + lwz r11, THREAD_NORMSAVE(3)(r10) mtcr r11 - mfspr r13, SPRN_SPRG_RSCRATCH3 - mfspr r12, SPRN_SPRG_RSCRATCH2 - mfspr r11, SPRN_SPRG_RSCRATCH1 + lwz r13, THREAD_NORMSAVE(2)(r10) + lwz r12, THREAD_NORMSAVE(1)(r10) + lwz r11, THREAD_NORMSAVE(0)(r10) mfspr r10, SPRN_SPRG_RSCRATCH0 b InstructionStorage @@ -621,11 +625,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) tlbwe /* Done...restore registers and get out of here. */ - mfspr r11, SPRN_SPRG_RSCRATCH4 + mfspr r10, SPRN_SPRG_THREAD + lwz r11, THREAD_NORMSAVE(3)(r10) mtcr r11 - mfspr r13, SPRN_SPRG_RSCRATCH3 - mfspr r12, SPRN_SPRG_RSCRATCH2 - mfspr r11, SPRN_SPRG_RSCRATCH1 + lwz r13, THREAD_NORMSAVE(2)(r10) + lwz r12, THREAD_NORMSAVE(1)(r10) + lwz r11, THREAD_NORMSAVE(0)(r10) mfspr r10, SPRN_SPRG_RSCRATCH0 rfi /* Force context change */ -- cgit v1.2.3 From c065488f1acfc0be75584c0fe156fc806820f39d Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 19 May 2011 22:26:18 -0500 Subject: powerpc/pci: Move FSL fixup from 32-bit to common We need the FSL specific header fixup code on both 32-bit and 64-bit platforms so just move the code into pci-common.c. Signed-off-by: Kumar Gala --- arch/powerpc/kernel/pci-common.c | 18 ++++++++++++++++++ arch/powerpc/kernel/pci_32.c | 19 ------------------- 2 files changed, 18 insertions(+), 19 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 893af2a9cd03..4f134132c195 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1728,3 +1728,21 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) if (mode == PCI_PROBE_NORMAL) hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); } + +static void fixup_hide_host_resource_fsl(struct pci_dev *dev) +{ + int i, class = dev->class >> 8; + + if ((class == PCI_CLASS_PROCESSOR_POWERPC || + class == PCI_CLASS_BRIDGE_OTHER) && + (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) && + (dev->bus->parent == NULL)) { + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index bedb370459f2..d521644030d1 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -50,25 +50,6 @@ static int pci_bus_count; struct pci_dev *isa_bridge_pcidev; EXPORT_SYMBOL_GPL(isa_bridge_pcidev); -static void -fixup_hide_host_resource_fsl(struct pci_dev *dev) -{ - int i, class = dev->class >> 8; - - if ((class == PCI_CLASS_PROCESSOR_POWERPC || - class == PCI_CLASS_BRIDGE_OTHER) && - (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) && - (dev->bus->parent == NULL)) { - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - dev->resource[i].start = 0; - dev->resource[i].end = 0; - dev->resource[i].flags = 0; - } - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); - static void fixup_cpc710_pci64(struct pci_dev* dev) { -- cgit v1.2.3 From 6ec36b5848a8336d3a0010727b9365c3254d2d2e Mon Sep 17 00:00:00 2001 From: Stuart Yoder Date: Thu, 19 May 2011 08:54:26 -0500 Subject: powerpc: make irq_choose_cpu() available to all PIC drivers Move irq_choose_cpu() into arch/powerpc/kernel/irq.c so that it can be used by other PIC drivers. The function is not MPIC-specific. Signed-off-by: Stuart Yoder Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/kernel/irq.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5b428e308666..38dd10e2841d 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -882,6 +882,41 @@ unsigned int irq_find_mapping(struct irq_host *host, } EXPORT_SYMBOL_GPL(irq_find_mapping); +#ifdef CONFIG_SMP +int irq_choose_cpu(const struct cpumask *mask) +{ + int cpuid; + + if (cpumask_equal(mask, cpu_all_mask)) { + static int irq_rover; + static DEFINE_RAW_SPINLOCK(irq_rover_lock); + unsigned long flags; + + /* Round-robin distribution... */ +do_round_robin: + raw_spin_lock_irqsave(&irq_rover_lock, flags); + + irq_rover = cpumask_next(irq_rover, cpu_online_mask); + if (irq_rover >= nr_cpu_ids) + irq_rover = cpumask_first(cpu_online_mask); + + cpuid = irq_rover; + + raw_spin_unlock_irqrestore(&irq_rover_lock, flags); + } else { + cpuid = cpumask_first_and(mask, cpu_online_mask); + if (cpuid >= nr_cpu_ids) + goto do_round_robin; + } + + return get_hard_smp_processor_id(cpuid); +} +#else +int irq_choose_cpu(const struct cpumask *mask) +{ + return hard_smp_processor_id(); +} +#endif unsigned int irq_radix_revmap_lookup(struct irq_host *host, irq_hw_number_t hwirq) -- cgit v1.2.3 From ebf714ff37561331eb39963945d80bfc2a59e00f Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Wed, 22 Jun 2011 18:10:30 -0500 Subject: powerpc/e500mc: Add support for the wait instruction in e500_idle e500mc cannot doze or nap due to an erratum (as well as having a different mechanism than previous e500), but it has a "wait" instruction that is similar to doze. On 64-bit, due to the soft-irq-disable mechanism, the existing book3e_idle should be used instead. Signed-off-by: Vakul Garg Signed-off-by: Scott Wood Signed-off-by: Kumar Gala --- arch/powerpc/kernel/idle_e500.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/idle_e500.S b/arch/powerpc/kernel/idle_e500.S index 47a1a983ff88..3e2b95c6ae67 100644 --- a/arch/powerpc/kernel/idle_e500.S +++ b/arch/powerpc/kernel/idle_e500.S @@ -26,6 +26,17 @@ _GLOBAL(e500_idle) ori r4,r4,_TLF_NAPPING /* so when we take an exception */ stw r4,TI_LOCAL_FLAGS(r3) /* it will return to our caller */ +#ifdef CONFIG_E500MC + wrteei 1 +1: wait + + /* + * Guard against spurious wakeups (e.g. from a hypervisor) -- + * any real interrupt will cause us to return to LR due to + * _TLF_NAPPING. + */ + b 1b +#else /* Check if we can nap or doze, put HID0 mask in r3 */ lis r3,0 BEGIN_FTR_SECTION @@ -72,6 +83,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_L2CSR|CPU_FTR_CAN_NAP) mtmsr r7 isync 2: b 2b +#endif /* !E500MC */ /* * Return from NAP/DOZE mode, restore some CPU specific registers, -- cgit v1.2.3 From 3d97a619acbb2c8a7a9a7da08c2d3041dfdd241f Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Wed, 22 Jun 2011 11:19:49 +0000 Subject: powerpc/book3e-64: Reraise doorbell when masked by soft-irq-disable Signed-off-by: Scott Wood Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/exceptions-64e.S | 22 +++++++++++++++++++++- arch/powerpc/kernel/irq.c | 6 ------ arch/powerpc/kernel/smp.c | 8 -------- 3 files changed, 21 insertions(+), 15 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index d24d4400cc79..429983c06f91 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -120,6 +120,12 @@ std r14,PACA_EXMC+EX_R14(r13); \ std r15,PACA_EXMC+EX_R15(r13) +#define PROLOG_ADDITION_DOORBELL_GEN \ + lbz r11,PACASOFTIRQEN(r13); /* are irqs soft-disabled ? */ \ + cmpwi cr0,r11,0; /* yes -> go out of line */ \ + beq masked_doorbell_book3e + + /* Core exception code for all exceptions except TLB misses. * XXX: Needs to make SPRN_SPRG_GEN depend on exception type */ @@ -522,7 +528,13 @@ kernel_dbg_exc: MASKABLE_EXCEPTION(0x260, perfmon, .performance_monitor_exception, ACK_NONE) /* Doorbell interrupt */ - MASKABLE_EXCEPTION(0x2070, doorbell, .doorbell_exception, ACK_NONE) + START_EXCEPTION(doorbell) + NORMAL_EXCEPTION_PROLOG(0x2070, PROLOG_ADDITION_DOORBELL) + EXCEPTION_COMMON(0x2070, PACA_EXGEN, INTS_DISABLE_ALL) + CHECK_NAPPING() + addi r3,r1,STACK_FRAME_OVERHEAD + bl .doorbell_exception + b .ret_from_except_lite /* Doorbell critical Interrupt */ START_EXCEPTION(doorbell_crit); @@ -545,8 +557,16 @@ kernel_dbg_exc: * An interrupt came in while soft-disabled; clear EE in SRR1, * clear paca->hard_enabled and return. */ +masked_doorbell_book3e: + mtcr r10 + /* Resend the doorbell to fire again when ints enabled */ + mfspr r10,SPRN_PIR + PPC_MSGSND(r10) + b masked_interrupt_book3e_common + masked_interrupt_book3e: mtcr r10 +masked_interrupt_book3e_common: stb r11,PACAHARDIRQEN(r13) mfspr r10,SPRN_SRR1 rldicl r11,r10,48,1 /* clear MSR_EE */ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 38dd10e2841d..164fb6ca692e 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -157,12 +157,6 @@ notrace void arch_local_irq_restore(unsigned long en) if (get_hard_enabled()) return; -#if defined(CONFIG_BOOKE) && defined(CONFIG_SMP) - /* Check for pending doorbell interrupts and resend to ourself */ - if (cpu_has_feature(CPU_FTR_DBELL)) - smp_muxed_ipi_resend(); -#endif - /* * Need to hard-enable interrupts here. Since currently disabled, * no need to take further asm precautions against preemption; but diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 2975f64cf310..6c8e739a12da 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -202,14 +202,6 @@ void smp_muxed_ipi_message_pass(int cpu, int msg) smp_ops->cause_ipi(cpu, info->data); } -void smp_muxed_ipi_resend(void) -{ - struct cpu_messages *info = &__get_cpu_var(ipi_message); - - if (info->messages) - smp_ops->cause_ipi(smp_processor_id(), info->data); -} - irqreturn_t smp_ipi_demux(void) { struct cpu_messages *info = &__get_cpu_var(ipi_message); -- cgit v1.2.3 From e48f7eb27f0e38e1a461fa4e43025d18100d250b Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 17 Jun 2011 03:10:06 +0000 Subject: powerpc/maple: Enable scom access functions on Maple Enable functions used to access SCOM if PPC_MAPLE is defined: they are used by cpufreq driver to control hardware. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/misc_64.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index e89df59cdc5a..616921ef1439 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -339,7 +339,7 @@ _GLOBAL(real_205_writeb) #endif /* CONFIG_PPC_PASEMI */ -#ifdef CONFIG_CPU_FREQ_PMAC64 +#if defined(CONFIG_CPU_FREQ_PMAC64) || defined(CONFIG_CPU_FREQ_MAPLE) /* * SCOM access functions for 970 (FX only for now) * @@ -408,7 +408,7 @@ _GLOBAL(scom970_write) /* restore interrupts */ mtmsrd r5,1 blr -#endif /* CONFIG_CPU_FREQ_PMAC64 */ +#endif /* CONFIG_CPU_FREQ_PMAC64 || CONFIG_CPU_FREQ_MAPLE */ /* -- cgit v1.2.3 From de2780a3d82372a6bfc7f474905e346c0f26dfa4 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Tue, 21 Jun 2011 03:35:56 +0000 Subject: powerpc/pseries: Improve error code on reconfiguration notifier failure Reconfiguration notifier call for device node may fail by several reasons, but it always assumes kmalloc failures. This enables reconfiguration notifier call chain to get the actual error code rather than -ENOMEM by converting all reconfiguration notifier calls to return encapsulate error code with notifier_from_errno(). Signed-off-by: Akinobu Mita Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/prom.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 534c50359e06..b8e6189298f4 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -849,16 +849,14 @@ static int prom_reconfig_notifier(struct notifier_block *nb, switch (action) { case PSERIES_RECONFIG_ADD: err = of_finish_dynamic_node(node); - if (err < 0) { + if (err < 0) printk(KERN_ERR "finish_node returned %d\n", err); - err = NOTIFY_BAD; - } break; default: - err = NOTIFY_DONE; + err = 0; break; } - return err; + return notifier_from_errno(err); } static struct notifier_block prom_reconfig_nb = { -- cgit v1.2.3 From dd2e356a3dd1fea6d911798044532304c3ef4050 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 16 Jun 2011 15:08:37 +0000 Subject: powerpc/udbg: Register udbg console generically When CONFIG_PPC_EARLY_DEBUG is set, call register_early_udbg_console() early from generic code. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/udbg.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 23d65abbedce..a57e61ea0558 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c @@ -68,6 +68,8 @@ void __init udbg_early_init(void) #ifdef CONFIG_PPC_EARLY_DEBUG console_loglevel = 10; + + register_early_udbg_console(); #endif } -- cgit v1.2.3 From 4d2bb3f5003617cb42b89faefd0009c505c3abd5 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 12 May 2011 13:46:38 +1000 Subject: powerpc/pseries: Re-implement HVSI as part of hvc_vio On pseries machines, consoles are provided by the hypervisor using a low level get_chars/put_chars type interface. However, this is really just a transport to the service processor which implements them either as "raw" console (networked consoles, HMC, ...) or as "hvsi" serial ports. The later is a simple packet protocol on top of the raw character interface that is supposed to convey additional "serial port" style semantics. In practice however, all it does is provide a way to read the CD line and set/clear our DTR line, that's it. We currently implement the "raw" protocol as an hvc console backend (/dev/hvcN) and the "hvsi" protocol using a separate tty driver (/dev/hvsi0). However this is quite impractical. The arbitrary difference between the two type of devices has been a major source of user (and distro) confusion. Additionally, there's an additional mini -hvsi implementation in the pseries platform code for our low level debug console and early boot kernel messages, which means code duplication, though that low level variant is impractical as it's incapable of doing the initial protocol negociation to establish the link to the FSP. This essentially replaces the dedicated hvsi driver and the platform udbg code completely by extending the existing hvc_vio backend used in "raw" mode so that: - It now supports HVSI as well - We add support for hvc backend providing tiocm{get,set} - It also provides a udbg interface for early debug and boot console This is overall less code, though this will only be obvious once we remove the old "hvsi" driver, which is still available for now. When the old driver is enabled, the new code still kicks in for the low level udbg console, replacing the old mini implementation in the platform code, it just doesn't provide the higher level "hvc" interface. In addition to producing generally simler code, this has several benefits over our current situation: - The user/distro only has to deal with /dev/hvcN for the hypervisor console, avoiding all sort of confusion that has plagued us in the past - The tty, kernel and low level debug console all use the same code base which supports the full protocol establishment process, thus the console is now available much earlier than it used to be with the old HVSI driver. The kernel console works much earlier and udbg is available much earlier too. Hackers can enable a hard coded very-early debug console as well that works with HVSI (previously that was only supported for the "raw" mode). I've tried to keep the same semantics as hvsi relative to how I react to things like CD changes, with some subtle differences though: - I clear DTR on close if HUPCL is set - Current hvsi triggers a hangup if it detects a up->down transition on CD (you can still open a console with CD down). My new implementation triggers a hangup if the link to the FSP is severed, and severs it upon detecting a up->down transition on CD. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/udbg.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index a57e61ea0558..faa82c1f3f68 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c @@ -31,6 +31,9 @@ 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_LPAR_HVSI) + /* For LPAR machines that have an HVSI console on vterm 0 */ + udbg_init_debug_lpar_hvsi(); #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) /* For use on Apple G5 machines */ udbg_init_pmac_realmode(); -- cgit v1.2.3 From a9c0f41b3a64955fd6f4e9d66ae1df1cbdee0cd0 Mon Sep 17 00:00:00 2001 From: Dave Carroll Date: Sat, 18 Jun 2011 07:36:40 +0000 Subject: powerpc: Add printk companion for ppc_md.progress This patch adds a printk companion to replace the udbg progress function when initmem is freed. Suggested-by: Milton Miller Suggested-by: Benjamin Herrenschmidt Signed-off-by: Dave Carroll Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup-common.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 79fca2651b65..e053b1641de3 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -704,6 +704,11 @@ static int powerpc_debugfs_init(void) arch_initcall(powerpc_debugfs_init); #endif +void ppc_printk_progress(char *s, unsigned short hex) +{ + pr_info("%s\n", s); +} + static int ppc_dflt_bus_notify(struct notifier_block *nb, unsigned long action, void *data) { -- cgit v1.2.3 From ac5f89c7d87f6f2fb7073723fc943488d9c3479d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 29 Jun 2011 19:16:59 +0000 Subject: powerpc: Add jump label support This patch adds support for the new "jump label" feature. Unlike x86 and sparc we just merrily patch the code with no locks etc, as far as I know this is safe, but I'm not really sure what the x86/sparc code is protecting against so maybe it's not. I also don't see any reason for us to implement the poke_early() routine, even though sparc does. [BenH: Updated the patch to upstream generic changes] Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/jump_label.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 arch/powerpc/kernel/jump_label.c (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index e8b981897d44..ce4f7f179117 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_44x) += cpu_setup_44x.o obj-$(CONFIG_PPC_FSL_BOOK3E) += cpu_setup_fsl_booke.o dbell.o obj-$(CONFIG_PPC_BOOK3E_64) += dbell.o +obj-$(CONFIG_JUMP_LABEL) += jump_label.o extra-y := head_$(CONFIG_WORD_SIZE).o extra-$(CONFIG_40x) := head_40x.o diff --git a/arch/powerpc/kernel/jump_label.c b/arch/powerpc/kernel/jump_label.c new file mode 100644 index 000000000000..368d158d665d --- /dev/null +++ b/arch/powerpc/kernel/jump_label.c @@ -0,0 +1,23 @@ +/* + * Copyright 2010 Michael Ellerman, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include + +void arch_jump_label_transform(struct jump_entry *entry, + enum jump_label_type type) +{ + u32 *addr = (u32 *)(unsigned long)entry->code; + + if (type == JUMP_LABEL_ENABLE) + patch_branch(addr, entry->target, 0); + else + patch_instruction(addr, PPC_INST_NOP); +} -- cgit v1.2.3 From 3160b09796129abc9523ea3cd1633b0faba64a02 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Tue, 28 Jun 2011 14:54:47 -0500 Subject: powerpc: Create next_tlbcam_idx percpu variable for FSL_BOOKE This is used to round-robin TLBCAM entries. Signed-off-by: Becky Bruce Signed-off-by: Kumar Gala --- arch/powerpc/kernel/smp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 6c8e739a12da..567a1746ed74 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -305,6 +305,10 @@ struct thread_info *current_set[NR_CPUS]; static void __devinit smp_store_cpu_info(int id) { per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR); +#ifdef CONFIG_PPC_FSL_BOOK3E + per_cpu(next_tlbcam_idx, id) + = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) - 1; +#endif } void __init smp_prepare_cpus(unsigned int max_cpus) -- cgit v1.2.3 From 314b02f503c2c219fde0fcf6f086fda415f8a847 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 8 Jul 2011 00:17:27 -0500 Subject: powerpc: implement arch_setup_pdev_archdata We have a long standing issues with platform devices not have a valid dma_mask pointer. This hasn't been an issue to date as no platform device has tried to set its dma_mask value to a non-default value. Acked-by: Greg Kroah-Hartman Signed-off-by: Kumar Gala --- arch/powerpc/kernel/setup-common.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index e053b1641de3..c600faf114d7 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -709,29 +709,9 @@ void ppc_printk_progress(char *s, unsigned short hex) pr_info("%s\n", s); } -static int ppc_dflt_bus_notify(struct notifier_block *nb, - unsigned long action, void *data) +void arch_setup_pdev_archdata(struct platform_device *pdev) { - struct device *dev = data; - - /* We are only intereted in device addition */ - if (action != BUS_NOTIFY_ADD_DEVICE) - return 0; - - set_dma_ops(dev, &dma_direct_ops); - - return NOTIFY_DONE; -} - -static struct notifier_block ppc_dflt_plat_bus_notifier = { - .notifier_call = ppc_dflt_bus_notify, - .priority = INT_MAX, -}; - -static int __init setup_bus_notifier(void) -{ - bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); - return 0; + pdev->archdata.dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &pdev->archdata.dma_mask; + set_dma_ops(&pdev->dev, &dma_direct_ops); } - -arch_initcall(setup_bus_notifier); -- cgit v1.2.3 From 6471fc6630a507fd54fdaceceee1ddaf3c917cde Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 10 Jun 2011 02:22:06 -0500 Subject: powerpc: Dont require a dma_ops struct to set dma mask The only reason to require a dma_ops struct is to see if it has implemented set_dma_mask. If not we can fall back to setting the mask directly. This resolves an issue with how to sequence the setting of a DMA mask for platform devices. Before we had an issue in that we have no way of setting the DMA mask before the various low level bus notifiers get called that might check it (swiotlb). So now we can do: pdev = platform_device_alloc("foobar", 0); dma_set_mask(&pdev->dev, DMA_BIT_MASK(37)); platform_device_add(pdev); And expect the right thing to happen with the bus notifiers get called via platform_device_add. Acked-by: Greg Kroah-Hartman Signed-off-by: Kumar Gala --- arch/powerpc/kernel/dma.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index d238c082c3c5..4f0959fbfbee 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -161,9 +161,7 @@ int dma_set_mask(struct device *dev, u64 dma_mask) if (ppc_md.dma_set_mask) return ppc_md.dma_set_mask(dev, dma_mask); - if (unlikely(dma_ops == NULL)) - return -EIO; - if (dma_ops->set_dma_mask != NULL) + if ((dma_ops != NULL) && (dma_ops->set_dma_mask != NULL)) return dma_ops->set_dma_mask(dev, dma_mask); if (!dev->dma_mask || !dma_supported(dev, dma_mask)) return -EIO; -- cgit v1.2.3 From 91b191c71eae79c0e652c52a968d06cd96b539c5 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Mon, 4 Jul 2011 18:38:03 +0000 Subject: powerpc/44x: don't use tlbivax on AMP systems Since other OS's may be running on the other cores don't use tlbivax Signed-off-by: Dave Kleikamp Signed-off-by: Tony Breeds Cc: Benjamin Herrenschmidt Cc: Josh Boyer Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Josh Boyer --- arch/powerpc/kernel/setup_32.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 1d2fbc905303..7544e39b4156 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -126,6 +126,8 @@ notrace void __init machine_init(unsigned long dt_ptr) /* Do some early initialization based on the flat device tree */ early_init_devtree(__va(dt_ptr)); + early_init_mmu(); + probe_machine(); setup_kdump_trampoline(); -- cgit v1.2.3 From 9661534d6ad75f881d8bbeb73dd7372f41cbad99 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Mon, 4 Jul 2011 18:36:57 +0000 Subject: powerpc/47x: allow kernel to be loaded in higher physical memory The 44x code (which is shared by 47x) assumes the available physical memory begins at 0x00000000. This is not necessarily the case in an AMP environment. Support CONFIG_RELOCATABLE for 476 in order to allow the kernel to be loaded into a higher memory range. Signed-off-by: Tony Breeds Signed-off-by: Dave Kleikamp Cc: Benjamin Herrenschmidt Cc: Josh Boyer Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Josh Boyer --- arch/powerpc/kernel/head_44x.S | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 5e12b741ba5f..f8e971ba94f5 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -93,6 +93,30 @@ _ENTRY(_start); bl early_init +#ifdef CONFIG_RELOCATABLE + /* + * r25 will contain RPN/ERPN for the start address of memory + * + * Add the difference between KERNELBASE and PAGE_OFFSET to the + * start of physical memory to get kernstart_addr. + */ + lis r3,kernstart_addr@ha + la r3,kernstart_addr@l(r3) + + lis r4,KERNELBASE@h + ori r4,r4,KERNELBASE@l + lis r5,PAGE_OFFSET@h + ori r5,r5,PAGE_OFFSET@l + subf r4,r5,r4 + + rlwinm r6,r25,0,28,31 /* ERPN */ + rlwinm r7,r25,0,0,3 /* RPN - assuming 256 MB page size */ + add r7,r7,r4 + + stw r6,0(r3) + stw r7,4(r3) +#endif + /* * Decide what sort of machine this is and initialize the MMU. */ @@ -1001,9 +1025,6 @@ clear_utlb_entry: lis r3,PAGE_OFFSET@h ori r3,r3,PAGE_OFFSET@l - /* Kernel is at the base of RAM */ - li r4, 0 /* Load the kernel physical address */ - /* Load the kernel PID = 0 */ li r0,0 mtspr SPRN_PID,r0 @@ -1013,9 +1034,8 @@ clear_utlb_entry: clrrwi r3,r3,12 /* Mask off the effective page number */ ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_256M - /* Word 1 */ - clrrwi r4,r4,12 /* Mask off the real page number */ - /* ERPN is 0 for first 4GB page */ + /* Word 1 - use r25. RPN is the same as the original entry */ + /* Word 2 */ li r5,0 ori r5,r5,PPC47x_TLB2_S_RWX @@ -1026,7 +1046,7 @@ clear_utlb_entry: /* We write to way 0 and bolted 0 */ lis r0,0x8800 tlbwe r3,r0,0 - tlbwe r4,r0,1 + tlbwe r25,r0,1 tlbwe r5,r0,2 /* @@ -1124,7 +1144,13 @@ head_start_common: lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ mtspr SPRN_IVPR,r4 - addis r22,r22,KERNELBASE@h + /* + * If the kernel was loaded at a non-zero 256 MB page, we need to + * mask off the most significant 4 bits to get the relative address + * from the start of physical memory + */ + rlwinm r22,r22,0,4,31 + addis r22,r22,PAGE_OFFSET@h mtlr r22 isync blr -- cgit v1.2.3 From 0e0ebdb9c2ba7b56a82ba36d29ab3d8cb99de9e7 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Fri, 10 Jun 2011 03:10:22 +0000 Subject: powerpc: Remove redundant set_fs(USER_DS) The address limit is already set in flush_old_exec() so this set_fs(USER_DS) is redundant. Signed-off-by: Mathias Krause Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/process.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 91e52df3d81d..885a2dd2ab80 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -831,8 +831,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */ #endif - set_fs(USER_DS); - /* * If we exec out of a kernel thread then thread.regs will not be * set. Do it now. -- cgit v1.2.3 From 77c2342a578c11f22a1003e641f50d138dd9833a Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 29 Jun 2011 04:54:00 +0000 Subject: powerpc: Correct annotations of pmu registration functions This fixes the following warning: WARNING: arch/powerpc/kernel/built-in.o(.text+0x29768): Section mismatch in reference from the function .register_power_pmu() to the function .cpuinit.text:.power_pmu_notifier() The function .register_power_pmu() references the function __cpuinit .power_pmu_notifier(). This is often because .register_power_pmu lacks a __cpuinit annotation or the annotation of .power_pmu_notifier is wrong. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/mpc7450-pmu.c | 2 +- arch/powerpc/kernel/perf_event.c | 2 +- arch/powerpc/kernel/power4-pmu.c | 2 +- arch/powerpc/kernel/power5+-pmu.c | 2 +- arch/powerpc/kernel/power5-pmu.c | 2 +- arch/powerpc/kernel/power6-pmu.c | 2 +- arch/powerpc/kernel/power7-pmu.c | 2 +- arch/powerpc/kernel/ppc970-pmu.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/mpc7450-pmu.c b/arch/powerpc/kernel/mpc7450-pmu.c index 2cc5e0301d0b..a6de23d5ef41 100644 --- a/arch/powerpc/kernel/mpc7450-pmu.c +++ b/arch/powerpc/kernel/mpc7450-pmu.c @@ -405,7 +405,7 @@ struct power_pmu mpc7450_pmu = { .cache_events = &mpc7450_cache_events, }; -static int init_mpc7450_pmu(void) +static int __init init_mpc7450_pmu(void) { if (!cur_cpu_spec->oprofile_cpu_type || strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450")) diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index 822f63008ae1..31ab78f3bee4 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c @@ -1408,7 +1408,7 @@ power_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu return NOTIFY_OK; } -int register_power_pmu(struct power_pmu *pmu) +int __cpuinit register_power_pmu(struct power_pmu *pmu) { if (ppmu) return -EBUSY; /* something's already registered */ diff --git a/arch/powerpc/kernel/power4-pmu.c b/arch/powerpc/kernel/power4-pmu.c index ead8b3c2649e..4eb709501396 100644 --- a/arch/powerpc/kernel/power4-pmu.c +++ b/arch/powerpc/kernel/power4-pmu.c @@ -604,7 +604,7 @@ static struct power_pmu power4_pmu = { .cache_events = &power4_cache_events, }; -static int init_power4_pmu(void) +static int __init init_power4_pmu(void) { if (!cur_cpu_spec->oprofile_cpu_type || strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power4")) diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c index eca0ac595cb6..23aaadbc729c 100644 --- a/arch/powerpc/kernel/power5+-pmu.c +++ b/arch/powerpc/kernel/power5+-pmu.c @@ -672,7 +672,7 @@ static struct power_pmu power5p_pmu = { .cache_events = &power5p_cache_events, }; -static int init_power5p_pmu(void) +static int __init init_power5p_pmu(void) { if (!cur_cpu_spec->oprofile_cpu_type || (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5+") diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c index d5ff0f64a5e6..589e49af8e72 100644 --- a/arch/powerpc/kernel/power5-pmu.c +++ b/arch/powerpc/kernel/power5-pmu.c @@ -612,7 +612,7 @@ static struct power_pmu power5_pmu = { .cache_events = &power5_cache_events, }; -static int init_power5_pmu(void) +static int __init init_power5_pmu(void) { if (!cur_cpu_spec->oprofile_cpu_type || strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5")) diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c index 31603927e376..e13dcda4fa98 100644 --- a/arch/powerpc/kernel/power6-pmu.c +++ b/arch/powerpc/kernel/power6-pmu.c @@ -535,7 +535,7 @@ static struct power_pmu power6_pmu = { .cache_events = &power6_cache_events, }; -static int init_power6_pmu(void) +static int __init init_power6_pmu(void) { if (!cur_cpu_spec->oprofile_cpu_type || strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power6")) diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c index 593740fcb799..81230400843c 100644 --- a/arch/powerpc/kernel/power7-pmu.c +++ b/arch/powerpc/kernel/power7-pmu.c @@ -360,7 +360,7 @@ static struct power_pmu power7_pmu = { .cache_events = &power7_cache_events, }; -static int init_power7_pmu(void) +static int __init init_power7_pmu(void) { if (!cur_cpu_spec->oprofile_cpu_type || strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power7")) diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index 9a6e093858fe..45d787920991 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c @@ -484,7 +484,7 @@ static struct power_pmu ppc970_pmu = { .cache_events = &ppc970_cache_events, }; -static int init_ppc970_pmu(void) +static int __init init_ppc970_pmu(void) { if (!cur_cpu_spec->oprofile_cpu_type || (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970") -- cgit v1.2.3 From 63f21a56f1cc0b800a4c00349c59448f82473d19 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Mon, 4 Jul 2011 20:40:10 +0000 Subject: powerpc/kdump: Fix timeout in crash_kexec_wait_realmode The existing code it pretty ugly. How about we clean it up even more like this? From: Anton Blanchard We check for timeout expiry in the outer loop, but we also need to check it in the inner loop or we can lock up forever waiting for a CPU to hit real mode. Signed-off-by: Anton Blanchard Signed-off-by: Michael Neuling Cc: Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/crash.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 4e6ee944495a..cc6a9d5d69ab 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -242,12 +242,8 @@ static void crash_kexec_wait_realmode(int cpu) while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { barrier(); - if (!cpu_possible(i)) { + if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0)) break; - } - if (!cpu_online(i)) { - break; - } msecs--; mdelay(1); } -- cgit v1.2.3 From 88962934226c570717c346684ab5ed2f09c2b359 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 7 Jul 2011 20:35:38 +0000 Subject: powerpc/irq: Quieten irq mapping printks HFI creates interrupts each time a window is setup. This results in a lot of messages in the kernel log buffer: irq: irq 199007 on host null mapped to virtual irq 351 This box has over 3500 of them, causing more important kernel messages to be overwritten. We can get at this information via debugfs now so we may as well turn it into a pr_debug. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 164fb6ca692e..346cc4a396fe 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -744,7 +744,7 @@ unsigned int irq_create_mapping(struct irq_host *host, if (irq_setup_virq(host, virq, hwirq)) return NO_IRQ; - printk(KERN_DEBUG "irq: irq %lu on host %s mapped to virtual irq %u\n", + pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n", hwirq, host->of_node ? host->of_node->full_name : "null", virq); return virq; -- cgit v1.2.3 From 5115a026cebeb5537016497e78f4402e5d4ac54e Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Thu, 14 Jul 2011 19:25:12 +0000 Subject: powerpc: Add CFAR to oops output Now we have the CFAR saved add it to the oops output. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/process.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 885a2dd2ab80..d1aa3f43a68c 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -650,6 +650,8 @@ void show_regs(struct pt_regs * regs) printbits(regs->msr, msr_bits); printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); trap = TRAP(regs); + if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) + printk("CFAR: "REG"\n", regs->orig_gpr3); if (trap == 0x300 || trap == 0x600) #ifdef CONFIG_PPC_ADV_DEBUG_REGS printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr); -- cgit v1.2.3 From 9974eec2b802b630aece96708349738e8d5a2cf6 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Sat, 16 Jul 2011 03:22:13 +0000 Subject: powerpc: Exporting boot_cpuid_phys Kernel loadable module can use hard_smp_processor_id() if building with SMP kernel. In order to make it work for UP kernels too, boot_cpuid_phys symbol (which is what hard_smp_processor_id() macro resolves to in non-SMP configuration) must be exported. Signed-off-by: Andrew Gabbasov Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup_32.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 1d2fbc905303..3dffce673c1f 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -49,6 +49,7 @@ extern void bootx_init(unsigned long r4, unsigned long phys); int boot_cpuid = -1; EXPORT_SYMBOL_GPL(boot_cpuid); int boot_cpuid_phys; +EXPORT_SYMBOL_GPL(boot_cpuid_phys); int smp_hw_index[NR_CPUS]; -- cgit v1.2.3 From 50d2a4223bb875d1e3a7ee97d40dd03bf31ce1b7 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 18 Jul 2011 17:17:22 +0000 Subject: powerpc: Copy back TIF flags on return from softirq stack We already did it for hard IRQs but it looks like we forgot to do it for softirqs. Without this, we would lose flags such as TIF_NEED_RESCHED set using current_thread_info() by something running of a softirq. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/irq.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 346cc4a396fe..d281fb6f12f3 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -451,11 +451,18 @@ static inline void do_softirq_onstack(void) curtp = current_thread_info(); irqtp = softirq_ctx[smp_processor_id()]; irqtp->task = curtp->task; + irqtp->flags = 0; current->thread.ksp_limit = (unsigned long)irqtp + _ALIGN_UP(sizeof(struct thread_info), 16); call_do_softirq(irqtp); current->thread.ksp_limit = saved_sp_limit; irqtp->task = NULL; + + /* Set any flag that may have been set on the + * alternate stack + */ + if (irqtp->flags) + set_bits(irqtp->flags, &curtp->flags); } void do_softirq(void) -- cgit v1.2.3