Commit 1d41d2e8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'riscv-for-linus-5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V fixes from Palmer Dabbelt:

 - A fix to avoid undefined behavior when stack backtracing, which
   manifests in GCC as incorrect stack addresses

 - A few fixes for the XIP kernels

 - A fix to tracking NUMA state on CPU hotplug

 - Support for the recently relesaed binutils-2.38, which changed the
   default ISA version to one without CSRs or fence.i in 'I' extension

* tag 'riscv-for-linus-5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  riscv: fix build with binutils 2.38
  riscv: cpu-hotplug: clear cpu from numa map when teardown
  riscv: extable: fix err reg writing in dedicated uaccess handler
  riscv/mm: Add XIP_FIXUP for riscv_pfn_base
  riscv/mm: Add XIP_FIXUP for phys_ram_base
  riscv: Fix XIP_FIXUP_FLASH_OFFSET
  riscv: eliminate unreliable __builtin_frame_address(1)
parents e47ca403 6df2a016
...@@ -50,6 +50,12 @@ riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima ...@@ -50,6 +50,12 @@ riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima
riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
# Newer binutils versions default to ISA spec version 20191213 which moves some
# instructions from the I extension to the Zicsr and Zifencei extensions.
toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei)
riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y)) KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
KBUILD_AFLAGS += -march=$(riscv-march-y) KBUILD_AFLAGS += -march=$(riscv-march-y)
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/sched/hotplug.h> #include <linux/sched/hotplug.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/cpu_ops.h> #include <asm/cpu_ops.h>
#include <asm/numa.h>
#include <asm/sbi.h> #include <asm/sbi.h>
bool cpu_has_hotplug(unsigned int cpu) bool cpu_has_hotplug(unsigned int cpu)
...@@ -40,6 +41,7 @@ int __cpu_disable(void) ...@@ -40,6 +41,7 @@ int __cpu_disable(void)
return ret; return ret;
remove_cpu_topology(cpu); remove_cpu_topology(cpu);
numa_remove_cpu(cpu);
set_cpu_online(cpu, false); set_cpu_online(cpu, false);
irq_migrate_all_off_this_cpu(); irq_migrate_all_off_this_cpu();
......
...@@ -22,14 +22,13 @@ ...@@ -22,14 +22,13 @@
add \reg, \reg, t0 add \reg, \reg, t0
.endm .endm
.macro XIP_FIXUP_FLASH_OFFSET reg .macro XIP_FIXUP_FLASH_OFFSET reg
la t1, __data_loc la t0, __data_loc
li t0, XIP_OFFSET_MASK REG_L t1, _xip_phys_offset
and t1, t1, t0 sub \reg, \reg, t1
li t1, XIP_OFFSET add \reg, \reg, t0
sub t0, t0, t1
sub \reg, \reg, t0
.endm .endm
_xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET _xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET
_xip_phys_offset: .dword CONFIG_XIP_PHYS_ADDR + XIP_OFFSET
#else #else
.macro XIP_FIXUP_OFFSET reg .macro XIP_FIXUP_OFFSET reg
.endm .endm
......
...@@ -22,15 +22,16 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, ...@@ -22,15 +22,16 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
bool (*fn)(void *, unsigned long), void *arg) bool (*fn)(void *, unsigned long), void *arg)
{ {
unsigned long fp, sp, pc; unsigned long fp, sp, pc;
int level = 0;
if (regs) { if (regs) {
fp = frame_pointer(regs); fp = frame_pointer(regs);
sp = user_stack_pointer(regs); sp = user_stack_pointer(regs);
pc = instruction_pointer(regs); pc = instruction_pointer(regs);
} else if (task == NULL || task == current) { } else if (task == NULL || task == current) {
fp = (unsigned long)__builtin_frame_address(1); fp = (unsigned long)__builtin_frame_address(0);
sp = (unsigned long)__builtin_frame_address(0); sp = sp_in_global;
pc = (unsigned long)__builtin_return_address(0); pc = (unsigned long)walk_stackframe;
} else { } else {
/* task blocked in __switch_to */ /* task blocked in __switch_to */
fp = task->thread.s[0]; fp = task->thread.s[0];
...@@ -42,7 +43,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, ...@@ -42,7 +43,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
unsigned long low, high; unsigned long low, high;
struct stackframe *frame; struct stackframe *frame;
if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc))) if (unlikely(!__kernel_text_address(pc) || (level++ >= 1 && !fn(arg, pc))))
break; break;
/* Validate frame pointer */ /* Validate frame pointer */
......
...@@ -33,7 +33,7 @@ static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset, ...@@ -33,7 +33,7 @@ static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset,
if (unlikely(offset > MAX_REG_OFFSET)) if (unlikely(offset > MAX_REG_OFFSET))
return; return;
if (!offset) if (offset)
*(unsigned long *)((unsigned long)regs + offset) = val; *(unsigned long *)((unsigned long)regs + offset) = val;
} }
...@@ -43,8 +43,8 @@ static bool ex_handler_uaccess_err_zero(const struct exception_table_entry *ex, ...@@ -43,8 +43,8 @@ static bool ex_handler_uaccess_err_zero(const struct exception_table_entry *ex,
int reg_err = FIELD_GET(EX_DATA_REG_ERR, ex->data); int reg_err = FIELD_GET(EX_DATA_REG_ERR, ex->data);
int reg_zero = FIELD_GET(EX_DATA_REG_ZERO, ex->data); int reg_zero = FIELD_GET(EX_DATA_REG_ZERO, ex->data);
regs_set_gpr(regs, reg_err, -EFAULT); regs_set_gpr(regs, reg_err * sizeof(unsigned long), -EFAULT);
regs_set_gpr(regs, reg_zero, 0); regs_set_gpr(regs, reg_zero * sizeof(unsigned long), 0);
regs->epc = get_ex_fixup(ex); regs->epc = get_ex_fixup(ex);
return true; return true;
......
...@@ -232,6 +232,7 @@ static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAG ...@@ -232,6 +232,7 @@ static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAG
#ifdef CONFIG_XIP_KERNEL #ifdef CONFIG_XIP_KERNEL
#define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops)) #define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops))
#define riscv_pfn_base (*(unsigned long *)XIP_FIXUP(&riscv_pfn_base))
#define trampoline_pg_dir ((pgd_t *)XIP_FIXUP(trampoline_pg_dir)) #define trampoline_pg_dir ((pgd_t *)XIP_FIXUP(trampoline_pg_dir))
#define fixmap_pte ((pte_t *)XIP_FIXUP(fixmap_pte)) #define fixmap_pte ((pte_t *)XIP_FIXUP(fixmap_pte))
#define early_pg_dir ((pgd_t *)XIP_FIXUP(early_pg_dir)) #define early_pg_dir ((pgd_t *)XIP_FIXUP(early_pg_dir))
...@@ -522,6 +523,7 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size) ...@@ -522,6 +523,7 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size)
} }
#ifdef CONFIG_XIP_KERNEL #ifdef CONFIG_XIP_KERNEL
#define phys_ram_base (*(phys_addr_t *)XIP_FIXUP(&phys_ram_base))
extern char _xiprom[], _exiprom[], __data_loc; extern char _xiprom[], _exiprom[], __data_loc;
/* called from head.S with MMU off */ /* called from head.S with MMU off */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment