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

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
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -50,6 +50,12 @@ riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
riscv-march-$(CONFIG_ARCH_RV64I)	:= rv64ima
riscv-march-$(CONFIG_FPU)		:= $(riscv-march-y)fd
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_AFLAGS += -march=$(riscv-march-y)

+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/sched/hotplug.h>
#include <asm/irq.h>
#include <asm/cpu_ops.h>
#include <asm/numa.h>
#include <asm/sbi.h>

bool cpu_has_hotplug(unsigned int cpu)
@@ -40,6 +41,7 @@ int __cpu_disable(void)
		return ret;

	remove_cpu_topology(cpu);
	numa_remove_cpu(cpu);
	set_cpu_online(cpu, false);
	irq_migrate_all_off_this_cpu();

+5 −6
Original line number Diff line number Diff line
@@ -22,14 +22,13 @@
	add \reg, \reg, t0
.endm
.macro XIP_FIXUP_FLASH_OFFSET reg
	la t1, __data_loc
	li t0, XIP_OFFSET_MASK
	and t1, t1, t0
	li t1, XIP_OFFSET
	sub t0, t0, t1
	sub \reg, \reg, t0
	la t0, __data_loc
	REG_L t1, _xip_phys_offset
	sub \reg, \reg, t1
	add \reg, \reg, t0
.endm
_xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET
_xip_phys_offset: .dword CONFIG_XIP_PHYS_ADDR + XIP_OFFSET
#else
.macro XIP_FIXUP_OFFSET reg
.endm
+5 −4
Original line number Diff line number Diff line
@@ -22,15 +22,16 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
			     bool (*fn)(void *, unsigned long), void *arg)
{
	unsigned long fp, sp, pc;
	int level = 0;

	if (regs) {
		fp = frame_pointer(regs);
		sp = user_stack_pointer(regs);
		pc = instruction_pointer(regs);
	} else if (task == NULL || task == current) {
		fp = (unsigned long)__builtin_frame_address(1);
		sp = (unsigned long)__builtin_frame_address(0);
		pc = (unsigned long)__builtin_return_address(0);
		fp = (unsigned long)__builtin_frame_address(0);
		sp = sp_in_global;
		pc = (unsigned long)walk_stackframe;
	} else {
		/* task blocked in __switch_to */
		fp = task->thread.s[0];
@@ -42,7 +43,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
		unsigned long low, high;
		struct stackframe *frame;

		if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
		if (unlikely(!__kernel_text_address(pc) || (level++ >= 1 && !fn(arg, pc))))
			break;

		/* Validate frame pointer */
+3 −3
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset,
	if (unlikely(offset > MAX_REG_OFFSET))
		return;

	if (!offset)
	if (offset)
		*(unsigned long *)((unsigned long)regs + offset) = val;
}

@@ -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_zero = FIELD_GET(EX_DATA_REG_ZERO, ex->data);

	regs_set_gpr(regs, reg_err, -EFAULT);
	regs_set_gpr(regs, reg_zero, 0);
	regs_set_gpr(regs, reg_err * sizeof(unsigned long), -EFAULT);
	regs_set_gpr(regs, reg_zero * sizeof(unsigned long), 0);

	regs->epc = get_ex_fixup(ex);
	return true;
Loading