Unverified Commit 615e705f authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

Merge tag 'riscv-fixes-6.15-rc3' of...

Merge tag 'riscv-fixes-6.15-rc3' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/alexghiti/linux into fixes

riscv fixes for 6.15-rc3

- A couple of fixes regarding module relocations
- Fix a build error by implementing missing alternative macros
- Another fix for kexec by fixing /proc/iomem

* tag 'riscv-fixes-6.15-rc3' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/alexghiti/linux:
  riscv: Avoid fortify warning in syscall_get_arguments()
  riscv: Provide all alternative macros all the time
  riscv: module: Allocate PLT entries for R_RISCV_PLT32
  riscv: module: Fix out-of-bounds relocation access
  riscv: Properly export reserved regions in /proc/iomem
  riscv: Fix unaligned access info messages
parents dc3e30b4 1413708f
Loading
Loading
Loading
Loading
+7 −12
Original line number Diff line number Diff line
@@ -115,24 +115,19 @@
	\old_c
.endm

#define _ALTERNATIVE_CFG(old_c, ...)	\
	ALTERNATIVE_CFG old_c

#define _ALTERNATIVE_CFG_2(old_c, ...)	\
	ALTERNATIVE_CFG old_c
#define __ALTERNATIVE_CFG(old_c, ...)		ALTERNATIVE_CFG old_c
#define __ALTERNATIVE_CFG_2(old_c, ...)		ALTERNATIVE_CFG old_c

#else /* !__ASSEMBLY__ */

#define __ALTERNATIVE_CFG(old_c)	\
	old_c "\n"
#define __ALTERNATIVE_CFG(old_c, ...)		old_c "\n"
#define __ALTERNATIVE_CFG_2(old_c, ...)		old_c "\n"

#define _ALTERNATIVE_CFG(old_c, ...)	\
	__ALTERNATIVE_CFG(old_c)
#endif /* __ASSEMBLY__ */

#define _ALTERNATIVE_CFG_2(old_c, ...)	\
	__ALTERNATIVE_CFG(old_c)
#define _ALTERNATIVE_CFG(old_c, ...)		__ALTERNATIVE_CFG(old_c)
#define _ALTERNATIVE_CFG_2(old_c, ...)		__ALTERNATIVE_CFG_2(old_c)

#endif /* __ASSEMBLY__ */
#endif /* CONFIG_RISCV_ALTERNATIVE */

/*
+7 −6
Original line number Diff line number Diff line
@@ -73,16 +73,17 @@ static bool duplicate_rela(const Elf_Rela *rela, int idx)
static void count_max_entries(Elf_Rela *relas, int num,
			      unsigned int *plts, unsigned int *gots)
{
	unsigned int type, i;

	for (i = 0; i < num; i++) {
		type = ELF_RISCV_R_TYPE(relas[i].r_info);
		if (type == R_RISCV_CALL_PLT) {
	for (int i = 0; i < num; i++) {
		switch (ELF_R_TYPE(relas[i].r_info)) {
		case R_RISCV_CALL_PLT:
		case R_RISCV_PLT32:
			if (!duplicate_rela(relas, i))
				(*plts)++;
		} else if (type == R_RISCV_GOT_HI20) {
			break;
		case R_RISCV_GOT_HI20:
			if (!duplicate_rela(relas, i))
				(*gots)++;
			break;
		}
	}
}
+1 −1
Original line number Diff line number Diff line
@@ -860,7 +860,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
				}

				j++;
				if (j > sechdrs[relsec].sh_size / sizeof(*rel))
				if (j == num_relocations)
					j = 0;

			} while (j_idx != j);
+35 −1
Original line number Diff line number Diff line
@@ -66,6 +66,9 @@ static struct resource bss_res = { .name = "Kernel bss", };
static struct resource elfcorehdr_res = { .name = "ELF Core hdr", };
#endif

static int num_standard_resources;
static struct resource *standard_resources;

static int __init add_resource(struct resource *parent,
				struct resource *res)
{
@@ -139,7 +142,7 @@ static void __init init_resources(void)
	struct resource *res = NULL;
	struct resource *mem_res = NULL;
	size_t mem_res_sz = 0;
	int num_resources = 0, res_idx = 0;
	int num_resources = 0, res_idx = 0, non_resv_res = 0;
	int ret = 0;

	/* + 1 as memblock_alloc() might increase memblock.reserved.cnt */
@@ -193,6 +196,7 @@ static void __init init_resources(void)
	/* Add /memory regions to the resource tree */
	for_each_mem_region(region) {
		res = &mem_res[res_idx--];
		non_resv_res++;

		if (unlikely(memblock_is_nomap(region))) {
			res->name = "Reserved";
@@ -210,6 +214,9 @@ static void __init init_resources(void)
			goto error;
	}

	num_standard_resources = non_resv_res;
	standard_resources = &mem_res[res_idx + 1];

	/* Clean-up any unused pre-allocated resources */
	if (res_idx >= 0)
		memblock_free(mem_res, (res_idx + 1) * sizeof(*mem_res));
@@ -221,6 +228,33 @@ static void __init init_resources(void)
	memblock_free(mem_res, mem_res_sz);
}

static int __init reserve_memblock_reserved_regions(void)
{
	u64 i, j;

	for (i = 0; i < num_standard_resources; i++) {
		struct resource *mem = &standard_resources[i];
		phys_addr_t r_start, r_end, mem_size = resource_size(mem);

		if (!memblock_is_region_reserved(mem->start, mem_size))
			continue;

		for_each_reserved_mem_range(j, &r_start, &r_end) {
			resource_size_t start, end;

			start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start);
			end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end);

			if (start > mem->end || end < mem->start)
				continue;

			reserve_region_with_split(mem, start, end, "Reserved");
		}
	}

	return 0;
}
arch_initcall(reserve_memblock_reserved_regions);

static void __init parse_dtb(void)
{
+21 −14
Original line number Diff line number Diff line
@@ -439,29 +439,36 @@ static int __init check_unaligned_access_all_cpus(void)
{
	int cpu;

	if (unaligned_scalar_speed_param == RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN &&
	    !check_unaligned_access_emulated_all_cpus()) {
		check_unaligned_access_speed_all_cpus();
	} else {
		pr_info("scalar unaligned access speed set to '%s' by command line\n",
			speed_str[unaligned_scalar_speed_param]);
	if (unaligned_scalar_speed_param != RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN) {
		pr_info("scalar unaligned access speed set to '%s' (%lu) by command line\n",
			speed_str[unaligned_scalar_speed_param], unaligned_scalar_speed_param);
		for_each_online_cpu(cpu)
			per_cpu(misaligned_access_speed, cpu) = unaligned_scalar_speed_param;
	} else if (!check_unaligned_access_emulated_all_cpus()) {
		check_unaligned_access_speed_all_cpus();
	}

	if (unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN) {
		if (!has_vector() &&
		    unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED) {
			pr_warn("vector support is not available, ignoring unaligned_vector_speed=%s\n",
				speed_str[unaligned_vector_speed_param]);
		} else {
			pr_info("vector unaligned access speed set to '%s' (%lu) by command line\n",
				speed_str[unaligned_vector_speed_param], unaligned_vector_speed_param);
		}
	}

	if (!has_vector())
		unaligned_vector_speed_param = RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED;

	if (unaligned_vector_speed_param == RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN &&
	    !check_vector_unaligned_access_emulated_all_cpus() &&
	if (unaligned_vector_speed_param != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN) {
		for_each_online_cpu(cpu)
			per_cpu(vector_misaligned_access, cpu) = unaligned_vector_speed_param;
	} else if (!check_vector_unaligned_access_emulated_all_cpus() &&
		   IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) {
		kthread_run(vec_check_unaligned_access_speed_all_cpus,
			    NULL, "vec_check_unaligned_access_speed_all_cpus");
	} else {
		pr_info("vector unaligned access speed set to '%s' by command line\n",
			speed_str[unaligned_vector_speed_param]);
		for_each_online_cpu(cpu)
			per_cpu(vector_misaligned_access, cpu) = unaligned_vector_speed_param;
	}

	/*