Blob Blame History Raw
commit f3a5305947077a65aea8091b05cdb542cea0d61a
Author: Dave Anderson <anderson@redhat.com>
Date:   Wed Oct 24 16:25:43 2018 -0400

    Modify the x86_64 "bt" behavior when a legitimate exception RIP value
    cannot be referenced symbolically, such as when the exception occurs
    while running in seccomp BPF filter code.  Without the patch, the
    exception frame register dump is preceded by "[exception RIP: unknown
    or invalid address]", and then followed by "bt: WARNING: possibly
    bogus exception frame".  With the patch applied, the translation of
    the exception RIP will show "[exception RIP: no symbolic reference]",
    and there will be no warning message.
    (anderson@redhat.com)

diff --git a/x86_64.c b/x86_64.c
index 345122c..d145f96 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -3259,6 +3259,18 @@ x86_64_in_alternate_stack(int cpu, ulong
 	return FALSE;
 }
 
+static char *
+x86_64_exception_RIP_message(struct bt_info *bt, ulong rip)
+{
+	physaddr_t phys;
+	
+	if (IS_VMALLOC_ADDR(rip) && 
+	    machdep->kvtop(bt->tc, rip, &phys, 0))
+		return ("no symbolic reference");
+ 
+	return ("unknown or invalid address");
+}
+
 #define STACK_TRANSITION_ERRMSG_E_I_P \
 "cannot transition from exception stack to IRQ stack to current process stack:\n    exception stack pointer: %lx\n          IRQ stack pointer: %lx\n      process stack pointer: %lx\n         current stack base: %lx\n" 
 #define STACK_TRANSITION_ERRMSG_E_P \
@@ -3370,7 +3382,7 @@ x86_64_low_budget_back_trace_cmd(struct
 				fprintf(ofp, (*gdb_output_radix == 16) ?
 					"+0x%lx" : "+%ld", offset);
 		} else
-			fprintf(ofp, "unknown or invalid address");
+			fprintf(ofp, "%s", x86_64_exception_RIP_message(bt, bt->instptr));
 		fprintf(ofp, "]\n");
 		if (KVMDUMP_DUMPFILE())
 			kvmdump_display_regs(bt->tc->processor, ofp);
@@ -4458,9 +4470,9 @@ x86_64_exception_frame(ulong flags, ulon
 						    (*gdb_output_radix == 16) ? 
 						    "+0x%lx" : "+%ld", 
 						    offset);
-				} else 
-					fprintf(ofp, 
-						"unknown or invalid address");
+				} else
+					fprintf(ofp, "%s", 
+						x86_64_exception_RIP_message(bt, rip));
 				fprintf(ofp, "]\n");
 			}
 		} else if (!(cs & 3)) {
@@ -4472,7 +4484,7 @@ x86_64_exception_frame(ulong flags, ulon
 						"+0x%lx" : "+%ld", offset);
 				bt->eframe_ip = rip;
 			} else
-                		fprintf(ofp, "unknown or invalid address");
+				fprintf(ofp, "%s", x86_64_exception_RIP_message(bt, rip));
 			fprintf(ofp, "]\n");
 		}
 		fprintf(ofp, "    RIP: %016lx  RSP: %016lx  RFLAGS: %08lx\n", 
@@ -4616,6 +4628,7 @@ x86_64_eframe_verify(struct bt_info *bt,
 	int estack;
 	struct syment *sp;
 	ulong offset, exception;
+	physaddr_t phys;
 
 	if ((rflags & RAZ_MASK) || !(rflags & 0x2))
 		return FALSE;
@@ -4682,6 +4695,12 @@ x86_64_eframe_verify(struct bt_info *bt,
 			return TRUE;
 	}
 
+	if ((cs == 0x10) && kvaddr) {
+                if (IS_KVADDR(rsp) && IS_VMALLOC_ADDR(rip) && 
+		    machdep->kvtop(bt->tc, rip, &phys, 0))
+			return TRUE;
+	}
+
         if ((cs == 0x33) && (ss == 0x2b)) {
                 if (IS_UVADDR(rip, bt->tc) && IS_UVADDR(rsp, bt->tc))
                         return TRUE;