Skip to content

Commit 4ad04e7

Browse files
committed
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>
1 parent dd55dd0 commit 4ad04e7

7 files changed

Lines changed: 187 additions & 16 deletions

File tree

arch/loongarch/include/asm/elf.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,36 @@
120120
#define R_LARCH_ADD_ULEB128 107
121121
#define R_LARCH_SUB_ULEB128 108
122122
#define R_LARCH_64_PCREL 109
123+
#define R_LARCH_CALL36 110
124+
#define R_LARCH_TLS_DESC_PC_HI20 111
125+
#define R_LARCH_TLS_DESC_PC_LO12 112
126+
#define R_LARCH_TLS_DESC64_PC_LO20 113
127+
#define R_LARCH_TLS_DESC64_PC_HI12 114
128+
#define R_LARCH_TLS_DESC_HI20 115
129+
#define R_LARCH_TLS_DESC_LO12 116
130+
#define R_LARCH_TLS_DESC64_LO20 117
131+
#define R_LARCH_TLS_DESC64_HI12 118
132+
#define R_LARCH_TLS_DESC_LD 119
133+
#define R_LARCH_TLS_DESC_CALL 120
134+
#define R_LARCH_TLS_LE_HI20_R 121
135+
#define R_LARCH_TLS_LE_ADD_R 122
136+
#define R_LARCH_TLS_LE_LO12_R 123
137+
#define R_LARCH_TLS_LD_PCREL20_S2 124
138+
#define R_LARCH_TLS_GD_PCREL20_S2 125
139+
#define R_LARCH_TLS_DESC_PCREL20_S2 126
140+
#define R_LARCH_CALL30 127
141+
#define R_LARCH_PCADD_HI20 128
142+
#define R_LARCH_PCADD_LO12 129
143+
#define R_LARCH_GOT_PCADD_HI20 130
144+
#define R_LARCH_GOT_PCADD_LO12 131
145+
#define R_LARCH_TLS_IE_PCADD_HI20 132
146+
#define R_LARCH_TLS_IE_PCADD_LO12 133
147+
#define R_LARCH_TLS_LD_PCADD_HI20 134
148+
#define R_LARCH_TLS_LD_PCADD_LO12 135
149+
#define R_LARCH_TLS_GD_PCADD_HI20 136
150+
#define R_LARCH_TLS_GD_PCADD_LO12 137
151+
#define R_LARCH_TLS_DESC_PCADD_HI20 138
152+
#define R_LARCH_TLS_DESC_PCADD_LO12 139
123153

124154
#ifndef ELF_ARCH
125155

@@ -156,6 +186,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
156186
typedef double elf_fpreg_t;
157187
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
158188

189+
void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs);
159190
void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs);
160191

161192
#ifdef CONFIG_32BIT

arch/loongarch/include/asm/inst.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -438,17 +438,21 @@ static inline bool is_branch_ins(union loongarch_instruction *ip)
438438

439439
static inline bool is_ra_save_ins(union loongarch_instruction *ip)
440440
{
441-
/* st.d $ra, $sp, offset */
442-
return ip->reg2i12_format.opcode == std_op &&
441+
const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? stw_op : std_op;
442+
443+
/* st.w / st.d $ra, $sp, offset */
444+
return ip->reg2i12_format.opcode == opcode &&
443445
ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
444446
ip->reg2i12_format.rd == LOONGARCH_GPR_RA &&
445447
!is_imm12_negative(ip->reg2i12_format.immediate);
446448
}
447449

448450
static inline bool is_stack_alloc_ins(union loongarch_instruction *ip)
449451
{
450-
/* addi.d $sp, $sp, -imm */
451-
return ip->reg2i12_format.opcode == addid_op &&
452+
const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? addiw_op : addid_op;
453+
454+
/* addi.w / addi.d $sp, $sp, -imm */
455+
return ip->reg2i12_format.opcode == opcode &&
452456
ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
453457
ip->reg2i12_format.rd == LOONGARCH_GPR_SP &&
454458
is_imm12_negative(ip->reg2i12_format.immediate);

arch/loongarch/include/uapi/asm/ptrace.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,13 @@ struct user_lbt_state {
6161
struct user_watch_state {
6262
__u64 dbg_info;
6363
struct {
64+
#if __BITS_PER_LONG == 32
65+
__u32 addr;
66+
__u32 mask;
67+
#else
6468
__u64 addr;
6569
__u64 mask;
70+
#endif
6671
__u32 ctrl;
6772
__u32 pad;
6873
} dbg_regs[8];
@@ -71,8 +76,13 @@ struct user_watch_state {
7176
struct user_watch_state_v2 {
7277
__u64 dbg_info;
7378
struct {
79+
#if __BITS_PER_LONG == 32
80+
__u32 addr;
81+
__u32 mask;
82+
#else
7483
__u64 addr;
7584
__u64 mask;
85+
#endif
7686
__u32 ctrl;
7787
__u32 pad;
7888
} dbg_regs[14];

arch/loongarch/kernel/fpu.S

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,49 @@
9696
EX fld.d $f31, \base, (31 * FPU_REG_WIDTH)
9797
.endm
9898

99+
#ifdef CONFIG_32BIT
100+
.macro sc_save_fcc thread tmp0 tmp1
101+
movcf2gr \tmp0, $fcc0
102+
move \tmp1, \tmp0
103+
movcf2gr \tmp0, $fcc1
104+
bstrins.w \tmp1, \tmp0, 15, 8
105+
movcf2gr \tmp0, $fcc2
106+
bstrins.w \tmp1, \tmp0, 23, 16
107+
movcf2gr \tmp0, $fcc3
108+
bstrins.w \tmp1, \tmp0, 31, 24
109+
EX st.w \tmp1, \thread, THREAD_FCC
110+
movcf2gr \tmp0, $fcc4
111+
move \tmp1, \tmp0
112+
movcf2gr \tmp0, $fcc5
113+
bstrins.w \tmp1, \tmp0, 15, 8
114+
movcf2gr \tmp0, $fcc6
115+
bstrins.w \tmp1, \tmp0, 23, 16
116+
movcf2gr \tmp0, $fcc7
117+
bstrins.w \tmp1, \tmp0, 31, 24
118+
EX st.w \tmp1, \thread, (THREAD_FCC + 4)
119+
.endm
120+
121+
.macro sc_restore_fcc thread tmp0 tmp1
122+
EX ld.w \tmp0, \thread, THREAD_FCC
123+
bstrpick.w \tmp1, \tmp0, 7, 0
124+
movgr2cf $fcc0, \tmp1
125+
bstrpick.w \tmp1, \tmp0, 15, 8
126+
movgr2cf $fcc1, \tmp1
127+
bstrpick.w \tmp1, \tmp0, 23, 16
128+
movgr2cf $fcc2, \tmp1
129+
bstrpick.w \tmp1, \tmp0, 31, 24
130+
movgr2cf $fcc3, \tmp1
131+
EX ld.w \tmp0, \thread, (THREAD_FCC + 4)
132+
bstrpick.w \tmp1, \tmp0, 7, 0
133+
movgr2cf $fcc4, \tmp1
134+
bstrpick.w \tmp1, \tmp0, 15, 8
135+
movgr2cf $fcc5, \tmp1
136+
bstrpick.w \tmp1, \tmp0, 23, 16
137+
movgr2cf $fcc6, \tmp1
138+
bstrpick.w \tmp1, \tmp0, 31, 24
139+
movgr2cf $fcc7, \tmp1
140+
.endm
141+
#else
99142
.macro sc_save_fcc base, tmp0, tmp1
100143
movcf2gr \tmp0, $fcc0
101144
move \tmp1, \tmp0
@@ -135,6 +178,7 @@
135178
bstrpick.d \tmp1, \tmp0, 63, 56
136179
movgr2cf $fcc7, \tmp1
137180
.endm
181+
#endif
138182

139183
.macro sc_save_fcsr base, tmp0
140184
movfcsr2gr \tmp0, fcsr0
@@ -410,6 +454,72 @@ SYM_FUNC_START(_init_fpu)
410454

411455
li.w t1, -1 # SNaN
412456

457+
#ifdef CONFIG_32BIT
458+
movgr2fr.w $f0, t1
459+
movgr2frh.w $f0, t1
460+
movgr2fr.w $f1, t1
461+
movgr2frh.w $f1, t1
462+
movgr2fr.w $f2, t1
463+
movgr2frh.w $f2, t1
464+
movgr2fr.w $f3, t1
465+
movgr2frh.w $f3, t1
466+
movgr2fr.w $f4, t1
467+
movgr2frh.w $f4, t1
468+
movgr2fr.w $f5, t1
469+
movgr2frh.w $f5, t1
470+
movgr2fr.w $f6, t1
471+
movgr2frh.w $f6, t1
472+
movgr2fr.w $f7, t1
473+
movgr2frh.w $f7, t1
474+
movgr2fr.w $f8, t1
475+
movgr2frh.w $f8, t1
476+
movgr2fr.w $f9, t1
477+
movgr2frh.w $f9, t1
478+
movgr2fr.w $f10, t1
479+
movgr2frh.w $f10, t1
480+
movgr2fr.w $f11, t1
481+
movgr2frh.w $f11, t1
482+
movgr2fr.w $f12, t1
483+
movgr2frh.w $f12, t1
484+
movgr2fr.w $f13, t1
485+
movgr2frh.w $f13, t1
486+
movgr2fr.w $f14, t1
487+
movgr2frh.w $f14, t1
488+
movgr2fr.w $f15, t1
489+
movgr2frh.w $f15, t1
490+
movgr2fr.w $f16, t1
491+
movgr2frh.w $f16, t1
492+
movgr2fr.w $f17, t1
493+
movgr2frh.w $f17, t1
494+
movgr2fr.w $f18, t1
495+
movgr2frh.w $f18, t1
496+
movgr2fr.w $f19, t1
497+
movgr2frh.w $f19, t1
498+
movgr2fr.w $f20, t1
499+
movgr2frh.w $f20, t1
500+
movgr2fr.w $f21, t1
501+
movgr2frh.w $f21, t1
502+
movgr2fr.w $f22, t1
503+
movgr2frh.w $f22, t1
504+
movgr2fr.w $f23, t1
505+
movgr2frh.w $f23, t1
506+
movgr2fr.w $f24, t1
507+
movgr2frh.w $f24, t1
508+
movgr2fr.w $f25, t1
509+
movgr2frh.w $f25, t1
510+
movgr2fr.w $f26, t1
511+
movgr2frh.w $f26, t1
512+
movgr2fr.w $f27, t1
513+
movgr2frh.w $f27, t1
514+
movgr2fr.w $f28, t1
515+
movgr2frh.w $f28, t1
516+
movgr2fr.w $f29, t1
517+
movgr2frh.w $f29, t1
518+
movgr2fr.w $f30, t1
519+
movgr2frh.w $f30, t1
520+
movgr2fr.w $f31, t1
521+
movgr2frh.w $f31, t1
522+
#else
413523
movgr2fr.d $f0, t1
414524
movgr2fr.d $f1, t1
415525
movgr2fr.d $f2, t1
@@ -442,6 +552,7 @@ SYM_FUNC_START(_init_fpu)
442552
movgr2fr.d $f29, t1
443553
movgr2fr.d $f30, t1
444554
movgr2fr.d $f31, t1
555+
#endif
445556

446557
jr ra
447558
SYM_FUNC_END(_init_fpu)

arch/loongarch/kernel/process.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,11 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
382382
nmi_trigger_cpumask_backtrace(mask, exclude_cpu, raise_backtrace);
383383
}
384384

385-
#ifdef CONFIG_64BIT
385+
#ifdef CONFIG_32BIT
386+
void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs)
387+
#else
386388
void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs)
389+
#endif
387390
{
388391
unsigned int i;
389392

@@ -400,4 +403,3 @@ void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs)
400403
uregs[LOONGARCH_EF_CSR_ECFG] = regs->csr_ecfg;
401404
uregs[LOONGARCH_EF_CSR_ESTAT] = regs->csr_estat;
402405
}
403-
#endif /* CONFIG_64BIT */

arch/loongarch/kernel/ptrace.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,13 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
650650
struct perf_event_attr attr;
651651

652652
/* Kernel-space address cannot be monitored by user-space */
653+
#ifdef CONFIG_32BIT
654+
if ((unsigned long)addr >= KPRANGE0)
655+
return -EINVAL;
656+
#else
653657
if ((unsigned long)addr >= XKPRANGE)
654658
return -EINVAL;
659+
#endif
655660

656661
bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
657662
if (IS_ERR(bp))

arch/loongarch/kernel/switch.S

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,35 @@
1616
*/
1717
.align 5
1818
SYM_FUNC_START(__switch_to)
19-
csrrd t1, LOONGARCH_CSR_PRMD
20-
stptr.d t1, a0, THREAD_CSRPRMD
19+
#ifdef CONFIG_32BIT
20+
PTR_ADDI a0, a0, TASK_STRUCT_OFFSET
21+
PTR_ADDI a1, a1, TASK_STRUCT_OFFSET
22+
#endif
23+
csrrd t1, LOONGARCH_CSR_PRMD
24+
LONG_SPTR t1, a0, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET)
2125

2226
cpu_save_nonscratch a0
23-
stptr.d ra, a0, THREAD_REG01
24-
stptr.d a3, a0, THREAD_SCHED_RA
25-
stptr.d a4, a0, THREAD_SCHED_CFA
27+
LONG_SPTR a3, a0, (THREAD_SCHED_RA - TASK_STRUCT_OFFSET)
28+
LONG_SPTR a4, a0, (THREAD_SCHED_CFA - TASK_STRUCT_OFFSET)
29+
2630
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
27-
la t7, __stack_chk_guard
28-
ldptr.d t8, a1, TASK_STACK_CANARY
29-
stptr.d t8, t7, 0
31+
la t7, __stack_chk_guard
32+
LONG_LPTR t8, a1, (TASK_STACK_CANARY - TASK_STRUCT_OFFSET)
33+
LONG_SPTR t8, t7, 0
3034
#endif
35+
3136
move tp, a2
3237
cpu_restore_nonscratch a1
3338

3439
li.w t0, _THREAD_SIZE
3540
PTR_ADD t0, t0, tp
3641
set_saved_sp t0, t1, t2
3742

38-
ldptr.d t1, a1, THREAD_CSRPRMD
39-
csrwr t1, LOONGARCH_CSR_PRMD
43+
LONG_LPTR t1, a1, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET)
44+
csrwr t1, LOONGARCH_CSR_PRMD
4045

46+
#ifdef CONFIG_32BIT
47+
PTR_ADDI a0, a0, -TASK_STRUCT_OFFSET
48+
#endif
4149
jr ra
4250
SYM_FUNC_END(__switch_to)

0 commit comments

Comments
 (0)