mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
RISC-V Fixes for 5.17-rc8
* A fix to prevent users from enabling the alternatives framework (and thus errata handling) on XIP kernels, where runtime code patching does not function correctly. * A fix to properly detect offset overflow for AUIPC-based relocations in modules. This may manifest as modules calling arbitrary invalid addresses, depending on the address allocated when a module is loaded. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAmIrfkkTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYib4WD/9C/v+AVqbFQuf4qhXlwlros+3s00/e LYlD79ddDYvU0wvjvUDBx3WLC/tk2dI96VDuPcUNC60T7W1x0K9TmzcR1YqV9efL sx3c7SnV5J1lnmGM+/1EtJWGbYJkSqmH6bk3BvTVCpFGpGd1UcEHu0zMkOq54AIK 5GD3IG7dpKYPpzziIG3T7F96RFn+N4N4cORLAGFXa07TAcQfwJvL2rnAy6YMza6Q NIhpD22sNrKX/9tImwN9YCwZB0G+mrNDLzU8KQAzz1DcBtoWQoEV1b+vRyuubVP+ YSCGO3e1PWMAU3UKzGMYjGPik8WHTqUrst25affV001v1xYEy835K3td+PiDcOfy eHwhhJJOE9TiQ28i1z4F5HsEbT+Sk61Xyf8cXra5y4utlQowIrO5mu4S2GNOi/3Z kbDmUzWHZtQ2yNyz4WlmXxwLWAgx7QeRTax7PvqnMLK/Wxbzy9qgbx1MzjmmaCBI aI3D6CMc3h54MoWidsrBu1Hmx+qm7UqR7ML2jcEI3LqBB+lIYHNJh/d/Brg/lyTh 5V/ncrILYalT0qd2zDSODzYYKFm2EucrneJNiJr720McFc54V2ZzLKOWg4gLdBUl KJypYoGw2fDbpVqmlN6/oSCWI1RETq6u5kOiCPBaXz/2sKz6aT3xq5m5wXynQAZi NzOHZEqS9GYAQQ== =qUfT -----END PGP SIGNATURE----- Merge tag 'riscv-for-linus-5.17-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux Pull RISC-V fixes from Palmer Dabbelt: - prevent users from enabling the alternatives framework (and thus errata handling) on XIP kernels, where runtime code patching does not function correctly. - properly detect offset overflow for AUIPC-based relocations in modules. This may manifest as modules calling arbitrary invalid addresses, depending on the address allocated when a module is loaded. * tag 'riscv-for-linus-5.17-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: riscv: Fix auipc+jalr relocation range checks riscv: alternative only works on !XIP_KERNEL
This commit is contained in:
commit
77fe1ba902
@ -2,6 +2,7 @@ menu "CPU errata selection"
|
||||
|
||||
config RISCV_ERRATA_ALTERNATIVE
|
||||
bool "RISC-V alternative scheme"
|
||||
depends on !XIP_KERNEL
|
||||
default y
|
||||
help
|
||||
This Kconfig allows the kernel to automatically patch the
|
||||
|
@ -14,8 +14,8 @@ config SOC_SIFIVE
|
||||
select CLK_SIFIVE
|
||||
select CLK_SIFIVE_PRCI
|
||||
select SIFIVE_PLIC
|
||||
select RISCV_ERRATA_ALTERNATIVE
|
||||
select ERRATA_SIFIVE
|
||||
select RISCV_ERRATA_ALTERNATIVE if !XIP_KERNEL
|
||||
select ERRATA_SIFIVE if !XIP_KERNEL
|
||||
help
|
||||
This enables support for SiFive SoC platform hardware.
|
||||
|
||||
|
@ -13,6 +13,19 @@
|
||||
#include <linux/pgtable.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
/*
|
||||
* The auipc+jalr instruction pair can reach any PC-relative offset
|
||||
* in the range [-2^31 - 2^11, 2^31 - 2^11)
|
||||
*/
|
||||
static bool riscv_insn_valid_32bit_offset(ptrdiff_t val)
|
||||
{
|
||||
#ifdef CONFIG_32BIT
|
||||
return true;
|
||||
#else
|
||||
return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
|
||||
{
|
||||
if (v != (u32)v) {
|
||||
@ -95,7 +108,7 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
|
||||
ptrdiff_t offset = (void *)v - (void *)location;
|
||||
s32 hi20;
|
||||
|
||||
if (offset != (s32)offset) {
|
||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||
pr_err(
|
||||
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
|
||||
me->name, (long long)v, location);
|
||||
@ -197,10 +210,9 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
|
||||
Elf_Addr v)
|
||||
{
|
||||
ptrdiff_t offset = (void *)v - (void *)location;
|
||||
s32 fill_v = offset;
|
||||
u32 hi20, lo12;
|
||||
|
||||
if (offset != fill_v) {
|
||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||
/* Only emit the plt entry if offset over 32-bit range */
|
||||
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
|
||||
offset = module_emit_plt_entry(me, v);
|
||||
@ -224,10 +236,9 @@ static int apply_r_riscv_call_rela(struct module *me, u32 *location,
|
||||
Elf_Addr v)
|
||||
{
|
||||
ptrdiff_t offset = (void *)v - (void *)location;
|
||||
s32 fill_v = offset;
|
||||
u32 hi20, lo12;
|
||||
|
||||
if (offset != fill_v) {
|
||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||
pr_err(
|
||||
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
|
||||
me->name, (long long)v, location);
|
||||
|
Loading…
Reference in New Issue
Block a user