mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
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:
commit
4b828867b3
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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"
|
||||
|
@ -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, ®s->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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user