summaryrefslogtreecommitdiff
path: root/arch/loongarch/kernel
diff options
context:
space:
mode:
authorWANG Rui <wangrui@loongson.cn>2023-06-29 15:58:42 +0300
committerHuacai Chen <chenhuacai@loongson.cn>2023-06-29 15:58:42 +0300
commit0d03e9dce5c91d841a35af05ca61a5cf318f5064 (patch)
tree24f8cd43a83332492c776c5928fc2956c970f87c /arch/loongarch/kernel
parentd7c24960975b02211c53afe97c36acde5c8ff933 (diff)
downloadlinux-0d03e9dce5c91d841a35af05ca61a5cf318f5064.tar.xz
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')
-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;
}