diff options
| author | Palmer Dabbelt <palmer@rivosinc.com> | 2025-04-16 11:10:25 -0700 | 
|---|---|---|
| committer | Palmer Dabbelt <palmer@rivosinc.com> | 2025-04-16 11:10:25 -0700 | 
| commit | 615e705fc8c7bdb6816faf09b5b16a0441f050e7 (patch) | |
| tree | d4826f73653020377dec85dce33d4f26171c4ba5 | |
| parent | dc3e30b4992336007c9798e5785b47819c7ef58e (diff) | |
| parent | 1413708f990cb7d025affd706ba9c23e2bfc1a27 (diff) | |
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
| -rw-r--r-- | arch/riscv/include/asm/alternative-macros.h | 19 | ||||
| -rw-r--r-- | arch/riscv/kernel/module-sections.c | 13 | ||||
| -rw-r--r-- | arch/riscv/kernel/module.c | 2 | ||||
| -rw-r--r-- | arch/riscv/kernel/setup.c | 36 | ||||
| -rw-r--r-- | arch/riscv/kernel/unaligned_access_speed.c | 35 | 
5 files changed, 71 insertions, 34 deletions
diff --git a/arch/riscv/include/asm/alternative-macros.h b/arch/riscv/include/asm/alternative-macros.h index 721ec275ce57..231d777d936c 100644 --- a/arch/riscv/include/asm/alternative-macros.h +++ b/arch/riscv/include/asm/alternative-macros.h @@ -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 */  /* diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c index e264e59e596e..91d0b355ceef 100644 --- a/arch/riscv/kernel/module-sections.c +++ b/arch/riscv/kernel/module-sections.c @@ -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;  		}  	}  } diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c index 0ae34d79b87b..7f6147c18033 100644 --- a/arch/riscv/kernel/module.c +++ b/arch/riscv/kernel/module.c @@ -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); diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index c174544eefc8..f7c9a1caa83e 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -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)  { diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c index 585d2dcf2dab..b8ba13819d05 100644 --- a/arch/riscv/kernel/unaligned_access_speed.c +++ b/arch/riscv/kernel/unaligned_access_speed.c @@ -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() && -	    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]); +	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");  	}  	/*  | 
