Commit c96bb958 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'loongarch-fixes-6.1-1' of...

Merge tag 'loongarch-fixes-6.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson

Pull LoongArch fixes from Huacai Chen:
 "Remove unused kernel stack padding, fix some build errors/warnings and
  two bugs in laptop platform driver"

* tag 'loongarch-fixes-6.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  platform/loongarch: laptop: Fix possible UAF and simplify generic_acpi_laptop_init()
  platform/loongarch: laptop: Adjust resume order for loongson_hotkey_resume()
  LoongArch: BPF: Avoid declare variables in switch-case
  LoongArch: Use flexible-array member instead of zero-length array
  LoongArch: Remove unused kernel stack padding
parents 28b7bd4a d8191691
...@@ -191,7 +191,7 @@ static inline void flush_thread(void) ...@@ -191,7 +191,7 @@ static inline void flush_thread(void)
unsigned long __get_wchan(struct task_struct *p); unsigned long __get_wchan(struct task_struct *p);
#define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \ #define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \
THREAD_SIZE - 32 - sizeof(struct pt_regs)) THREAD_SIZE - sizeof(struct pt_regs))
#define task_pt_regs(tsk) ((struct pt_regs *)__KSTK_TOS(tsk)) #define task_pt_regs(tsk) ((struct pt_regs *)__KSTK_TOS(tsk))
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->csr_era) #define KSTK_EIP(tsk) (task_pt_regs(tsk)->csr_era)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[3]) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[3])
......
...@@ -29,7 +29,7 @@ struct pt_regs { ...@@ -29,7 +29,7 @@ struct pt_regs {
unsigned long csr_euen; unsigned long csr_euen;
unsigned long csr_ecfg; unsigned long csr_ecfg;
unsigned long csr_estat; unsigned long csr_estat;
unsigned long __last[0]; unsigned long __last[];
} __aligned(8); } __aligned(8);
static inline int regs_irqs_disabled(struct pt_regs *regs) static inline int regs_irqs_disabled(struct pt_regs *regs)
...@@ -133,7 +133,7 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs) ...@@ -133,7 +133,7 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs)
#define current_pt_regs() \ #define current_pt_regs() \
({ \ ({ \
unsigned long sp = (unsigned long)__builtin_frame_address(0); \ unsigned long sp = (unsigned long)__builtin_frame_address(0); \
(struct pt_regs *)((sp | (THREAD_SIZE - 1)) + 1 - 32) - 1; \ (struct pt_regs *)((sp | (THREAD_SIZE - 1)) + 1) - 1; \
}) })
/* Helpers for working with the user stack pointer */ /* Helpers for working with the user stack pointer */
......
...@@ -84,10 +84,9 @@ SYM_CODE_START(kernel_entry) # kernel entry point ...@@ -84,10 +84,9 @@ SYM_CODE_START(kernel_entry) # kernel entry point
la.pcrel tp, init_thread_union la.pcrel tp, init_thread_union
/* Set the SP after an empty pt_regs. */ /* Set the SP after an empty pt_regs. */
PTR_LI sp, (_THREAD_SIZE - 32 - PT_SIZE) PTR_LI sp, (_THREAD_SIZE - PT_SIZE)
PTR_ADD sp, sp, tp PTR_ADD sp, sp, tp
set_saved_sp sp, t0, t1 set_saved_sp sp, t0, t1
PTR_ADDI sp, sp, -4 * SZREG # init stack pointer
bl start_kernel bl start_kernel
ASM_BUG() ASM_BUG()
......
...@@ -129,7 +129,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) ...@@ -129,7 +129,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
unsigned long clone_flags = args->flags; unsigned long clone_flags = args->flags;
struct pt_regs *childregs, *regs = current_pt_regs(); struct pt_regs *childregs, *regs = current_pt_regs();
childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
/* set up new TSS. */ /* set up new TSS. */
childregs = (struct pt_regs *) childksp - 1; childregs = (struct pt_regs *) childksp - 1;
...@@ -236,7 +236,7 @@ bool in_task_stack(unsigned long stack, struct task_struct *task, ...@@ -236,7 +236,7 @@ bool in_task_stack(unsigned long stack, struct task_struct *task,
struct stack_info *info) struct stack_info *info)
{ {
unsigned long begin = (unsigned long)task_stack_page(task); unsigned long begin = (unsigned long)task_stack_page(task);
unsigned long end = begin + THREAD_SIZE - 32; unsigned long end = begin + THREAD_SIZE;
if (stack < begin || stack >= end) if (stack < begin || stack >= end)
return false; return false;
......
...@@ -26,7 +26,7 @@ SYM_FUNC_START(__switch_to) ...@@ -26,7 +26,7 @@ SYM_FUNC_START(__switch_to)
move tp, a2 move tp, a2
cpu_restore_nonscratch a1 cpu_restore_nonscratch a1
li.w t0, _THREAD_SIZE - 32 li.w t0, _THREAD_SIZE
PTR_ADD t0, t0, tp PTR_ADD t0, t0, tp
set_saved_sp t0, t1, t2 set_saved_sp t0, t1, t2
......
...@@ -279,6 +279,7 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -279,6 +279,7 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
const u8 t1 = LOONGARCH_GPR_T1; const u8 t1 = LOONGARCH_GPR_T1;
const u8 t2 = LOONGARCH_GPR_T2; const u8 t2 = LOONGARCH_GPR_T2;
const u8 t3 = LOONGARCH_GPR_T3; const u8 t3 = LOONGARCH_GPR_T3;
const u8 r0 = regmap[BPF_REG_0];
const u8 src = regmap[insn->src_reg]; const u8 src = regmap[insn->src_reg];
const u8 dst = regmap[insn->dst_reg]; const u8 dst = regmap[insn->dst_reg];
const s16 off = insn->off; const s16 off = insn->off;
...@@ -359,8 +360,6 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -359,8 +360,6 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
break; break;
/* r0 = atomic_cmpxchg(dst + off, r0, src); */ /* r0 = atomic_cmpxchg(dst + off, r0, src); */
case BPF_CMPXCHG: case BPF_CMPXCHG:
u8 r0 = regmap[BPF_REG_0];
move_reg(ctx, t2, r0); move_reg(ctx, t2, r0);
if (isdw) { if (isdw) {
emit_insn(ctx, lld, r0, t1, 0); emit_insn(ctx, lld, r0, t1, 0);
...@@ -390,8 +389,11 @@ static bool is_signed_bpf_cond(u8 cond) ...@@ -390,8 +389,11 @@ static bool is_signed_bpf_cond(u8 cond)
static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool extra_pass) static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool extra_pass)
{ {
const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || u8 tm = -1;
BPF_CLASS(insn->code) == BPF_JMP32; u64 func_addr;
bool func_addr_fixed;
int i = insn - ctx->prog->insnsi;
int ret, jmp_offset;
const u8 code = insn->code; const u8 code = insn->code;
const u8 cond = BPF_OP(code); const u8 cond = BPF_OP(code);
const u8 t1 = LOONGARCH_GPR_T1; const u8 t1 = LOONGARCH_GPR_T1;
...@@ -400,8 +402,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext ...@@ -400,8 +402,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
const u8 dst = regmap[insn->dst_reg]; const u8 dst = regmap[insn->dst_reg];
const s16 off = insn->off; const s16 off = insn->off;
const s32 imm = insn->imm; const s32 imm = insn->imm;
int jmp_offset; const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm;
int i = insn - ctx->prog->insnsi; const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || BPF_CLASS(insn->code) == BPF_JMP32;
switch (code) { switch (code) {
/* dst = src */ /* dst = src */
...@@ -724,24 +726,23 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext ...@@ -724,24 +726,23 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
case BPF_JMP32 | BPF_JSGE | BPF_K: case BPF_JMP32 | BPF_JSGE | BPF_K:
case BPF_JMP32 | BPF_JSLT | BPF_K: case BPF_JMP32 | BPF_JSLT | BPF_K:
case BPF_JMP32 | BPF_JSLE | BPF_K: case BPF_JMP32 | BPF_JSLE | BPF_K:
u8 t7 = -1;
jmp_offset = bpf2la_offset(i, off, ctx); jmp_offset = bpf2la_offset(i, off, ctx);
if (imm) { if (imm) {
move_imm(ctx, t1, imm, false); move_imm(ctx, t1, imm, false);
t7 = t1; tm = t1;
} else { } else {
/* If imm is 0, simply use zero register. */ /* If imm is 0, simply use zero register. */
t7 = LOONGARCH_GPR_ZERO; tm = LOONGARCH_GPR_ZERO;
} }
move_reg(ctx, t2, dst); move_reg(ctx, t2, dst);
if (is_signed_bpf_cond(BPF_OP(code))) { if (is_signed_bpf_cond(BPF_OP(code))) {
emit_sext_32(ctx, t7, is32); emit_sext_32(ctx, tm, is32);
emit_sext_32(ctx, t2, is32); emit_sext_32(ctx, t2, is32);
} else { } else {
emit_zext_32(ctx, t7, is32); emit_zext_32(ctx, tm, is32);
emit_zext_32(ctx, t2, is32); emit_zext_32(ctx, t2, is32);
} }
if (emit_cond_jmp(ctx, cond, t2, t7, jmp_offset) < 0) if (emit_cond_jmp(ctx, cond, t2, tm, jmp_offset) < 0)
goto toofar; goto toofar;
break; break;
...@@ -775,10 +776,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext ...@@ -775,10 +776,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
/* function call */ /* function call */
case BPF_JMP | BPF_CALL: case BPF_JMP | BPF_CALL:
int ret;
u64 func_addr;
bool func_addr_fixed;
mark_call(ctx); mark_call(ctx);
ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
&func_addr, &func_addr_fixed); &func_addr, &func_addr_fixed);
...@@ -811,8 +808,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext ...@@ -811,8 +808,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
/* dst = imm64 */ /* dst = imm64 */
case BPF_LD | BPF_IMM | BPF_DW: case BPF_LD | BPF_IMM | BPF_DW:
u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm;
move_imm(ctx, dst, imm64, is32); move_imm(ctx, dst, imm64, is32);
return 1; return 1;
......
...@@ -199,6 +199,13 @@ static int loongson_hotkey_resume(struct device *dev) ...@@ -199,6 +199,13 @@ static int loongson_hotkey_resume(struct device *dev)
struct key_entry ke; struct key_entry ke;
struct backlight_device *bd; struct backlight_device *bd;
bd = backlight_device_get_by_type(BACKLIGHT_PLATFORM);
if (bd) {
loongson_laptop_backlight_update(bd) ?
pr_warn("Loongson_backlight: resume brightness failed") :
pr_info("Loongson_backlight: resume brightness %d\n", bd->props.brightness);
}
/* /*
* Only if the firmware supports SW_LID event model, we can handle the * Only if the firmware supports SW_LID event model, we can handle the
* event. This is for the consideration of development board without EC. * event. This is for the consideration of development board without EC.
...@@ -228,13 +235,6 @@ static int loongson_hotkey_resume(struct device *dev) ...@@ -228,13 +235,6 @@ static int loongson_hotkey_resume(struct device *dev)
} }
} }
bd = backlight_device_get_by_type(BACKLIGHT_PLATFORM);
if (bd) {
loongson_laptop_backlight_update(bd) ?
pr_warn("Loongson_backlight: resume brightness failed") :
pr_info("Loongson_backlight: resume brightness %d\n", bd->props.brightness);
}
return 0; return 0;
} }
...@@ -448,6 +448,7 @@ static int __init event_init(struct generic_sub_driver *sub_driver) ...@@ -448,6 +448,7 @@ static int __init event_init(struct generic_sub_driver *sub_driver)
if (ret < 0) { if (ret < 0) {
pr_err("Failed to setup input device keymap\n"); pr_err("Failed to setup input device keymap\n");
input_free_device(generic_inputdev); input_free_device(generic_inputdev);
generic_inputdev = NULL;
return ret; return ret;
} }
...@@ -502,8 +503,11 @@ static int __init generic_subdriver_init(struct generic_sub_driver *sub_driver) ...@@ -502,8 +503,11 @@ static int __init generic_subdriver_init(struct generic_sub_driver *sub_driver)
if (ret) if (ret)
return -EINVAL; return -EINVAL;
if (sub_driver->init) if (sub_driver->init) {
sub_driver->init(sub_driver); ret = sub_driver->init(sub_driver);
if (ret)
goto err_out;
}
if (sub_driver->notify) { if (sub_driver->notify) {
ret = setup_acpi_notify(sub_driver); ret = setup_acpi_notify(sub_driver);
...@@ -519,7 +523,7 @@ static int __init generic_subdriver_init(struct generic_sub_driver *sub_driver) ...@@ -519,7 +523,7 @@ static int __init generic_subdriver_init(struct generic_sub_driver *sub_driver)
err_out: err_out:
generic_subdriver_exit(sub_driver); generic_subdriver_exit(sub_driver);
return (ret < 0) ? ret : 0; return ret;
} }
static void generic_subdriver_exit(struct generic_sub_driver *sub_driver) static void generic_subdriver_exit(struct generic_sub_driver *sub_driver)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment