|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/traps: widen condition for logging top-of-stack
commit 445891bb8ea77ebc9bee98c4507b077d96928521
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Sep 24 10:48:44 2019 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Sep 24 10:48:44 2019 +0200
x86/traps: widen condition for logging top-of-stack
Despite -fno-omit-frame-pointer the compiler may omit the frame pointer,
often for relatively simple leaf functions. (To give a specific example,
the case I've run into this with is _pci_hide_device() and gcc 8.
Interestingly the even more simple neighboring iommu_has_feature() does
get a frame pointer set up, around just a single instruction. But this
may be a result of the size-of-asm() effects discussed elsewhere.)
Log the top-of-stack value if it looks valid _or_ if RIP looks invalid.
Also annotate all stack trace entries with a marker, to indicate their
origin:
R: register state
F: frame pointer based
S: raw stack contents
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
xen/arch/x86/traps.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 31d270b1ee..98919a0725 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -439,7 +439,7 @@ static void _show_trace(unsigned long sp, unsigned long
__maybe_unused bp)
{
addr = *stack++;
if ( is_active_kernel_text(addr) )
- printk(" [<%p>] %pS\n", _p(addr), _p(addr));
+ printk(" [<%p>] S %pS\n", _p(addr), _p(addr));
}
}
@@ -482,7 +482,7 @@ static void _show_trace(unsigned long sp, unsigned long bp)
addr = frame[1];
}
- printk(" [<%p>] %pS\n", _p(addr), _p(addr));
+ printk(" [<%p>] F %pS\n", _p(addr), _p(addr));
low = (unsigned long)&frame[2];
}
@@ -511,21 +511,26 @@ static void show_trace(const struct cpu_user_regs *regs)
*/
if ( is_active_kernel_text(regs->rip) ||
!is_active_kernel_text(tos) )
- printk(" [<%p>] %pS\n", _p(regs->rip), _p(regs->rip));
- else if ( fault )
+ printk(" [<%p>] R %pS\n", _p(regs->rip), _p(regs->rip));
+
+ if ( fault )
{
printk(" [Fault on access]\n");
return;
}
+
/*
- * Else RIP looks bad but the top of the stack looks good. Perhaps we
- * followed a wild function pointer? Lets assume the top of the stack is a
+ * If RIP looks bad or the top of the stack looks good, log the top of
+ * stack as well. Perhaps we followed a wild function pointer, or we're
+ * in a function without frame pointer, or in a function prologue before
+ * the frame pointer gets set up? Let's assume the top of the stack is a
* return address; print it and skip past so _show_trace() doesn't print
* it again.
*/
- else
+ if ( !is_active_kernel_text(regs->rip) ||
+ is_active_kernel_text(tos) )
{
- printk(" [<%p>] %pS\n", _p(tos), _p(tos));
+ printk(" [<%p>] S %pS\n", _p(tos), _p(tos));
sp++;
}
--
generated by git-patchbot for /home/xen/git/xen.git#staging
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |