Commit be835674 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
  powerpc/perf_event: Fix oops due to perf_event_do_pending call
  powerpc/swiotlb: Fix off by one in determining boundary of which ops to use
parents 5ec390e0 131c6c9e
...@@ -130,43 +130,5 @@ static inline int irqs_disabled_flags(unsigned long flags) ...@@ -130,43 +130,5 @@ static inline int irqs_disabled_flags(unsigned long flags)
*/ */
struct irq_chip; struct irq_chip;
#ifdef CONFIG_PERF_EVENTS
#ifdef CONFIG_PPC64
static inline unsigned long test_perf_event_pending(void)
{
unsigned long x;
asm volatile("lbz %0,%1(13)"
: "=r" (x)
: "i" (offsetof(struct paca_struct, perf_event_pending)));
return x;
}
static inline void set_perf_event_pending(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (1),
"i" (offsetof(struct paca_struct, perf_event_pending)));
}
static inline void clear_perf_event_pending(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (0),
"i" (offsetof(struct paca_struct, perf_event_pending)));
}
#endif /* CONFIG_PPC64 */
#else /* CONFIG_PERF_EVENTS */
static inline unsigned long test_perf_event_pending(void)
{
return 0;
}
static inline void clear_perf_event_pending(void) {}
#endif /* CONFIG_PERF_EVENTS */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HW_IRQ_H */ #endif /* _ASM_POWERPC_HW_IRQ_H */
...@@ -133,7 +133,6 @@ int main(void) ...@@ -133,7 +133,6 @@ int main(void)
DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr)); DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled)); DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending));
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
#ifdef CONFIG_PPC_MM_SLICES #ifdef CONFIG_PPC_MM_SLICES
DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct, DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
......
/* /*
* Contains routines needed to support swiotlb for ppc. * Contains routines needed to support swiotlb for ppc.
* *
* Copyright (C) 2009 Becky Bruce, Freescale Semiconductor * Copyright (C) 2009-2010 Freescale Semiconductor, Inc.
* Author: Becky Bruce
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the
...@@ -70,7 +71,7 @@ static int ppc_swiotlb_bus_notify(struct notifier_block *nb, ...@@ -70,7 +71,7 @@ static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
sd->max_direct_dma_addr = 0; sd->max_direct_dma_addr = 0;
/* May need to bounce if the device can't address all of DRAM */ /* May need to bounce if the device can't address all of DRAM */
if (dma_get_mask(dev) < lmb_end_of_DRAM()) if ((dma_get_mask(dev) + 1) < lmb_end_of_DRAM())
set_dma_ops(dev, &swiotlb_dma_ops); set_dma_ops(dev, &swiotlb_dma_ops);
return NOTIFY_DONE; return NOTIFY_DONE;
......
...@@ -556,15 +556,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) ...@@ -556,15 +556,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
2: 2:
TRACE_AND_RESTORE_IRQ(r5); TRACE_AND_RESTORE_IRQ(r5);
#ifdef CONFIG_PERF_EVENTS
/* check paca->perf_event_pending if we're enabling ints */
lbz r3,PACAPERFPEND(r13)
and. r3,r3,r5
beq 27f
bl .perf_event_do_pending
27:
#endif /* CONFIG_PERF_EVENTS */
/* extract EE bit and use it to restore paca->hard_enabled */ /* extract EE bit and use it to restore paca->hard_enabled */
ld r3,_MSR(r1) ld r3,_MSR(r1)
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/perf_event.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -145,11 +144,6 @@ notrace void raw_local_irq_restore(unsigned long en) ...@@ -145,11 +144,6 @@ notrace void raw_local_irq_restore(unsigned long en)
} }
#endif /* CONFIG_PPC_STD_MMU_64 */ #endif /* CONFIG_PPC_STD_MMU_64 */
if (test_perf_event_pending()) {
clear_perf_event_pending();
perf_event_do_pending();
}
/* /*
* if (get_paca()->hard_enabled) return; * if (get_paca()->hard_enabled) return;
* But again we need to take care that gcc gets hard_enabled directly * But again we need to take care that gcc gets hard_enabled directly
......
...@@ -532,25 +532,60 @@ void __init iSeries_time_init_early(void) ...@@ -532,25 +532,60 @@ void __init iSeries_time_init_early(void)
} }
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */
#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32) #ifdef CONFIG_PERF_EVENTS
DEFINE_PER_CPU(u8, perf_event_pending);
void set_perf_event_pending(void) /*
* 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable...
*/
#ifdef CONFIG_PPC64
static inline unsigned long test_perf_event_pending(void)
{ {
get_cpu_var(perf_event_pending) = 1; unsigned long x;
set_dec(1);
put_cpu_var(perf_event_pending); asm volatile("lbz %0,%1(13)"
: "=r" (x)
: "i" (offsetof(struct paca_struct, perf_event_pending)));
return x;
} }
static inline void set_perf_event_pending_flag(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (1),
"i" (offsetof(struct paca_struct, perf_event_pending)));
}
static inline void clear_perf_event_pending(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (0),
"i" (offsetof(struct paca_struct, perf_event_pending)));
}
#else /* 32-bit */
DEFINE_PER_CPU(u8, perf_event_pending);
#define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1
#define test_perf_event_pending() __get_cpu_var(perf_event_pending) #define test_perf_event_pending() __get_cpu_var(perf_event_pending)
#define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0 #define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0
#else /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */ #endif /* 32 vs 64 bit */
void set_perf_event_pending(void)
{
preempt_disable();
set_perf_event_pending_flag();
set_dec(1);
preempt_enable();
}
#else /* CONFIG_PERF_EVENTS */
#define test_perf_event_pending() 0 #define test_perf_event_pending() 0
#define clear_perf_event_pending() #define clear_perf_event_pending()
#endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */ #endif /* CONFIG_PERF_EVENTS */
/* /*
* For iSeries shared processors, we have to let the hypervisor * For iSeries shared processors, we have to let the hypervisor
...@@ -582,10 +617,6 @@ void timer_interrupt(struct pt_regs * regs) ...@@ -582,10 +617,6 @@ void timer_interrupt(struct pt_regs * regs)
set_dec(DECREMENTER_MAX); set_dec(DECREMENTER_MAX);
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
if (test_perf_event_pending()) {
clear_perf_event_pending();
perf_event_do_pending();
}
if (atomic_read(&ppc_n_lost_interrupts) != 0) if (atomic_read(&ppc_n_lost_interrupts) != 0)
do_IRQ(regs); do_IRQ(regs);
#endif #endif
...@@ -604,6 +635,11 @@ void timer_interrupt(struct pt_regs * regs) ...@@ -604,6 +635,11 @@ void timer_interrupt(struct pt_regs * regs)
calculate_steal_time(); calculate_steal_time();
if (test_perf_event_pending()) {
clear_perf_event_pending();
perf_event_do_pending();
}
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES)) if (firmware_has_feature(FW_FEATURE_ISERIES))
get_lppaca()->int_dword.fields.decr_int = 0; get_lppaca()->int_dword.fields.decr_int = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment