Skip to content

Commit 024bb96

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6: sparc64: Kill bogus TPC/address truncation during 32-bit faults. sparc: fixup for sparseirq changes sparc64: Validate kernel generated fault addresses on sparc64. sparc64: On non-Niagara, need to touch NMI watchdog in NOHZ mode. sparc64: Implement NMI watchdog on capable cpus. sparc: Probe PMU type and record in sparc_pmu_type. sparc64: Move generic PCR support code to seperate file.
2 parents 25431e9 + 9b02605 commit 024bb96

File tree

17 files changed

+548
-284
lines changed

17 files changed

+548
-284
lines changed

arch/sparc/include/asm/cpudata_64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
typedef struct {
1818
/* Dcache line 1 */
1919
unsigned int __softirq_pending; /* must be 1st, see rtrap.S */
20-
unsigned int __pad0;
20+
unsigned int __nmi_count;
2121
unsigned long clock_tick; /* %tick's per second */
2222
unsigned long __pad;
2323
unsigned int __pad1;

arch/sparc/include/asm/irq_64.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ extern void virt_irq_free(unsigned int virt_irq);
6666
extern void __init init_IRQ(void);
6767
extern void fixup_irqs(void);
6868

69-
extern int register_perfctr_intr(void (*handler)(struct pt_regs *));
70-
extern void release_perfctr_intr(void (*handler)(struct pt_regs *));
71-
7269
static inline void set_softint(unsigned long bits)
7370
{
7471
__asm__ __volatile__("wr %0, 0x0, %%set_softint"
@@ -98,5 +95,6 @@ void __trigger_all_cpu_backtrace(void);
9895
extern void *hardirq_stack[NR_CPUS];
9996
extern void *softirq_stack[NR_CPUS];
10097
#define __ARCH_HAS_DO_SOFTIRQ
98+
#define ARCH_HAS_NMI_WATCHDOG
10199

102100
#endif

arch/sparc/include/asm/kdebug_64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ enum die_val {
1414
DIE_TRAP,
1515
DIE_TRAP_TL1,
1616
DIE_CALL,
17+
DIE_NMI,
18+
DIE_NMIWATCHDOG,
1719
};
1820

1921
#endif

arch/sparc/include/asm/nmi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef __NMI_H
2+
#define __NMI_H
3+
4+
extern int __init nmi_init(void);
5+
extern void perfctr_irq(int irq, struct pt_regs *regs);
6+
extern void nmi_adjust_hz(unsigned int new_hz);
7+
8+
extern int nmi_usable;
9+
10+
#endif /* __NMI_H */

arch/sparc/include/asm/pcr.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#ifndef __PCR_H
2+
#define __PCR_H
3+
4+
struct pcr_ops {
5+
u64 (*read)(void);
6+
void (*write)(u64);
7+
};
8+
extern const struct pcr_ops *pcr_ops;
9+
10+
extern void deferred_pcr_work_irq(int irq, struct pt_regs *regs);
11+
extern void schedule_deferred_pcr_work(void);
12+
13+
#define PCR_PIC_PRIV 0x00000001 /* PIC access is privileged */
14+
#define PCR_STRACE 0x00000002 /* Trace supervisor events */
15+
#define PCR_UTRACE 0x00000004 /* Trace user events */
16+
#define PCR_N2_HTRACE 0x00000008 /* Trace hypervisor events */
17+
#define PCR_N2_TOE_OV0 0x00000010 /* Trap if PIC 0 overflows */
18+
#define PCR_N2_TOE_OV1 0x00000020 /* Trap if PIC 1 overflows */
19+
#define PCR_N2_MASK0 0x00003fc0
20+
#define PCR_N2_MASK0_SHIFT 6
21+
#define PCR_N2_SL0 0x0003c000
22+
#define PCR_N2_SL0_SHIFT 14
23+
#define PCR_N2_OV0 0x00040000
24+
#define PCR_N2_MASK1 0x07f80000
25+
#define PCR_N2_MASK1_SHIFT 19
26+
#define PCR_N2_SL1 0x78000000
27+
#define PCR_N2_SL1_SHIFT 27
28+
#define PCR_N2_OV1 0x80000000
29+
30+
extern unsigned int picl_shift;
31+
32+
/* In order to commonize as much of the implementation as
33+
* possible, we use PICH as our counter. Mostly this is
34+
* to accomodate Niagara-1 which can only count insn cycles
35+
* in PICH.
36+
*/
37+
static inline u64 picl_value(unsigned int nmi_hz)
38+
{
39+
u32 delta = local_cpu_data().clock_tick / (nmi_hz << picl_shift);
40+
41+
return ((u64)((0 - delta) & 0xffffffff)) << 32;
42+
}
43+
44+
extern u64 pcr_enable;
45+
46+
#endif /* __PCR_H */

arch/sparc/include/asm/pil.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define PIL_SMP_CTX_NEW_VERSION 4
2424
#define PIL_DEVICE_IRQ 5
2525
#define PIL_SMP_CALL_FUNC_SNGL 6
26+
#define PIL_DEFERRED_PCR_WORK 7
2627
#define PIL_NORMAL_MAX 14
2728
#define PIL_NMI 15
2829

arch/sparc/kernel/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ obj-$(CONFIG_SPARC64) += visemul.o
5252
obj-$(CONFIG_SPARC64) += hvapi.o
5353
obj-$(CONFIG_SPARC64) += sstate.o
5454
obj-$(CONFIG_SPARC64) += mdesc.o
55+
obj-$(CONFIG_SPARC64) += pcr.o
56+
obj-$(CONFIG_SPARC64) += nmi.o
5557

5658
# sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation
5759
obj-$(CONFIG_SPARC32) += devres.o

arch/sparc/kernel/cpu.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ EXPORT_PER_CPU_SYMBOL(__cpu_data);
2626
struct cpu_info {
2727
int psr_vers;
2828
const char *name;
29+
const char *pmu_name;
2930
};
3031

3132
struct fpu_info {
@@ -45,6 +46,9 @@ struct manufacturer_info {
4546
#define CPU(ver, _name) \
4647
{ .psr_vers = ver, .name = _name }
4748

49+
#define CPU_PMU(ver, _name, _pmu_name) \
50+
{ .psr_vers = ver, .name = _name, .pmu_name = _pmu_name }
51+
4852
#define FPU(ver, _name) \
4953
{ .fp_vers = ver, .name = _name }
5054

@@ -183,10 +187,10 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
183187
},{
184188
0x17,
185189
.cpu_info = {
186-
CPU(0x10, "TI UltraSparc I (SpitFire)"),
187-
CPU(0x11, "TI UltraSparc II (BlackBird)"),
188-
CPU(0x12, "TI UltraSparc IIi (Sabre)"),
189-
CPU(0x13, "TI UltraSparc IIe (Hummingbird)"),
190+
CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"),
191+
CPU_PMU(0x11, "TI UltraSparc II (BlackBird)", "ultra12"),
192+
CPU_PMU(0x12, "TI UltraSparc IIi (Sabre)", "ultra12"),
193+
CPU_PMU(0x13, "TI UltraSparc IIe (Hummingbird)", "ultra12"),
190194
CPU(-1, NULL)
191195
},
192196
.fpu_info = {
@@ -199,7 +203,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
199203
},{
200204
0x22,
201205
.cpu_info = {
202-
CPU(0x10, "TI UltraSparc I (SpitFire)"),
206+
CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"),
203207
CPU(-1, NULL)
204208
},
205209
.fpu_info = {
@@ -209,12 +213,12 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
209213
},{
210214
0x3e,
211215
.cpu_info = {
212-
CPU(0x14, "TI UltraSparc III (Cheetah)"),
213-
CPU(0x15, "TI UltraSparc III+ (Cheetah+)"),
214-
CPU(0x16, "TI UltraSparc IIIi (Jalapeno)"),
215-
CPU(0x18, "TI UltraSparc IV (Jaguar)"),
216-
CPU(0x19, "TI UltraSparc IV+ (Panther)"),
217-
CPU(0x22, "TI UltraSparc IIIi+ (Serrano)"),
216+
CPU_PMU(0x14, "TI UltraSparc III (Cheetah)", "ultra3"),
217+
CPU_PMU(0x15, "TI UltraSparc III+ (Cheetah+)", "ultra3+"),
218+
CPU_PMU(0x16, "TI UltraSparc IIIi (Jalapeno)", "ultra3i"),
219+
CPU_PMU(0x18, "TI UltraSparc IV (Jaguar)", "ultra3+"),
220+
CPU_PMU(0x19, "TI UltraSparc IV+ (Panther)", "ultra4+"),
221+
CPU_PMU(0x22, "TI UltraSparc IIIi+ (Serrano)", "ultra3i"),
218222
CPU(-1, NULL)
219223
},
220224
.fpu_info = {
@@ -234,6 +238,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
234238

235239
const char *sparc_cpu_type;
236240
const char *sparc_fpu_type;
241+
const char *sparc_pmu_type;
237242

238243
unsigned int fsr_storage;
239244

@@ -244,6 +249,7 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
244249

245250
sparc_cpu_type = NULL;
246251
sparc_fpu_type = NULL;
252+
sparc_pmu_type = NULL;
247253
manuf = NULL;
248254

249255
for (i = 0; i < ARRAY_SIZE(manufacturer_info); i++)
@@ -263,6 +269,7 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
263269
{
264270
if (cpu->psr_vers == psr_vers) {
265271
sparc_cpu_type = cpu->name;
272+
sparc_pmu_type = cpu->pmu_name;
266273
sparc_fpu_type = "No FPU";
267274
break;
268275
}
@@ -290,6 +297,8 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
290297
psr_impl, fpu_vers);
291298
sparc_fpu_type = "Unknown FPU";
292299
}
300+
if (sparc_pmu_type == NULL)
301+
sparc_pmu_type = "Unknown PMU";
293302
}
294303

295304
#ifdef CONFIG_SPARC32
@@ -315,11 +324,13 @@ static void __init sun4v_cpu_probe(void)
315324
case SUN4V_CHIP_NIAGARA1:
316325
sparc_cpu_type = "UltraSparc T1 (Niagara)";
317326
sparc_fpu_type = "UltraSparc T1 integrated FPU";
327+
sparc_pmu_type = "niagara";
318328
break;
319329

320330
case SUN4V_CHIP_NIAGARA2:
321331
sparc_cpu_type = "UltraSparc T2 (Niagara2)";
322332
sparc_fpu_type = "UltraSparc T2 integrated FPU";
333+
sparc_pmu_type = "niagara2";
323334
break;
324335

325336
default:

arch/sparc/kernel/irq_64.c

Lines changed: 5 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ int show_interrupts(struct seq_file *p, void *v)
196196
seq_putc(p, '\n');
197197
skip:
198198
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
199+
} else if (i == NR_IRQS) {
200+
seq_printf(p, "NMI: ");
201+
for_each_online_cpu(j)
202+
seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
203+
seq_printf(p, " Non-maskable interrupts\n");
199204
}
200205
return 0;
201206
}
@@ -778,69 +783,6 @@ void do_softirq(void)
778783
local_irq_restore(flags);
779784
}
780785

781-
static void unhandled_perf_irq(struct pt_regs *regs)
782-
{
783-
unsigned long pcr, pic;
784-
785-
read_pcr(pcr);
786-
read_pic(pic);
787-
788-
write_pcr(0);
789-
790-
printk(KERN_EMERG "CPU %d: Got unexpected perf counter IRQ.\n",
791-
smp_processor_id());
792-
printk(KERN_EMERG "CPU %d: PCR[%016lx] PIC[%016lx]\n",
793-
smp_processor_id(), pcr, pic);
794-
}
795-
796-
/* Almost a direct copy of the powerpc PMC code. */
797-
static DEFINE_SPINLOCK(perf_irq_lock);
798-
static void *perf_irq_owner_caller; /* mostly for debugging */
799-
static void (*perf_irq)(struct pt_regs *regs) = unhandled_perf_irq;
800-
801-
/* Invoked from level 15 PIL handler in trap table. */
802-
void perfctr_irq(int irq, struct pt_regs *regs)
803-
{
804-
clear_softint(1 << irq);
805-
perf_irq(regs);
806-
}
807-
808-
int register_perfctr_intr(void (*handler)(struct pt_regs *))
809-
{
810-
int ret;
811-
812-
if (!handler)
813-
return -EINVAL;
814-
815-
spin_lock(&perf_irq_lock);
816-
if (perf_irq != unhandled_perf_irq) {
817-
printk(KERN_WARNING "register_perfctr_intr: "
818-
"perf IRQ busy (reserved by caller %p)\n",
819-
perf_irq_owner_caller);
820-
ret = -EBUSY;
821-
goto out;
822-
}
823-
824-
perf_irq_owner_caller = __builtin_return_address(0);
825-
perf_irq = handler;
826-
827-
ret = 0;
828-
out:
829-
spin_unlock(&perf_irq_lock);
830-
831-
return ret;
832-
}
833-
EXPORT_SYMBOL_GPL(register_perfctr_intr);
834-
835-
void release_perfctr_intr(void (*handler)(struct pt_regs *))
836-
{
837-
spin_lock(&perf_irq_lock);
838-
perf_irq_owner_caller = NULL;
839-
perf_irq = unhandled_perf_irq;
840-
spin_unlock(&perf_irq_lock);
841-
}
842-
EXPORT_SYMBOL_GPL(release_perfctr_intr);
843-
844786
#ifdef CONFIG_HOTPLUG_CPU
845787
void fixup_irqs(void)
846788
{

arch/sparc/kernel/kernel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
/* cpu.c */
77
extern const char *sparc_cpu_type;
8+
extern const char *sparc_pmu_type;
89
extern const char *sparc_fpu_type;
910

1011
extern unsigned int fsr_storage;

0 commit comments

Comments
 (0)