mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
e01d48c699
The out-of-bounds access is reported by UBSAN:
[ 0.000000] UBSAN: array-index-out-of-bounds in ../arch/riscv/kernel/vendor_extensions.c:41:66
[ 0.000000] index -1 is out of range for type 'riscv_isavendorinfo [32]'
[ 0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.11.0-rc2ubuntu-defconfig #2
[ 0.000000] Hardware name: riscv-virtio,qemu (DT)
[ 0.000000] Call Trace:
[ 0.000000] [<ffffffff94e078ba>] dump_backtrace+0x32/0x40
[ 0.000000] [<ffffffff95c83c1a>] show_stack+0x38/0x44
[ 0.000000] [<ffffffff95c94614>] dump_stack_lvl+0x70/0x9c
[ 0.000000] [<ffffffff95c94658>] dump_stack+0x18/0x20
[ 0.000000] [<ffffffff95c8bbb2>] ubsan_epilogue+0x10/0x46
[ 0.000000] [<ffffffff95485a82>] __ubsan_handle_out_of_bounds+0x94/0x9c
[ 0.000000] [<ffffffff94e09442>] __riscv_isa_vendor_extension_available+0x90/0x92
[ 0.000000] [<ffffffff94e043b6>] riscv_cpufeature_patch_func+0xc4/0x148
[ 0.000000] [<ffffffff94e035f8>] _apply_alternatives+0x42/0x50
[ 0.000000] [<ffffffff95e04196>] apply_boot_alternatives+0x3c/0x100
[ 0.000000] [<ffffffff95e05b52>] setup_arch+0x85a/0x8bc
[ 0.000000] [<ffffffff95e00ca0>] start_kernel+0xa4/0xfb6
The dereferencing using cpu should actually not happen, so remove it.
Fixes: 23c996fc2b
("riscv: Extend cpufeature.c to detect vendor extensions")
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Link: https://lore.kernel.org/r/20240814192619.276794-1-alexghiti@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
57 lines
1.5 KiB
C
57 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright 2024 Rivos, Inc
|
|
*/
|
|
|
|
#include <asm/vendorid_list.h>
|
|
#include <asm/vendor_extensions.h>
|
|
#include <asm/vendor_extensions/andes.h>
|
|
|
|
#include <linux/array_size.h>
|
|
#include <linux/types.h>
|
|
|
|
struct riscv_isa_vendor_ext_data_list *riscv_isa_vendor_ext_list[] = {
|
|
#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_ANDES
|
|
&riscv_isa_vendor_ext_list_andes,
|
|
#endif
|
|
};
|
|
|
|
const size_t riscv_isa_vendor_ext_list_size = ARRAY_SIZE(riscv_isa_vendor_ext_list);
|
|
|
|
/**
|
|
* __riscv_isa_vendor_extension_available() - Check whether given vendor
|
|
* extension is available or not.
|
|
*
|
|
* @cpu: check if extension is available on this cpu
|
|
* @vendor: vendor that the extension is a member of
|
|
* @bit: bit position of the desired extension
|
|
* Return: true or false
|
|
*
|
|
* NOTE: When cpu is -1, will check if extension is available on all cpus
|
|
*/
|
|
bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsigned int bit)
|
|
{
|
|
struct riscv_isavendorinfo *bmap;
|
|
struct riscv_isavendorinfo *cpu_bmap;
|
|
|
|
switch (vendor) {
|
|
#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_ANDES
|
|
case ANDES_VENDOR_ID:
|
|
bmap = &riscv_isa_vendor_ext_list_andes.all_harts_isa_bitmap;
|
|
cpu_bmap = riscv_isa_vendor_ext_list_andes.per_hart_isa_bitmap;
|
|
break;
|
|
#endif
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
if (cpu != -1)
|
|
bmap = &cpu_bmap[cpu];
|
|
|
|
if (bit >= RISCV_ISA_VENDOR_EXT_MAX)
|
|
return false;
|
|
|
|
return test_bit(bit, bmap->isa) ? true : false;
|
|
}
|
|
EXPORT_SYMBOL_GPL(__riscv_isa_vendor_extension_available);
|