mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 04:23:35 +02:00
LoongArch: Adjust process management for 32BIT/64BIT
Adjust process management for both 32BIT and 64BIT, including: CPU context switching, FPU loading/restoring, process dumping and process tracing routines. Q: Why modify switch.S? A: LoongArch32 has no ldptr.d/stptr.d instructions, and asm offsets of thead_struct members are too large to be filled in the 12b immediate field of ld.w/st.w. Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
This commit is contained in:
parent
dd55dd0d7e
commit
4ad04e7c7e
|
|
@ -120,6 +120,36 @@
|
|||
#define R_LARCH_ADD_ULEB128 107
|
||||
#define R_LARCH_SUB_ULEB128 108
|
||||
#define R_LARCH_64_PCREL 109
|
||||
#define R_LARCH_CALL36 110
|
||||
#define R_LARCH_TLS_DESC_PC_HI20 111
|
||||
#define R_LARCH_TLS_DESC_PC_LO12 112
|
||||
#define R_LARCH_TLS_DESC64_PC_LO20 113
|
||||
#define R_LARCH_TLS_DESC64_PC_HI12 114
|
||||
#define R_LARCH_TLS_DESC_HI20 115
|
||||
#define R_LARCH_TLS_DESC_LO12 116
|
||||
#define R_LARCH_TLS_DESC64_LO20 117
|
||||
#define R_LARCH_TLS_DESC64_HI12 118
|
||||
#define R_LARCH_TLS_DESC_LD 119
|
||||
#define R_LARCH_TLS_DESC_CALL 120
|
||||
#define R_LARCH_TLS_LE_HI20_R 121
|
||||
#define R_LARCH_TLS_LE_ADD_R 122
|
||||
#define R_LARCH_TLS_LE_LO12_R 123
|
||||
#define R_LARCH_TLS_LD_PCREL20_S2 124
|
||||
#define R_LARCH_TLS_GD_PCREL20_S2 125
|
||||
#define R_LARCH_TLS_DESC_PCREL20_S2 126
|
||||
#define R_LARCH_CALL30 127
|
||||
#define R_LARCH_PCADD_HI20 128
|
||||
#define R_LARCH_PCADD_LO12 129
|
||||
#define R_LARCH_GOT_PCADD_HI20 130
|
||||
#define R_LARCH_GOT_PCADD_LO12 131
|
||||
#define R_LARCH_TLS_IE_PCADD_HI20 132
|
||||
#define R_LARCH_TLS_IE_PCADD_LO12 133
|
||||
#define R_LARCH_TLS_LD_PCADD_HI20 134
|
||||
#define R_LARCH_TLS_LD_PCADD_LO12 135
|
||||
#define R_LARCH_TLS_GD_PCADD_HI20 136
|
||||
#define R_LARCH_TLS_GD_PCADD_LO12 137
|
||||
#define R_LARCH_TLS_DESC_PCADD_HI20 138
|
||||
#define R_LARCH_TLS_DESC_PCADD_LO12 139
|
||||
|
||||
#ifndef ELF_ARCH
|
||||
|
||||
|
|
@ -156,6 +186,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
|||
typedef double elf_fpreg_t;
|
||||
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
|
||||
|
||||
void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs);
|
||||
void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs);
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
|
|
|
|||
|
|
@ -438,8 +438,10 @@ static inline bool is_branch_ins(union loongarch_instruction *ip)
|
|||
|
||||
static inline bool is_ra_save_ins(union loongarch_instruction *ip)
|
||||
{
|
||||
/* st.d $ra, $sp, offset */
|
||||
return ip->reg2i12_format.opcode == std_op &&
|
||||
const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? stw_op : std_op;
|
||||
|
||||
/* st.w / st.d $ra, $sp, offset */
|
||||
return ip->reg2i12_format.opcode == opcode &&
|
||||
ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
|
||||
ip->reg2i12_format.rd == LOONGARCH_GPR_RA &&
|
||||
!is_imm12_negative(ip->reg2i12_format.immediate);
|
||||
|
|
@ -447,8 +449,10 @@ static inline bool is_ra_save_ins(union loongarch_instruction *ip)
|
|||
|
||||
static inline bool is_stack_alloc_ins(union loongarch_instruction *ip)
|
||||
{
|
||||
/* addi.d $sp, $sp, -imm */
|
||||
return ip->reg2i12_format.opcode == addid_op &&
|
||||
const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? addiw_op : addid_op;
|
||||
|
||||
/* addi.w / addi.d $sp, $sp, -imm */
|
||||
return ip->reg2i12_format.opcode == opcode &&
|
||||
ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
|
||||
ip->reg2i12_format.rd == LOONGARCH_GPR_SP &&
|
||||
is_imm12_negative(ip->reg2i12_format.immediate);
|
||||
|
|
|
|||
|
|
@ -61,8 +61,13 @@ struct user_lbt_state {
|
|||
struct user_watch_state {
|
||||
__u64 dbg_info;
|
||||
struct {
|
||||
#if __BITS_PER_LONG == 32
|
||||
__u32 addr;
|
||||
__u32 mask;
|
||||
#else
|
||||
__u64 addr;
|
||||
__u64 mask;
|
||||
#endif
|
||||
__u32 ctrl;
|
||||
__u32 pad;
|
||||
} dbg_regs[8];
|
||||
|
|
@ -71,8 +76,13 @@ struct user_watch_state {
|
|||
struct user_watch_state_v2 {
|
||||
__u64 dbg_info;
|
||||
struct {
|
||||
#if __BITS_PER_LONG == 32
|
||||
__u32 addr;
|
||||
__u32 mask;
|
||||
#else
|
||||
__u64 addr;
|
||||
__u64 mask;
|
||||
#endif
|
||||
__u32 ctrl;
|
||||
__u32 pad;
|
||||
} dbg_regs[14];
|
||||
|
|
|
|||
|
|
@ -96,6 +96,49 @@
|
|||
EX fld.d $f31, \base, (31 * FPU_REG_WIDTH)
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
.macro sc_save_fcc thread tmp0 tmp1
|
||||
movcf2gr \tmp0, $fcc0
|
||||
move \tmp1, \tmp0
|
||||
movcf2gr \tmp0, $fcc1
|
||||
bstrins.w \tmp1, \tmp0, 15, 8
|
||||
movcf2gr \tmp0, $fcc2
|
||||
bstrins.w \tmp1, \tmp0, 23, 16
|
||||
movcf2gr \tmp0, $fcc3
|
||||
bstrins.w \tmp1, \tmp0, 31, 24
|
||||
EX st.w \tmp1, \thread, THREAD_FCC
|
||||
movcf2gr \tmp0, $fcc4
|
||||
move \tmp1, \tmp0
|
||||
movcf2gr \tmp0, $fcc5
|
||||
bstrins.w \tmp1, \tmp0, 15, 8
|
||||
movcf2gr \tmp0, $fcc6
|
||||
bstrins.w \tmp1, \tmp0, 23, 16
|
||||
movcf2gr \tmp0, $fcc7
|
||||
bstrins.w \tmp1, \tmp0, 31, 24
|
||||
EX st.w \tmp1, \thread, (THREAD_FCC + 4)
|
||||
.endm
|
||||
|
||||
.macro sc_restore_fcc thread tmp0 tmp1
|
||||
EX ld.w \tmp0, \thread, THREAD_FCC
|
||||
bstrpick.w \tmp1, \tmp0, 7, 0
|
||||
movgr2cf $fcc0, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 15, 8
|
||||
movgr2cf $fcc1, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 23, 16
|
||||
movgr2cf $fcc2, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 31, 24
|
||||
movgr2cf $fcc3, \tmp1
|
||||
EX ld.w \tmp0, \thread, (THREAD_FCC + 4)
|
||||
bstrpick.w \tmp1, \tmp0, 7, 0
|
||||
movgr2cf $fcc4, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 15, 8
|
||||
movgr2cf $fcc5, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 23, 16
|
||||
movgr2cf $fcc6, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 31, 24
|
||||
movgr2cf $fcc7, \tmp1
|
||||
.endm
|
||||
#else
|
||||
.macro sc_save_fcc base, tmp0, tmp1
|
||||
movcf2gr \tmp0, $fcc0
|
||||
move \tmp1, \tmp0
|
||||
|
|
@ -135,6 +178,7 @@
|
|||
bstrpick.d \tmp1, \tmp0, 63, 56
|
||||
movgr2cf $fcc7, \tmp1
|
||||
.endm
|
||||
#endif
|
||||
|
||||
.macro sc_save_fcsr base, tmp0
|
||||
movfcsr2gr \tmp0, fcsr0
|
||||
|
|
@ -410,6 +454,72 @@ SYM_FUNC_START(_init_fpu)
|
|||
|
||||
li.w t1, -1 # SNaN
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
movgr2fr.w $f0, t1
|
||||
movgr2frh.w $f0, t1
|
||||
movgr2fr.w $f1, t1
|
||||
movgr2frh.w $f1, t1
|
||||
movgr2fr.w $f2, t1
|
||||
movgr2frh.w $f2, t1
|
||||
movgr2fr.w $f3, t1
|
||||
movgr2frh.w $f3, t1
|
||||
movgr2fr.w $f4, t1
|
||||
movgr2frh.w $f4, t1
|
||||
movgr2fr.w $f5, t1
|
||||
movgr2frh.w $f5, t1
|
||||
movgr2fr.w $f6, t1
|
||||
movgr2frh.w $f6, t1
|
||||
movgr2fr.w $f7, t1
|
||||
movgr2frh.w $f7, t1
|
||||
movgr2fr.w $f8, t1
|
||||
movgr2frh.w $f8, t1
|
||||
movgr2fr.w $f9, t1
|
||||
movgr2frh.w $f9, t1
|
||||
movgr2fr.w $f10, t1
|
||||
movgr2frh.w $f10, t1
|
||||
movgr2fr.w $f11, t1
|
||||
movgr2frh.w $f11, t1
|
||||
movgr2fr.w $f12, t1
|
||||
movgr2frh.w $f12, t1
|
||||
movgr2fr.w $f13, t1
|
||||
movgr2frh.w $f13, t1
|
||||
movgr2fr.w $f14, t1
|
||||
movgr2frh.w $f14, t1
|
||||
movgr2fr.w $f15, t1
|
||||
movgr2frh.w $f15, t1
|
||||
movgr2fr.w $f16, t1
|
||||
movgr2frh.w $f16, t1
|
||||
movgr2fr.w $f17, t1
|
||||
movgr2frh.w $f17, t1
|
||||
movgr2fr.w $f18, t1
|
||||
movgr2frh.w $f18, t1
|
||||
movgr2fr.w $f19, t1
|
||||
movgr2frh.w $f19, t1
|
||||
movgr2fr.w $f20, t1
|
||||
movgr2frh.w $f20, t1
|
||||
movgr2fr.w $f21, t1
|
||||
movgr2frh.w $f21, t1
|
||||
movgr2fr.w $f22, t1
|
||||
movgr2frh.w $f22, t1
|
||||
movgr2fr.w $f23, t1
|
||||
movgr2frh.w $f23, t1
|
||||
movgr2fr.w $f24, t1
|
||||
movgr2frh.w $f24, t1
|
||||
movgr2fr.w $f25, t1
|
||||
movgr2frh.w $f25, t1
|
||||
movgr2fr.w $f26, t1
|
||||
movgr2frh.w $f26, t1
|
||||
movgr2fr.w $f27, t1
|
||||
movgr2frh.w $f27, t1
|
||||
movgr2fr.w $f28, t1
|
||||
movgr2frh.w $f28, t1
|
||||
movgr2fr.w $f29, t1
|
||||
movgr2frh.w $f29, t1
|
||||
movgr2fr.w $f30, t1
|
||||
movgr2frh.w $f30, t1
|
||||
movgr2fr.w $f31, t1
|
||||
movgr2frh.w $f31, t1
|
||||
#else
|
||||
movgr2fr.d $f0, t1
|
||||
movgr2fr.d $f1, t1
|
||||
movgr2fr.d $f2, t1
|
||||
|
|
@ -442,6 +552,7 @@ SYM_FUNC_START(_init_fpu)
|
|||
movgr2fr.d $f29, t1
|
||||
movgr2fr.d $f30, t1
|
||||
movgr2fr.d $f31, t1
|
||||
#endif
|
||||
|
||||
jr ra
|
||||
SYM_FUNC_END(_init_fpu)
|
||||
|
|
|
|||
|
|
@ -382,8 +382,11 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
|
|||
nmi_trigger_cpumask_backtrace(mask, exclude_cpu, raise_backtrace);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#ifdef CONFIG_32BIT
|
||||
void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs)
|
||||
#else
|
||||
void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs)
|
||||
#endif
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
|
@ -400,4 +403,3 @@ void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs)
|
|||
uregs[LOONGARCH_EF_CSR_ECFG] = regs->csr_ecfg;
|
||||
uregs[LOONGARCH_EF_CSR_ESTAT] = regs->csr_estat;
|
||||
}
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
|
|
|||
|
|
@ -650,8 +650,13 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
|
|||
struct perf_event_attr attr;
|
||||
|
||||
/* Kernel-space address cannot be monitored by user-space */
|
||||
#ifdef CONFIG_32BIT
|
||||
if ((unsigned long)addr >= KPRANGE0)
|
||||
return -EINVAL;
|
||||
#else
|
||||
if ((unsigned long)addr >= XKPRANGE)
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
|
||||
if (IS_ERR(bp))
|
||||
|
|
|
|||
|
|
@ -16,18 +16,23 @@
|
|||
*/
|
||||
.align 5
|
||||
SYM_FUNC_START(__switch_to)
|
||||
csrrd t1, LOONGARCH_CSR_PRMD
|
||||
stptr.d t1, a0, THREAD_CSRPRMD
|
||||
#ifdef CONFIG_32BIT
|
||||
PTR_ADDI a0, a0, TASK_STRUCT_OFFSET
|
||||
PTR_ADDI a1, a1, TASK_STRUCT_OFFSET
|
||||
#endif
|
||||
csrrd t1, LOONGARCH_CSR_PRMD
|
||||
LONG_SPTR t1, a0, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET)
|
||||
|
||||
cpu_save_nonscratch a0
|
||||
stptr.d ra, a0, THREAD_REG01
|
||||
stptr.d a3, a0, THREAD_SCHED_RA
|
||||
stptr.d a4, a0, THREAD_SCHED_CFA
|
||||
LONG_SPTR a3, a0, (THREAD_SCHED_RA - TASK_STRUCT_OFFSET)
|
||||
LONG_SPTR a4, a0, (THREAD_SCHED_CFA - TASK_STRUCT_OFFSET)
|
||||
|
||||
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
|
||||
la t7, __stack_chk_guard
|
||||
ldptr.d t8, a1, TASK_STACK_CANARY
|
||||
stptr.d t8, t7, 0
|
||||
la t7, __stack_chk_guard
|
||||
LONG_LPTR t8, a1, (TASK_STACK_CANARY - TASK_STRUCT_OFFSET)
|
||||
LONG_SPTR t8, t7, 0
|
||||
#endif
|
||||
|
||||
move tp, a2
|
||||
cpu_restore_nonscratch a1
|
||||
|
||||
|
|
@ -35,8 +40,11 @@ SYM_FUNC_START(__switch_to)
|
|||
PTR_ADD t0, t0, tp
|
||||
set_saved_sp t0, t1, t2
|
||||
|
||||
ldptr.d t1, a1, THREAD_CSRPRMD
|
||||
csrwr t1, LOONGARCH_CSR_PRMD
|
||||
LONG_LPTR t1, a1, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET)
|
||||
csrwr t1, LOONGARCH_CSR_PRMD
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
PTR_ADDI a0, a0, -TASK_STRUCT_OFFSET
|
||||
#endif
|
||||
jr ra
|
||||
SYM_FUNC_END(__switch_to)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user