ソースを参照

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS fixes from Ralf Baechle:

 - Three highmem fixes:
    + Fixed mapping initialization
    + Adjust the pkmap location
    + Ensure we use at most one page for PTEs

 - Fix makefile dependencies for .its targets to depend on vmlinux

 - Fix reversed condition in BNEZC and JIALC software branch emulation

 - Only flush initialized flush_insn_slot to avoid NULL pointer
   dereference

 - perf: Remove incorrect odd/even counter handling for I6400

 - ftrace: Fix init functions tracing

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus:
  MIPS: .its targets depend on vmlinux
  MIPS: Fix bnezc/jialc return address calculation
  MIPS: kprobes: flush_insn_slot should flush only if probe initialised
  MIPS: ftrace: fix init functions tracing
  MIPS: mm: adjust PKMAP location
  MIPS: highmem: ensure that we don't use more than one page for PTEs
  MIPS: mm: fixed mappings: correct initialisation
  MIPS: perf: Remove incorrect odd/even counter handling for I6400
Linus Torvalds 8 年 前
コミット
b3ee4edd8a

+ 5 - 5
arch/mips/boot/Makefile

@@ -128,19 +128,19 @@ quiet_cmd_cpp_its_S = ITS     $@
 			-DADDR_BITS=$(ADDR_BITS) \
 			-DADDR_BITS=$(ADDR_BITS) \
 			-DADDR_CELLS=$(itb_addr_cells)
 			-DADDR_CELLS=$(itb_addr_cells)
 
 
-$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
 	$(call if_changed_dep,cpp_its_S,none,vmlinux.bin)
 	$(call if_changed_dep,cpp_its_S,none,vmlinux.bin)
 
 
-$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
 	$(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz)
 	$(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz)
 
 
-$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX)  FORCE
 	$(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2)
 	$(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2)
 
 
-$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
 	$(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma)
 	$(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma)
 
 
-$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
+$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
 	$(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo)
 	$(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo)
 
 
 quiet_cmd_itb-image = ITB     $@
 quiet_cmd_itb-image = ITB     $@

+ 5 - 0
arch/mips/include/asm/highmem.h

@@ -35,7 +35,12 @@ extern pte_t *pkmap_page_table;
  * easily, subsequent pte tables have to be allocated in one physical
  * easily, subsequent pte tables have to be allocated in one physical
  * chunk of RAM.
  * chunk of RAM.
  */
  */
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+#define LAST_PKMAP 512
+#else
 #define LAST_PKMAP 1024
 #define LAST_PKMAP 1024
+#endif
+
 #define LAST_PKMAP_MASK (LAST_PKMAP-1)
 #define LAST_PKMAP_MASK (LAST_PKMAP-1)
 #define PKMAP_NR(virt)	((virt-PKMAP_BASE) >> PAGE_SHIFT)
 #define PKMAP_NR(virt)	((virt-PKMAP_BASE) >> PAGE_SHIFT)
 #define PKMAP_ADDR(nr)	(PKMAP_BASE + ((nr) << PAGE_SHIFT))
 #define PKMAP_ADDR(nr)	(PKMAP_BASE + ((nr) << PAGE_SHIFT))

+ 2 - 1
arch/mips/include/asm/kprobes.h

@@ -43,7 +43,8 @@ typedef union mips_instruction kprobe_opcode_t;
 
 
 #define flush_insn_slot(p)						\
 #define flush_insn_slot(p)						\
 do {									\
 do {									\
-	flush_icache_range((unsigned long)p->addr,			\
+	if (p->addr)							\
+		flush_icache_range((unsigned long)p->addr,		\
 			   (unsigned long)p->addr +			\
 			   (unsigned long)p->addr +			\
 			   (MAX_INSN_SIZE * sizeof(kprobe_opcode_t)));	\
 			   (MAX_INSN_SIZE * sizeof(kprobe_opcode_t)));	\
 } while (0)
 } while (0)

+ 6 - 1
arch/mips/include/asm/pgtable-32.h

@@ -19,6 +19,10 @@
 #define __ARCH_USE_5LEVEL_HACK
 #define __ARCH_USE_5LEVEL_HACK
 #include <asm-generic/pgtable-nopmd.h>
 #include <asm-generic/pgtable-nopmd.h>
 
 
+#ifdef CONFIG_HIGHMEM
+#include <asm/highmem.h>
+#endif
+
 extern int temp_tlb_entry;
 extern int temp_tlb_entry;
 
 
 /*
 /*
@@ -62,7 +66,8 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
 
 
 #define VMALLOC_START	  MAP_BASE
 #define VMALLOC_START	  MAP_BASE
 
 
-#define PKMAP_BASE		(0xfe000000UL)
+#define PKMAP_END	((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1))
+#define PKMAP_BASE	(PKMAP_END - PAGE_SIZE * LAST_PKMAP)
 
 
 #ifdef CONFIG_HIGHMEM
 #ifdef CONFIG_HIGHMEM
 # define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)
 # define VMALLOC_END	(PKMAP_BASE-2*PAGE_SIZE)

+ 3 - 1
arch/mips/kernel/branch.c

@@ -804,8 +804,10 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
 			break;
 			break;
 		}
 		}
 		/* Compact branch: BNEZC || JIALC */
 		/* Compact branch: BNEZC || JIALC */
-		if (insn.i_format.rs)
+		if (!insn.i_format.rs) {
+			/* JIALC: set $31/ra */
 			regs->regs[31] = epc + 4;
 			regs->regs[31] = epc + 4;
+		}
 		regs->cp0_epc += 8;
 		regs->cp0_epc += 8;
 		break;
 		break;
 #endif
 #endif

+ 5 - 19
arch/mips/kernel/ftrace.c

@@ -38,20 +38,6 @@ void arch_ftrace_update_code(int command)
 
 
 #endif
 #endif
 
 
-/*
- * Check if the address is in kernel space
- *
- * Clone core_kernel_text() from kernel/extable.c, but doesn't call
- * init_kernel_text() for Ftrace doesn't trace functions in init sections.
- */
-static inline int in_kernel_space(unsigned long ip)
-{
-	if (ip >= (unsigned long)_stext &&
-	    ip <= (unsigned long)_etext)
-		return 1;
-	return 0;
-}
-
 #ifdef CONFIG_DYNAMIC_FTRACE
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 
 #define JAL 0x0c000000		/* jump & link: ip --> ra, jump to target */
 #define JAL 0x0c000000		/* jump & link: ip --> ra, jump to target */
@@ -198,7 +184,7 @@ int ftrace_make_nop(struct module *mod,
 	 * If ip is in kernel space, no long call, otherwise, long call is
 	 * If ip is in kernel space, no long call, otherwise, long call is
 	 * needed.
 	 * needed.
 	 */
 	 */
-	new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F;
+	new = core_kernel_text(ip) ? INSN_NOP : INSN_B_1F;
 #ifdef CONFIG_64BIT
 #ifdef CONFIG_64BIT
 	return ftrace_modify_code(ip, new);
 	return ftrace_modify_code(ip, new);
 #else
 #else
@@ -218,12 +204,12 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	unsigned int new;
 	unsigned int new;
 	unsigned long ip = rec->ip;
 	unsigned long ip = rec->ip;
 
 
-	new = in_kernel_space(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0];
+	new = core_kernel_text(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0];
 
 
 #ifdef CONFIG_64BIT
 #ifdef CONFIG_64BIT
 	return ftrace_modify_code(ip, new);
 	return ftrace_modify_code(ip, new);
 #else
 #else
-	return ftrace_modify_code_2r(ip, new, in_kernel_space(ip) ?
+	return ftrace_modify_code_2r(ip, new, core_kernel_text(ip) ?
 						INSN_NOP : insn_la_mcount[1]);
 						INSN_NOP : insn_la_mcount[1]);
 #endif
 #endif
 }
 }
@@ -289,7 +275,7 @@ unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
 	 * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for
 	 * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for
 	 * kernel, move after the instruction "move ra, at"(offset is 16)
 	 * kernel, move after the instruction "move ra, at"(offset is 16)
 	 */
 	 */
-	ip = self_ra - (in_kernel_space(self_ra) ? 16 : 24);
+	ip = self_ra - (core_kernel_text(self_ra) ? 16 : 24);
 
 
 	/*
 	/*
 	 * search the text until finding the non-store instruction or "s{d,w}
 	 * search the text until finding the non-store instruction or "s{d,w}
@@ -394,7 +380,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
 	 * entries configured through the tracing/set_graph_function interface.
 	 * entries configured through the tracing/set_graph_function interface.
 	 */
 	 */
 
 
-	insns = in_kernel_space(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1;
+	insns = core_kernel_text(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1;
 	trace.func = self_ra - (MCOUNT_INSN_SIZE * insns);
 	trace.func = self_ra - (MCOUNT_INSN_SIZE * insns);
 
 
 	/* Only trace if the calling function expects to */
 	/* Only trace if the calling function expects to */

+ 5 - 1
arch/mips/kernel/perf_event_mipsxx.c

@@ -1597,7 +1597,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
 		break;
 		break;
 	case CPU_P5600:
 	case CPU_P5600:
 	case CPU_P6600:
 	case CPU_P6600:
-	case CPU_I6400:
 		/* 8-bit event numbers */
 		/* 8-bit event numbers */
 		raw_id = config & 0x1ff;
 		raw_id = config & 0x1ff;
 		base_id = raw_id & 0xff;
 		base_id = raw_id & 0xff;
@@ -1610,6 +1609,11 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
 		raw_event.range = P;
 		raw_event.range = P;
 #endif
 #endif
 		break;
 		break;
+	case CPU_I6400:
+		/* 8-bit event numbers */
+		base_id = config & 0xff;
+		raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+		break;
 	case CPU_1004K:
 	case CPU_1004K:
 		if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
 		if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
 			raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
 			raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;

+ 3 - 3
arch/mips/mm/pgtable-32.c

@@ -51,15 +51,15 @@ void __init pagetable_init(void)
 	/*
 	/*
 	 * Fixed mappings:
 	 * Fixed mappings:
 	 */
 	 */
-	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-	fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base);
+	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
+	fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base);
 
 
 #ifdef CONFIG_HIGHMEM
 #ifdef CONFIG_HIGHMEM
 	/*
 	/*
 	 * Permanent kmaps:
 	 * Permanent kmaps:
 	 */
 	 */
 	vaddr = PKMAP_BASE;
 	vaddr = PKMAP_BASE;
-	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+	fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
 
 
 	pgd = swapper_pg_dir + __pgd_offset(vaddr);
 	pgd = swapper_pg_dir + __pgd_offset(vaddr);
 	pud = pud_offset(pgd, vaddr);
 	pud = pud_offset(pgd, vaddr);