mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2026-01-06 15:44:02 +00:00
Inspired by commit 9fb7410f955("arm64/BUG: Use BRK instruction for
generic BUG traps"), do similar for LoongArch to use generic BUG()
handler.
This patch uses the BREAK software breakpoint instruction to generate
a trap instead, similarly to most other arches, with the generic BUG
code generating the dmesg boilerplate.
This allows bug metadata to be moved to a separate table and reduces
the amount of inline code at BUG() and WARN() sites. This also avoids
clobbering any registers before they can be dumped.
To mitigate the size of the bug table further, this patch makes use of
the existing infrastructure for encoding addresses within the bug table
as 32-bit relative pointers instead of absolute pointers.
(Note: this limits the max kernel size to 2GB.)
Before patch:
[ 3018.338013] lkdtm: Performing direct entry BUG
[ 3018.342445] Kernel bug detected[#5]:
[ 3018.345992] CPU: 2 PID: 865 Comm: cat Tainted: G D 6.0.0-rc6+ #35
After patch:
[ 125.585985] lkdtm: Performing direct entry BUG
[ 125.590433] ------------[ cut here ]------------
[ 125.595020] kernel BUG at drivers/misc/lkdtm/bugs.c:78!
[ 125.600211] Oops - BUG[#1]:
[ 125.602980] CPU: 3 PID: 410 Comm: cat Not tainted 6.0.0-rc6+ #36
Out-of-line file/line data information obtained compared to before.
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
128 lines
2.9 KiB
ArmAsm
128 lines
2.9 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
|
*/
|
|
#include <linux/init.h>
|
|
#include <linux/threads.h>
|
|
|
|
#include <asm/addrspace.h>
|
|
#include <asm/asm.h>
|
|
#include <asm/asmmacro.h>
|
|
#include <asm/bug.h>
|
|
#include <asm/regdef.h>
|
|
#include <asm/loongarch.h>
|
|
#include <asm/stackframe.h>
|
|
|
|
#ifdef CONFIG_EFI_STUB
|
|
|
|
#include "efi-header.S"
|
|
|
|
__HEAD
|
|
|
|
_head:
|
|
.word MZ_MAGIC /* "MZ", MS-DOS header */
|
|
.org 0x3c /* 0x04 ~ 0x3b reserved */
|
|
.long pe_header - _head /* Offset to the PE header */
|
|
|
|
pe_header:
|
|
__EFI_PE_HEADER
|
|
|
|
SYM_DATA(kernel_asize, .long _end - _text);
|
|
SYM_DATA(kernel_fsize, .long _edata - _text);
|
|
SYM_DATA(kernel_offset, .long kernel_offset - _text);
|
|
|
|
#endif
|
|
|
|
__REF
|
|
|
|
.align 12
|
|
|
|
SYM_CODE_START(kernel_entry) # kernel entry point
|
|
|
|
/* Config direct window and set PG */
|
|
li.d t0, CSR_DMW0_INIT # UC, PLV0, 0x8000 xxxx xxxx xxxx
|
|
csrwr t0, LOONGARCH_CSR_DMWIN0
|
|
li.d t0, CSR_DMW1_INIT # CA, PLV0, 0x9000 xxxx xxxx xxxx
|
|
csrwr t0, LOONGARCH_CSR_DMWIN1
|
|
|
|
/* We might not get launched at the address the kernel is linked to,
|
|
so we jump there. */
|
|
la.abs t0, 0f
|
|
jr t0
|
|
0:
|
|
/* Enable PG */
|
|
li.w t0, 0xb0 # PLV=0, IE=0, PG=1
|
|
csrwr t0, LOONGARCH_CSR_CRMD
|
|
li.w t0, 0x04 # PLV=0, PIE=1, PWE=0
|
|
csrwr t0, LOONGARCH_CSR_PRMD
|
|
li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0
|
|
csrwr t0, LOONGARCH_CSR_EUEN
|
|
|
|
la.pcrel t0, __bss_start # clear .bss
|
|
st.d zero, t0, 0
|
|
la.pcrel t1, __bss_stop - LONGSIZE
|
|
1:
|
|
addi.d t0, t0, LONGSIZE
|
|
st.d zero, t0, 0
|
|
bne t0, t1, 1b
|
|
|
|
la.pcrel t0, fw_arg0
|
|
st.d a0, t0, 0 # firmware arguments
|
|
la.pcrel t0, fw_arg1
|
|
st.d a1, t0, 0
|
|
la.pcrel t0, fw_arg2
|
|
st.d a2, t0, 0
|
|
|
|
/* KSave3 used for percpu base, initialized as 0 */
|
|
csrwr zero, PERCPU_BASE_KS
|
|
/* GPR21 used for percpu base (runtime), initialized as 0 */
|
|
move u0, zero
|
|
|
|
la.pcrel tp, init_thread_union
|
|
/* Set the SP after an empty pt_regs. */
|
|
PTR_LI sp, (_THREAD_SIZE - 32 - PT_SIZE)
|
|
PTR_ADD sp, sp, tp
|
|
set_saved_sp sp, t0, t1
|
|
PTR_ADDI sp, sp, -4 * SZREG # init stack pointer
|
|
|
|
bl start_kernel
|
|
ASM_BUG()
|
|
|
|
SYM_CODE_END(kernel_entry)
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
/*
|
|
* SMP slave cpus entry point. Board specific code for bootstrap calls this
|
|
* function after setting up the stack and tp registers.
|
|
*/
|
|
SYM_CODE_START(smpboot_entry)
|
|
li.d t0, CSR_DMW0_INIT # UC, PLV0
|
|
csrwr t0, LOONGARCH_CSR_DMWIN0
|
|
li.d t0, CSR_DMW1_INIT # CA, PLV0
|
|
csrwr t0, LOONGARCH_CSR_DMWIN1
|
|
|
|
la.abs t0, 0f
|
|
jr t0
|
|
0:
|
|
/* Enable PG */
|
|
li.w t0, 0xb0 # PLV=0, IE=0, PG=1
|
|
csrwr t0, LOONGARCH_CSR_CRMD
|
|
li.w t0, 0x04 # PLV=0, PIE=1, PWE=0
|
|
csrwr t0, LOONGARCH_CSR_PRMD
|
|
li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0
|
|
csrwr t0, LOONGARCH_CSR_EUEN
|
|
|
|
la.abs t0, cpuboot_data
|
|
ld.d sp, t0, CPU_BOOT_STACK
|
|
ld.d tp, t0, CPU_BOOT_TINFO
|
|
|
|
bl start_secondary
|
|
ASM_BUG()
|
|
|
|
SYM_CODE_END(smpboot_entry)
|
|
|
|
#endif /* CONFIG_SMP */
|
|
|
|
SYM_ENTRY(kernel_entry_end, SYM_L_GLOBAL, SYM_A_NONE)
|