From 7abb840b496f834a71a8943bb189683da320f047 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 14 Oct 2009 19:32:15 +0000 Subject: powerpc/perf_events: Fix priority of MSR HV vs PR bits The architecture defines that if MSR PR is set we are in problem state irrespective of the HV bit. This fixes perf events to reflect this. Also, on bare metal systems, samples taken in Linux will now be reported as kernel rather than hypervisor. Signed-off-by: Michael Neuling CC: paulus@samba.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/perf_event.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index bbcbae183e92..87f1663584b0 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c @@ -116,20 +116,23 @@ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) static inline u32 perf_get_misc_flags(struct pt_regs *regs) { unsigned long mmcra = regs->dsisr; + unsigned long sihv = MMCRA_SIHV; + unsigned long sipr = MMCRA_SIPR; if (TRAP(regs) != 0xf00) return 0; /* not a PMU interrupt */ if (ppmu->flags & PPMU_ALT_SIPR) { - if (mmcra & POWER6_MMCRA_SIHV) - return PERF_RECORD_MISC_HYPERVISOR; - return (mmcra & POWER6_MMCRA_SIPR) ? - PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL; + sihv = POWER6_MMCRA_SIHV; + sipr = POWER6_MMCRA_SIPR; } - if (mmcra & MMCRA_SIHV) + + /* PR has priority over HV, so order below is important */ + if (mmcra & sipr) + return PERF_RECORD_MISC_USER; + if ((mmcra & sihv) && (freeze_events_kernel != MMCR0_FCHV)) return PERF_RECORD_MISC_HYPERVISOR; - return (mmcra & MMCRA_SIPR) ? PERF_RECORD_MISC_USER : - PERF_RECORD_MISC_KERNEL; + return PERF_RECORD_MISC_KERNEL; } /* -- cgit v1.2.2 From 7de80284d60837f13ecb2347ba7bf57470309541 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Fri, 2 Oct 2009 23:25:31 +0000 Subject: powerpc: Fix segment mapping in vdso32 Due to missing segment assignments the .text section was put in the NOTES segment (and marked as NOTE section), and the .got was put in the DYNAMIC segment. Signed-off-by: Andreas Schwab Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vdso32/vdso32.lds.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 904ef1360dd7..0546bcd49cd0 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -25,7 +25,7 @@ SECTIONS . = ALIGN(16); .text : { *(.text .stub .text.* .gnu.linkonce.t.* __ftr_alt_*) - } + } :text PROVIDE(__etext = .); PROVIDE(_etext = .); PROVIDE(etext = .); @@ -56,7 +56,7 @@ SECTIONS .fixup : { *(.fixup) } .dynamic : { *(.dynamic) } :text :dynamic - .got : { *(.got) } + .got : { *(.got) } :text .plt : { *(.plt) } _end = .; -- cgit v1.2.2 From 348aa3030096e61474a5537fed5bd69e70b755c0 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sun, 4 Oct 2009 02:35:41 +0000 Subject: powerpc: Align vDSO base address The ABI specifies a 64K alignment, we need to map the vDSO accordingly Signed-off-by: Andreas Schwab Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vdso.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 94e2df3cae07..137dc22afa42 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -50,6 +50,9 @@ /* Max supported size for symbol names */ #define MAX_SYMNAME 64 +/* The alignment of the vDSO */ +#define VDSO_ALIGNMENT (1 << 16) + extern char vdso32_start, vdso32_end; static void *vdso32_kbase = &vdso32_start; static unsigned int vdso32_pages; @@ -231,15 +234,21 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * pick a base address for the vDSO in process space. We try to put it * at vdso_base which is the "natural" base for it, but we might fail * and end up putting it elsewhere. + * Add enough to the size so that the result can be aligned. */ down_write(&mm->mmap_sem); vdso_base = get_unmapped_area(NULL, vdso_base, - vdso_pages << PAGE_SHIFT, 0, 0); + (vdso_pages << PAGE_SHIFT) + + ((VDSO_ALIGNMENT - 1) & PAGE_MASK), + 0, 0); if (IS_ERR_VALUE(vdso_base)) { rc = vdso_base; goto fail_mmapsem; } + /* Add required alignment. */ + vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT); + /* * Put vDSO base into mm struct. We need to do this before calling * install_special_mapping or the perf counter mmap tracking code -- cgit v1.2.2 From ce7a35c73a308c62f9f0ca9f0821ebe0dc553008 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 16 Oct 2009 07:05:17 +0000 Subject: powerpc: Fix compile errors found by new ppc64e_defconfig Fix the following 3 issues: arch/powerpc/kernel/process.c: In function 'arch_randomize_brk': arch/powerpc/kernel/process.c:1183: error: 'mmu_highuser_ssize' undeclared (first use in this function) arch/powerpc/kernel/process.c:1183: error: (Each undeclared identifier is reported only once arch/powerpc/kernel/process.c:1183: error: for each function it appears in.) arch/powerpc/kernel/process.c:1183: error: 'MMU_SEGSIZE_1T' undeclared (first use in this function) In file included from arch/powerpc/kernel/setup_64.c:60: arch/powerpc/include/asm/mmu-hash64.h:132: error: redefinition of 'struct mmu_psize_def' arch/powerpc/include/asm/mmu-hash64.h:159: error: expected identifier or '(' before numeric constant arch/powerpc/include/asm/mmu-hash64.h:396: error: conflicting types for 'mm_context_t' arch/powerpc/include/asm/mmu-book3e.h:184: error: previous declaration of 'mm_context_t' was here cc1: warnings being treated as errors arch/powerpc/kernel/pci_64.c: In function 'pcibios_unmap_io_space': arch/powerpc/kernel/pci_64.c:100: error: unused variable 'res' Signed-off-by: Kumar Gala Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/pci_64.c | 2 ++ arch/powerpc/kernel/process.c | 2 +- arch/powerpc/kernel/setup_64.c | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index ba949a2c93ac..ccf56ac92de5 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -97,7 +97,9 @@ int pcibios_unmap_io_space(struct pci_bus *bus) * to do an appropriate TLB flush here too */ if (bus->self) { +#ifdef CONFIG_PPC_STD_MMU_64 struct resource *res = bus->resource[0]; +#endif pr_debug("IO unmapping for PCI-PCI bridge %s\n", pci_name(bus->self)); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 2ec1eaed19ca..c930ac38e59f 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1172,7 +1172,7 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) unsigned long base = mm->brk; unsigned long ret; -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_STD_MMU_64 /* * If we are using 1TB segments and we are allowed to randomise * the heap, we can put it above 1TB so it is backed by a 1TB diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 797ea95aae2e..04f638d82fb3 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.2 From 4f917ba3d5ee9c98d60fa357e799942df8412de3 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 26 Oct 2009 19:41:17 +0000 Subject: powerpc/ppc64: Use preempt_schedule_irq instead of preempt_schedule Based on an original patch by Valentine Barshak Use preempt_schedule_irq to prevent infinite irq-entry and eventual stack overflow problems with fast-paced IRQ sources. This kind of problems has been observed on the PASemi Electra IDE controller. We have to make sure we are soft-disabled before calling preempt_schedule_irq and hard disable interrupts after that to avoid unrecoverable exceptions. This patch also moves the "clrrdi r9,r1,THREAD_SHIFT" out of the #ifdef CONFIG_PPC_BOOK3E scope, since r9 is clobbered and has to be restored in both cases. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/entry_64.S | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index f9fd54bfcc84..9763267e38b4 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -658,42 +658,43 @@ do_work: cmpdi r0,0 crandc eq,cr1*4+eq,eq bne restore - /* here we are preempting the current task */ -1: -#ifdef CONFIG_TRACE_IRQFLAGS - bl .trace_hardirqs_on - /* Note: we just clobbered r10 which used to contain the previous - * MSR before the hard-disabling done by the caller of do_work. - * We don't have that value anymore, but it doesn't matter as - * we will hard-enable unconditionally, we can just reload the - * current MSR into r10 + + /* Here we are preempting the current task. + * + * Ensure interrupts are soft-disabled. We also properly mark + * the PACA to reflect the fact that they are hard-disabled + * and trace the change */ - mfmsr r10 -#endif /* CONFIG_TRACE_IRQFLAGS */ - li r0,1 + li r0,0 stb r0,PACASOFTIRQEN(r13) stb r0,PACAHARDIRQEN(r13) + TRACE_DISABLE_INTS + + /* Call the scheduler with soft IRQs off */ +1: bl .preempt_schedule_irq + + /* Hard-disable interrupts again (and update PACA) */ #ifdef CONFIG_PPC_BOOK3E - wrteei 1 - bl .preempt_schedule wrteei 0 #else - ori r10,r10,MSR_EE - mtmsrd r10,1 /* reenable interrupts */ - bl .preempt_schedule mfmsr r10 - clrrdi r9,r1,THREAD_SHIFT - rldicl r10,r10,48,1 /* disable interrupts again */ + rldicl r10,r10,48,1 rotldi r10,r10,16 mtmsrd r10,1 #endif /* CONFIG_PPC_BOOK3E */ + li r0,0 + stb r0,PACAHARDIRQEN(r13) + + /* Re-test flags and eventually loop */ + clrrdi r9,r1,THREAD_SHIFT ld r4,TI_FLAGS(r9) andi. r0,r4,_TIF_NEED_RESCHED bne 1b b restore user_work: -#endif +#endif /* CONFIG_PREEMPT */ + /* Enable interrupts */ #ifdef CONFIG_PPC_BOOK3E wrteei 1 -- cgit v1.2.2 From 978d7eb31d44de34a7f71e04ed4158f3f854688d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 1 Nov 2009 19:11:03 +0000 Subject: powerpc: Avoid giving out RTC dates below EPOCH Doing so causes xtime to be negative which crashes the timekeeping code in funny ways when doing suspend/resume Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/time.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 92dc844299b6..a136a11c490d 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -777,7 +777,7 @@ int update_persistent_clock(struct timespec now) return ppc_md.set_rtc_time(&tm); } -void read_persistent_clock(struct timespec *ts) +static void __read_persistent_clock(struct timespec *ts) { struct rtc_time tm; static int first = 1; @@ -800,10 +800,23 @@ void read_persistent_clock(struct timespec *ts) return; } ppc_md.get_rtc_time(&tm); + ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); } +void read_persistent_clock(struct timespec *ts) +{ + __read_persistent_clock(ts); + + /* Sanitize it in case real time clock is set below EPOCH */ + if (ts->tv_sec < 0) { + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + +} + /* clocksource code */ static cycle_t rtc_read(struct clocksource *cs) { -- cgit v1.2.2