From: Don Slutz <dslutz@xxxxxxxxxxx> The most common mismatch between crash and older kernels is phys_base. In the remote case, see if the remote server supports vitrual memory access, and if so, see if phys_base can be retreived. Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx> --- defs.h | 1 + remote.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- x86_64.c | 24 +++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/defs.h b/defs.h index 4cb2113..e7073c6 100755 --- a/defs.h +++ b/defs.h @@ -5526,6 +5526,7 @@ void dump_sockets_workhorse(ulong, ulong, struct reference *); * remote.c */ int is_remote_daemon(char *); +physaddr_t get_remote_phys_base(physaddr_t, physaddr_t); void remote_fd_init(void); int get_remote_file(struct remote_file *); uint remote_page_size(void); diff --git a/remote.c b/remote.c index 823aba0..58588ce 100755 --- a/remote.c +++ b/remote.c @@ -1797,6 +1797,7 @@ static void copy_to_local_namelist(struct remote_file *); static char *create_local_namelist(struct remote_file *); static int remote_find_booted_kernel(struct remote_file *); static int remote_proc_version(char *); +static int validate_phys_base(physaddr_t, physaddr_t, physaddr_t); static int remote_file_open(struct remote_file *); static int remote_file_close(struct remote_file *); static int identical_namelist(char *, struct remote_file *); @@ -1813,6 +1814,14 @@ static int remote_tcp_read_string(int, const char *, size_t, int); static int remote_tcp_write(int, const void *, size_t); static int remote_tcp_write_string(int, const char *); +struct _remote_context { + int nCpus; + int vFd; + char remoteType[10]; +} remote_context; + +struct _remote_context *rc = &remote_context; + /* * Parse, verify and establish a connection with the network daemon * specified on the crash command line. @@ -1848,7 +1857,7 @@ is_remote_daemon(char *dp) pc->port = 0; pc->server = pc->server_memsrc = NULL; - pc->rmfd = pc->rkfd = -1; + rc->vFd = pc->rmfd = pc->rkfd = -1; file1 = file2 = NULL; if ((filep = strstr(dp, ","))) { @@ -2280,6 +2289,59 @@ remote_proc_version(char *buf) } /* + * Check that virt_phys_base when accessed via + * phys_base - text_start is phys_base. + */ +static int +validate_phys_base(physaddr_t phys_base, physaddr_t text_start, physaddr_t virt_phys_base) +{ + ulong value; + + if (CRASHDEBUG(3)) + fprintf(fp, "validate_phys_base: virt_phys_base=0x%llx phys_base=0x%llx text_start=0x%llx calc=0x%llx\n", + virt_phys_base, phys_base, text_start, virt_phys_base + phys_base - text_start); + + if (READMEM(pc->rmfd, (void*)&value, sizeof(value), + virt_phys_base, virt_phys_base + phys_base - text_start) + == sizeof(value)) { + if (value == phys_base) + return 1; + } + return 0; +} + +/* + * Get remote phys_base based on virtual address of "phys_base". + */ +physaddr_t +get_remote_phys_base(physaddr_t text_start, physaddr_t virt_phys_base) +{ + int vcpu; + ulong value; + + if (rc->vFd < 0) { + struct remote_file remote_file, *rfp; + + rfp = &remote_file; + BZERO(rfp, sizeof(struct remote_file)); + rfp->filename = "/dev/vmem"; + if (remote_file_open(rfp)) { + rc->vFd = rfp->fd; + } else + return 0; + } + + for (vcpu = 0; vcpu < rc->nCpus; vcpu++) + if (remote_memory_read(rc->vFd, (void*)&value, sizeof(value), + virt_phys_base, vcpu) == sizeof(value)) { + if (validate_phys_base(value, text_start, virt_phys_base)) + return value; + } + + return 0; +} + +/* * * Set up the file descriptors and file name strings if they haven't * been set up before: @@ -2999,7 +3061,7 @@ remote_page_size(void) { char sendbuf[BUFSIZE]; char recvbuf[BUFSIZE]; - char *p1; + char *p1, *p2, *p3; uint psz; BZERO(sendbuf, BUFSIZE); @@ -3026,12 +3088,21 @@ remote_page_size(void) strtok(recvbuf, " "); /* PAGESIZE */ p1 = strtok(NULL, " "); /* LIVE, MCLXCD or LKCD */ p1 = strtok(NULL, " "); /* page size */ + p2 = strtok(NULL, " "); /* remote type */ + p3 = strtok(NULL, " "); /* number of Cpus */ psz = atoi(p1); if (psz > MAXRECVBUFSIZE) error(FATAL, "remote page size %d is larger than MAXRECVBUFSIZE!\n", psz); + if (p2) { + strncpy(rc->remoteType, p2, sizeof(rc->remoteType) - 1); + rc->remoteType[sizeof(rc->remoteType) - 1] = 0; + } + if (p3) + rc->nCpus = atoi(p3); + return psz; } diff --git a/x86_64.c b/x86_64.c index e8196f8..e5f8f19 100755 --- a/x86_64.c +++ b/x86_64.c @@ -5838,6 +5838,18 @@ x86_64_calc_phys_base(void) return; else text_start = symbol_value("_text"); + if (REMOTE()) { + phys_base = get_remote_phys_base(text_start, symbol_value("phys_base")); + if (phys_base) { + machdep->machspec->phys_base = phys_base; + if (CRASHDEBUG(1)) { + fprintf(fp, "_text: %lx ", text_start); + fprintf(fp, "phys_base: %lx\n\n", + machdep->machspec->phys_base); + } + return; + } + } } if (ACTIVE()) { @@ -7680,3 +7692,15 @@ x86_64_verify_paddr(uint64_t paddr) } #endif /* X86_64 */ + +/* + * Specify Emacs local variables so the formating + * of the code stays the same. + * + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 8 + * indent-tabs-mode: t + * End: + */ -- 1.8.4 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility