Skip to content

Commit c586c97

Browse files
committed
Merge tag 'loongarch-fixes-6.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch fixes from Huacai Chen: "Fix some bugs in kernel-fpu, cpu idle function, hibernation and uprobes" * tag 'loongarch-fixes-6.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson: LoongArch: uprobes: Remove redundant code about resume_era LoongArch: uprobes: Remove user_{en,dis}able_single_step() LoongArch: Save and restore CSR.CNTC for hibernation LoongArch: Move __arch_cpu_idle() to .cpuidle.text section LoongArch: Fix MAX_REG_OFFSET calculation LoongArch: Prevent cond_resched() occurring within kernel-fpu
2 parents a1317e1 + 12614f7 commit c586c97

File tree

7 files changed

+31
-17
lines changed

7 files changed

+31
-17
lines changed

arch/loongarch/include/asm/ptrace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static inline void instruction_pointer_set(struct pt_regs *regs, unsigned long v
5555

5656
/* Query offset/name of register from its name/offset */
5757
extern int regs_query_register_offset(const char *name);
58-
#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last))
58+
#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last) - sizeof(unsigned long))
5959

6060
/**
6161
* regs_get_register() - get register value from its offset

arch/loongarch/include/asm/uprobes.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ typedef u32 uprobe_opcode_t;
1515
#define UPROBE_XOLBP_INSN __emit_break(BRK_UPROBE_XOLBP)
1616

1717
struct arch_uprobe {
18-
unsigned long resume_era;
1918
u32 insn[2];
2019
u32 ixol[2];
2120
bool simulate;

arch/loongarch/kernel/genex.S

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <asm/stackframe.h>
1717
#include <asm/thread_info.h>
1818

19+
.section .cpuidle.text, "ax"
1920
.align 5
2021
SYM_FUNC_START(__arch_cpu_idle)
2122
/* start of idle interrupt region */
@@ -31,14 +32,16 @@ SYM_FUNC_START(__arch_cpu_idle)
3132
*/
3233
idle 0
3334
/* end of idle interrupt region */
34-
1: jr ra
35+
idle_exit:
36+
jr ra
3537
SYM_FUNC_END(__arch_cpu_idle)
38+
.previous
3639

3740
SYM_CODE_START(handle_vint)
3841
UNWIND_HINT_UNDEFINED
3942
BACKUP_T0T1
4043
SAVE_ALL
41-
la_abs t1, 1b
44+
la_abs t1, idle_exit
4245
LONG_L t0, sp, PT_ERA
4346
/* 3 instructions idle interrupt region */
4447
ori t0, t0, 0b1100

arch/loongarch/kernel/kfpu.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,28 @@ static unsigned int euen_mask = CSR_EUEN_FPEN;
1818
static DEFINE_PER_CPU(bool, in_kernel_fpu);
1919
static DEFINE_PER_CPU(unsigned int, euen_current);
2020

21+
static inline void fpregs_lock(void)
22+
{
23+
if (IS_ENABLED(CONFIG_PREEMPT_RT))
24+
preempt_disable();
25+
else
26+
local_bh_disable();
27+
}
28+
29+
static inline void fpregs_unlock(void)
30+
{
31+
if (IS_ENABLED(CONFIG_PREEMPT_RT))
32+
preempt_enable();
33+
else
34+
local_bh_enable();
35+
}
36+
2137
void kernel_fpu_begin(void)
2238
{
2339
unsigned int *euen_curr;
2440

25-
preempt_disable();
41+
if (!irqs_disabled())
42+
fpregs_lock();
2643

2744
WARN_ON(this_cpu_read(in_kernel_fpu));
2845

@@ -73,7 +90,8 @@ void kernel_fpu_end(void)
7390

7491
this_cpu_write(in_kernel_fpu, false);
7592

76-
preempt_enable();
93+
if (!irqs_disabled())
94+
fpregs_unlock();
7795
}
7896
EXPORT_SYMBOL_GPL(kernel_fpu_end);
7997

arch/loongarch/kernel/time.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ static unsigned long __init get_loops_per_jiffy(void)
111111
return lpj;
112112
}
113113

114-
static long init_offset __nosavedata;
114+
static long init_offset;
115115

116116
void save_counter(void)
117117
{

arch/loongarch/kernel/uprobes.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
4242
utask->autask.saved_trap_nr = current->thread.trap_nr;
4343
current->thread.trap_nr = UPROBE_TRAP_NR;
4444
instruction_pointer_set(regs, utask->xol_vaddr);
45-
user_enable_single_step(current);
4645

4746
return 0;
4847
}
@@ -53,13 +52,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
5352

5453
WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR);
5554
current->thread.trap_nr = utask->autask.saved_trap_nr;
56-
57-
if (auprobe->simulate)
58-
instruction_pointer_set(regs, auprobe->resume_era);
59-
else
60-
instruction_pointer_set(regs, utask->vaddr + LOONGARCH_INSN_SIZE);
61-
62-
user_disable_single_step(current);
55+
instruction_pointer_set(regs, utask->vaddr + LOONGARCH_INSN_SIZE);
6356

6457
return 0;
6558
}
@@ -70,7 +63,6 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
7063

7164
current->thread.trap_nr = utask->autask.saved_trap_nr;
7265
instruction_pointer_set(regs, utask->vaddr);
73-
user_disable_single_step(current);
7466
}
7567

7668
bool arch_uprobe_xol_was_trapped(struct task_struct *t)
@@ -90,7 +82,6 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
9082

9183
insn.word = auprobe->insn[0];
9284
arch_simulate_insn(insn, regs);
93-
auprobe->resume_era = regs->csr_era;
9485

9586
return true;
9687
}

arch/loongarch/power/hibernate.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <asm/fpu.h>
33
#include <asm/loongson.h>
44
#include <asm/sections.h>
5+
#include <asm/time.h>
56
#include <asm/tlbflush.h>
67
#include <linux/suspend.h>
78

@@ -14,6 +15,7 @@ struct pt_regs saved_regs;
1415

1516
void save_processor_state(void)
1617
{
18+
save_counter();
1719
saved_crmd = csr_read32(LOONGARCH_CSR_CRMD);
1820
saved_prmd = csr_read32(LOONGARCH_CSR_PRMD);
1921
saved_euen = csr_read32(LOONGARCH_CSR_EUEN);
@@ -26,6 +28,7 @@ void save_processor_state(void)
2628

2729
void restore_processor_state(void)
2830
{
31+
sync_counter();
2932
csr_write32(saved_crmd, LOONGARCH_CSR_CRMD);
3033
csr_write32(saved_prmd, LOONGARCH_CSR_PRMD);
3134
csr_write32(saved_euen, LOONGARCH_CSR_EUEN);

0 commit comments

Comments
 (0)