diff options
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 19 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/sysfs.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/dtl.c | 4 |
7 files changed, 31 insertions, 10 deletions
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index d3466490104a..9eed29eee604 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -313,6 +313,25 @@ static inline void prefetchw(const void *x) #define HAVE_ARCH_PICK_MMAP_LAYOUT #endif +#ifdef CONFIG_PPC64 +static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) +{ + unsigned long sp; + + if (is_32) + sp = regs->gpr[1] & 0x0ffffffffUL; + else + sp = regs->gpr[1]; + + return sp; +} +#else +static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) +{ + return regs->gpr[1]; +} +#endif + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PROCESSOR_H */ diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a54405ebd7b0..00b5078da9a3 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -26,12 +26,12 @@ int show_unhandled_signals = 0; * Allocate space for the signal frame */ void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size) + size_t frame_size, int is_32) { unsigned long oldsp, newsp; /* Default to using normal stack */ - oldsp = regs->gpr[1]; + oldsp = get_clean_sp(regs, is_32); /* Check for alt stack */ if ((ka->sa.sa_flags & SA_ONSTACK) && diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index f1442d69d4ec..6c0ddfc0603e 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -15,7 +15,7 @@ extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags); extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size); + size_t frame_size, int is_32); extern void restore_sigmask(sigset_t *set); extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index b13abf305996..d670429a1608 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -836,7 +836,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ - rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf)); + rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1); addr = rt_sf; if (unlikely(rt_sf == NULL)) goto badframe; @@ -1182,7 +1182,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, unsigned long newsp = 0; /* Set up Signal Frame */ - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ka, regs, sizeof(*frame), 1); if (unlikely(frame == NULL)) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index e132891d3cea..2fe6fc64b614 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -402,7 +402,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, unsigned long newsp = 0; long err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ka, regs, sizeof(*frame), 0); if (unlikely(frame == NULL)) goto badframe; diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index e6cd6c990c25..f41aec85aa49 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -134,17 +134,15 @@ void ppc_enable_pmcs(void) } EXPORT_SYMBOL(ppc_enable_pmcs); - #define SYSFS_PMCSETUP(NAME, ADDRESS) \ static void read_##NAME(void *val) \ { \ - mtspr(ADDRESS, *(unsigned long *)val); \ + *(unsigned long *)val = mfspr(ADDRESS); \ } \ -static unsigned long write_##NAME(unsigned long val) \ +static void write_##NAME(void *val) \ { \ ppc_enable_pmcs(); \ mtspr(ADDRESS, *(unsigned long *)val); \ - return 0; \ } \ static ssize_t show_##NAME(struct sys_device *dev, \ struct sysdev_attribute *attr, \ diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index dc9b0f81e60f..fafcaa0e81ef 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -107,6 +107,10 @@ static int dtl_enable(struct dtl *dtl) /* set our initial buffer indices */ dtl->last_idx = lppaca[dtl->cpu].dtl_idx = 0; + /* ensure that our updates to the lppaca fields have occurred before + * we actually enable the logging */ + smp_wmb(); + /* enable event logging */ lppaca[dtl->cpu].dtl_enable_mask = dtl_event_mask; |