Skip to content

Commit ee9eb9b

Browse files
seehearfeelopsiff
authored andcommitted
objtool/LoongArch: Mark special atomic instruction as INSN_BUG type
mainline inclusion form mainline-v6.17-rc7 category: bugfix When compiling with LLVM and CONFIG_RUST is set, there exists the following objtool warning: rust/compiler_builtins.o: warning: objtool: __rust__unordsf2(): unexpected end of section .text.unlikely. objdump shows that the end of section .text.unlikely is an atomic instruction: amswap.w $zero, $ra, $zero According to the LoongArch Reference Manual, if the amswap.w atomic memory access instruction has the same register number as rd and rj, the execution will trigger an Instruction Non-defined Exception, so mark the above instruction as INSN_BUG type to fix the warning. Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> [It also fixes objtool other warning such as "warning: objtool: __checkpoint_and_complete_reqs() falls through to next function issue_checkpoint_thread()"] (cherry picked from commit 539d734) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
1 parent eef9634 commit ee9eb9b

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

tools/arch/loongarch/include/asm/inst.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ enum reg2i16_op {
5151
bgeu_op = 0x1b,
5252
};
5353

54+
enum reg3_op {
55+
amswapw_op = 0x70c0,
56+
};
57+
5458
struct reg0i15_format {
5559
unsigned int immediate : 15;
5660
unsigned int opcode : 17;
@@ -96,6 +100,13 @@ struct reg2i16_format {
96100
unsigned int opcode : 6;
97101
};
98102

103+
struct reg3_format {
104+
unsigned int rd : 5;
105+
unsigned int rj : 5;
106+
unsigned int rk : 5;
107+
unsigned int opcode : 17;
108+
};
109+
99110
union loongarch_instruction {
100111
unsigned int word;
101112
struct reg0i15_format reg0i15_format;
@@ -105,6 +116,7 @@ union loongarch_instruction {
105116
struct reg2i12_format reg2i12_format;
106117
struct reg2i14_format reg2i14_format;
107118
struct reg2i16_format reg2i16_format;
119+
struct reg3_format reg3_format;
108120
};
109121

110122
#define LOONGARCH_INSN_SIZE sizeof(union loongarch_instruction)

tools/objtool/arch/loongarch/decode.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,25 @@ static bool decode_insn_reg2i16_fomat(union loongarch_instruction inst,
281281
return true;
282282
}
283283

284+
static bool decode_insn_reg3_fomat(union loongarch_instruction inst,
285+
struct instruction *insn)
286+
{
287+
switch (inst.reg3_format.opcode) {
288+
case amswapw_op:
289+
if (inst.reg3_format.rd == LOONGARCH_GPR_ZERO &&
290+
inst.reg3_format.rk == LOONGARCH_GPR_RA &&
291+
inst.reg3_format.rj == LOONGARCH_GPR_ZERO) {
292+
/* amswap.w $zero, $ra, $zero */
293+
insn->type = INSN_BUG;
294+
}
295+
break;
296+
default:
297+
return false;
298+
}
299+
300+
return true;
301+
}
302+
284303
int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
285304
unsigned long offset, unsigned int maxlen,
286305
struct instruction *insn)
@@ -312,6 +331,8 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
312331
return 0;
313332
if (decode_insn_reg2i16_fomat(inst, insn))
314333
return 0;
334+
if (decode_insn_reg3_fomat(inst, insn))
335+
return 0;
315336

316337
if (inst.word == 0)
317338
insn->type = INSN_NOP;

0 commit comments

Comments
 (0)