aboutsummaryrefslogtreecommitdiff
path: root/arch/loongarch/kernel/inst.c
diff options
context:
space:
mode:
authorGravatar WANG Rui <wangrui@loongson.cn> 2023-06-29 20:58:42 +0800
committerGravatar Huacai Chen <chenhuacai@loongson.cn> 2023-06-29 20:58:42 +0800
commit0d03e9dce5c91d841a35af05ca61a5cf318f5064 (patch)
tree24f8cd43a83332492c776c5928fc2956c970f87c /arch/loongarch/kernel/inst.c
parentLoongArch: Delete unnecessary debugfs checking (diff)
downloadlinux-0d03e9dce5c91d841a35af05ca61a5cf318f5064.tar.gz
linux-0d03e9dce5c91d841a35af05ca61a5cf318f5064.tar.bz2
linux-0d03e9dce5c91d841a35af05ca61a5cf318f5064.zip
LoongArch: Add guard for the larch_insn_gen_xxx functions
Add guard for the larch_insn_gen_xxx functions to verify whether the immediate operand is within the acceptable range. Signed-off-by: WANG Rui <wangrui@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'arch/loongarch/kernel/inst.c')
-rw-r--r--arch/loongarch/kernel/inst.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c
index 258ef267cd30..ffe13c5ba557 100644
--- a/arch/loongarch/kernel/inst.c
+++ b/arch/loongarch/kernel/inst.c
@@ -226,6 +226,11 @@ u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm)
{
union loongarch_instruction insn;
+ if (imm < -SZ_512K || imm >= SZ_512K) {
+ pr_warn("The generated lu12i.w instruction is out of range.\n");
+ return INSN_BREAK;
+ }
+
emit_lu12iw(&insn, rd, imm);
return insn.word;
@@ -235,6 +240,11 @@ u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm)
{
union loongarch_instruction insn;
+ if (imm < -SZ_512K || imm >= SZ_512K) {
+ pr_warn("The generated lu32i.d instruction is out of range.\n");
+ return INSN_BREAK;
+ }
+
emit_lu32id(&insn, rd, imm);
return insn.word;
@@ -244,16 +254,26 @@ u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm)
{
union loongarch_instruction insn;
+ if (imm < -SZ_2K || imm >= SZ_2K) {
+ pr_warn("The generated lu52i.d instruction is out of range.\n");
+ return INSN_BREAK;
+ }
+
emit_lu52id(&insn, rd, rj, imm);
return insn.word;
}
-u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsigned long pc, unsigned long dest)
+u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm)
{
union loongarch_instruction insn;
- emit_jirl(&insn, rj, rd, (dest - pc) >> 2);
+ if ((imm & 3) || imm < -SZ_128K || imm >= SZ_128K) {
+ pr_warn("The generated jirl instruction is out of range.\n");
+ return INSN_BREAK;
+ }
+
+ emit_jirl(&insn, rj, rd, imm >> 2);
return insn.word;
}