diff options
Diffstat (limited to 'arch/tile/kernel')
-rw-r--r-- | arch/tile/kernel/backtrace.c | 137 | ||||
-rw-r--r-- | arch/tile/kernel/compat_signal.c | 4 | ||||
-rw-r--r-- | arch/tile/kernel/hardwall.c | 1 | ||||
-rw-r--r-- | arch/tile/kernel/intvec_32.S | 21 | ||||
-rw-r--r-- | arch/tile/kernel/irq.c | 4 | ||||
-rw-r--r-- | arch/tile/kernel/proc.c | 1 | ||||
-rw-r--r-- | arch/tile/kernel/process.c | 35 | ||||
-rw-r--r-- | arch/tile/kernel/setup.c | 4 | ||||
-rw-r--r-- | arch/tile/kernel/signal.c | 27 | ||||
-rw-r--r-- | arch/tile/kernel/stack.c | 10 | ||||
-rw-r--r-- | arch/tile/kernel/time.c | 33 | ||||
-rw-r--r-- | arch/tile/kernel/traps.c | 4 |
12 files changed, 180 insertions, 101 deletions
diff --git a/arch/tile/kernel/backtrace.c b/arch/tile/kernel/backtrace.c index 77265f3b58d..d3c41c1ff6b 100644 --- a/arch/tile/kernel/backtrace.c +++ b/arch/tile/kernel/backtrace.c @@ -19,9 +19,6 @@ #include <arch/chip.h> -#if TILE_CHIP < 10 - - #include <asm/opcode-tile.h> @@ -29,6 +26,27 @@ #define TREG_LR 55 +#if TILE_CHIP >= 10 +#define tile_bundle_bits tilegx_bundle_bits +#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE +#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES +#define tile_decoded_instruction tilegx_decoded_instruction +#define tile_mnemonic tilegx_mnemonic +#define parse_insn_tile parse_insn_tilegx +#define TILE_OPC_IRET TILEGX_OPC_IRET +#define TILE_OPC_ADDI TILEGX_OPC_ADDI +#define TILE_OPC_ADDLI TILEGX_OPC_ADDLI +#define TILE_OPC_INFO TILEGX_OPC_INFO +#define TILE_OPC_INFOL TILEGX_OPC_INFOL +#define TILE_OPC_JRP TILEGX_OPC_JRP +#define TILE_OPC_MOVE TILEGX_OPC_MOVE +#define OPCODE_STORE TILEGX_OPC_ST +typedef long long bt_int_reg_t; +#else +#define OPCODE_STORE TILE_OPC_SW +typedef int bt_int_reg_t; +#endif + /** A decoded bundle used for backtracer analysis. */ struct BacktraceBundle { tile_bundle_bits bits; @@ -41,7 +59,7 @@ struct BacktraceBundle { /* This implementation only makes sense for native tools. */ /** Default function to read memory. */ static bool bt_read_memory(void *result, VirtualAddress addr, - size_t size, void *extra) + unsigned int size, void *extra) { /* FIXME: this should do some horrible signal stuff to catch * SEGV cleanly and fail. @@ -106,6 +124,12 @@ static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust) find_matching_insn(bundle, TILE_OPC_ADDI, vals, 2); if (insn == NULL) insn = find_matching_insn(bundle, TILE_OPC_ADDLI, vals, 2); +#if TILE_CHIP >= 10 + if (insn == NULL) + insn = find_matching_insn(bundle, TILEGX_OPC_ADDXLI, vals, 2); + if (insn == NULL) + insn = find_matching_insn(bundle, TILEGX_OPC_ADDXI, vals, 2); +#endif if (insn == NULL) return false; @@ -190,13 +214,52 @@ static inline bool bt_has_move_r52_sp(const struct BacktraceBundle *bundle) return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL; } -/** Does this bundle contain the instruction 'sw sp, lr'? */ +/** Does this bundle contain a store of lr to sp? */ static inline bool bt_has_sw_sp_lr(const struct BacktraceBundle *bundle) { static const int vals[2] = { TREG_SP, TREG_LR }; - return find_matching_insn(bundle, TILE_OPC_SW, vals, 2) != NULL; + return find_matching_insn(bundle, OPCODE_STORE, vals, 2) != NULL; +} + +#if TILE_CHIP >= 10 +/** Track moveli values placed into registers. */ +static inline void bt_update_moveli(const struct BacktraceBundle *bundle, + int moveli_args[]) +{ + int i; + for (i = 0; i < bundle->num_insns; i++) { + const struct tile_decoded_instruction *insn = + &bundle->insns[i]; + + if (insn->opcode->mnemonic == TILEGX_OPC_MOVELI) { + int reg = insn->operand_values[0]; + moveli_args[reg] = insn->operand_values[1]; + } + } } +/** Does this bundle contain an 'add sp, sp, reg' instruction + * from a register that we saw a moveli into, and if so, what + * is the value in the register? + */ +static bool bt_has_add_sp(const struct BacktraceBundle *bundle, int *adjust, + int moveli_args[]) +{ + static const int vals[2] = { TREG_SP, TREG_SP }; + + const struct tile_decoded_instruction *insn = + find_matching_insn(bundle, TILEGX_OPC_ADDX, vals, 2); + if (insn) { + int reg = insn->operand_values[2]; + if (moveli_args[reg]) { + *adjust = moveli_args[reg]; + return true; + } + } + return false; +} +#endif + /** Locates the caller's PC and SP for a program starting at the * given address. */ @@ -227,6 +290,11 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location, int next_bundle = 0; VirtualAddress pc; +#if TILE_CHIP >= 10 + /* Naively try to track moveli values to support addx for -m32. */ + int moveli_args[TILEGX_NUM_REGISTERS] = { 0 }; +#endif + /* Default to assuming that the caller's sp is the current sp. * This is necessary to handle the case where we start backtracing * right at the end of the epilog. @@ -380,7 +448,11 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location, if (!sp_determined) { int adjust; - if (bt_has_addi_sp(&bundle, &adjust)) { + if (bt_has_addi_sp(&bundle, &adjust) +#if TILE_CHIP >= 10 + || bt_has_add_sp(&bundle, &adjust, moveli_args) +#endif + ) { location->sp_location = SP_LOC_OFFSET; if (adjust <= 0) { @@ -427,6 +499,11 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location, sp_determined = true; } } + +#if TILE_CHIP >= 10 + /* Track moveli arguments for -m32 mode. */ + bt_update_moveli(&bundle, moveli_args); +#endif } if (bt_has_iret(&bundle)) { @@ -502,11 +579,10 @@ void backtrace_init(BacktraceIterator *state, break; } - /* The frame pointer should theoretically be aligned mod 8. If - * it's not even aligned mod 4 then something terrible happened - * and we should mark it as invalid. + /* If the frame pointer is not aligned to the basic word size + * something terrible happened and we should mark it as invalid. */ - if (fp % 4 != 0) + if (fp % sizeof(bt_int_reg_t) != 0) fp = -1; /* -1 means "don't know initial_frame_caller_pc". */ @@ -547,9 +623,16 @@ void backtrace_init(BacktraceIterator *state, state->read_memory_func_extra = read_memory_func_extra; } +/* Handle the case where the register holds more bits than the VA. */ +static bool valid_addr_reg(bt_int_reg_t reg) +{ + return ((VirtualAddress)reg == reg); +} + bool backtrace_next(BacktraceIterator *state) { - VirtualAddress next_fp, next_pc, next_frame[2]; + VirtualAddress next_fp, next_pc; + bt_int_reg_t next_frame[2]; if (state->fp == -1) { /* No parent frame. */ @@ -563,11 +646,9 @@ bool backtrace_next(BacktraceIterator *state) } next_fp = next_frame[1]; - if (next_fp % 4 != 0) { - /* Caller's frame pointer is suspect, so give up. - * Technically it should be aligned mod 8, but we will - * be forgiving here. - */ + if (!valid_addr_reg(next_frame[1]) || + next_fp % sizeof(bt_int_reg_t) != 0) { + /* Caller's frame pointer is suspect, so give up. */ return false; } @@ -585,7 +666,7 @@ bool backtrace_next(BacktraceIterator *state) } else { /* Get the caller PC from the frame linkage area. */ next_pc = next_frame[0]; - if (next_pc == 0 || + if (!valid_addr_reg(next_frame[0]) || next_pc == 0 || next_pc % TILE_BUNDLE_ALIGNMENT_IN_BYTES != 0) { /* The PC is suspect, so give up. */ return false; @@ -599,23 +680,3 @@ bool backtrace_next(BacktraceIterator *state) return true; } - -#else /* TILE_CHIP < 10 */ - -void backtrace_init(BacktraceIterator *state, - BacktraceMemoryReader read_memory_func, - void *read_memory_func_extra, - VirtualAddress pc, VirtualAddress lr, - VirtualAddress sp, VirtualAddress r52) -{ - state->pc = pc; - state->sp = sp; - state->fp = -1; - state->initial_frame_caller_pc = -1; - state->read_memory_func = read_memory_func; - state->read_memory_func_extra = read_memory_func_extra; -} - -bool backtrace_next(BacktraceIterator *state) { return false; } - -#endif /* TILE_CHIP < 10 */ diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index d5efb215dd5..9c710db43f1 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c @@ -56,13 +56,15 @@ struct compat_ucontext { sigset_t uc_sigmask; /* mask last for extensibility */ }; +#define COMPAT_SI_PAD_SIZE ((SI_MAX_SIZE - 3 * sizeof(int)) / sizeof(int)) + struct compat_siginfo { int si_signo; int si_errno; int si_code; union { - int _pad[SI_PAD_SIZE]; + int _pad[COMPAT_SI_PAD_SIZE]; /* kill() */ struct { diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 584b965dc82..1e54a784341 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c @@ -774,6 +774,7 @@ static const struct file_operations dev_hardwall_fops = { #endif .flush = hardwall_flush, .release = hardwall_release, + .llseek = noop_llseek, }; static struct cdev hardwall_dev; diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 3404c75f8e6..8f58bdff20d 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S @@ -952,7 +952,7 @@ STD_ENTRY(interrupt_return) * able to safely read all the remaining words on those cache * lines without waiting for the memory subsystem. */ - pop_reg_zero r0, r1, sp, PTREGS_OFFSET_REG(30) - PTREGS_OFFSET_REG(0) + pop_reg_zero r0, r28, sp, PTREGS_OFFSET_REG(30) - PTREGS_OFFSET_REG(0) pop_reg_zero r30, r2, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(30) pop_reg_zero r21, r3, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC pop_reg_zero lr, r4, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_EX1 @@ -1017,7 +1017,17 @@ STD_ENTRY(interrupt_return) { move r22, zero; move r23, zero } { move r24, zero; move r25, zero } { move r26, zero; move r27, zero } - { move r28, zero; move r29, zero } + + /* Set r1 to errno if we are returning an error, otherwise zero. */ + { + moveli r29, 1024 + sub r1, zero, r0 + } + slt_u r29, r1, r29 + { + mnz r1, r29, r1 + move r29, zero + } iret /* @@ -1496,13 +1506,6 @@ handle_ill: } STD_ENDPROC(handle_ill) - .pushsection .rodata, "a" - .align 8 -bpt_code: - bpt - ENDPROC(bpt_code) - .popsection - /* Various stub interrupt handlers and syscall handlers */ STD_ENTRY_LOCAL(_kernel_double_fault) diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index 596c6008693..9a27d563fc3 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c @@ -208,7 +208,7 @@ static void tile_irq_chip_eoi(unsigned int irq) } static struct irq_chip tile_irq_chip = { - .typename = "tile_irq_chip", + .name = "tile_irq_chip", .ack = tile_irq_chip_ack, .eoi = tile_irq_chip_eoi, .mask = tile_irq_chip_mask, @@ -288,7 +288,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].chip->name); seq_printf(p, " %s", action->name); for (action = action->next; action; action = action->next) diff --git a/arch/tile/kernel/proc.c b/arch/tile/kernel/proc.c index 92ef925d2f8..2e02c41ddf3 100644 --- a/arch/tile/kernel/proc.c +++ b/arch/tile/kernel/proc.c @@ -23,7 +23,6 @@ #include <linux/sysctl.h> #include <linux/hardirq.h> #include <linux/mman.h> -#include <linux/smp.h> #include <asm/pgtable.h> #include <asm/processor.h> #include <asm/sections.h> diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index ed590ad0acd..84c29111756 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c @@ -408,6 +408,15 @@ static void save_arch_state(struct thread_struct *t) #if CHIP_HAS_PROC_STATUS_SPR() t->proc_status = __insn_mfspr(SPR_PROC_STATUS); #endif +#if !CHIP_HAS_FIXED_INTVEC_BASE() + t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0); +#endif +#if CHIP_HAS_TILE_RTF_HWM() + t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM); +#endif +#if CHIP_HAS_DSTREAM_PF() + t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF); +#endif } static void restore_arch_state(const struct thread_struct *t) @@ -428,14 +437,14 @@ static void restore_arch_state(const struct thread_struct *t) #if CHIP_HAS_PROC_STATUS_SPR() __insn_mtspr(SPR_PROC_STATUS, t->proc_status); #endif +#if !CHIP_HAS_FIXED_INTVEC_BASE() + __insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base); +#endif #if CHIP_HAS_TILE_RTF_HWM() - /* - * Clear this whenever we switch back to a process in case - * the previous process was monkeying with it. Even if enabled - * in CBOX_MSR1 via TILE_RTF_HWM_MIN, it's still just a - * performance hint, so isn't worth a full save/restore. - */ - __insn_mtspr(SPR_TILE_RTF_HWM, 0); + __insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm); +#endif +#if CHIP_HAS_DSTREAM_PF() + __insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf); #endif } @@ -543,8 +552,9 @@ long _sys_vfork(struct pt_regs *regs) /* * sys_execve() executes a new program. */ -long _sys_execve(char __user *path, char __user *__user *argv, - char __user *__user *envp, struct pt_regs *regs) +long _sys_execve(const char __user *path, + const char __user *const __user *argv, + const char __user *const __user *envp, struct pt_regs *regs) { long error; char *filename; @@ -560,8 +570,9 @@ out: } #ifdef CONFIG_COMPAT -long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, - compat_uptr_t __user *envp, struct pt_regs *regs) +long _compat_sys_execve(const char __user *path, + const compat_uptr_t __user *argv, + const compat_uptr_t __user *envp, struct pt_regs *regs) { long error; char *filename; @@ -656,7 +667,7 @@ void show_regs(struct pt_regs *regs) regs->regs[51], regs->regs[52], regs->tp); pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); #else - for (i = 0; i < 52; i += 3) + for (i = 0; i < 52; i += 4) pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", i, regs->regs[i], i+1, regs->regs[i+1], diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index 4dd21c1e6d5..e7d54c73d5c 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -953,7 +953,7 @@ static void __init load_hv_initrd(void) if (rc != stat.size) { pr_err("Error reading %d bytes from hvfs file '%s': %d\n", stat.size, initramfs_file, rc); - free_bootmem((unsigned long) initrd, stat.size); + free_initrd_mem((unsigned long) initrd, stat.size); return; } initrd_start = (unsigned long) initrd; @@ -962,7 +962,7 @@ static void __init load_hv_initrd(void) void __init free_initrd_mem(unsigned long begin, unsigned long end) { - free_bootmem(begin, end - begin); + free_bootmem(__pa(begin), end - begin); } static void __init validate_hv(void) diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index 45b66a3c991..ce183aa1492 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c @@ -61,13 +61,19 @@ int restore_sigcontext(struct pt_regs *regs, /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; + /* + * Enforce that sigcontext is like pt_regs, and doesn't mess + * up our stack alignment rules. + */ + BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs)); + BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0); + for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) - err |= __get_user(((long *)regs)[i], - &((long __user *)(&sc->regs))[i]); + err |= __get_user(regs->regs[i], &sc->gregs[i]); regs->faultnum = INT_SWINT_1_SIGRETURN; - err |= __get_user(*pr0, &sc->regs.regs[0]); + err |= __get_user(*pr0, &sc->gregs[0]); return err; } @@ -112,8 +118,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) int i, err = 0; for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) - err |= __put_user(((long *)regs)[i], - &((long __user *)(&sc->regs))[i]); + err |= __put_user(regs->regs[i], &sc->gregs[i]); return err; } @@ -203,19 +208,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * Set up registers for signal handler. * Registers that we don't modify keep the value they had from * user-space at the time we took the signal. + * We always pass siginfo and mcontext, regardless of SA_SIGINFO, + * since some things rely on this (e.g. glibc's debug/segfault.c). */ regs->pc = (unsigned long) ka->sa.sa_handler; regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ regs->sp = (unsigned long) frame; regs->lr = restorer; regs->regs[0] = (unsigned long) usig; - - if (ka->sa.sa_flags & SA_SIGINFO) { - /* Need extra arguments, so mark to restore caller-saves. */ - regs->regs[1] = (unsigned long) &frame->info; - regs->regs[2] = (unsigned long) &frame->uc; - regs->flags |= PT_FLAGS_CALLER_SAVES; - } + regs->regs[1] = (unsigned long) &frame->info; + regs->regs[2] = (unsigned long) &frame->uc; + regs->flags |= PT_FLAGS_CALLER_SAVES; /* * Notify any tracer that was single-stepping it. diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index b6268d3ae86..ea2e0ce2838 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c @@ -108,7 +108,6 @@ static bool read_memory_func(void *result, VirtualAddress address, /* Return a pt_regs pointer for a valid fault handler frame */ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt) { -#ifndef __tilegx__ const char *fault = NULL; /* happy compiler */ char fault_buf[64]; VirtualAddress sp = kbt->it.sp; @@ -146,7 +145,6 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt) } if (!kbt->profile || (INT_MASK(p->faultnum) & QUEUED_INTERRUPTS) == 0) return p; -#endif return NULL; } @@ -177,7 +175,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt) pr_err(" <received signal %d>\n", frame->info.si_signo); } - return &frame->uc.uc_mcontext.regs; + return (struct pt_regs *)&frame->uc.uc_mcontext; } return NULL; } @@ -351,12 +349,6 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) kbt->task->pid, kbt->task->tgid, kbt->task->comm, smp_processor_id(), get_cycles()); } -#ifdef __tilegx__ - if (kbt->is_current) { - __insn_mtspr(SPR_SIM_CONTROL, - SIM_DUMP_SPR_ARG(SIM_DUMP_BACKTRACE)); - } -#endif kbt->verbose = 1; i = 0; for (; !KBacktraceIterator_end(kbt); KBacktraceIterator_next(kbt)) { diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index b9ab25a889b..6bed820e142 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -36,16 +36,6 @@ /* How many cycles per second we are running at. */ static cycles_t cycles_per_sec __write_once; -/* - * We set up shift and multiply values with a minsec of five seconds, - * since our timer counter counts down 31 bits at a frequency of - * no less than 500 MHz. See @minsec for clocks_calc_mult_shift(). - * We could use a different value for the 64-bit free-running - * cycle counter, but we use the same one for consistency, and since - * we will be reasonably precise with this value anyway. - */ -#define TILE_MINSEC 5 - cycles_t get_clock_rate(void) { return cycles_per_sec; @@ -68,6 +58,14 @@ cycles_t get_cycles(void) } #endif +/* + * We use a relatively small shift value so that sched_clock() + * won't wrap around very often. + */ +#define SCHED_CLOCK_SHIFT 10 + +static unsigned long sched_clock_mult __write_once; + static cycles_t clocksource_get_cycles(struct clocksource *cs) { return get_cycles(); @@ -78,6 +76,7 @@ static struct clocksource cycle_counter_cs = { .rating = 300, .read = clocksource_get_cycles, .mask = CLOCKSOURCE_MASK(64), + .shift = 22, /* typical value, e.g. x86 tsc uses this */ .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -88,8 +87,10 @@ static struct clocksource cycle_counter_cs = { void __init setup_clock(void) { cycles_per_sec = hv_sysconf(HV_SYSCONF_CPU_SPEED); - clocksource_calc_mult_shift(&cycle_counter_cs, cycles_per_sec, - TILE_MINSEC); + sched_clock_mult = + clocksource_hz2mult(cycles_per_sec, SCHED_CLOCK_SHIFT); + cycle_counter_cs.mult = + clocksource_hz2mult(cycles_per_sec, cycle_counter_cs.shift); } void __init calibrate_delay(void) @@ -117,9 +118,14 @@ void __init time_init(void) * counter, plus bit 31, which signifies that the counter has wrapped * from zero to (2**31) - 1. The INT_TILE_TIMER interrupt will be * raised as long as bit 31 is set. + * + * The TILE_MINSEC value represents the largest range of real-time + * we can possibly cover with the timer, based on MAX_TICK combined + * with the slowest reasonable clock rate we might run at. */ #define MAX_TICK 0x7fffffff /* we have 31 bits of countdown timer */ +#define TILE_MINSEC 5 /* timer covers no more than 5 seconds */ static int tile_timer_set_next_event(unsigned long ticks, struct clock_event_device *evt) @@ -211,8 +217,7 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num) unsigned long long sched_clock(void) { return clocksource_cyc2ns(get_cycles(), - cycle_counter_cs.mult, - cycle_counter_cs.shift); + sched_clock_mult, SCHED_CLOCK_SHIFT); } int setup_profiling_timer(unsigned int multiplier) diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c index 3870abbeeaa..0f362dc2c57 100644 --- a/arch/tile/kernel/traps.c +++ b/arch/tile/kernel/traps.c @@ -128,7 +128,9 @@ static int special_ill(bundle_bits bundle, int *sigp, int *codep) #ifdef __tilegx__ if ((bundle & TILEGX_BUNDLE_MODE_MASK) != 0) return 0; - if (get_Opcode_X1(bundle) != UNARY_OPCODE_X1) + if (get_Opcode_X1(bundle) != RRR_0_OPCODE_X1) + return 0; + if (get_RRROpcodeExtension_X1(bundle) != UNARY_RRR_0_OPCODE_X1) return 0; if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1) return 0; |