From 7265d103902c0bc2b76fe04e87e0c486016391c3 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 18 Jan 2019 15:03:04 +0100 Subject: riscv: add missing newlines to printk messages Add missing newline characters to printk messages. Also replace two pr_warning with the shorter pr_warn, and fix up the tense of one error message while at it. Signed-off-by: Johan Hovold Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/cpu.c | 2 +- arch/riscv/kernel/cpufeature.c | 8 ++++---- arch/riscv/kernel/ftrace.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index f8fa2c63aa89..11ba67f010e7 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -106,7 +106,7 @@ static void print_isa(struct seq_file *f, const char *orig_isa) * a bit of info describing what went wrong. */ if (isa[0] != '\0') - pr_info("unsupported ISA \"%s\" in device tree", orig_isa); + pr_info("unsupported ISA \"%s\" in device tree\n", orig_isa); } static void print_mmu(struct seq_file *f, const char *mmu_type) diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index a6e369edbbd7..4891fd62b95e 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -50,12 +50,12 @@ void riscv_fill_hwcap(void) if (riscv_of_processor_hartid(node) >= 0) break; if (!node) { - pr_warning("Unable to find \"cpu\" devicetree entry"); + pr_warn("Unable to find \"cpu\" devicetree entry\n"); return; } if (of_property_read_string(node, "riscv,isa", &isa)) { - pr_warning("Unable to find \"riscv,isa\" devicetree entry"); + pr_warn("Unable to find \"riscv,isa\" devicetree entry\n"); of_node_put(node); return; } @@ -67,11 +67,11 @@ void riscv_fill_hwcap(void) /* We don't support systems with F but without D, so mask those out * here. */ if ((elf_hwcap & COMPAT_HWCAP_ISA_F) && !(elf_hwcap & COMPAT_HWCAP_ISA_D)) { - pr_info("This kernel does not support systems with F but not D"); + pr_info("This kernel does not support systems with F but not D\n"); elf_hwcap &= ~COMPAT_HWCAP_ISA_F; } - pr_info("elf_hwcap is 0x%lx", elf_hwcap); + pr_info("elf_hwcap is 0x%lx\n", elf_hwcap); #ifdef CONFIG_FPU if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)) diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c index a840b7d074f7..b94d8db5ddcc 100644 --- a/arch/riscv/kernel/ftrace.c +++ b/arch/riscv/kernel/ftrace.c @@ -32,7 +32,7 @@ static int ftrace_check_current_call(unsigned long hook_pos, * return must be -EINVAL on failed comparison */ if (memcmp(expected, replaced, sizeof(replaced))) { - pr_err("%p: expected (%08x %08x) but get (%08x %08x)", + pr_err("%p: expected (%08x %08x) but got (%08x %08x)\n", (void *)hook_pos, expected[0], expected[1], replaced[0], replaced[1]); return -EINVAL; -- cgit v1.2.3-59-g8ed1b From e1b1381b31793dde71eb87a78071c22c3f02f75c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 18 Jan 2019 15:03:05 +0100 Subject: riscv: use pr_info and friends Use the pr_info and pr_err macros instead of printk with explicit log levels. Signed-off-by: Johan Hovold Reviewed-by: Paul Walmsley Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 77564310235f..fb09e0136026 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -76,11 +76,11 @@ static void __init setup_initrd(void) unsigned long size; if (initrd_start >= initrd_end) { - printk(KERN_INFO "initrd not found or empty"); + pr_info("initrd not found or empty"); goto disable; } if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { - printk(KERN_ERR "initrd extends beyond end of memory"); + pr_err("initrd extends beyond end of memory"); goto disable; } @@ -88,7 +88,7 @@ static void __init setup_initrd(void) memblock_reserve(__pa(initrd_start), size); initrd_below_start_ok = 1; - printk(KERN_INFO "Initial ramdisk at: 0x%p (%lu bytes)\n", + pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n", (void *)(initrd_start), size); return; disable: -- cgit v1.2.3-59-g8ed1b From 149820c6cf3cf51cd9dc1cf50cbe59b5b61e3909 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 18 Jan 2019 15:03:06 +0100 Subject: riscv: fix riscv_of_processor_hartid() comment The riscv_of_processor_hartid() helper returns -ENODEV when the specified node isn't an enabled and valid RISC-V hart node. Also drop the unnecessary parenthesis around errno defines. Signed-off-by: Johan Hovold Reviewed-by: Paul Walmsley Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/cpu.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index 11ba67f010e7..974d374fd36b 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -17,8 +17,8 @@ #include /* - * Returns the hart ID of the given device tree node, or -1 if the device tree - * node isn't a RISC-V hart. + * Returns the hart ID of the given device tree node, or -ENODEV if the node + * isn't an enabled and valid RISC-V hart node. */ int riscv_of_processor_hartid(struct device_node *node) { @@ -27,34 +27,34 @@ int riscv_of_processor_hartid(struct device_node *node) if (!of_device_is_compatible(node, "riscv")) { pr_warn("Found incompatible CPU\n"); - return -(ENODEV); + return -ENODEV; } if (of_property_read_u32(node, "reg", &hart)) { pr_warn("Found CPU without hart ID\n"); - return -(ENODEV); + return -ENODEV; } if (hart >= NR_CPUS) { pr_info("Found hart ID %d, which is above NR_CPUs. Disabling this hart\n", hart); - return -(ENODEV); + return -ENODEV; } if (of_property_read_string(node, "status", &status)) { pr_warn("CPU with hartid=%d has no \"status\" property\n", hart); - return -(ENODEV); + return -ENODEV; } if (strcmp(status, "okay")) { pr_info("CPU with hartid=%d has a non-okay status of \"%s\"\n", hart, status); - return -(ENODEV); + return -ENODEV; } if (of_property_read_string(node, "riscv,isa", &isa)) { pr_warn("CPU with hartid=%d has no \"riscv,isa\" property\n", hart); - return -(ENODEV); + return -ENODEV; } if (isa[0] != 'r' || isa[1] != 'v') { pr_warn("CPU with hartid=%d has an invalid ISA of \"%s\"\n", hart, isa); - return -(ENODEV); + return -ENODEV; } return hart; -- cgit v1.2.3-59-g8ed1b From e3d794d555cda31d48c89bdbc96ce862857be93f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 18 Jan 2019 15:03:07 +0100 Subject: riscv: treat cpu devicetree nodes without status as enabled Follow the Linux convention and treat devicetree nodes without a status property as enabled rather than disabled, while also allowing "ok" as a shorthand for "okay". Signed-off-by: Johan Hovold Reviewed-by: Paul Walmsley Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/cpu.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index 974d374fd36b..d1d9bfd5a89f 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -22,7 +22,7 @@ */ int riscv_of_processor_hartid(struct device_node *node) { - const char *isa, *status; + const char *isa; u32 hart; if (!of_device_is_compatible(node, "riscv")) { @@ -39,12 +39,8 @@ int riscv_of_processor_hartid(struct device_node *node) return -ENODEV; } - if (of_property_read_string(node, "status", &status)) { - pr_warn("CPU with hartid=%d has no \"status\" property\n", hart); - return -ENODEV; - } - if (strcmp(status, "okay")) { - pr_info("CPU with hartid=%d has a non-okay status of \"%s\"\n", hart, status); + if (!of_device_is_available(node)) { + pr_info("CPU with hartid=%d is not available\n", hart); return -ENODEV; } -- cgit v1.2.3-59-g8ed1b From dd81c8ab819d360c92703564d0a8d0b9d4688267 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 18 Jan 2019 15:03:08 +0100 Subject: riscv: use for_each_of_cpu_node iterator Use the new for_each_of_cpu_node() helper to iterate over cpu nodes instead of open coding. Note that this will allow matching also on the node name instead of the (for FDT) deprecated device_type property. Signed-off-by: Johan Hovold Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/cpufeature.c | 5 +++-- arch/riscv/kernel/smpboot.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 4891fd62b95e..e7a4701f0256 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -28,7 +28,7 @@ bool has_fpu __read_mostly; void riscv_fill_hwcap(void) { - struct device_node *node = NULL; + struct device_node *node; const char *isa; size_t i; static unsigned long isa2hwcap[256] = {0}; @@ -46,9 +46,10 @@ void riscv_fill_hwcap(void) * We don't support running Linux on hertergenous ISA systems. For * now, we just check the ISA of the first "okay" processor. */ - while ((node = of_find_node_by_type(node, "cpu"))) + for_each_of_cpu_node(node) { if (riscv_of_processor_hartid(node) >= 0) break; + } if (!node) { pr_warn("Unable to find \"cpu\" devicetree entry\n"); return; diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 18cda0e8cf94..6e2813257e03 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -50,12 +50,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) void __init setup_smp(void) { - struct device_node *dn = NULL; + struct device_node *dn; int hart; bool found_boot_cpu = false; int cpuid = 1; - while ((dn = of_find_node_by_type(dn, "cpu"))) { + for_each_of_cpu_node(dn) { hart = riscv_of_processor_hartid(dn); if (hart < 0) continue; -- cgit v1.2.3-59-g8ed1b From 79a47bad61bb340aed94e73b471616b246b2ecf3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 13 Feb 2019 18:39:56 +0100 Subject: riscv: remove the HAVE_KPROBES option HAVE_KPROBES is defined genericly in arch/Kconfig and architectures should just select it if supported. Signed-off-by: Christoph Hellwig Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 515fc3cc9687..b60f4e3e36f4 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -94,9 +94,6 @@ config PGTABLE_LEVELS default 3 if 64BIT default 2 -config HAVE_KPROBES - def_bool n - menu "Platform type" choice -- cgit v1.2.3-59-g8ed1b From 680f9b8e6c56414b6ade41e01950cc1318856b6b Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Mon, 7 Jan 2019 19:19:14 +0530 Subject: RISC-V: Setup init_mm before parse_early_param() We should setup init_mm before doing parse_early_param() in setup_arch() to be consistent with setup_arch() of other architectures such as x86, ARM, and ARM64. Signed-off-by: Anup Patel Reviewed-by: Christoph Hellwig Reviewed-by: Palmer Dabbelt --- arch/riscv/kernel/setup.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index fb09e0136026..6a8a89740b7c 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -204,15 +204,15 @@ static void __init setup_bootmem(void) void __init setup_arch(char **cmdline_p) { - *cmdline_p = boot_command_line; - - parse_early_param(); - init_mm.start_code = (unsigned long) _stext; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; init_mm.brk = (unsigned long) _end; + *cmdline_p = boot_command_line; + + parse_early_param(); + setup_bootmem(); paging_init(); unflatten_device_tree(); @@ -231,4 +231,3 @@ void __init setup_arch(char **cmdline_p) riscv_fill_hwcap(); } - -- cgit v1.2.3-59-g8ed1b From 0651c263c8e39f409a72ba01bfd73ddf3d3e6748 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 21 Feb 2019 11:25:49 +0530 Subject: RISC-V: Move setup_bootmem() to mm/init.c The setup_bootmem() mainly populates memblocks and does early memory reservations. The right location for this function is mm/init.c. It calls setup_initrd() so we move that as well. Signed-off-by: Anup Patel Reviewed-by: Christoph Hellwig Reviewed-by: Palmer Dabbelt Reviewed-by: Mike Rapoport --- arch/riscv/include/asm/pgtable.h | 1 + arch/riscv/kernel/setup.c | 72 ---------------------------------------- arch/riscv/mm/init.c | 70 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 72 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index a8179a8c1491..1141364d990e 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -404,6 +404,7 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, #define kern_addr_valid(addr) (1) /* FIXME */ #endif +extern void setup_bootmem(void); extern void paging_init(void); static inline void pgtable_cache_init(void) diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 6a8a89740b7c..49bce6692f39 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -70,34 +69,6 @@ void __init smp_setup_processor_id(void) cpuid_to_hartid_map(0) = boot_cpu_hartid; } -#ifdef CONFIG_BLK_DEV_INITRD -static void __init setup_initrd(void) -{ - unsigned long size; - - if (initrd_start >= initrd_end) { - pr_info("initrd not found or empty"); - goto disable; - } - if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { - pr_err("initrd extends beyond end of memory"); - goto disable; - } - - size = initrd_end - initrd_start; - memblock_reserve(__pa(initrd_start), size); - initrd_below_start_ok = 1; - - pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n", - (void *)(initrd_start), size); - return; -disable: - pr_cont(" - disabling initrd\n"); - initrd_start = 0; - initrd_end = 0; -} -#endif /* CONFIG_BLK_DEV_INITRD */ - pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss; pgd_t trampoline_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); @@ -159,49 +130,6 @@ void __init parse_dtb(unsigned int hartid, void *dtb) #endif } -static void __init setup_bootmem(void) -{ - struct memblock_region *reg; - phys_addr_t mem_size = 0; - - /* Find the memory region containing the kernel */ - for_each_memblock(memory, reg) { - phys_addr_t vmlinux_end = __pa(_end); - phys_addr_t end = reg->base + reg->size; - - if (reg->base <= vmlinux_end && vmlinux_end <= end) { - /* - * Reserve from the start of the region to the end of - * the kernel - */ - memblock_reserve(reg->base, vmlinux_end - reg->base); - mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET); - } - } - BUG_ON(mem_size == 0); - - set_max_mapnr(PFN_DOWN(mem_size)); - max_low_pfn = PFN_DOWN(memblock_end_of_DRAM()); - -#ifdef CONFIG_BLK_DEV_INITRD - setup_initrd(); -#endif /* CONFIG_BLK_DEV_INITRD */ - - early_init_fdt_reserve_self(); - 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) { init_mm.start_code = (unsigned long) _stext; diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 658ebf645f42..30af42d78e35 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -66,7 +67,76 @@ void free_initmem(void) } #ifdef CONFIG_BLK_DEV_INITRD +static void __init setup_initrd(void) +{ + unsigned long size; + + if (initrd_start >= initrd_end) { + pr_info("initrd not found or empty"); + goto disable; + } + if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { + pr_err("initrd extends beyond end of memory"); + goto disable; + } + + size = initrd_end - initrd_start; + memblock_reserve(__pa(initrd_start), size); + initrd_below_start_ok = 1; + + pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n", + (void *)(initrd_start), size); + return; +disable: + pr_cont(" - disabling initrd\n"); + initrd_start = 0; + initrd_end = 0; +} + void free_initrd_mem(unsigned long start, unsigned long end) { } #endif /* CONFIG_BLK_DEV_INITRD */ + +void __init setup_bootmem(void) +{ + struct memblock_region *reg; + phys_addr_t mem_size = 0; + + /* Find the memory region containing the kernel */ + for_each_memblock(memory, reg) { + phys_addr_t vmlinux_end = __pa(_end); + phys_addr_t end = reg->base + reg->size; + + if (reg->base <= vmlinux_end && vmlinux_end <= end) { + /* + * Reserve from the start of the region to the end of + * the kernel + */ + memblock_reserve(reg->base, vmlinux_end - reg->base); + mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET); + } + } + BUG_ON(mem_size == 0); + + set_max_mapnr(PFN_DOWN(mem_size)); + max_low_pfn = PFN_DOWN(memblock_end_of_DRAM()); + +#ifdef CONFIG_BLK_DEV_INITRD + setup_initrd(); +#endif /* CONFIG_BLK_DEV_INITRD */ + + early_init_fdt_reserve_self(); + 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); + } +} -- cgit v1.2.3-59-g8ed1b From 6f1e9e946f0bc32cf55a7d7c36f80cb365e1877a Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 13 Feb 2019 16:38:36 +0530 Subject: RISC-V: Move setup_vm() to mm/init.c The setup_vm() is responsible for setting up initial page table hence should be placed in mm/init.c. Signed-off-by: Anup Patel Reviewed-by: Christoph Hellwig Reviewed-by: Palmer Dabbelt --- arch/riscv/kernel/setup.c | 49 ----------------------------------------------- arch/riscv/mm/init.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 49 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 49bce6692f39..cffe0b3caba4 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -69,55 +69,6 @@ void __init smp_setup_processor_id(void) cpuid_to_hartid_map(0) = boot_cpu_hartid; } -pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss; -pgd_t trampoline_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); - -#ifndef __PAGETABLE_PMD_FOLDED -#define NUM_SWAPPER_PMDS ((uintptr_t)-PAGE_OFFSET >> PGDIR_SHIFT) -pmd_t swapper_pmd[PTRS_PER_PMD*((-PAGE_OFFSET)/PGDIR_SIZE)] __page_aligned_bss; -pmd_t trampoline_pmd[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); -#endif - -asmlinkage void __init setup_vm(void) -{ - extern char _start; - uintptr_t i; - uintptr_t pa = (uintptr_t) &_start; - pgprot_t prot = __pgprot(pgprot_val(PAGE_KERNEL) | _PAGE_EXEC); - - va_pa_offset = PAGE_OFFSET - pa; - pfn_base = PFN_DOWN(pa); - - /* Sanity check alignment and size */ - BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0); - BUG_ON((pa % (PAGE_SIZE * PTRS_PER_PTE)) != 0); - -#ifndef __PAGETABLE_PMD_FOLDED - trampoline_pg_dir[(PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD] = - pfn_pgd(PFN_DOWN((uintptr_t)trampoline_pmd), - __pgprot(_PAGE_TABLE)); - trampoline_pmd[0] = pfn_pmd(PFN_DOWN(pa), prot); - - for (i = 0; i < (-PAGE_OFFSET)/PGDIR_SIZE; ++i) { - size_t o = (PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD + i; - swapper_pg_dir[o] = - pfn_pgd(PFN_DOWN((uintptr_t)swapper_pmd) + i, - __pgprot(_PAGE_TABLE)); - } - for (i = 0; i < ARRAY_SIZE(swapper_pmd); i++) - swapper_pmd[i] = pfn_pmd(PFN_DOWN(pa + i * PMD_SIZE), prot); -#else - trampoline_pg_dir[(PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD] = - pfn_pgd(PFN_DOWN(pa), prot); - - for (i = 0; i < (-PAGE_OFFSET)/PGDIR_SIZE; ++i) { - size_t o = (PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD + i; - swapper_pg_dir[o] = - pfn_pgd(PFN_DOWN(pa + i * PGDIR_SIZE), prot); - } -#endif -} - void __init parse_dtb(unsigned int hartid, void *dtb) { if (!early_init_dt_scan(__va(dtb))) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 30af42d78e35..ee9cf26b3855 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -140,3 +140,52 @@ void __init setup_bootmem(void) &memblock.memory, 0); } } + +pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss; +pgd_t trampoline_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); + +#ifndef __PAGETABLE_PMD_FOLDED +#define NUM_SWAPPER_PMDS ((uintptr_t)-PAGE_OFFSET >> PGDIR_SHIFT) +pmd_t swapper_pmd[PTRS_PER_PMD*((-PAGE_OFFSET)/PGDIR_SIZE)] __page_aligned_bss; +pmd_t trampoline_pmd[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); +#endif + +asmlinkage void __init setup_vm(void) +{ + extern char _start; + uintptr_t i; + uintptr_t pa = (uintptr_t) &_start; + pgprot_t prot = __pgprot(pgprot_val(PAGE_KERNEL) | _PAGE_EXEC); + + va_pa_offset = PAGE_OFFSET - pa; + pfn_base = PFN_DOWN(pa); + + /* Sanity check alignment and size */ + BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0); + BUG_ON((pa % (PAGE_SIZE * PTRS_PER_PTE)) != 0); + +#ifndef __PAGETABLE_PMD_FOLDED + trampoline_pg_dir[(PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD] = + pfn_pgd(PFN_DOWN((uintptr_t)trampoline_pmd), + __pgprot(_PAGE_TABLE)); + trampoline_pmd[0] = pfn_pmd(PFN_DOWN(pa), prot); + + for (i = 0; i < (-PAGE_OFFSET)/PGDIR_SIZE; ++i) { + size_t o = (PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD + i; + swapper_pg_dir[o] = + pfn_pgd(PFN_DOWN((uintptr_t)swapper_pmd) + i, + __pgprot(_PAGE_TABLE)); + } + for (i = 0; i < ARRAY_SIZE(swapper_pmd); i++) + swapper_pmd[i] = pfn_pmd(PFN_DOWN(pa + i * PMD_SIZE), prot); +#else + trampoline_pg_dir[(PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD] = + pfn_pgd(PFN_DOWN(pa), prot); + + for (i = 0; i < (-PAGE_OFFSET)/PGDIR_SIZE; ++i) { + size_t o = (PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD + i; + swapper_pg_dir[o] = + pfn_pgd(PFN_DOWN(pa + i * PGDIR_SIZE), prot); + } +#endif +} -- cgit v1.2.3-59-g8ed1b From f2c17aabc917e1092eedb16fa2b8891e9379f7e6 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Mon, 7 Jan 2019 20:57:01 +0530 Subject: RISC-V: Implement compile-time fixed mappings This patch implements compile-time virtual to physical mappings. These compile-time fixed mappings can be used by earlycon, ACPI, and early ioremap for creating fixed mappings when FIX_EARLYCON_MEM=y. To start with, we have enabled compile-time fixed mappings for earlycon. Signed-off-by: Anup Patel Reviewed-by: Christoph Hellwig Reviewed-by: Palmer Dabbelt --- arch/riscv/Kconfig | 3 +++ arch/riscv/include/asm/fixmap.h | 44 +++++++++++++++++++++++++++++++++++++++++ arch/riscv/mm/init.c | 34 +++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 arch/riscv/include/asm/fixmap.h (limited to 'arch/riscv') diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index b60f4e3e36f4..ceed055179c8 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -89,6 +89,9 @@ config GENERIC_CSUM config GENERIC_HWEIGHT def_bool y +config FIX_EARLYCON_MEM + def_bool y + config PGTABLE_LEVELS int default 3 if 64BIT diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h new file mode 100644 index 000000000000..57afe604b495 --- /dev/null +++ b/arch/riscv/include/asm/fixmap.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 Western Digital Corporation or its affiliates. + */ + +#ifndef _ASM_RISCV_FIXMAP_H +#define _ASM_RISCV_FIXMAP_H + +#include +#include +#include +#include + +/* + * Here we define all the compile-time 'special' virtual addresses. + * The point is to have a constant address at compile time, but to + * set the physical address only in the boot process. + * + * These 'compile-time allocated' memory buffers are page-sized. Use + * set_fixmap(idx,phys) to associate physical memory with fixmap indices. + */ +enum fixed_addresses { + FIX_HOLE, + FIX_EARLYCON_MEM_BASE, + __end_of_fixed_addresses +}; + +#define FIXADDR_SIZE (__end_of_fixed_addresses * PAGE_SIZE) +#define FIXADDR_TOP (PAGE_OFFSET) +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) + +#define FIXMAP_PAGE_IO PAGE_KERNEL + +#define __early_set_fixmap __set_fixmap + +#define __late_set_fixmap __set_fixmap +#define __late_clear_fixmap(idx) __set_fixmap((idx), 0, FIXMAP_PAGE_CLEAR) + +extern void __set_fixmap(enum fixed_addresses idx, + phys_addr_t phys, pgprot_t prot); + +#include + +#endif /* _ASM_RISCV_FIXMAP_H */ diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index ee9cf26b3855..9e7b3ee78089 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -148,8 +149,28 @@ pgd_t trampoline_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); #define NUM_SWAPPER_PMDS ((uintptr_t)-PAGE_OFFSET >> PGDIR_SHIFT) pmd_t swapper_pmd[PTRS_PER_PMD*((-PAGE_OFFSET)/PGDIR_SIZE)] __page_aligned_bss; pmd_t trampoline_pmd[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); +pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss; #endif +pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss; + +void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) +{ + unsigned long addr = __fix_to_virt(idx); + pte_t *ptep; + + BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses); + + ptep = &fixmap_pte[pte_index(addr)]; + + if (pgprot_val(prot)) { + set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); + } else { + pte_clear(&init_mm, addr, ptep); + local_flush_tlb_page(addr); + } +} + asmlinkage void __init setup_vm(void) { extern char _start; @@ -172,20 +193,33 @@ asmlinkage void __init setup_vm(void) for (i = 0; i < (-PAGE_OFFSET)/PGDIR_SIZE; ++i) { size_t o = (PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD + i; + swapper_pg_dir[o] = pfn_pgd(PFN_DOWN((uintptr_t)swapper_pmd) + i, __pgprot(_PAGE_TABLE)); } for (i = 0; i < ARRAY_SIZE(swapper_pmd); i++) swapper_pmd[i] = pfn_pmd(PFN_DOWN(pa + i * PMD_SIZE), prot); + + swapper_pg_dir[(FIXADDR_START >> PGDIR_SHIFT) % PTRS_PER_PGD] = + pfn_pgd(PFN_DOWN((uintptr_t)fixmap_pmd), + __pgprot(_PAGE_TABLE)); + fixmap_pmd[(FIXADDR_START >> PMD_SHIFT) % PTRS_PER_PMD] = + pfn_pmd(PFN_DOWN((uintptr_t)fixmap_pte), + __pgprot(_PAGE_TABLE)); #else trampoline_pg_dir[(PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD] = pfn_pgd(PFN_DOWN(pa), prot); for (i = 0; i < (-PAGE_OFFSET)/PGDIR_SIZE; ++i) { size_t o = (PAGE_OFFSET >> PGDIR_SHIFT) % PTRS_PER_PGD + i; + swapper_pg_dir[o] = pfn_pgd(PFN_DOWN(pa + i * PGDIR_SIZE), prot); } + + swapper_pg_dir[(FIXADDR_START >> PGDIR_SHIFT) % PTRS_PER_PGD] = + pfn_pgd(PFN_DOWN((uintptr_t)fixmap_pte), + __pgprot(_PAGE_TABLE)); #endif } -- cgit v1.2.3-59-g8ed1b From 823900cd01301c4720b23afa9f3d08036e07245a Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 13 Feb 2019 16:43:01 +0530 Subject: RISC-V: Free-up initrd in free_initrd_mem() We should free-up initrd memory in free_initrd_mem() instead of doing nothing. Signed-off-by: Anup Patel Reviewed-by: Mike Rapoport --- arch/riscv/mm/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/riscv') diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 9e7b3ee78089..b379a75ac6a6 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -94,8 +94,9 @@ disable: initrd_end = 0; } -void free_initrd_mem(unsigned long start, unsigned long end) +void __init free_initrd_mem(unsigned long start, unsigned long end) { + free_reserved_area((void *)start, (void *)end, -1, "initrd"); } #endif /* CONFIG_BLK_DEV_INITRD */ -- cgit v1.2.3-59-g8ed1b From e15c6e37066e9ce6705f22b71e60ca2d78db8d45 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 22 Feb 2019 11:41:35 -0800 Subject: RISC-V: Do not wait indefinitely in __cpu_up In SMP path, __cpu_up waits for other CPU to come online indefinitely. This is wrong as other CPU might be disabled in machine mode and possible CPU is set to the cpus present in DT. Introduce a completion variable and waits only for a second. Signed-off-by: Atish Patra Reviewed-by: Anup Patel Reviewed-by: Christoph Hellwig Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/smpboot.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 6e2813257e03..d369b669fe04 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -39,6 +39,7 @@ void *__cpu_up_stack_pointer[NR_CPUS]; void *__cpu_up_task_pointer[NR_CPUS]; +static DECLARE_COMPLETION(cpu_running); void __init smp_prepare_boot_cpu(void) { @@ -77,6 +78,7 @@ void __init setup_smp(void) int __cpu_up(unsigned int cpu, struct task_struct *tidle) { + int ret = 0; int hartid = cpuid_to_hartid_map(cpu); tidle->thread_info.cpu = cpu; @@ -92,10 +94,16 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) task_stack_page(tidle) + THREAD_SIZE); WRITE_ONCE(__cpu_up_task_pointer[hartid], tidle); - while (!cpu_online(cpu)) - cpu_relax(); + lockdep_assert_held(&cpu_running); + wait_for_completion_timeout(&cpu_running, + msecs_to_jiffies(1000)); - return 0; + if (!cpu_online(cpu)) { + pr_crit("CPU%u: failed to come online\n", cpu); + ret = -EIO; + } + + return ret; } void __init smp_cpus_done(unsigned int max_cpus) @@ -121,6 +129,7 @@ asmlinkage void __init smp_callin(void) * a local TLB flush right now just in case. */ local_flush_tlb_all(); + complete(&cpu_running); /* * Disable preemption before enabling interrupts, so we don't try to * schedule a CPU that hasn't actually started yet. -- cgit v1.2.3-59-g8ed1b From 78d1daa36489d44ecb97b400e75639e79422de67 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 22 Feb 2019 11:41:36 -0800 Subject: RISC-V: Move cpuid to hartid mapping to SMP. Currently, logical CPU id to physical hartid mapping is defined for both smp and non-smp configurations. This is not required as we need this only for smp configuration. The mapping function can define directly boot_cpu_hartid for non-smp use case. The reverse mapping function i.e. hartid to cpuid can be called for any valid but not booted harts. So it should return default cpu 0 only if it is a boot hartid. Signed-off-by: Atish Patra Reviewed-by: Anup Patel Reviewed-by: Christoph Hellwig Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/smp.h | 18 +++++++++++++----- arch/riscv/kernel/setup.c | 9 --------- arch/riscv/kernel/smp.c | 9 +++++++++ 3 files changed, 22 insertions(+), 14 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h index 41aa73b476f4..636a934f013a 100644 --- a/arch/riscv/include/asm/smp.h +++ b/arch/riscv/include/asm/smp.h @@ -19,16 +19,17 @@ #include #define INVALID_HARTID ULONG_MAX + +struct seq_file; +extern unsigned long boot_cpu_hartid; + +#ifdef CONFIG_SMP /* * Mapping between linux logical cpu index and hartid. */ extern unsigned long __cpuid_to_hartid_map[NR_CPUS]; #define cpuid_to_hartid_map(cpu) __cpuid_to_hartid_map[cpu] -struct seq_file; - -#ifdef CONFIG_SMP - /* print IPI stats */ void show_ipi_stats(struct seq_file *p, int prec); @@ -58,7 +59,14 @@ static inline void show_ipi_stats(struct seq_file *p, int prec) static inline int riscv_hartid_to_cpuid(int hartid) { - return 0; + if (hartid == boot_cpu_hartid) + return 0; + + return -1; +} +static inline unsigned long cpuid_to_hartid_map(int cpu) +{ + return boot_cpu_hartid; } static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in, diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index fb09e0136026..61c8161650ef 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -61,15 +61,6 @@ EXPORT_SYMBOL(empty_zero_page); atomic_t hart_lottery; unsigned long boot_cpu_hartid; -unsigned long __cpuid_to_hartid_map[NR_CPUS] = { - [0 ... NR_CPUS-1] = INVALID_HARTID -}; - -void __init smp_setup_processor_id(void) -{ - cpuid_to_hartid_map(0) = boot_cpu_hartid; -} - #ifdef CONFIG_BLK_DEV_INITRD static void __init setup_initrd(void) { diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index 246635eac7bb..b69883c61f3e 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -36,6 +36,15 @@ enum ipi_message_type { IPI_MAX }; +unsigned long __cpuid_to_hartid_map[NR_CPUS] = { + [0 ... NR_CPUS-1] = INVALID_HARTID +}; + +void __init smp_setup_processor_id(void) +{ + cpuid_to_hartid_map(0) = boot_cpu_hartid; +} + /* A collection of single bit ipi messages. */ static struct { unsigned long stats[IPI_MAX] ____cacheline_aligned; -- cgit v1.2.3-59-g8ed1b From ba15c86185e9017f03b31a0699a0c09d1dc0d41c Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 22 Feb 2019 11:41:37 -0800 Subject: RISC-V: Remove NR_CPUs check during hartid search from DT In non-smp configuration, hartid can be higher that NR_CPUS. riscv_of_processor_hartid should not be compared to hartid to NR_CPUS in that case. Moreover, this function checks all the DT properties of a hart node. NR_CPUS comparison seems out of place. Signed-off-by: Atish Patra Reviewed-by: Christoph Hellwig Reviewed-by: Anup Patel Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/cpu.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index d1d9bfd5a89f..cf2fca12414a 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -34,10 +34,6 @@ int riscv_of_processor_hartid(struct device_node *node) pr_warn("Found CPU without hart ID\n"); return -ENODEV; } - if (hart >= NR_CPUS) { - pr_info("Found hart ID %d, which is above NR_CPUs. Disabling this hart\n", hart); - return -ENODEV; - } if (!of_device_is_available(node)) { pr_info("CPU with hartid=%d is not available\n", hart); -- cgit v1.2.3-59-g8ed1b From dd641e2686734ff78a1dec592ee82054d06bd456 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 22 Feb 2019 11:41:38 -0800 Subject: RISC-V: Allow hartid-to-cpuid function to fail. It is perfectly okay to call riscv_hartid_to_cpuid for a hartid that is not mapped with an CPU id. It can happen if the calling functions retrieves the hartid from DT. However, that hartid was never brought online by the firmware or kernel for any reasons. No need to BUG() in the above case. A negative error return is sufficient and the calling function should check for the return value always. Signed-off-by: Atish Patra Reviewed-by: Anup Patel Reviewed-by: Christoph Hellwig Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/smp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index b69883c61f3e..ca99f0fb49b1 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -60,7 +60,6 @@ int riscv_hartid_to_cpuid(int hartid) return i; pr_err("Couldn't find cpu id for hartid [%d]\n", hartid); - BUG(); return i; } -- cgit v1.2.3-59-g8ed1b From 291debb38dbbce9d5e7c342c5d6dc616f1d9777e Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 22 Feb 2019 11:41:39 -0800 Subject: RISC-V: Compare cpuid with NR_CPUS before mapping. We should never have a cpuid greater that NR_CPUS. Compare with NR_CPUS before creating the mapping between logical and physical CPU ids. This is also mandatory as NR_CPUS check is removed from riscv_of_processor_hartid. Signed-off-by: Atish Patra Reviewed-by: Anup Patel Reviewed-by: Christoph Hellwig Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/smpboot.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index d369b669fe04..eb533b5c2c8c 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -66,6 +66,11 @@ void __init setup_smp(void) found_boot_cpu = 1; continue; } + if (cpuid >= NR_CPUS) { + pr_warn("Invalid cpuid [%d] for hartid [%d]\n", + cpuid, hart); + break; + } cpuid_to_hartid_map(cpuid) = hart; set_cpu_possible(cpuid, true); -- cgit v1.2.3-59-g8ed1b From fbdc6193dc706c863b70accf2006fa00331a7c3f Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Fri, 22 Feb 2019 11:41:40 -0800 Subject: RISC-V: Assign hwcap as per comman capabilities. Currently, we set hwcap based on first valid hart from DT. This may not be correct always as that hart might not be current booting cpu or may have a different capability. Set hwcap as the capabilities supported by all possible harts with "okay" status. Signed-off-by: Atish Patra Reviewed-by: Anup Patel Reviewed-by: Johan Hovold Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/cpufeature.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index e7a4701f0256..bc29b010b722 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -20,6 +20,7 @@ #include #include #include +#include unsigned long elf_hwcap __read_mostly; #ifdef CONFIG_FPU @@ -42,28 +43,30 @@ void riscv_fill_hwcap(void) elf_hwcap = 0; - /* - * We don't support running Linux on hertergenous ISA systems. For - * now, we just check the ISA of the first "okay" processor. - */ for_each_of_cpu_node(node) { - if (riscv_of_processor_hartid(node) >= 0) - break; - } - if (!node) { - pr_warn("Unable to find \"cpu\" devicetree entry\n"); - return; - } + unsigned long this_hwcap = 0; - if (of_property_read_string(node, "riscv,isa", &isa)) { - pr_warn("Unable to find \"riscv,isa\" devicetree entry\n"); - of_node_put(node); - return; - } - of_node_put(node); + if (riscv_of_processor_hartid(node) < 0) + continue; - for (i = 0; i < strlen(isa); ++i) - elf_hwcap |= isa2hwcap[(unsigned char)(isa[i])]; + if (of_property_read_string(node, "riscv,isa", &isa)) { + pr_warn("Unable to find \"riscv,isa\" devicetree entry\n"); + continue; + } + + for (i = 0; i < strlen(isa); ++i) + this_hwcap |= isa2hwcap[(unsigned char)(isa[i])]; + + /* + * All "okay" hart should have same isa. Set HWCAP based on + * common capabilities of every "okay" hart, in case they don't + * have. + */ + if (elf_hwcap) + elf_hwcap &= this_hwcap; + else + elf_hwcap = this_hwcap; + } /* We don't support systems with F but without D, so mask those out * here. */ -- cgit v1.2.3-59-g8ed1b From f7ccc35aa3bd728ad8451f4d06e801cfe5c5498c Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 7 Feb 2019 15:44:26 +0100 Subject: arch: riscv: fix logic error in parse_dtb The function early_init_dt_scan returns true if a DTB was detected. Fixes: 8fd6e05c7463 ("arch: riscv: support kernel command line forcing when no DTB passed") Signed-off-by: Andreas Schwab Reviewed-by: Atish Patra Reviewed-by: Paul Walmsley Tested-by: Paul Walmsley # FU540 HiFive-U BBL Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/riscv') diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 61c8161650ef..12a16df4d422 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -140,7 +140,7 @@ asmlinkage void __init setup_vm(void) void __init parse_dtb(unsigned int hartid, void *dtb) { - if (!early_init_dt_scan(__va(dtb))) + if (early_init_dt_scan(__va(dtb))) return; pr_err("No DTB passed to the kernel\n"); -- cgit v1.2.3-59-g8ed1b