From 97d1e3dc8d98f97b65350f8ab221e6d061705abc Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Mon, 28 May 2018 18:29:02 +0200 Subject: [PATCH 1/6] nds32: define __NDS32_E[BL]__ for sparse nds32 depends on the macros '__NDS32_E[BL]__' to correctly select or define endian-specific macros, structures or pieces of code. These macros are predefined by the compiler but sparse knows nothing about them and thus may pre-process files differently from what GCC would. Fix this by adding '-D__NDS32_E[BL]__' to CHECKFLAGS. Signed-off-by: Luc Van Oostenryck Acked-by: Greentime Hu Signed-off-by: Greentime Hu --- arch/nds32/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/nds32/Makefile b/arch/nds32/Makefile index 513bb2e9baf9..031c676821ff 100644 --- a/arch/nds32/Makefile +++ b/arch/nds32/Makefile @@ -34,10 +34,12 @@ ifdef CONFIG_CPU_LITTLE_ENDIAN KBUILD_CFLAGS += $(call cc-option, -EL) KBUILD_AFLAGS += $(call cc-option, -EL) LDFLAGS += $(call cc-option, -EL) +CHECKFLAGS += -D__NDS32_EL__ else KBUILD_CFLAGS += $(call cc-option, -EB) KBUILD_AFLAGS += $(call cc-option, -EB) LDFLAGS += $(call cc-option, -EB) +CHECKFLAGS += -D__NDS32_EB__ endif boot := arch/nds32/boot From a78945c357f58665d6a5da8a69e085898e831c70 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 14 Jun 2018 15:28:52 +0100 Subject: [PATCH 2/6] nds32: Fix build error caused by configuration flag rename Fix build error on nds32 due to the merge of commit e3d5980568f ("lib: Rename compiler intrinsic selects to GENERIC_LIB_*") during the 4.18 merge window which renames Kconfig symbols. This had raced with commit aeaa7af744fa ("nds32: lib: To use generic lib instead of libgcc to prevent the symbol undefined issue.") merged late in the 4.17 cycle, which added selects to nds32 using the original Kconfig symbol names. When they came together in merge commit 763f96944c95 ("Merge tag 'mips_4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux") this resulted in the following build errors: nds32le-linux-ld: kernel/time/timekeeping.o: in function `timekeeping_init': timekeeping.c:(.init.text+0x140): undefined reference to `__ashldi3' nds32le-linux-ld: timekeeping.c:(.init.text+0x144): undefined reference to `__ashldi3' nds32le-linux-ld: timekeeping.c:(.init.text+0x17e): undefined reference to `__lshrdi3' nds32le-linux-ld: timekeeping.c:(.init.text+0x182): undefined reference to `__lshrdi3' nds32le-linux-ld: drivers/clocksource/mmio.o: in function `clocksource_mmio_init': mmio.c:(.init.text+0x54): undefined reference to `__lshrdi3' nds32le-linux-ld: mmio.c:(.init.text+0x58): undefined reference to `__lshrdi3' Rename all 6 selects in nds32 and adjust the ordering accordingly to be alphabetical. Fixes: 763f96944c95 ("Merge tag 'mips_4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux") Signed-off-by: Guenter Roeck [jhogan@kernel.org: Rename all 6 symbols, sort, update commit message] Signed-off-by: James Hogan Cc: Greentime Hu Cc: Vincent Chen Cc: Matt Redfearn Cc: Palmer Dabbelt Acked-by: Greentime Hu Signed-off-by: Greentime Hu --- arch/nds32/Kconfig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig index 6aed974276d8..34f7222c5efe 100644 --- a/arch/nds32/Kconfig +++ b/arch/nds32/Kconfig @@ -12,17 +12,17 @@ config NDS32 select CLONE_BACKWARDS select COMMON_CLK select DMA_NONCOHERENT_OPS - select GENERIC_ASHLDI3 - select GENERIC_ASHRDI3 - select GENERIC_LSHRDI3 - select GENERIC_CMPDI2 - select GENERIC_MULDI3 - select GENERIC_UCMPDI2 select GENERIC_ATOMIC64 select GENERIC_CPU_DEVICES select GENERIC_CLOCKEVENTS select GENERIC_IRQ_CHIP select GENERIC_IRQ_SHOW + select GENERIC_LIB_ASHLDI3 + select GENERIC_LIB_ASHRDI3 + select GENERIC_LIB_CMPDI2 + select GENERIC_LIB_LSHRDI3 + select GENERIC_LIB_MULDI3 + select GENERIC_LIB_UCMPDI2 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select GENERIC_TIME_VSYSCALL From f706abf188a82c9d961ed267a18ff5cb5e9aace9 Mon Sep 17 00:00:00 2001 From: Greentime Hu Date: Thu, 28 Jun 2018 18:03:25 +0800 Subject: [PATCH 3/6] nds32: To implement these icache invalidation APIs since nds32 cores don't snoop data cache. This issue is found by Guo Ren. Based on the Documentation/core-api/cachetlb.rst and it says: "Any necessary cache flushing or other coherency operations that need to occur should happen here. If the processor's instruction cache does not snoop cpu stores, it is very likely that you will need to flush the instruction cache for copy_to_user_page()." "If the icache does not snoop stores then this routine(flush_icache_range) will need to flush it." Signed-off-by: Guo Ren Signed-off-by: Greentime Hu --- arch/nds32/include/asm/cacheflush.h | 9 +++-- arch/nds32/mm/cacheflush.c | 53 +++++++++++++++++------------ 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/arch/nds32/include/asm/cacheflush.h b/arch/nds32/include/asm/cacheflush.h index 10b48f0d8e85..8b26198d51bb 100644 --- a/arch/nds32/include/asm/cacheflush.h +++ b/arch/nds32/include/asm/cacheflush.h @@ -8,6 +8,8 @@ #define PG_dcache_dirty PG_arch_1 +void flush_icache_range(unsigned long start, unsigned long end); +void flush_icache_page(struct vm_area_struct *vma, struct page *page); #ifdef CONFIG_CPU_CACHE_ALIASING void flush_cache_mm(struct mm_struct *mm); void flush_cache_dup_mm(struct mm_struct *mm); @@ -34,13 +36,16 @@ void flush_anon_page(struct vm_area_struct *vma, void flush_kernel_dcache_page(struct page *page); void flush_kernel_vmap_range(void *addr, int size); void invalidate_kernel_vmap_range(void *addr, int size); -void flush_icache_range(unsigned long start, unsigned long end); -void flush_icache_page(struct vm_area_struct *vma, struct page *page); #define flush_dcache_mmap_lock(mapping) xa_lock_irq(&(mapping)->i_pages) #define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&(mapping)->i_pages) #else #include +#undef flush_icache_range +#undef flush_icache_page +#undef flush_icache_user_range +void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len); #endif #endif /* __NDS32_CACHEFLUSH_H__ */ diff --git a/arch/nds32/mm/cacheflush.c b/arch/nds32/mm/cacheflush.c index ce8fd34497bf..7fcaa4e6be78 100644 --- a/arch/nds32/mm/cacheflush.c +++ b/arch/nds32/mm/cacheflush.c @@ -13,6 +13,38 @@ extern struct cache_info L1_cache_info[2]; +void flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long line_size, flags; + line_size = L1_cache_info[DCACHE].line_size; + start = start & ~(line_size - 1); + end = (end + line_size - 1) & ~(line_size - 1); + local_irq_save(flags); + cpu_cache_wbinval_range(start, end, 1); + local_irq_restore(flags); +} +EXPORT_SYMBOL(flush_icache_range); + +void flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + unsigned long flags; + unsigned long kaddr; + local_irq_save(flags); + kaddr = (unsigned long)kmap_atomic(page); + cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC); + kunmap_atomic((void *)kaddr); + local_irq_restore(flags); +} +EXPORT_SYMBOL(flush_icache_page); + +void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len) +{ + unsigned long kaddr; + kaddr = (unsigned long)kmap_atomic(page) + (addr & ~PAGE_MASK); + flush_icache_range(kaddr, kaddr + len); + kunmap_atomic((void *)kaddr); +} #ifndef CONFIG_CPU_CACHE_ALIASING void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t * pte) @@ -318,27 +350,6 @@ void invalidate_kernel_vmap_range(void *addr, int size) } EXPORT_SYMBOL(invalidate_kernel_vmap_range); -void flush_icache_range(unsigned long start, unsigned long end) -{ - unsigned long line_size, flags; - line_size = L1_cache_info[DCACHE].line_size; - start = start & ~(line_size - 1); - end = (end + line_size - 1) & ~(line_size - 1); - local_irq_save(flags); - cpu_cache_wbinval_range(start, end, 1); - local_irq_restore(flags); -} -EXPORT_SYMBOL(flush_icache_range); - -void flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - unsigned long flags; - local_irq_save(flags); - cpu_cache_wbinval_page((unsigned long)page_address(page), - vma->vm_flags & VM_EXEC); - local_irq_restore(flags); -} - void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t * pte) { From 6897e6ecb3167598cb45e1a1424dd4d5e3778837 Mon Sep 17 00:00:00 2001 From: Greentime Hu Date: Thu, 28 Jun 2018 18:29:21 +0800 Subject: [PATCH 4/6] nds32: Fix the dts pointer is not passed correctly issue. We found that the original implementation will only use the built-in dtb pointer instead of the pointer pass from bootloader. This bug is fixed by this patch. Signed-off-by: Greentime Hu --- arch/nds32/kernel/setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/nds32/kernel/setup.c b/arch/nds32/kernel/setup.c index 2f5b2ccebe47..63a1a5ef5219 100644 --- a/arch/nds32/kernel/setup.c +++ b/arch/nds32/kernel/setup.c @@ -278,7 +278,8 @@ static void __init setup_memory(void) void __init setup_arch(char **cmdline_p) { - early_init_devtree( __dtb_start); + early_init_devtree(__atags_pointer ? \ + phys_to_virt(__atags_pointer) : __dtb_start); setup_cpuinfo(); From bc9cb86e6514bed3d317208556d3cd48acff40e0 Mon Sep 17 00:00:00 2001 From: Greentime Hu Date: Tue, 3 Jul 2018 14:07:11 +0800 Subject: [PATCH 5/6] nds32: To simplify the implementation of update_mmu_cache() The checking code is done in kmap_atomic() so that we don't need to check it in update_mmu_cache() again. There is no need to implement it for cache aliasing or cache non-aliasing versions. We can just implement one version for both. Signed-off-by: Greentime Hu --- arch/nds32/mm/cacheflush.c | 47 +++++++------------------------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/arch/nds32/mm/cacheflush.c b/arch/nds32/mm/cacheflush.c index 7fcaa4e6be78..254703653b6f 100644 --- a/arch/nds32/mm/cacheflush.c +++ b/arch/nds32/mm/cacheflush.c @@ -45,7 +45,7 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, flush_icache_range(kaddr, kaddr + len); kunmap_atomic((void *)kaddr); } -#ifndef CONFIG_CPU_CACHE_ALIASING + void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t * pte) { @@ -67,19 +67,15 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, if ((test_and_clear_bit(PG_dcache_dirty, &page->flags)) || (vma->vm_flags & VM_EXEC)) { - - if (!PageHighMem(page)) { - cpu_cache_wbinval_page((unsigned long) - page_address(page), - vma->vm_flags & VM_EXEC); - } else { - unsigned long kaddr = (unsigned long)kmap_atomic(page); - cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC); - kunmap_atomic((void *)kaddr); - } + unsigned long kaddr; + local_irq_save(flags); + kaddr = (unsigned long)kmap_atomic(page); + cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC); + kunmap_atomic((void *)kaddr); + local_irq_restore(flags); } } -#else +#ifdef CONFIG_CPU_CACHE_ALIASING extern pte_t va_present(struct mm_struct *mm, unsigned long addr); static inline unsigned long aliasing(unsigned long addr, unsigned long page) @@ -349,31 +345,4 @@ void invalidate_kernel_vmap_range(void *addr, int size) local_irq_restore(flags); } EXPORT_SYMBOL(invalidate_kernel_vmap_range); - -void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, - pte_t * pte) -{ - struct page *page; - unsigned long flags; - unsigned long pfn = pte_pfn(*pte); - - if (!pfn_valid(pfn)) - return; - - if (vma->vm_mm == current->active_mm) { - local_irq_save(flags); - __nds32__mtsr_dsb(addr, NDS32_SR_TLB_VPN); - __nds32__tlbop_rwr(*pte); - __nds32__isb(); - local_irq_restore(flags); - } - - page = pfn_to_page(pfn); - if (test_and_clear_bit(PG_dcache_dirty, &page->flags) || - (vma->vm_flags & VM_EXEC)) { - local_irq_save(flags); - cpu_dcache_wbinval_page((unsigned long)page_address(page)); - local_irq_restore(flags); - } -} #endif From 987553894f0ce8c1d83578136603a89009f42d35 Mon Sep 17 00:00:00 2001 From: Greentime Hu Date: Thu, 5 Jul 2018 16:13:47 +0800 Subject: [PATCH 6/6] nds32: fix build error "relocation truncated to fit: R_NDS32_25_PCREL_RELA" when make allyesconfig It will cause a linking error because the jump assembly code were using j, however it may be not enough to jump to the destination. We have to change it with pseudo instruction b. In that way, assembler will generate a set of safe assembly codes to make sure the destination is able to jump. Toolchain: https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/x86_64-gcc-8.1.0-nolibc-nds32le-linux.tar.gz Command: PATH=/NOBACKUP/atcsqa06/greentime/os/toolchain-kernel.org/gcc-8.1.0-nolibc/nds32le-linux/bin:$PATH ARCH=nds32 CROSS_COMPILE=nds32le-linux- make allyesconfig PATH=/NOBACKUP/atcsqa06/greentime/os/toolchain-kernel.org/gcc-8.1.0-nolibc/nds32le-linux/bin:$PATH ARCH=nds32 CROSS_COMPILE=nds32le-linux- make -j8 MODPOST vmlinux.o WARNING: EXPORT symbol "copy_page" [vmlinux] version generation failed, symbol will not be versioned. WARNING: EXPORT symbol "clear_page" [vmlinux] version generation failed, symbol will not be versioned. nds32le-linux-ld: kernel/futex.o:(.fixup+0x4): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text' nds32le-linux-ld: kernel/futex.o:(.fixup+0xaa): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text' nds32le-linux-ld: kernel/futex.o:(.fixup+0xb0): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text' nds32le-linux-ld: kernel/futex.o:(.fixup+0xb6): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text' nds32le-linux-ld: kernel/futex.o:(.fixup+0xbc): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text' nds32le-linux-ld: kernel/futex.o:(.fixup+0xc4): relocation truncated to fit: R_NDS32_25_PCREL_RELA against `.text' Makefile:1010: recipe for target 'vmlinux' failed make: *** [vmlinux] Error 1 Signed-off-by: Greentime Hu --- arch/nds32/include/asm/futex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/nds32/include/asm/futex.h b/arch/nds32/include/asm/futex.h index eab5e84bd991..cb6cb91cfdf8 100644 --- a/arch/nds32/include/asm/futex.h +++ b/arch/nds32/include/asm/futex.h @@ -16,7 +16,7 @@ " .popsection\n" \ " .pushsection .fixup,\"ax\"\n" \ "4: move %0, " err_reg "\n" \ - " j 3b\n" \ + " b 3b\n" \ " .popsection" #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \