RISC-V Fixes for 6.15-rc3

* A fix for an issue where C instructions ended up in non-C builds, do
   to some broken inline assembly in the KGDB breakpoint insertion code.
 * A fix to avoid spurious printk messages about misaligned access
   performance probing.
 * A fix for a handful of issues with /proc/iomem's reserved region
   handling.
 * A pair of fixes for module relocation processing.
 * A few build-time fixes.
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCAAxFiEEAM520YNJYN/OiG3470yhUCzLq0EFAmgCjYcTHHBhbG1lckBk
 YWJiZWx0LmNvbQAKCRDvTKFQLMurQUA6EACSoPJmejuLlUVQxeXkpt+3mJMrjNMZ
 AzpdkAQc01HJ65ANBEUKngkJw7srtG47EGfspYbu1bI2NcOJ70v57azUiR0X5mbo
 p26NEOrVP2tiXSVFMJ4Mox7k2ij8xmXTORldbtm8/Lt5Zu+2+3VDEV0hQD/Yg7YY
 wn0E7e0GRzH9pzBSpMQN7LGMVM0zrkTKvbLsXqi/Z+tU2g2uXTuK55RFr3+/CB0k
 eTQfUZC7OByPbAxSejclZgQkYvL9hxk3bTLPc9QGSdZNCDdN6sfIxOzkI3061gQ1
 /hNlbOcGmSQGJu3wRKHwqsWYUQGRo1xIBpQC4MHJmE9v6vPNoZFAEqR7TOggeDn2
 TrIX/WEBv+Y5EylMY1xox3ci92k3CkWFyDFhOGQbFs8JJvI806GeEL2vEeHDLH3A
 ML5XHa9T3NnGpk1lM6qkkFrvfigSLhLo8iOyxgXRnWkr0FsUQ1RhZlUqe8mhL4IG
 uqpR3QEhxbZvjVFw8nlN/JiQMwh7pTozweS0+yuKJgDVwMcwSTX/YIs6wJrY1Gjv
 nUbKRX7pZjfwt6VBlIs6Rcd3L4sOzgL0V367lwFs7S7KGZ2N3/x2qknNq0opA4MY
 KuGTwVsDwyrBkrC12LhqmwEeAOx8PcRxqB1CGScKlC3CbIf9C3MLlw45CQ4SS04X
 Dufi6Rt7rGQszQ==
 =Jo59
 -----END PGP SIGNATURE-----

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

Pull RISC-V fixes from Palmer Dabbelt:

 - A fix for an issue where C instructions ended up in non-C builds, due
   to some broken inline assembly in the KGDB breakpoint insertion code

 - A fix to avoid spurious printk messages about misaligned access
   performance probing

 - A fix for a handful of issues with /proc/iomem's reserved region
   handling

 - A pair of fixes for module relocation processing

 - A few build-time fixes

* tag 'riscv-for-linus-6.15-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  riscv: KGDB: Remove ".option norvc/.option rvc" for kgdb_compiled_break
  riscv: KGDB: Do not inline arch_kgdb_breakpoint()
  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
  riscv: Avoid fortify warning in syscall_get_arguments()
  Documentation: riscv: Fix typo MIMPLID -> MIMPID
  riscv: Use kvmalloc_array on relocation_hashtable
This commit is contained in:
Linus Torvalds 2025-04-18 11:46:44 -07:00
commit 4b828867b3
9 changed files with 90 additions and 50 deletions

View File

@ -51,7 +51,7 @@ The following keys are defined:
* :c:macro:`RISCV_HWPROBE_KEY_MARCHID`: Contains the value of ``marchid``, as
defined by the RISC-V privileged architecture specification.
* :c:macro:`RISCV_HWPROBE_KEY_MIMPLID`: Contains the value of ``mimplid``, as
* :c:macro:`RISCV_HWPROBE_KEY_MIMPID`: Contains the value of ``mimpid``, as
defined by the RISC-V privileged architecture specification.
* :c:macro:`RISCV_HWPROBE_KEY_BASE_BEHAVIOR`: A bitmask containing the base

View File

@ -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, ...) \
__ALTERNATIVE_CFG(old_c)
#define _ALTERNATIVE_CFG_2(old_c, ...) \
__ALTERNATIVE_CFG(old_c)
#define __ALTERNATIVE_CFG(old_c, ...) old_c "\n"
#define __ALTERNATIVE_CFG_2(old_c, ...) old_c "\n"
#endif /* __ASSEMBLY__ */
#define _ALTERNATIVE_CFG(old_c, ...) __ALTERNATIVE_CFG(old_c)
#define _ALTERNATIVE_CFG_2(old_c, ...) __ALTERNATIVE_CFG_2(old_c)
#endif /* CONFIG_RISCV_ALTERNATIVE */
/*

View File

@ -19,16 +19,9 @@
#ifndef __ASSEMBLY__
void arch_kgdb_breakpoint(void);
extern unsigned long kgdb_compiled_break;
static inline void arch_kgdb_breakpoint(void)
{
asm(".global kgdb_compiled_break\n"
".option norvc\n"
"kgdb_compiled_break: ebreak\n"
".option rvc\n");
}
#endif /* !__ASSEMBLY__ */
#define DBG_REG_ZERO "zero"

View File

@ -62,8 +62,11 @@ static inline void syscall_get_arguments(struct task_struct *task,
unsigned long *args)
{
args[0] = regs->orig_a0;
args++;
memcpy(args, &regs->a1, 5 * sizeof(args[0]));
args[1] = regs->a1;
args[2] = regs->a2;
args[3] = regs->a3;
args[4] = regs->a4;
args[5] = regs->a5;
}
static inline int syscall_get_arch(struct task_struct *task)

View File

@ -254,6 +254,12 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
regs->epc = pc;
}
noinline void arch_kgdb_breakpoint(void)
{
asm(".global kgdb_compiled_break\n"
"kgdb_compiled_break: ebreak\n");
}
void kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer,
char *remcom_out_buffer)
{

View File

@ -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;
}
}
}

View File

@ -648,7 +648,7 @@ process_accumulated_relocations(struct module *me,
kfree(bucket_iter);
}
kfree(*relocation_hashtable);
kvfree(*relocation_hashtable);
}
static int add_relocation_to_accumulate(struct module *me, int type,
@ -752,9 +752,10 @@ initialize_relocation_hashtable(unsigned int num_relocations,
hashtable_size <<= should_double_size;
*relocation_hashtable = kmalloc_array(hashtable_size,
sizeof(**relocation_hashtable),
GFP_KERNEL);
/* Number of relocations may be large, so kvmalloc it */
*relocation_hashtable = kvmalloc_array(hashtable_size,
sizeof(**relocation_hashtable),
GFP_KERNEL);
if (!*relocation_hashtable)
return 0;
@ -859,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);

View File

@ -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)
{

View File

@ -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");
}
/*