--- crash-4.0-7.2/tools.c 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/tools.c 2008-09-29 16:40:37.000000000 -0400 @@ -1673,6 +1673,9 @@ switch(c) { case 'c': + if (XEN_HYPER_MODE()) + option_not_supported(c); + if (!runtime) { error(INFO, "cpu setting not allowed from .%src\n", @@ -1689,6 +1692,9 @@ return; case 'p': + if (XEN_HYPER_MODE()) + option_not_supported(c); + if (!runtime) return; @@ -1723,7 +1729,10 @@ } if (!args[optind]) { - if (runtime) + if (XEN_HYPER_MODE()) + error(INFO, + "requires an option with the Xen hypervisor\n"); + else if (runtime) show_context(CURRENT_CONTEXT()); return; } @@ -2144,6 +2153,8 @@ "on" : "off"); return; + } else if (XEN_HYPER_MODE()) { + error(FATAL, "invalid argument for the Xen hypervisor\n"); } else if (runtime) { ulong pid, task; @@ -4548,13 +4559,15 @@ void command_not_supported() { - error(FATAL, "command not supported on this architecture or kernel\n"); + error(FATAL, + "command not supported or applicable on this architecture or kernel\n"); } void option_not_supported(int c) { - error(FATAL, "-%c option not supported on this architecture or kernel\n", + error(FATAL, + "-%c option not supported or applicable on this architecture or kernel\n", (char)c); } --- crash-4.0-7.2/memory.c 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/memory.c 2008-10-09 11:31:19.000000000 -0400 @@ -1086,6 +1086,7 @@ uint16_t u16; uint32_t u32; uint64_t u64; + uint64_t limit64; }; static void @@ -1137,6 +1138,7 @@ addr, count, flag, addrtype); origaddr = addr; + BZERO(&mem, sizeof(struct memloc)); switch (flag & (DISPLAY_TYPES)) { @@ -1146,6 +1148,8 @@ location = &mem.u64; sprintf(readtype, "64-bit %s", addrtype); per_line = ENTRIES_64; + if (machine_type("IA64")) + mem.limit64 = kt->end; break; case DISPLAY_32: @@ -1197,10 +1201,10 @@ case DISPLAY_64: if ((flag & (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) == (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) { - if (in_ksymbol_range(mem.u64) && + if ((!mem.limit64 || (mem.u64 <= mem.limit64)) && + in_ksymbol_range(mem.u64) && strlen(value_to_symstr(mem.u64, buf, 0))) { - fprintf(fp, "%-16s ", - value_to_symstr(mem.u64, buf, 0)); + fprintf(fp, "%-16s ", buf); linelen += strlen(buf)+1; break; } @@ -1237,9 +1241,7 @@ if (in_ksymbol_range(mem.u32) && strlen(value_to_symstr(mem.u32, buf, 0))) { fprintf(fp, INT_PRLEN == 16 ? - "%-16s " : "%-8s ", - value_to_symstr(mem.u32, - buf, 0)); + "%-16s " : "%-8s ", buf); linelen += strlen(buf)+1; break; } @@ -11297,7 +11299,9 @@ if (vaddr < vaddr_orig) /* wrapped back to zero? */ return FALSE; - if (IS_VMALLOC_ADDR(vaddr_orig)) { + if (IS_VMALLOC_ADDR(vaddr_orig) || + (machine_type("IA64") && IS_VMALLOC_ADDR(vaddr))) { + if (IS_VMALLOC_ADDR(vaddr) && (vaddr < last_vmalloc_address())) { if (machine_type("X86_64")) --- crash-4.0-7.2/kernel.c 2008-10-10 13:48:49.000000000 -0400 +++ crash-4.0-7.3/kernel.c 2008-09-29 16:37:05.000000000 -0400 @@ -1604,11 +1604,14 @@ break; case 'o': + if (XEN_HYPER_MODE()) + option_not_supported(c); bt->flags |= BT_OLD_BACK_TRACE; break; case 'O': - if (!(machine_type("X86") || machine_type("X86_64"))) + if (!(machine_type("X86") || machine_type("X86_64")) || + XEN_HYPER_MODE()) option_not_supported(c); else if (kt->flags & USE_OLD_BT) { /* @@ -1644,11 +1647,15 @@ break; case 'E': + if (XEN_HYPER_MODE()) + option_not_supported(c); bt->flags |= BT_EFRAME_SEARCH|BT_EFRAME_SEARCH2; bt->hp = &hook; break; case 'e': + if (XEN_HYPER_MODE()) + option_not_supported(c); bt->flags |= BT_EFRAME_SEARCH; break; @@ -1738,11 +1745,6 @@ } } - if (XEN_HYPER_MODE()) { - if (bt->flags & BT_EFRAME_SEARCH) - argerrs++; - } - if (argerrs) cmd_usage(pc->curcmd, SYNOPSIS); @@ -1783,7 +1785,9 @@ continue; fake_tc.task = xen_hyper_pcpu_to_active_vcpu(c); BT_SETUP(&fake_tc); - xen_hyper_print_bt_header(fp, fake_tc.task, subsequent++); + if (!BT_REFERENCE_CHECK(bt)) + xen_hyper_print_bt_header(fp, fake_tc.task, + subsequent++); back_trace(bt); } } else { @@ -1794,7 +1798,8 @@ fake_tc.task = XEN_HYPER_VCPU_LAST_CONTEXT()->vcpu; } BT_SETUP(&fake_tc); - xen_hyper_print_bt_header(fp, fake_tc.task, 0); + if (!BT_REFERENCE_CHECK(bt)) + xen_hyper_print_bt_header(fp, fake_tc.task, 0); back_trace(bt); } return; @@ -2080,7 +2085,10 @@ goto complete_trace; if (BT_REFERENCE_FOUND(bt)) { - print_task_header(fp, task_to_context(bt->task), 0); + if (XEN_HYPER_MODE()) + xen_hyper_print_bt_header(fp, bt->task, 0); + else + print_task_header(fp, task_to_context(bt->task), 0); BCOPY(&btsave, bt, sizeof(struct bt_info)); bt->ref = NULL; machdep->back_trace(bt); @@ -2104,8 +2112,12 @@ { case BT_HARDIRQ: bt->instptr = symbol_value("do_IRQ"); - bt->stkptr = ULONG(bt->stackbuf + - SIZE(irq_ctx) - (sizeof(unsigned int)*2)); + if (symbol_exists("__do_IRQ")) + bt->stkptr = ULONG(bt->stackbuf + + OFFSET(thread_info_previous_esp)); + else + bt->stkptr = ULONG(bt->stackbuf + + SIZE(irq_ctx) - (sizeof(unsigned int)*2)); type = BT_HARDIRQ; break; --- crash-4.0-7.2/x86.c 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/x86.c 2008-10-10 08:55:35.000000000 -0400 @@ -3240,7 +3240,8 @@ fprintf(fp, " cmd_mach: x86_cmd_mach()\n"); fprintf(fp, " get_smp_cpus: x86_get_smp_cpus()\n"); fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n"); - fprintf(fp, " is_uvaddr: generic_is_uvaddr()\n"); + fprintf(fp, " is_uvaddr: %s\n", COMMON_VADDR_SPACE() ? + "x86_is_uvaddr()" : "generic_is_uvaddr()"); fprintf(fp, " verify_paddr: generic_verify_paddr()\n"); fprintf(fp, " init_kernel_pgd: x86_init_kernel_pgd()\n"); fprintf(fp, " value_to_symbol: %s\n", @@ -4125,8 +4126,6 @@ int i; ulong value; - value = symbol_value("swapper_pg_dir"); - if (XEN()) get_symbol_data("swapper_pg_dir", sizeof(ulong), &value); else --- crash-4.0-7.2/ia64.c 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/ia64.c 2008-09-25 14:56:20.000000000 -0400 @@ -1053,6 +1053,12 @@ case KERNEL_VMALLOC_REGION: if (ia64_IS_VMALLOC_ADDR(kvaddr)) break; + if ((kvaddr < machdep->machspec->kernel_start) && + (machdep->machspec->kernel_region == + KERNEL_VMALLOC_REGION)) { + *paddr = PADDR_NOT_AVAILABLE; + return FALSE; + } *paddr = ia64_VTOP(kvaddr); if (verbose) fprintf(fp, "[MAPPED IN TRANSLATION REGISTER]\n"); --- crash-4.0-7.2/x86_64.c 2008-10-10 13:48:49.000000000 -0400 +++ crash-4.0-7.3/x86_64.c 2008-10-02 09:15:17.000000000 -0400 @@ -3784,6 +3784,10 @@ char buf[BUFSIZE]; ulong *ip; + if (INVALID_SIZE(gate_struct)) { + option_not_supported('d'); + return; + } idt_table_buf = GETBUF(SIZE(gate_struct) * 256); readmem(symbol_value("idt_table"), KVADDR, idt_table_buf, SIZE(gate_struct) * 256, "idt_table", FAULT_ON_ERROR); --- crash-4.0-7.2/netdump.c 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/netdump.c 2008-10-10 11:10:38.000000000 -0400 @@ -876,6 +876,10 @@ nd->xen_kdump_data->p2m_frames); netdump_print(" xen_phys_start: %lx\n", nd->xen_kdump_data->xen_phys_start); + netdump_print(" xen_major_version: %d\n", + nd->xen_kdump_data->xen_major_version); + netdump_print(" xen_minor_version: %d\n", + nd->xen_kdump_data->xen_minor_version); netdump_print(" p2m_mfn_frame_list: %lx\n", nd->xen_kdump_data->p2m_mfn_frame_list); for (i = 0; i < nd->xen_kdump_data->p2m_frames; i++) @@ -1525,6 +1529,8 @@ nd->xen_kdump_data->p2m_mfn = *(uptr+(words-1)); if (words > 9 && !nd->xen_kdump_data->xen_phys_start) nd->xen_kdump_data->xen_phys_start = *(uptr+(words-2)); + nd->xen_kdump_data->xen_major_version = *uptr; + nd->xen_kdump_data->xen_minor_version = *(uptr+1); } } break; @@ -1730,6 +1736,8 @@ nd->xen_kdump_data->p2m_mfn = *(up+(words-1)); if (words > 9 && !nd->xen_kdump_data->xen_phys_start) nd->xen_kdump_data->xen_phys_start = *(up+(words-2)); + nd->xen_kdump_data->xen_major_version = *up; + nd->xen_kdump_data->xen_minor_version = *(up+1); } } break; @@ -2343,3 +2351,15 @@ { return nd->xen_kdump_data->xen_phys_start; } + +int +xen_major_version(void) +{ + return nd->xen_kdump_data->xen_major_version; +} + +int +xen_minor_version(void) +{ + return nd->xen_kdump_data->xen_minor_version; +} --- crash-4.0-7.2/xen_hyper.c 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/xen_hyper.c 2008-10-10 10:44:28.000000000 -0400 @@ -71,6 +71,13 @@ #endif #if defined(X86) || defined(X86_64) + if (symbol_exists("__per_cpu_shift")) { + xht->percpu_shift = (int)symbol_value("__per_cpu_shift"); + } else if (xen_major_version() >= 3 && xen_minor_version() >= 3) { + xht->percpu_shift = 13; + } else { + xht->percpu_shift = 12; + } member_offset = MEMBER_OFFSET("cpuinfo_x86", "x86_model_id"); buf = GETBUF(XEN_HYPER_SIZE(cpuinfo_x86)); if (xen_hyper_test_pcpu_id(XEN_HYPER_CRASHING_CPU())) { @@ -1746,9 +1753,11 @@ tmp2 = (ulong)jiffies_64; jiffies_64 = (ulonglong)(tmp2 - tmp1); } - } else { + } else if (symbol_exists("jiffies")) { get_symbol_data("jiffies", sizeof(long), &jiffies); jiffies_64 = (ulonglong)jiffies; + } else { + jiffies_64 = 0; /* hypervisor does not have uptime */ } return jiffies_64; --- crash-4.0-7.2/xen_hyper_command.c 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/xen_hyper_command.c 2008-10-10 10:44:28.000000000 -0400 @@ -1022,7 +1022,8 @@ (buf1, "%d\n", XEN_HYPER_NR_DOMAINS())); /* !!!Display a date here if it can be found. */ XEN_HYPER_PRI(fp, len, "UPTIME: ", buf1, flag, - (buf1, "%s\n", convert_time(xen_hyper_get_uptime_hyper(), buf2))); + (buf1, "%s\n", (xen_hyper_get_uptime_hyper() ? + convert_time(xen_hyper_get_uptime_hyper(), buf2) : "--:--:--"))); /* !!!Display a version here if it can be found. */ XEN_HYPER_PRI_CONST(fp, len, "MACHINE: ", flag); if (strlen(uts->machine)) { --- crash-4.0-7.2/xen_hyper_global_data.c 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/xen_hyper_global_data.c 2008-09-29 16:38:45.000000000 -0400 @@ -74,7 +74,6 @@ {"eval", cmd_eval, help_eval, 0}, {"exit", cmd_quit, help_exit, 0}, {"extend", cmd_extend, help_extend, 0}, - {"foreach", cmd_foreach, help_foreach, 0}, {"gdb", cmd_gdb, help_gdb, 0}, {"help", xen_hyper_cmd_help, help_help, 0}, {"list", cmd_list, help__list, 0}, --- crash-4.0-7.2/defs.h 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/defs.h 2008-10-10 10:44:28.000000000 -0400 @@ -4118,6 +4118,8 @@ int is_sadump_xen(void); void set_xen_phys_start(char *); ulong xen_phys_start(void); +int xen_major_version(void); +int xen_minor_version(void); /* * diskdump.c --- crash-4.0-7.2/xen_hyper_defs.h 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/xen_hyper_defs.h 2008-10-10 10:44:28.000000000 -0400 @@ -134,9 +134,8 @@ #endif #if defined(X86) || defined(X86_64) -#define XEN_HYPER_PERCPU_SHIFT 12 #define xen_hyper_per_cpu(var, cpu) \ - ((ulong)(var) + (((ulong)(cpu))<percpu_shift)) #elif defined(IA64) #define xen_hyper_per_cpu(var, cpu) \ ((xht->flags & XEN_HYPER_SMP) ? \ @@ -404,6 +403,7 @@ ulong *cpumask; uint *cpu_idxs; ulong *__per_cpu_offset; + int percpu_shift; }; struct xen_hyper_dumpinfo_context { --- crash-4.0-7.2/netdump.h 2008-10-10 13:48:48.000000000 -0400 +++ crash-4.0-7.3/netdump.h 2008-10-10 10:44:28.000000000 -0400 @@ -110,6 +110,8 @@ int p2m_frames; ulong *p2m_mfn_frame_list; ulong xen_phys_start; + int xen_major_version; + int xen_minor_version; }; #define KDUMP_P2M_INIT (0x1)