riscv: remove usage of function-pointers from cpufeatures and t-head errata
authorHeiko Stuebner <heiko@sntech.de>
Thu, 26 May 2022 20:56:46 +0000 (22:56 +0200)
committerPalmer Dabbelt <palmer@rivosinc.com>
Thu, 16 Jun 2022 22:47:41 +0000 (15:47 -0700)
commit1771c8c9e65a20128f93df107353a5f4cb91546a
treedcc85313ae3d46db31358c07a1fcff9513804287
parentb684001a5eb79d9bf36f655547bc226dedc8bc03
riscv: remove usage of function-pointers from cpufeatures and t-head errata

Having a list of alternatives to check with a per-entry function pointer
to a check function is nice style-wise. But in case of early-alternatives
it can clash with the non-relocated kernel and the function pointer in
the list pointing to a completely wrong location.

This isn't an issue with one or two list entries, as in that case the
compiler seems to unroll the loop and even usage of the list structure
and then only does relative jumps into the check functions based on this.

When adding a third entry to either list though, the issue that was
hiding there from the beginning is triggered resulting a jump to a
memory address that isn't part of the kernel at all.

The list of features/erratas only contained an unused name and the
pointer to the check function, so an easy solution for the problem
is to just unroll the loop in code, dismantle the whole list structure
and just call the relevant check functions one by one ourself.

For the T-Head errata this includes moving the stage-check inside
the check functions.

The issue is only relevant for things that might be called for early-
alternatives (T-Head and possible future main extensions), so the
SiFive erratas were not affected from the beginning, as they got
an early return for early-alternatives in the original patchset.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Samuel Holland <samuel@sholland.org>
Link: https://lore.kernel.org/r/20220526205646.258337-6-heiko@sntech.de
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/errata/thead/errata.c
arch/riscv/kernel/cpufeature.c