Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
Browse files Browse the repository at this point in the history
Pull arch/tile updates from Chris Metcalf:
 "These fix a few stray build issues seen in linux-next, and also add
  the minimal required support for perf to tilegx"

* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile:
  arch/tile: remove unused variable 'devcap'
  tile: Fix vDSO compilation issue with allyesconfig
  perf tools: Allow building for tile
  tile/perf: Support perf_events on tilegx and tilepro
  tile: Enable NMIs on return from handle_nmi() without errors
  tile: Add support for handling PMC hardware
  tile: don't use __get_cpu_var() with structure-typed arguments
  tile: avoid overflow in ns2cycles
  • Loading branch information
torvalds committed Apr 6, 2014
2 parents 04535d2 + 5eb0bdf commit 18a1a7a
Show file tree
Hide file tree
Showing 15 changed files with 1,295 additions and 20 deletions.
6 changes: 6 additions & 0 deletions arch/tile/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

config TILE
def_bool y
select HAVE_PERF_EVENTS
select USE_PMC if PERF_EVENTS
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_KVM if !TILEGX
Expand Down Expand Up @@ -66,6 +68,10 @@ config HUGETLB_SUPER_PAGES
config GENERIC_TIME_VSYSCALL
def_bool y

# Enable PMC if PERF_EVENTS, OPROFILE, or WATCHPOINTS are enabled.
config USE_PMC
bool

# FIXME: tilegx can implement a more efficient rwsem.
config RWSEM_GENERIC_SPINLOCK
def_bool y
Expand Down
22 changes: 22 additions & 0 deletions arch/tile/include/asm/perf_event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2014 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/

#ifndef _ASM_TILE_PERF_EVENT_H
#define _ASM_TILE_PERF_EVENT_H

#include <linux/percpu.h>
DECLARE_PER_CPU(u64, perf_irqs);

unsigned long handle_syscall_link_address(void);
#endif /* _ASM_TILE_PERF_EVENT_H */
64 changes: 64 additions & 0 deletions arch/tile/include/asm/pmc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2014 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/

#ifndef _ASM_TILE_PMC_H
#define _ASM_TILE_PMC_H

#include <linux/ptrace.h>

#define TILE_BASE_COUNTERS 2

/* Bitfields below are derived from SPR PERF_COUNT_CTL*/
#ifndef __tilegx__
/* PERF_COUNT_CTL on TILEPro */
#define TILE_CTL_EXCL_USER (1 << 7) /* exclude user level */
#define TILE_CTL_EXCL_KERNEL (1 << 8) /* exclude kernel level */
#define TILE_CTL_EXCL_HV (1 << 9) /* exclude hypervisor level */

#define TILE_SEL_MASK 0x7f /* 7 bits for event SEL,
COUNT_0_SEL */
#define TILE_PLM_MASK 0x780 /* 4 bits priv level msks,
COUNT_0_MASK*/
#define TILE_EVENT_MASK (TILE_SEL_MASK | TILE_PLM_MASK)

#else /* __tilegx__*/
/* PERF_COUNT_CTL on TILEGx*/
#define TILE_CTL_EXCL_USER (1 << 10) /* exclude user level */
#define TILE_CTL_EXCL_KERNEL (1 << 11) /* exclude kernel level */
#define TILE_CTL_EXCL_HV (1 << 12) /* exclude hypervisor level */

#define TILE_SEL_MASK 0x3f /* 6 bits for event SEL,
COUNT_0_SEL*/
#define TILE_BOX_MASK 0x1c0 /* 3 bits box msks,
COUNT_0_BOX */
#define TILE_PLM_MASK 0x3c00 /* 4 bits priv level msks,
COUNT_0_MASK */
#define TILE_EVENT_MASK (TILE_SEL_MASK | TILE_BOX_MASK | TILE_PLM_MASK)
#endif /* __tilegx__*/

/* Takes register and fault number. Returns error to disable the interrupt. */
typedef int (*perf_irq_t)(struct pt_regs *, int);

int userspace_perf_handler(struct pt_regs *regs, int fault);

perf_irq_t reserve_pmc_hardware(perf_irq_t new_perf_irq);
void release_pmc_hardware(void);

unsigned long pmc_get_overflow(void);
void pmc_ack_overflow(unsigned long status);

void unmask_pmc_interrupts(void);
void mask_pmc_interrupts(void);

#endif /* _ASM_TILE_PMC_H */
2 changes: 2 additions & 0 deletions arch/tile/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ obj-$(CONFIG_PCI) += pci_gx.o
else
obj-$(CONFIG_PCI) += pci.o
endif
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_USE_PMC) += pmc.o
obj-$(CONFIG_TILE_USB) += usb.o
obj-$(CONFIG_TILE_HVGLUE_TRACE) += hvglue_trace.o
obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o mcount_64.o
Expand Down
24 changes: 18 additions & 6 deletions arch/tile/kernel/intvec_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,13 @@ intvec_\vecname:
movei r3, 0
}
.else
.ifc \c_routine, op_handle_perf_interrupt
.ifc \c_routine, handle_perf_interrupt
{
mfspr r2, PERF_COUNT_STS
movei r3, -1 /* not used, but set for consistency */
}
.else
.ifc \c_routine, op_handle_aux_perf_interrupt
.ifc \c_routine, handle_perf_interrupt
{
mfspr r2, AUX_PERF_COUNT_STS
movei r3, -1 /* not used, but set for consistency */
Expand Down Expand Up @@ -946,6 +946,13 @@ STD_ENTRY(interrupt_return)
bzt r30, .Lrestore_regs
3:

/* We are relying on INT_PERF_COUNT at 33, and AUX_PERF_COUNT at 48 */
{
moveli r0, lo16(1 << (INT_PERF_COUNT - 32))
bz r31, .Lrestore_regs
}
auli r0, r0, ha16(1 << (INT_AUX_PERF_COUNT - 32))
mtspr SPR_INTERRUPT_MASK_RESET_K_1, r0

/*
* We now commit to returning from this interrupt, since we will be
Expand Down Expand Up @@ -1171,6 +1178,10 @@ handle_nmi:
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
}
FEEDBACK_REENTER(handle_nmi)
{
movei r30, 1
seq r31, r0, zero
}
j interrupt_return
STD_ENDPROC(handle_nmi)

Expand Down Expand Up @@ -1835,8 +1846,9 @@ int_unalign:
/* Include .intrpt array of interrupt vectors */
.section ".intrpt", "ax"

#define op_handle_perf_interrupt bad_intr
#define op_handle_aux_perf_interrupt bad_intr
#ifndef CONFIG_USE_PMC
#define handle_perf_interrupt bad_intr
#endif

#ifndef CONFIG_HARDWALL
#define do_hardwall_trap bad_intr
Expand Down Expand Up @@ -1877,7 +1889,7 @@ int_unalign:
int_hand INT_IDN_AVAIL, IDN_AVAIL, bad_intr
int_hand INT_UDN_AVAIL, UDN_AVAIL, bad_intr
int_hand INT_PERF_COUNT, PERF_COUNT, \
op_handle_perf_interrupt, handle_nmi
handle_perf_interrupt, handle_nmi
int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr
#if CONFIG_KERNEL_PL == 2
dc_dispatch INT_INTCTRL_2, INTCTRL_2
Expand All @@ -1902,7 +1914,7 @@ int_unalign:
int_hand INT_SN_CPL, SN_CPL, bad_intr
int_hand INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap
int_hand INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \
op_handle_aux_perf_interrupt, handle_nmi
handle_perf_interrupt, handle_nmi

/* Synthetic interrupt delivered only by the simulator */
int_hand INT_BREAKPOINT, BREAKPOINT, do_breakpoint
24 changes: 17 additions & 7 deletions arch/tile/kernel/intvec_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,10 @@ intvec_\vecname:
.ifc \c_routine, do_trap
mfspr r2, GPV_REASON
.else
.ifc \c_routine, op_handle_perf_interrupt
.ifc \c_routine, handle_perf_interrupt
mfspr r2, PERF_COUNT_STS
.else
.ifc \c_routine, op_handle_aux_perf_interrupt
.ifc \c_routine, handle_perf_interrupt
mfspr r2, AUX_PERF_COUNT_STS
.endif
.endif
Expand Down Expand Up @@ -971,6 +971,15 @@ STD_ENTRY(interrupt_return)
beqzt r30, .Lrestore_regs
3:

#if INT_PERF_COUNT + 1 != INT_AUX_PERF_COUNT
# error Bad interrupt assumption
#endif
{
movei r0, 3 /* two adjacent bits for the PERF_COUNT mask */
beqz r31, .Lrestore_regs
}
shli r0, r0, INT_PERF_COUNT
mtspr SPR_INTERRUPT_MASK_RESET_K, r0

/*
* We now commit to returning from this interrupt, since we will be
Expand Down Expand Up @@ -1187,7 +1196,7 @@ handle_nmi:
FEEDBACK_REENTER(handle_nmi)
{
movei r30, 1
move r31, r0
cmpeq r31, r0, zero
}
j interrupt_return
STD_ENDPROC(handle_nmi)
Expand Down Expand Up @@ -1491,8 +1500,9 @@ STD_ENTRY(fill_ra_stack)
.global intrpt_start
intrpt_start:

#define op_handle_perf_interrupt bad_intr
#define op_handle_aux_perf_interrupt bad_intr
#ifndef CONFIG_USE_PMC
#define handle_perf_interrupt bad_intr
#endif

#ifndef CONFIG_HARDWALL
#define do_hardwall_trap bad_intr
Expand Down Expand Up @@ -1540,9 +1550,9 @@ intrpt_start:
#endif
int_hand INT_IPI_0, IPI_0, bad_intr
int_hand INT_PERF_COUNT, PERF_COUNT, \
op_handle_perf_interrupt, handle_nmi
handle_perf_interrupt, handle_nmi
int_hand INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \
op_handle_perf_interrupt, handle_nmi
handle_perf_interrupt, handle_nmi
int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr
#if CONFIG_KERNEL_PL == 2
dc_dispatch INT_INTCTRL_2, INTCTRL_2
Expand Down
18 changes: 18 additions & 0 deletions arch/tile/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <hv/drv_pcie_rc_intf.h>
#include <arch/spr_def.h>
#include <asm/traps.h>
#include <linux/perf_event.h>

/* Bit-flag stored in irq_desc->chip_data to indicate HW-cleared irqs. */
#define IS_HW_CLEARED 1
Expand Down Expand Up @@ -260,6 +261,23 @@ void ack_bad_irq(unsigned int irq)
pr_err("unexpected IRQ trap at vector %02x\n", irq);
}

/*
* /proc/interrupts printing:
*/
int arch_show_interrupts(struct seq_file *p, int prec)
{
#ifdef CONFIG_PERF_EVENTS
int i;

seq_printf(p, "%*s: ", prec, "PMI");

for_each_online_cpu(i)
seq_printf(p, "%10llu ", per_cpu(perf_irqs, i));
seq_puts(p, " perf_events\n");
#endif
return 0;
}

/*
* Generic, controller-independent functions:
*/
Expand Down
4 changes: 2 additions & 2 deletions arch/tile/kernel/messaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ void hv_message_intr(struct pt_regs *regs, int intnum)
#endif

while (1) {
rmi = hv_receive_message(__get_cpu_var(msg_state),
(HV_VirtAddr) message,
HV_MsgState *state = this_cpu_ptr(&msg_state);
rmi = hv_receive_message(*state, (HV_VirtAddr) message,
sizeof(message));
if (rmi.msglen == 0)
break;
Expand Down
2 changes: 0 additions & 2 deletions arch/tile/kernel/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ static void fixup_read_and_payload_sizes(void)

/* Scan for the smallest maximum payload size. */
for_each_pci_dev(dev) {
u32 devcap;

if (!pci_is_pcie(dev))
continue;

Expand Down
Loading

0 comments on commit 18a1a7a

Please sign in to comment.