diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-07 11:33:08 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-07 11:33:08 -0800 |
commit | 413879a10b0b0eb563a23c4df896773b2d9413f9 (patch) | |
tree | 6bf6664b45b28148087fb6b50c2d20bbc8d13d19 /arch/riscv/kernel | |
parent | 0bd2afc74808389591894dd7c7c83952006a1283 (diff) | |
parent | 4889dec6c87d90619cc1e8436327b91f4bb0e467 (diff) | |
download | linux-413879a10b0b0eb563a23c4df896773b2d9413f9.tar.bz2 |
Merge tag 'riscv-for-linus-4.16-merge_window' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/riscv-linux
Pull RISC-V updates from Palmer Dabbelt:
"This contains the fixes we'd like to target for the 4.16 merge window.
It's not as much as I was originally hoping to do but between glibc,
the chip, and FOSDEM there just wasn't enough time to get everything
put together. As such, this merge window is essentially just going to
be small changes. This includes mostly cleanups:
- A build fix failure to the audit test cases.
RISC-V doesn't have renameat because the generic syscall ABI moved
to renameat2 by the time of our port. The syscall audit test cases
don't understand this, so I added a trivial fix. This went through
mailing list review during the 4.15 merge window, but nobody has
picked it up so I think it's best to just do this here.
- The removal of our command-line argument processing code. The
"mem_end" stuff was broken and the rest duplicated generic device
tree code. The generic code was already being called.
- Some unused/redundant code has been removed, including
__ARCH_HAVE_MMU, current_pgdir, and the initialization of
init_mm.pgd.
- SUM is disabled upon taking a trap, which means that user memory is
protected during traps taking inside copy_{to,from}_user().
- The sptbr CSR has been renamed to satp in C code. We haven't
changed the assembly code in order to maintain compatibility with
binutils 2.29, which doesn't understand the new name.
Additionally, we're adding some new features:
- Basic ftrace support, thanks to Alan Kao!
- Support for ZONE_DMA32.
This is necessary for all the normal reasons, but also to deal with
a deficiency in the Xilinx PCIe controller we're using on our
FPGA-based systems. While the ZONE_DMA32 addition should be
sufficient for most uses, it doesn't complete the fix for the
Xilinx controller.
- TLB shootdowns now only target the harts where they're necessary,
instead of applying to all harts in the system.
These patches have all been sitting on our linux-next branch for a
while now. Due to time constraints this is all I feel comfortable
submitting during the 4.16 merge window, hopefully we'll do better
next time!"
[ Note to self: "harts" is RISC-V speak for "hardware threads". I had
to look that up. - Linus ]
* tag 'riscv-for-linus-4.16-merge_window' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/riscv-linux:
riscv: inline set_pgdir into its only caller
riscv: rename sptbr to satp
riscv: don't read back satp in paging_init
riscv: remove the unused current_pgdir function
riscv: add ZONE_DMA32
RISC-V: Limit the scope of TLB shootdowns
riscv: disable SUM in the exception handler
riscv: remove redundant unlikely()
riscv: remove unused __ARCH_HAVE_MMU define
riscv/ftrace: Add basic support
RISC-V: Remove mem_end command line processing
RISC-V: Remove duplicate command-line parsing logic
audit: Avoid build failures on systems without renameat
Diffstat (limited to 'arch/riscv/kernel')
-rw-r--r-- | arch/riscv/kernel/Makefile | 7 | ||||
-rw-r--r-- | arch/riscv/kernel/entry.S | 9 | ||||
-rw-r--r-- | arch/riscv/kernel/ftrace.c | 41 | ||||
-rw-r--r-- | arch/riscv/kernel/head.S | 6 | ||||
-rw-r--r-- | arch/riscv/kernel/mcount.S | 126 | ||||
-rw-r--r-- | arch/riscv/kernel/setup.c | 44 | ||||
-rw-r--r-- | arch/riscv/kernel/vdso.c | 2 |
7 files changed, 193 insertions, 42 deletions
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index ab8baf7bd142..196f62ffc428 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -2,6 +2,11 @@ # Makefile for the RISC-V Linux kernel # +ifdef CONFIG_FTRACE +CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_setup.o = -pg +endif + extra-y += head.o extra-y += vmlinux.lds @@ -29,5 +34,7 @@ CFLAGS_setup.o := -mcmodel=medany obj-$(CONFIG_SMP) += smpboot.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_FUNCTION_TRACER) += mcount.o +obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o clean: diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 7404ec222406..87fc045be51f 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -78,10 +78,13 @@ _save_context: REG_S x31, PT_T6(sp) /* - * Disable FPU to detect illegal usage of - * floating point in kernel space + * Disable user-mode memory access as it should only be set in the + * actual user copy routines. + * + * Disable the FPU to detect illegal usage of floating point in kernel + * space. */ - li t0, SR_FS + li t0, SR_SUM | SR_FS REG_L s0, TASK_TI_USER_SP(tp) csrrc s1, sstatus, t0 diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c new file mode 100644 index 000000000000..d0de68d144cb --- /dev/null +++ b/arch/riscv/kernel/ftrace.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2013 Linaro Limited + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> + * Copyright (C) 2017 Andes Technology Corporation + */ + +#include <linux/ftrace.h> + +/* + * Most of this file is copied from arm64. + */ +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, + unsigned long frame_pointer) +{ + unsigned long return_hooker = (unsigned long)&return_to_handler; + unsigned long old; + struct ftrace_graph_ent trace; + int err; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; + + /* + * We don't suffer access faults, so no extra fault-recovery assembly + * is needed here. + */ + old = *parent; + + trace.func = self_addr; + trace.depth = current->curr_ret_stack + 1; + + if (!ftrace_graph_entry(&trace)) + return; + + err = ftrace_push_return_trace(old, self_addr, &trace.depth, + frame_pointer, NULL); + if (err == -EBUSY) + return; + *parent = return_hooker; +} diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 78f670d70133..226eeb190f90 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -74,15 +74,15 @@ relocate: sub a1, a1, a0 add ra, ra, a1 - /* Point stvec to virtual address of intruction after sptbr write */ + /* Point stvec to virtual address of intruction after satp write */ la a0, 1f add a0, a0, a1 csrw stvec, a0 - /* Compute sptbr for kernel page tables, but don't load it yet */ + /* Compute satp for kernel page tables, but don't load it yet */ la a2, swapper_pg_dir srl a2, a2, PAGE_SHIFT - li a1, SPTBR_MODE + li a1, SATP_MODE or a2, a2, a1 /* diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S new file mode 100644 index 000000000000..c46a778627be --- /dev/null +++ b/arch/riscv/kernel/mcount.S @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2017 Andes Technology Corporation */ + +#include <linux/init.h> +#include <linux/linkage.h> +#include <asm/asm.h> +#include <asm/csr.h> +#include <asm/unistd.h> +#include <asm/thread_info.h> +#include <asm/asm-offsets.h> +#include <asm-generic/export.h> +#include <asm/ftrace.h> + + .text + + .macro SAVE_ABI_STATE + addi sp, sp, -16 + sd s0, 0(sp) + sd ra, 8(sp) + addi s0, sp, 16 + .endm + + /* + * The call to ftrace_return_to_handler would overwrite the return + * register if a0 was not saved. + */ + .macro SAVE_RET_ABI_STATE + addi sp, sp, -32 + sd s0, 16(sp) + sd ra, 24(sp) + sd a0, 8(sp) + addi s0, sp, 32 + .endm + + .macro STORE_ABI_STATE + ld ra, 8(sp) + ld s0, 0(sp) + addi sp, sp, 16 + .endm + + .macro STORE_RET_ABI_STATE + ld ra, 24(sp) + ld s0, 16(sp) + ld a0, 8(sp) + addi sp, sp, 32 + .endm + +ENTRY(ftrace_stub) + ret +ENDPROC(ftrace_stub) + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +ENTRY(return_to_handler) +/* + * On implementing the frame point test, the ideal way is to compare the + * s0 (frame pointer, if enabled) on entry and the sp (stack pointer) on return. + * However, the psABI of variable-length-argument functions does not allow this. + * + * So alternatively we check the *old* frame pointer position, that is, the + * value stored in -16(s0) on entry, and the s0 on return. + */ +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + mv t6, s0 +#endif + SAVE_RET_ABI_STATE +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + mv a0, t6 +#endif + la t0, ftrace_return_to_handler + jalr t0 + mv a1, a0 + STORE_RET_ABI_STATE + jalr a1 +ENDPROC(return_to_handler) +EXPORT_SYMBOL(return_to_handler) +#endif + +ENTRY(_mcount) + la t4, ftrace_stub +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + la t0, ftrace_graph_return + ld t1, 0(t0) + bne t1, t4, do_ftrace_graph_caller + + la t3, ftrace_graph_entry + ld t2, 0(t3) + la t6, ftrace_graph_entry_stub + bne t2, t6, do_ftrace_graph_caller +#endif + la t3, ftrace_trace_function + ld t5, 0(t3) + bne t5, t4, do_trace + ret + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +/* + * A pseudo representation for the function graph tracer: + * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller) + */ +do_ftrace_graph_caller: + addi a0, s0, -8 + mv a1, ra +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + ld a2, -16(s0) +#endif + SAVE_ABI_STATE + la t0, prepare_ftrace_return + jalr t0 + STORE_ABI_STATE + ret +#endif + +/* + * A pseudo representation for the function tracer: + * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller) + */ +do_trace: + ld a1, -8(s0) + mv a0, ra + + SAVE_ABI_STATE + jalr t5 + STORE_ABI_STATE + ret +ENDPROC(_mcount) +EXPORT_SYMBOL(_mcount) diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index cb7b0c63014e..09f7064e898c 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -49,10 +49,6 @@ struct screen_info screen_info = { }; #endif -#ifdef CONFIG_CMDLINE_BOOL -static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; -#endif /* CONFIG_CMDLINE_BOOL */ - unsigned long va_pa_offset; EXPORT_SYMBOL(va_pa_offset); unsigned long pfn_base; @@ -153,25 +149,6 @@ void __init sbi_save(unsigned int hartid, void *dtb) early_init_dt_scan(__va(dtb)); } -/* - * Allow the user to manually add a memory region (in case DTS is broken); - * "mem_end=nn[KkMmGg]" - */ -static int __init mem_end_override(char *p) -{ - resource_size_t base, end; - - if (!p) - return -EINVAL; - base = (uintptr_t) __pa(PAGE_OFFSET); - end = memparse(p, &p) & PMD_MASK; - if (end == 0) - return -EINVAL; - memblock_add(base, end - base); - return 0; -} -early_param("mem_end", mem_end_override); - static void __init setup_bootmem(void) { struct memblock_region *reg; @@ -204,22 +181,19 @@ static void __init setup_bootmem(void) early_init_fdt_scan_reserved_mem(); memblock_allow_resize(); memblock_dump_all(); + + for_each_memblock(memory, reg) { + unsigned long start_pfn = memblock_region_memory_base_pfn(reg); + unsigned long end_pfn = memblock_region_memory_end_pfn(reg); + + memblock_set_node(PFN_PHYS(start_pfn), + PFN_PHYS(end_pfn - start_pfn), + &memblock.memory, 0); + } } void __init setup_arch(char **cmdline_p) { -#ifdef CONFIG_CMDLINE_BOOL -#ifdef CONFIG_CMDLINE_OVERRIDE - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); -#else - if (builtin_cmdline[0] != '\0') { - /* Append bootloader command line to built-in */ - strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); - strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); - } -#endif /* CONFIG_CMDLINE_OVERRIDE */ -#endif /* CONFIG_CMDLINE_BOOL */ *cmdline_p = boot_command_line; parse_early_param(); diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c index e8a178df8144..582cb153eb24 100644 --- a/arch/riscv/kernel/vdso.c +++ b/arch/riscv/kernel/vdso.c @@ -74,7 +74,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, down_write(&mm->mmap_sem); vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0); - if (unlikely(IS_ERR_VALUE(vdso_base))) { + if (IS_ERR_VALUE(vdso_base)) { ret = vdso_base; goto end; } |