mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
26e7aacb83
Add 2 early command line parameters that allow to downgrade satp mode (using the same naming as x86): - "no5lvl": use a 4-level page table (down from sv57 to sv48) - "no4lvl": use a 3-level page table (down from sv57/sv48 to sv39) Note that going through the device tree to get the kernel command line works with ACPI too since the efi stub creates a device tree anyway with the command line. In KASAN kernels, we can't use the libfdt that early in the boot process since we are not ready to execute instrumented functions. So instead of using the "generic" libfdt, we compile our own versions of those functions that are not instrumented and that are prefixed so that they do not conflict with the generic ones. We also need the non-instrumented versions of the string functions and the prefixed versions of memcpy/memmove. This is largely inspired by commitaacd149b62
("arm64: head: avoid relocating the kernel twice for KASLR") from which I removed compilation flags that were not relevant to RISC-V at the moment (LTO, SCS). Also note that we have to link with -z norelro to avoid ld.lld to throw a warning with the new .got sections, like in commit311bea3cb9
("arm64: link with -z norelro for LLD or aarch64-elf"). Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com> Tested-by: Björn Töpel <bjorn@rivosinc.com> Reviewed-by: Björn Töpel <bjorn@rivosinc.com> Link: https://lore.kernel.org/r/20230424092313.178699-2-alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
134 lines
2.2 KiB
ArmAsm
134 lines
2.2 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#include <linux/linkage.h>
|
|
#include <asm/asm.h>
|
|
#include <asm/alternative-macros.h>
|
|
#include <asm/hwcap.h>
|
|
|
|
/* int strlen(const char *s) */
|
|
SYM_FUNC_START(strlen)
|
|
|
|
ALTERNATIVE("nop", "j strlen_zbb", 0, RISCV_ISA_EXT_ZBB, CONFIG_RISCV_ISA_ZBB)
|
|
|
|
/*
|
|
* Returns
|
|
* a0 - string length
|
|
*
|
|
* Parameters
|
|
* a0 - String to measure
|
|
*
|
|
* Clobbers:
|
|
* t0, t1
|
|
*/
|
|
mv t1, a0
|
|
1:
|
|
lbu t0, 0(t1)
|
|
beqz t0, 2f
|
|
addi t1, t1, 1
|
|
j 1b
|
|
2:
|
|
sub a0, t1, a0
|
|
ret
|
|
|
|
/*
|
|
* Variant of strlen using the ZBB extension if available
|
|
*/
|
|
#ifdef CONFIG_RISCV_ISA_ZBB
|
|
strlen_zbb:
|
|
|
|
#ifdef CONFIG_CPU_BIG_ENDIAN
|
|
# define CZ clz
|
|
# define SHIFT sll
|
|
#else
|
|
# define CZ ctz
|
|
# define SHIFT srl
|
|
#endif
|
|
|
|
.option push
|
|
.option arch,+zbb
|
|
|
|
/*
|
|
* Returns
|
|
* a0 - string length
|
|
*
|
|
* Parameters
|
|
* a0 - String to measure
|
|
*
|
|
* Clobbers
|
|
* t0, t1, t2, t3
|
|
*/
|
|
|
|
/* Number of irrelevant bytes in the first word. */
|
|
andi t2, a0, SZREG-1
|
|
|
|
/* Align pointer. */
|
|
andi t0, a0, -SZREG
|
|
|
|
li t3, SZREG
|
|
sub t3, t3, t2
|
|
slli t2, t2, 3
|
|
|
|
/* Get the first word. */
|
|
REG_L t1, 0(t0)
|
|
|
|
/*
|
|
* Shift away the partial data we loaded to remove the irrelevant bytes
|
|
* preceding the string with the effect of adding NUL bytes at the
|
|
* end of the string's first word.
|
|
*/
|
|
SHIFT t1, t1, t2
|
|
|
|
/* Convert non-NUL into 0xff and NUL into 0x00. */
|
|
orc.b t1, t1
|
|
|
|
/* Convert non-NUL into 0x00 and NUL into 0xff. */
|
|
not t1, t1
|
|
|
|
/*
|
|
* Search for the first set bit (corresponding to a NUL byte in the
|
|
* original chunk).
|
|
*/
|
|
CZ t1, t1
|
|
|
|
/*
|
|
* The first chunk is special: compare against the number
|
|
* of valid bytes in this chunk.
|
|
*/
|
|
srli a0, t1, 3
|
|
bgtu t3, a0, 2f
|
|
|
|
/* Prepare for the word comparison loop. */
|
|
addi t2, t0, SZREG
|
|
li t3, -1
|
|
|
|
/*
|
|
* Our critical loop is 4 instructions and processes data in
|
|
* 4 byte or 8 byte chunks.
|
|
*/
|
|
.p2align 3
|
|
1:
|
|
REG_L t1, SZREG(t0)
|
|
addi t0, t0, SZREG
|
|
orc.b t1, t1
|
|
beq t1, t3, 1b
|
|
|
|
not t1, t1
|
|
CZ t1, t1
|
|
srli t1, t1, 3
|
|
|
|
/* Get number of processed bytes. */
|
|
sub t2, t0, t2
|
|
|
|
/* Add number of characters in the first word. */
|
|
add a0, a0, t2
|
|
|
|
/* Add number of characters in the last word. */
|
|
add a0, a0, t1
|
|
2:
|
|
ret
|
|
|
|
.option pop
|
|
#endif
|
|
SYM_FUNC_END(strlen)
|
|
SYM_FUNC_ALIAS(__pi_strlen, strlen)
|