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 | 3 +++ remote.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- x86_64.c | 12 +++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/defs.h b/defs.h index 86b4fae..8d56da8 100755 --- a/defs.h +++ b/defs.h @@ -504,6 +504,8 @@ struct program_context { #define GET_LOG (0x200ULL) #define VMCOREINFO (0x400ULL) #define ALLOW_FP (0x800ULL) +#define REM_PAUSED_F (0x1000ULL) +#define REMOTE_PAUSED() (pc->flags2 & REM_PAUSED_F) char *cleanup; char *namelist_orig; char *namelist_debug_orig; @@ -5525,6 +5527,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 204f7b8..a4069a7 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 *); @@ -1815,6 +1816,9 @@ static int remote_tcp_write_string(int, const char *); struct _remote_context { uint flags; + int n_cpus; + int vfd; + char remote_type[10]; } remote_context; #define NIL_FLAG (0x01U) @@ -1858,7 +1862,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, ","))) { @@ -2290,6 +2294,62 @@ 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", + (long long unsigned int)virt_phys_base, + (long long unsigned int)phys_base, + (long long unsigned int)text_start, + (long long unsigned int)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->n_cpus; 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: @@ -3009,7 +3069,7 @@ remote_page_size(void) { char sendbuf[BUFSIZE]; char recvbuf[BUFSIZE]; - char *p1; + char *p1, *p2, *p3; uint psz; BZERO(sendbuf, BUFSIZE); @@ -3036,12 +3096,23 @@ 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->remote_type, p2, sizeof(rc->remote_type) - 1); + rc->remote_type[sizeof(rc->remote_type) - 1] = 0; + if (rc->remote_type[0] != 'L') + pc->flags2 |= REM_PAUSED_F; + } + if (p3) + rc->n_cpus = atoi(p3); + return psz; } diff --git a/x86_64.c b/x86_64.c index e8196f8..cc26fec 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()) { -- 1.8.4 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility