Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS fixes from Ralf Baechle: "More 3.18 fixes for MIPS: - backtraces were not quite working on on 64-bit kernels - loongson needs a different cache coherency setting - Loongson 3 is a MIPS64 R2 version but due to erratum we treat is an older architecture revision. - fix build errors due to undefined references to __node_distances for certain configurations. - fix instruction decodig in the jump label code. - for certain configurations copy_{from,to}_user destroy the content of $3 so that register needs to be marked as clobbed by the calling code. - Hardware Table Walker fixes. - fill the delay slot of the last instruction of memcpy otherwise whatever ends up there randomly might have undesirable effects. - ensure get_user/__get_user always zero the variable to be read even in case of an error" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: MIPS: jump_label.c: Handle the microMIPS J instruction encoding MIPS: jump_label.c: Correct the span of the J instruction MIPS: Zero variable read by get_user / __get_user in case of an error. MIPS: lib: memcpy: Restore NOP on delay slot before returning to caller MIPS: tlb-r4k: Add missing HTW stop/start sequences MIPS: asm: uaccess: Add v1 register to clobber list on EVA MIPS: oprofile: Fix backtrace on 64-bit kernel MIPS: Loongson: Set Loongson-3's ISA level to MIPS64R1 MIPS: Loongson: Fix the write-combine CCA value setting MIPS: IP27: Fix __node_distances undefined error MIPS: Loongson3: Fix __node_distances undefined error
This commit is contained in:
Коммит
e6a588d086
|
@ -20,9 +20,15 @@
|
|||
#define WORD_INSN ".word"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
#define NOP_INSN "nop32"
|
||||
#else
|
||||
#define NOP_INSN "nop"
|
||||
#endif
|
||||
|
||||
static __always_inline bool arch_static_branch(struct static_key *key)
|
||||
{
|
||||
asm_volatile_goto("1:\tnop\n\t"
|
||||
asm_volatile_goto("1:\t" NOP_INSN "\n\t"
|
||||
"nop\n\t"
|
||||
".pushsection __jump_table, \"aw\"\n\t"
|
||||
WORD_INSN " 1b, %l[l_yes], %0\n\t"
|
||||
|
|
|
@ -41,10 +41,8 @@
|
|||
#define cpu_has_mcheck 0
|
||||
#define cpu_has_mdmx 0
|
||||
#define cpu_has_mips16 0
|
||||
#define cpu_has_mips32r1 0
|
||||
#define cpu_has_mips32r2 0
|
||||
#define cpu_has_mips3d 0
|
||||
#define cpu_has_mips64r1 0
|
||||
#define cpu_has_mips64r2 0
|
||||
#define cpu_has_mipsmt 0
|
||||
#define cpu_has_prefetch 0
|
||||
|
|
|
@ -301,7 +301,8 @@ do { \
|
|||
__get_kernel_common((x), size, __gu_ptr); \
|
||||
else \
|
||||
__get_user_common((x), size, __gu_ptr); \
|
||||
} \
|
||||
} else \
|
||||
(x) = 0; \
|
||||
\
|
||||
__gu_err; \
|
||||
})
|
||||
|
@ -316,6 +317,7 @@ do { \
|
|||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"3: li %0, %4 \n" \
|
||||
" move %1, $0 \n" \
|
||||
" j 2b \n" \
|
||||
" .previous \n" \
|
||||
" .section __ex_table,\"a\" \n" \
|
||||
|
@ -630,6 +632,7 @@ do { \
|
|||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"3: li %0, %4 \n" \
|
||||
" move %1, $0 \n" \
|
||||
" j 2b \n" \
|
||||
" .previous \n" \
|
||||
" .section __ex_table,\"a\" \n" \
|
||||
|
@ -773,10 +776,11 @@ extern void __put_user_unaligned_unknown(void);
|
|||
"jal\t" #destination "\n\t"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
|
||||
#define DADDI_SCRATCH "$0"
|
||||
#else
|
||||
#if defined(CONFIG_CPU_DADDI_WORKAROUNDS) || (defined(CONFIG_EVA) && \
|
||||
defined(CONFIG_CPU_HAS_PREFETCH))
|
||||
#define DADDI_SCRATCH "$3"
|
||||
#else
|
||||
#define DADDI_SCRATCH "$0"
|
||||
#endif
|
||||
|
||||
extern size_t __copy_user(void *__to, const void *__from, size_t __n);
|
||||
|
|
|
@ -757,31 +757,34 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
|||
c->cputype = CPU_LOONGSON2;
|
||||
__cpu_name[cpu] = "ICT Loongson-2";
|
||||
set_elf_platform(cpu, "loongson2e");
|
||||
set_isa(c, MIPS_CPU_ISA_III);
|
||||
break;
|
||||
case PRID_REV_LOONGSON2F:
|
||||
c->cputype = CPU_LOONGSON2;
|
||||
__cpu_name[cpu] = "ICT Loongson-2";
|
||||
set_elf_platform(cpu, "loongson2f");
|
||||
set_isa(c, MIPS_CPU_ISA_III);
|
||||
break;
|
||||
case PRID_REV_LOONGSON3A:
|
||||
c->cputype = CPU_LOONGSON3;
|
||||
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
|
||||
__cpu_name[cpu] = "ICT Loongson-3";
|
||||
set_elf_platform(cpu, "loongson3a");
|
||||
set_isa(c, MIPS_CPU_ISA_M64R1);
|
||||
break;
|
||||
case PRID_REV_LOONGSON3B_R1:
|
||||
case PRID_REV_LOONGSON3B_R2:
|
||||
c->cputype = CPU_LOONGSON3;
|
||||
__cpu_name[cpu] = "ICT Loongson-3";
|
||||
set_elf_platform(cpu, "loongson3b");
|
||||
set_isa(c, MIPS_CPU_ISA_M64R1);
|
||||
break;
|
||||
}
|
||||
|
||||
set_isa(c, MIPS_CPU_ISA_III);
|
||||
c->options = R4K_OPTS |
|
||||
MIPS_CPU_FPU | MIPS_CPU_LLSC |
|
||||
MIPS_CPU_32FPR;
|
||||
c->tlbsize = 64;
|
||||
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
|
||||
break;
|
||||
case PRID_IMP_LOONGSON_32: /* Loongson-1 */
|
||||
decode_configs(c);
|
||||
|
|
|
@ -18,31 +18,53 @@
|
|||
|
||||
#ifdef HAVE_JUMP_LABEL
|
||||
|
||||
#define J_RANGE_MASK ((1ul << 28) - 1)
|
||||
/*
|
||||
* Define parameters for the standard MIPS and the microMIPS jump
|
||||
* instruction encoding respectively:
|
||||
*
|
||||
* - the ISA bit of the target, either 0 or 1 respectively,
|
||||
*
|
||||
* - the amount the jump target address is shifted right to fit in the
|
||||
* immediate field of the machine instruction, either 2 or 1,
|
||||
*
|
||||
* - the mask determining the size of the jump region relative to the
|
||||
* delay-slot instruction, either 256MB or 128MB,
|
||||
*
|
||||
* - the jump target alignment, either 4 or 2 bytes.
|
||||
*/
|
||||
#define J_ISA_BIT IS_ENABLED(CONFIG_CPU_MICROMIPS)
|
||||
#define J_RANGE_SHIFT (2 - J_ISA_BIT)
|
||||
#define J_RANGE_MASK ((1ul << (26 + J_RANGE_SHIFT)) - 1)
|
||||
#define J_ALIGN_MASK ((1ul << J_RANGE_SHIFT) - 1)
|
||||
|
||||
void arch_jump_label_transform(struct jump_entry *e,
|
||||
enum jump_label_type type)
|
||||
{
|
||||
union mips_instruction *insn_p;
|
||||
union mips_instruction insn;
|
||||
union mips_instruction *insn_p =
|
||||
(union mips_instruction *)(unsigned long)e->code;
|
||||
|
||||
/* Jump only works within a 256MB aligned region. */
|
||||
BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK));
|
||||
insn_p = (union mips_instruction *)msk_isa16_mode(e->code);
|
||||
|
||||
/* Target must have 4 byte alignment. */
|
||||
BUG_ON((e->target & 3) != 0);
|
||||
/* Jump only works within an aligned region its delay slot is in. */
|
||||
BUG_ON((e->target & ~J_RANGE_MASK) != ((e->code + 4) & ~J_RANGE_MASK));
|
||||
|
||||
/* Target must have the right alignment and ISA must be preserved. */
|
||||
BUG_ON((e->target & J_ALIGN_MASK) != J_ISA_BIT);
|
||||
|
||||
if (type == JUMP_LABEL_ENABLE) {
|
||||
insn.j_format.opcode = j_op;
|
||||
insn.j_format.target = (e->target & J_RANGE_MASK) >> 2;
|
||||
insn.j_format.opcode = J_ISA_BIT ? mm_j32_op : j_op;
|
||||
insn.j_format.target = e->target >> J_RANGE_SHIFT;
|
||||
} else {
|
||||
insn.word = 0; /* nop */
|
||||
}
|
||||
|
||||
get_online_cpus();
|
||||
mutex_lock(&text_mutex);
|
||||
*insn_p = insn;
|
||||
if (IS_ENABLED(CONFIG_CPU_MICROMIPS)) {
|
||||
insn_p->halfword[0] = insn.word >> 16;
|
||||
insn_p->halfword[1] = insn.word;
|
||||
} else
|
||||
*insn_p = insn;
|
||||
|
||||
flush_icache_range((unsigned long)insn_p,
|
||||
(unsigned long)insn_p + sizeof(*insn_p));
|
||||
|
|
|
@ -503,6 +503,7 @@
|
|||
STOREB(t0, NBYTES-2(dst), .Ls_exc_p1\@)
|
||||
.Ldone\@:
|
||||
jr ra
|
||||
nop
|
||||
.if __memcpy == 1
|
||||
END(memcpy)
|
||||
.set __memcpy, 0
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
static struct node_data prealloc__node_data[MAX_NUMNODES];
|
||||
unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES];
|
||||
EXPORT_SYMBOL(__node_distances);
|
||||
struct node_data *__node_data[MAX_NUMNODES];
|
||||
EXPORT_SYMBOL(__node_data);
|
||||
|
||||
|
|
|
@ -299,6 +299,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
|
|||
|
||||
local_irq_save(flags);
|
||||
|
||||
htw_stop();
|
||||
pid = read_c0_entryhi() & ASID_MASK;
|
||||
address &= (PAGE_MASK << 1);
|
||||
write_c0_entryhi(address | pid);
|
||||
|
@ -346,6 +347,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
|
|||
tlb_write_indexed();
|
||||
}
|
||||
tlbw_use_hazard();
|
||||
htw_start();
|
||||
flush_itlb_vm(vma);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
@ -422,6 +424,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
|||
|
||||
local_irq_save(flags);
|
||||
/* Save old context and create impossible VPN2 value */
|
||||
htw_stop();
|
||||
old_ctx = read_c0_entryhi();
|
||||
old_pagemask = read_c0_pagemask();
|
||||
wired = read_c0_wired();
|
||||
|
@ -443,6 +446,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
|||
|
||||
write_c0_entryhi(old_ctx);
|
||||
write_c0_pagemask(old_pagemask);
|
||||
htw_start();
|
||||
out:
|
||||
local_irq_restore(flags);
|
||||
return ret;
|
||||
|
|
|
@ -92,7 +92,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
|
|||
/* This marks the end of the previous function,
|
||||
which means we overran. */
|
||||
break;
|
||||
stack_size = (unsigned) stack_adjustment;
|
||||
stack_size = (unsigned long) stack_adjustment;
|
||||
} else if (is_ra_save_ins(&ip)) {
|
||||
int ra_slot = ip.i_format.simmediate;
|
||||
if (ra_slot < 0)
|
||||
|
|
|
@ -107,6 +107,7 @@ static void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
|
|||
}
|
||||
|
||||
unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
|
||||
EXPORT_SYMBOL(__node_distances);
|
||||
|
||||
static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче