From 3d2d03247632920aa21b42a0b032a4ffd44ce15e Mon Sep 17 00:00:00 2001 From: Cong Ding Date: Mon, 14 Jan 2013 17:23:29 +0000 Subject: [PATCH 01/16] MIPS: vpe.c: Fix null pointer dereference in print arguments. In the printk, the variable t euqals to NULL, so there is no t->index. Use v->tc->index instead. [ralf@linux-mips.org: Use opportunity of changing this line anyway to make this line whitespacely correct.] Signed-off-by: Cong Ding Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/4792/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/vpe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index eec690af658..147cec19621 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -705,7 +705,7 @@ static int vpe_run(struct vpe * v) printk(KERN_WARNING "VPE loader: TC %d is already in use.\n", - t->index); + v->tc->index); return -ENOEXEC; } } else { From a9e985783ed936376de9f27eff54e37d584fb855 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 4 Jan 2013 19:10:05 +0100 Subject: [PATCH 02/16] MIPS: BCM47xx: Select GPIOLIB for BCMA on bcm47xx platform The Kconfig items BCM47XX_BCMA and BCM47XX_SSB selected respectively BCMA_DRIVER_GPIO and SSB_DRIVER_GPIO. These options depend on GPIOLIB without explicitly selecting it so it results in a warning when GPIOLIB is not set: scripts/kconfig/conf --oldconfig Kconfig warning: (BCM47XX_BCMA) selects BCMA_DRIVER_GPIO ... unmet direct dependencies (BCMA_POSSIBLE && BCMA && GPIOLIB) warning: (BCM47XX_SSB) selects SSB_DRIVER_GPIO ... unmet direct dependencies (SSB_POSSIBLE && SSB && GPIOLIB) which subsequently results in compile errors. Signed-off-by: Arend van Spriel Cc: Hauke Mehrtens Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/4759/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index d7af29f1fcf..ae47727b0a4 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig @@ -10,6 +10,7 @@ config BCM47XX_SSB select SSB_B43_PCI_BRIDGE if PCI select SSB_PCICORE_HOSTMODE if PCI select SSB_DRIVER_GPIO + select GPIOLIB default y help Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support. @@ -25,6 +26,7 @@ config BCM47XX_BCMA select BCMA_HOST_PCI if PCI select BCMA_DRIVER_PCI_HOSTMODE if PCI select BCMA_DRIVER_GPIO + select GPIOLIB default y help Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus. From b26d9ac76b22f53f1553d63c676dc2e70a8e3157 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 16 Jan 2013 16:03:44 +0100 Subject: [PATCH 03/16] MIPS: BCM47xx: Enable SSB prerequisite SSB_DRIVER_PCICORE. Split of from Arend's patch. Signed-off-by: Arend van Spriel Cc: Sergei Shtylyov Cc: linux-mips@linux-mips.org Cc: Hauke Mehrtens Patchwork: https://patchwork.linux-mips.org/patch/4759/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index ae47727b0a4..ba611927749 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig @@ -8,6 +8,7 @@ config BCM47XX_SSB select SSB_DRIVER_EXTIF select SSB_EMBEDDED select SSB_B43_PCI_BRIDGE if PCI + select SSB_DRIVER_PCICORE if PCI select SSB_PCICORE_HOSTMODE if PCI select SSB_DRIVER_GPIO select GPIOLIB From 0bc1c15735f103803d76d30a9fd97ea3610eaee6 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 16 Jan 2013 16:56:22 +0100 Subject: [PATCH 04/16] MIPS: Export . It always should have been ... Signed-off-by: Ralf Baechle --- arch/mips/include/uapi/asm/Kbuild | 1 + arch/mips/include/{ => uapi}/asm/break.h | 0 2 files changed, 1 insertion(+) rename arch/mips/include/{ => uapi}/asm/break.h (100%) diff --git a/arch/mips/include/uapi/asm/Kbuild b/arch/mips/include/uapi/asm/Kbuild index a1a0452ac18..77d4fb33f75 100644 --- a/arch/mips/include/uapi/asm/Kbuild +++ b/arch/mips/include/uapi/asm/Kbuild @@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm header-y += auxvec.h header-y += bitsperlong.h +header-y += break.h header-y += byteorder.h header-y += cachectl.h header-y += errno.h diff --git a/arch/mips/include/asm/break.h b/arch/mips/include/uapi/asm/break.h similarity index 100% rename from arch/mips/include/asm/break.h rename to arch/mips/include/uapi/asm/break.h From 9561fefc9816e9c7a952bf0e25331e395ff03a6e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 17 Jan 2013 15:21:03 +0100 Subject: [PATCH 05/16] MIPS: Add struct p_format to union mips_instruction. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/inst.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h index ab84064283d..33c34adbecf 100644 --- a/arch/mips/include/asm/inst.h +++ b/arch/mips/include/asm/inst.h @@ -353,6 +353,7 @@ union mips_instruction { struct u_format u_format; struct c_format c_format; struct r_format r_format; + struct p_format p_format; struct f_format f_format; struct ma_format ma_format; struct b_format b_format; From f051e3a9335bce8915165a6b1e73db5af8ba86df Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 22 Jan 2013 12:52:22 +0100 Subject: [PATCH 06/16] MIPS: PNX833x: Fix comment. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-pnx833x/war.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/mach-pnx833x/war.h b/arch/mips/include/asm/mach-pnx833x/war.h index edaa06d9d49..e410df4e1b3 100644 --- a/arch/mips/include/asm/mach-pnx833x/war.h +++ b/arch/mips/include/asm/mach-pnx833x/war.h @@ -21,4 +21,4 @@ #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 -#endif /* __ASM_MIPS_MACH_PNX8550_WAR_H */ +#endif /* __ASM_MIPS_MACH_PNX833X_WAR_H */ From 4ea494b528ac1b9df9f0c77ba49e3e8ee108d9ec Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 6 Dec 2012 18:12:17 +0000 Subject: [PATCH 07/16] MIPS: delay.c: Check BITS_PER_LONG instead of __SIZEOF_LONG__ When building a 32-bit kernel for RBTX4927 with gcc version 4.1.2 20061115 (prerelease) (Ubuntu 4.1.1-21), I get: arch/mips/lib/delay.c:24:5: warning: "__SIZEOF_LONG__" is not defined As a consequence, __delay() always uses the 64-bit "dsubu" instruction. Replace the check for "__SIZEOF_LONG__ == 4" by "BITS_PER_LONG == 32" to fix this. Introduced by commit 5210edcd527773c227465ad18e416a894966324f [MIPS: Make __{,n,u}delay declarations match definitions and generic delay.h"] Signed-off-by: Geert Uytterhoeven Patchwork: https://patchwork.linux-mips.org/patch/4678/ Acked-by: David Daney Signed-off-by: Ralf Baechle --- arch/mips/lib/delay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index dc81ca8dc0d..288f7954988 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c @@ -21,7 +21,7 @@ void __delay(unsigned long loops) " .set noreorder \n" " .align 3 \n" "1: bnez %0, 1b \n" -#if __SIZEOF_LONG__ == 4 +#if BITS_PER_LONG == 32 " subu %0, 1 \n" #else " dsubu %0, 1 \n" From 757be67f565b4336f0d847f3ca9332e050c9ba83 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 22 Jan 2013 18:03:45 +0100 Subject: [PATCH 08/16] MIPS: Octeon: Fix warning. Cong Ding reports correctly that the variable dummy is being used without initialization. That said, I can't reproduce this warning with GCC 4.7.1. However, since the variable dummy servces no real purpose, I'm going for a different fix. This fix includes https://patchwork.linux-mips.org/patch/4801/ plus Geert's suggestion to use ACCESS_ONCE(). Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/executive/cvmx-l2c.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c index 9f883bf7695..33b72144db3 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c @@ -30,6 +30,7 @@ * measurement, and debugging facilities. */ +#include #include #include #include @@ -285,22 +286,22 @@ uint64_t cvmx_l2c_read_perf(uint32_t counter) */ static void fault_in(uint64_t addr, int len) { - volatile char *ptr; - volatile char dummy; + char *ptr; + /* * Adjust addr and length so we get all cache lines even for * small ranges spanning two cache lines. */ len += addr & CVMX_CACHE_LINE_MASK; addr &= ~CVMX_CACHE_LINE_MASK; - ptr = (volatile char *)cvmx_phys_to_ptr(addr); + ptr = cvmx_phys_to_ptr(addr); /* * Invalidate L1 cache to make sure all loads result in data * being in L2. */ CVMX_DCACHE_INVALIDATE; while (len > 0) { - dummy += *ptr; + ACCESS_ONCE(*ptr); len -= CVMX_CACHE_LINE_SIZE; ptr += CVMX_CACHE_LINE_SIZE; } From 86ea9c51b9bc4db363a1cb2bfc2b001260eb6e1f Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 18 Jan 2013 18:16:40 +0000 Subject: [PATCH 09/16] MIPS: Fix build failure by adding definition of pfn_pmd(). With CONFIG_TRANSPARENT_HUGEPAGE=y and CONFIG_HUGETLBFS=y we get the following build failure: CC mm/huge_memory.o mm/huge_memory.c: In function 'set_huge_zero_page': mm/huge_memory.c:780:2: error: implicit declaration of function 'pfn_pmd' [-Werror=implicit-function-declaration] mm/huge_memory.c:780:8: error: incompatible types when assigning to type 'pmd_t' from type 'int' Add a definition of pfn_pmd() for 64-bit kernels (the only place huge pages are currently supported). Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/4813/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/pgtable-64.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h index c63191055e6..013d5f78126 100644 --- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h @@ -230,6 +230,7 @@ static inline void pud_clear(pud_t *pudp) #else #define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) #define pfn_pte(pfn, prot) __pte(((pfn) << _PFN_SHIFT) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) __pmd(((pfn) << _PFN_SHIFT) | pgprot_val(prot)) #endif #define __pgd_offset(address) pgd_index(address) From 6829aeae47233f7d9937a03a7304b760ee5bd1be Mon Sep 17 00:00:00 2001 From: "Steven J. Hill" Date: Thu, 6 Dec 2012 22:52:03 -0600 Subject: [PATCH 10/16] MIPS: DSP: Fix DSP mask for registers. The DSP bit mask for the RDDSP and WRDSP instructions was wrong. [ralf@linux-mips.org: The mask field of the RDDSP and WRDSP instructions is 10 bits long. DSP_MASK had all these fields which according to the architecture specification may result in UNPREDICTABLE operation.] Signed-off-by: Steven J. Hill Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/4683/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/dsp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/dsp.h b/arch/mips/include/asm/dsp.h index e9bfc0813c7..7bfad0520e2 100644 --- a/arch/mips/include/asm/dsp.h +++ b/arch/mips/include/asm/dsp.h @@ -16,7 +16,7 @@ #include #define DSP_DEFAULT 0x00000000 -#define DSP_MASK 0x3ff +#define DSP_MASK 0x3f #define __enable_dsp_hazard() \ do { \ From 79d61a046bf02a3eff9da15e607ac35c172de3a7 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 29 Jan 2013 18:46:02 +0000 Subject: [PATCH 11/16] MIPS: Lantiq: Fix cp0_perfcount_irq mapping The introduction of the OF support broke the cp0_perfcount_irq mapping. This resulted in oprofile not working anymore. Offending commit is : commit 3645da0276ae9f6938ff29b13904b803ecb68424 Author: John Crispin Date: Tue Apr 17 10:18:32 2012 +0200 OF: MIPS: lantiq: implement irq_domain support Signed-off-by: Conor O'Gorman Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/4875/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index f36acd1b380..a7935bf0fec 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -408,7 +408,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) #endif /* tell oprofile which irq to use */ - cp0_perfcount_irq = LTQ_PERF_IRQ; + cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); /* * if the timer irq is not one of the mips irqs we need to From 4c960910e2fb3a301ee4a504fa6b2c5204efeab0 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 29 Jan 2013 08:27:03 +0000 Subject: [PATCH 12/16] MIPS: AR724x: Fix AR724X_PCI_MEM_SIZE The base address of the PCI memory is 0x10000000 and the base address of the PCI configuration space is 0x14000000 on the AR724x SoCs. The AR724X_PCI_MEM_SIZE is defined as 0x08000000 which is wrong because that overlaps with the configuration space. The patch fixes the value of the AR724X_PCI_MEM_SIZE constant, in order to avoid this resource conflicts. Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4872/ Signed-off-by: John Crispin Signed-off-by: Ralf Baechle --- arch/mips/pci/pci-ar724x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 86d77a66645..c11c75be2d7 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -21,7 +21,7 @@ #define AR724X_PCI_CTRL_SIZE 0x100 #define AR724X_PCI_MEM_BASE 0x10000000 -#define AR724X_PCI_MEM_SIZE 0x08000000 +#define AR724X_PCI_MEM_SIZE 0x04000000 #define AR724X_PCI_REG_RESET 0x18 #define AR724X_PCI_REG_INT_STATUS 0x4c From fe950df70013a9f3368918aab697eec15f80ac67 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 29 Jan 2013 08:27:04 +0000 Subject: [PATCH 13/16] MIPS: AR71xx: Fix AR71XX_PCI_MEM_SIZE The base address of the PCI memory is 0x10000000 and the base address of the PCI configuration space is 0x17000000 on the AR71xx SoCs. The AR71XX_PCI_MEM_SIZE is defined as 0x08000000 which is wrong because that overlaps with the configuration space. This patch fixes the value of the AR71XX_PCI_MEM_SIZE constant, in order to avoid this resource conflicts. Signed-off-by: Gabor Juhos Patchwork: http://patchwork.linux-mips.org/patch/4873/ Signed-off-by: John Crispin Signed-off-by: Ralf Baechle --- arch/mips/pci/pci-ar71xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index 1552522b871..6eaa4f2d0e3 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -24,7 +24,7 @@ #include #define AR71XX_PCI_MEM_BASE 0x10000000 -#define AR71XX_PCI_MEM_SIZE 0x08000000 +#define AR71XX_PCI_MEM_SIZE 0x07000000 #define AR71XX_PCI_WIN0_OFFS 0x10000000 #define AR71XX_PCI_WIN1_OFFS 0x11000000 From 26f5ae865d7b324e46fff91acf43c485939bf6ea Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Mon, 7 Jan 2013 13:21:08 +0000 Subject: [PATCH 14/16] MIPS: Netlogic: Fix UP compilation on XLR The commit 2a37b1a "MIPS: Netlogic: Move from u32 cpumask to cpumask_t" breaks uniprocessor compilation on XLR with: arch/mips/netlogic/xlr/setup.c: In function 'prom_init': arch/mips/netlogic/xlr/setup.c:196:6: error: unused variable 'i' Fix by defining 'i' only when CONFIG_SMP is defined. Signed-off-by: Jayachandran C Patchwork: http://patchwork.linux-mips.org/patch/4760/ Signed-off-by: John Crispin Signed-off-by: Ralf Baechle --- arch/mips/netlogic/xlr/setup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index 4e7f49d3d5a..c5ce6992ac4 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c @@ -193,8 +193,11 @@ static void nlm_init_node(void) void __init prom_init(void) { - int i, *argv, *envp; /* passed as 32 bit ptrs */ + int *argv, *envp; /* passed as 32 bit ptrs */ struct psb_info *prom_infop; +#ifdef CONFIG_SMP + int i; +#endif /* truncate to 32 bit and sign extend all args */ argv = (int *)(long)(int)fw_arg1; From 196897a2979498d19edbdf5b4af02261afbc1a96 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 25 Jan 2013 17:13:15 +0000 Subject: [PATCH 15/16] mips: Move __virt_addr_valid() to a place for MIPS 64 Commit d3ce88431892 "MIPS: Fix modpost error in modules attepting to use virt_addr_valid()" moved __virt_addr_valid() from a macro in a header file to a function in ioremap.c. But ioremap.c is only compiled for MIPS 32, and not for MIPS 64. When compiling for my yeeloong2, which supposedly supports hibernation, which compiles kernel/power/snapshot.c which calls virt_addr_valid(), I got this error: LD init/built-in.o kernel/built-in.o: In function `memory_bm_free': snapshot.c:(.text+0x4c9c4): undefined reference to `__virt_addr_valid' snapshot.c:(.text+0x4ca58): undefined reference to `__virt_addr_valid' kernel/built-in.o: In function `snapshot_write_next': (.text+0x4e44c): undefined reference to `__virt_addr_valid' kernel/built-in.o: In function `snapshot_write_next': (.text+0x4e890): undefined reference to `__virt_addr_valid' make[1]: *** [vmlinux] Error 1 make: *** [sub-make] Error 2 I suspect that __virt_addr_valid() is fine for mips 64. I moved it to mmap.c such that it gets compiled for mips 64 and 32. Signed-off-by: Steven Rostedt Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/4842/ Signed-off-by: Ralf Baechle --- arch/mips/mm/ioremap.c | 6 ------ arch/mips/mm/mmap.c | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 7657fd21cd3..cacfd31e8ec 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -190,9 +190,3 @@ void __iounmap(const volatile void __iomem *addr) EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(__iounmap); - -int __virt_addr_valid(const volatile void *kaddr) -{ - return pfn_valid(PFN_DOWN(virt_to_phys(kaddr))); -} -EXPORT_SYMBOL_GPL(__virt_addr_valid); diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index d9be7540a6b..7e5fe2790d8 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -192,3 +192,9 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) return ret; } + +int __virt_addr_valid(const volatile void *kaddr) +{ + return pfn_valid(PFN_DOWN(virt_to_phys(kaddr))); +} +EXPORT_SYMBOL_GPL(__virt_addr_valid); From 58b69401c797e470c8f638c598dddc44a4ce8a96 Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Wed, 16 Jan 2013 22:43:28 +0000 Subject: [PATCH 16/16] MIPS: Function tracer: Fix broken function tracing Function tracing is currently broken for all 32 bit MIPS platforms. When tracing is enabled, the kernel immediately hangs on boot. This is a result of commit b732d439cb43336cd6d7e804ecb2c81193ef63b0 that changes the kernel/trace/Kconfig file so that is no longer forces FRAME_POINTER when FUNCTION_TRACING is enabled. MIPS frame pointers are generally considered to be useless because they cannot be used to unwind the stack. Unfortunately the MIPS function tracing code has bugs that are masked by the use of frame pointers. This commit fixes the bugs so that MIPS frame pointers don't need to be enabled. The bugs are a result of the odd calling sequence used to call the trace routine. This calling sequence is inserted into every traceable function when the tracing CONFIG option is enabled. This sequence is generated for 32bit MIPS platforms by the compiler via the "-pg" flag. Part of the sequence is "addiu sp,sp,-8" in the delay slot after every call to the trace routine "_mcount" (some legacy thing where 2 arguments used to be pushed on the stack). The _mcount routine is expected to adjust the sp by +8 before returning. So when not disabled, the original jalr and addiu will be there, so _mcount has to adjust sp. The problem is that when tracing is disabled for a function, the "jalr _mcount" instruction is replaced with a nop, but the "addiu sp,sp,-8" is still executed and the stack pointer is left trashed. When frame pointers are enabled the problem is masked because any access to the stack is done through the frame pointer and the stack pointer is restored from the frame pointer when the function returns. This patch writes two nops starting at the address of the "jalr _mcount" instruction whenever tracing is disabled. This means that the "addiu sp,sp.-8" will be converted to a nop along with the "jalr". When disabled, there will be two nops. This is SMP safe because the first time this happens is during ftrace_init() which is before any other processor has been started. Subsequent calls to enable/disable tracing when other CPUs ARE running will still be safe because the enable will only change the first nop to a "jalr" and the disable, while writing 2 nops, will only be changing the "jalr". This patch also stops using stop_machine() to call the tracer enable/disable routines and calls them directly because the routines are SMP safe. When the kernel first boots we have to be able to handle the gcc generated jalr, addui sequence until ftrace_init gets a chance to run and change the sequence. At this point mcount just adjusts the stack and returns. When ftrace_init runs, we convert the jalr/addui to nops. Then whenever tracing is enabled we convert the first nop to a "jalr mcount+8". The mcount+8 entry point skips the stack adjust. [ralf@linux-mips.org: Folded in Steven Rostedt's build fix.] Signed-off-by: Al Cooper Cc: rostedt@goodmis.org Cc: ddaney.cavm@gmail.com Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/4806/ Patchwork: https://patchwork.linux-mips.org/patch/4841/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/ftrace.c | 36 +++++++++++++++++++++++++++++++++++- arch/mips/kernel/mcount.S | 7 ++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 6a2d758dd8e..83fa1460e29 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -25,6 +25,12 @@ #define MCOUNT_OFFSET_INSNS 4 #endif +/* Arch override because MIPS doesn't need to run this from stop_machine() */ +void arch_ftrace_update_code(int command) +{ + ftrace_modify_all_code(command); +} + /* * Check if the address is in kernel space * @@ -89,6 +95,24 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code) return 0; } +#ifndef CONFIG_64BIT +static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, + unsigned int new_code2) +{ + int faulted; + + safe_store_code(new_code1, ip, faulted); + if (unlikely(faulted)) + return -EFAULT; + ip += 4; + safe_store_code(new_code2, ip, faulted); + if (unlikely(faulted)) + return -EFAULT; + flush_icache_range(ip, ip + 8); /* original ip + 12 */ + return 0; +} +#endif + /* * The details about the calling site of mcount on MIPS * @@ -131,8 +155,18 @@ int ftrace_make_nop(struct module *mod, * needed. */ new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F; - +#ifdef CONFIG_64BIT return ftrace_modify_code(ip, new); +#else + /* + * On 32 bit MIPS platforms, gcc adds a stack adjust + * instruction in the delay slot after the branch to + * mcount and expects mcount to restore the sp on return. + * This is based on a legacy API and does nothing but + * waste instructions so it's being removed at runtime. + */ + return ftrace_modify_code_2(ip, new, INSN_NOP); +#endif } int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index 4c968e7efb7..16586767335 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -46,9 +46,8 @@ PTR_L a5, PT_R9(sp) PTR_L a6, PT_R10(sp) PTR_L a7, PT_R11(sp) - PTR_ADDIU sp, PT_SIZE #else - PTR_ADDIU sp, (PT_SIZE + 8) + PTR_ADDIU sp, PT_SIZE #endif .endm @@ -69,7 +68,9 @@ NESTED(ftrace_caller, PT_SIZE, ra) .globl _mcount _mcount: b ftrace_stub - nop + addiu sp,sp,8 + + /* When tracing is activated, it calls ftrace_caller+8 (aka here) */ lw t1, function_trace_stop bnez t1, ftrace_stub nop