x86/unwind/orc: Detect the end of the stack
The existing UNWIND_HINT_EMPTY annotations happen to be good indicators of where entry code calls into C code for the first time. So also use them to mark the end of the stack for the ORC unwinder. Use that information to set unwind->error if the ORC unwinder doesn't unwind all the way to the end. This will be needed for enabling HAVE_RELIABLE_STACKTRACE for the ORC unwinder so we can use it with the livepatch consistency model. Thanks to Jiri Slaby for teaching the ORCs about the unwind hints. Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Jiri Slaby <jslaby@suse.cz> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: https://lkml.kernel.org/lkml/20180518064713.26440-5-jslaby@suse.cz Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:

committed by
Ingo Molnar

parent
0c414367c0
commit
d31a580266
@@ -88,6 +88,7 @@ struct orc_entry {
|
||||
unsigned sp_reg:4;
|
||||
unsigned bp_reg:4;
|
||||
unsigned type:2;
|
||||
unsigned end:1;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@@ -101,6 +102,7 @@ struct unwind_hint {
|
||||
s16 sp_offset;
|
||||
u8 sp_reg;
|
||||
u8 type;
|
||||
u8 end;
|
||||
};
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
@@ -1156,6 +1156,7 @@ static int read_unwind_hints(struct objtool_file *file)
|
||||
|
||||
cfa->offset = hint->sp_offset;
|
||||
insn->state.type = hint->type;
|
||||
insn->state.end = hint->end;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -31,7 +31,7 @@ struct insn_state {
|
||||
int stack_size;
|
||||
unsigned char type;
|
||||
bool bp_scratch;
|
||||
bool drap;
|
||||
bool drap, end;
|
||||
int drap_reg, drap_offset;
|
||||
struct cfi_reg vals[CFI_NUM_REGS];
|
||||
};
|
||||
|
@@ -203,7 +203,8 @@ int orc_dump(const char *_objname)
|
||||
|
||||
print_reg(orc[i].bp_reg, orc[i].bp_offset);
|
||||
|
||||
printf(" type:%s\n", orc_type_name(orc[i].type));
|
||||
printf(" type:%s end:%d\n",
|
||||
orc_type_name(orc[i].type), orc[i].end);
|
||||
}
|
||||
|
||||
elf_end(elf);
|
||||
|
@@ -31,6 +31,8 @@ int create_orc(struct objtool_file *file)
|
||||
struct cfi_reg *cfa = &insn->state.cfa;
|
||||
struct cfi_reg *bp = &insn->state.regs[CFI_BP];
|
||||
|
||||
orc->end = insn->state.end;
|
||||
|
||||
if (cfa->base == CFI_UNDEFINED) {
|
||||
orc->sp_reg = ORC_REG_UNDEFINED;
|
||||
continue;
|
||||
|
Reference in New Issue
Block a user