Introduce the 'crashtables' interface as an extensible method of passing data to the crashdump kernel, providing a substantially more flexability than the current method XenServer uses of hacking around with the symbol file. Care is taken to suitably align values, and to expliticly disabiguate pointers from sizes by use of a separate table, despite the raw data being compatabile between the two. In addition, all the details for "low_crashinfo=min" are passed into their respective tables. Changes since v1: * Fix up naming conventions and static qualifiers. * Remove XENLOG_WARNINGs, as in the case of a crash, they are little or no use. Instead, mark entries as invalid so as to reduce confusion to the crashdump kernel trying to parse the table. * Change strtab setup so a failure at that point wont fail the entire kexec setup. * Change the modifications to console.c to prevent marking conring and conring_size as global symbols. * Add more details into crashtables.h clarifying certain information. * Add emacs local variables at the end of crashtables.h Signed-off-by: Andrew Cooper diff -r 8ef04a0f6241 -r 90208fe69bd4 xen/common/kexec.c --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,9 @@ #include #include #include +#include #include +#include #include #include #ifdef CONFIG_COMPAT @@ -41,7 +44,7 @@ static crash_note_range_t * crash_notes; * crash note buffers in lower memory. */ static DEFINE_SPINLOCK(crash_notes_lock); -static Elf_Note *xen_crash_note; +static Elf_Note *xen_crash_note, *xen_stringtab, *xen_valtab, *xen_symtab; static cpumask_t crash_saved_cpus; @@ -82,6 +85,22 @@ paddr_t crashinfo_maxaddr_bits = 64; /* Pointers to keep track of the crash heap region. */ static void *crash_heap_current = NULL, *crash_heap_end = NULL; +/* Crash table data structures */ +static char * crash_strtab = NULL; +static size_t crash_strtab_size = 0; + +static val64tab_t crash_val64tab[] = +{ + { XEN_VALTAB_MAX_PAGE, 0 }, + { XEN_VALTAB_CONRING_SIZE, 0 } +}; + +static sym64tab_t crash_sym64tab[] = +{ + { XEN_SYMTAB_CONRING, 0 } +}; + + /* * Parse command lines in the format * @@ -262,12 +281,115 @@ void kexec_crash_save_cpu(void) elf_core_save_regs(&prstatus->pr_reg, xencore); } +/* Round val up to a machine word alignment */ +size_t round_up(size_t val) +{ + return ((val + (sizeof(unsigned long)-1)) & + ~((sizeof (unsigned long))-1)); +} + +extern xen_commandline_t saved_cmdline; +/* Setup the stringtable. In case of failue, crash_strtab pointer is left + * as NULL. */ +static int setup_strtab(void) +{ + char * ptr; + size_t sl = sizeof(unsigned long); + +#define STRING(x) #x +#define INT2STR(x) STRING(x) + +#define XEN_STR_VERSION INT2STR(XEN_VERSION) "." INT2STR(XEN_SUBVERSION) \ + XEN_EXTRAVERSION +#define XEN_STR_COMPILED_BY XEN_COMPILE_BY "@" XEN_COMPILE_HOST "." \ + XEN_COMPILE_DOMAIN + + size_t size = + sl + round_up(sizeof(XEN_STR_VERSION)) + + sl + round_up(sizeof(XEN_CHANGESET)) + + sl + round_up(sizeof(XEN_COMPILE_DATE)) + + sl + round_up(sizeof(XEN_STR_COMPILED_BY)) + + sl + round_up(sizeof(XEN_COMPILER)) + + sl + round_up(strlen(saved_cmdline)+1); + + crash_strtab = xzalloc_bytes(size); + if ( ! crash_strtab ) + return -ENOMEM; + + crash_strtab_size = size; + ptr = crash_strtab; + +#define WRITE_STRTAB_ENTRY_CONST(v, s) \ + *(unsigned long*)ptr = (v); ptr += sl; \ + memcpy(ptr, s, sizeof(s)); ptr += round_up(sizeof(s)) + +#define WRITE_STRTAB_ENTRY_VAR(v, s) \ + *(unsigned long*)ptr = (v); ptr += sl; \ + memcpy(ptr, s, strlen(s)); ptr += round_up(strlen(s)+1) + + WRITE_STRTAB_ENTRY_CONST(XEN_STRINGTAB_VERSION, XEN_STR_VERSION); + WRITE_STRTAB_ENTRY_CONST(XEN_STRINGTAB_CSET, XEN_CHANGESET); + WRITE_STRTAB_ENTRY_CONST(XEN_STRINGTAB_COMPILE_DATE, XEN_COMPILE_DATE); + WRITE_STRTAB_ENTRY_CONST(XEN_STRINGTAB_COMPILED_BY, XEN_STR_COMPILED_BY); + WRITE_STRTAB_ENTRY_CONST(XEN_STRINGTAB_COMPILER, XEN_COMPILER); + WRITE_STRTAB_ENTRY_VAR(XEN_STRINGTAB_CMDLINE, saved_cmdline); + +#undef WRITE_STRTAB_ENTRY_VAR +#undef WRITE_STRTAB_ENTRY_CONST +#undef XEN_STR_COMPILED_BY +#undef XEN_STR_VERSION +#undef INT2STR +#undef STRING + + return 0; +} + +static void write_val64tab(void) +{ + int i; + for ( i=0; i LOW_CRASHINFO_NONE ) { size_t crash_heap_size; diff -r 8ef04a0f6241 -r 90208fe69bd4 xen/drivers/char/console.c --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -996,6 +996,34 @@ void __warn(char *file, int line) } +/* Write static values into crashtables. This saves making these symbols + * non static. */ +void console_write_val64tab(val64tab_t * valtab) +{ + switch(valtab->id) + { + case XEN_VALTAB_CONRING_SIZE: + valtab->val = (uint64_t)conring_size; + break; + default: + break; + } +} + +void console_write_sym64tab(sym64tab_t * symtab) +{ + switch(symtab->id) + { + case XEN_SYMTAB_CONRING: + symtab->addr = (uint64_t)__pa(conring); + break; + default: + break; + } +} + + + /* * ************************************************************** * ****************** Console suspend/resume ******************** diff -r 8ef04a0f6241 -r 90208fe69bd4 xen/include/public/crashtables.h --- /dev/null +++ b/xen/include/public/crashtables.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * crashtables.h + * + * Definitions used for the Xen ELF crash notes. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2011,2012 Andrew Cooper, Citrix Ltd. + */ + +#ifndef __XEN_PUBLIC_CRASHTABLES_H__ +#define __XEN_PUBLIC_CRASHTABLES_H__ + +#include "xen.h" + +/* + * Xen crash tables. + * + * Base number chosen as the logical progression following + * XEN_ELFNOTE_CRASH and XEN_ELFNOTE_DUMPCORE. + * + * Crashdump envronments can work out how long an 'unsigned long' is by the type + * of core file Xen produces. This simplifies the Xen code as it will never + * have to write tables with mixed word sizes for the id parameter. + */ + +/* + * Xen string crash table. + * Note is a list in the form of: + * Machine word (32/64bit) String ID. + * Null terminating string, 0-extended to word alignment. + */ +#define XEN_CRASHTABLE_STRINGTAB 0x3000000 + +#define XEN_STRINGTAB_INVALID 0 +#define XEN_STRINGTAB_VERSION 1 +#define XEN_STRINGTAB_CSET 2 +#define XEN_STRINGTAB_COMPILE_DATE 3 +#define XEN_STRINGTAB_COMPILED_BY 4 +#define XEN_STRINGTAB_COMPILER 5 +#define XEN_STRINGTAB_CMDLINE 6 + +/* + * Xen value crash table. + * Note is a list in the form of: + * Machine word (32/64bit) Value ID. + * 64bit value. + */ +#define XEN_CRASHTABLE_VAL64TAB 0x3000001 + +typedef struct { unsigned long id; uint64_t val; } val64tab_t; + +#define XEN_VALTAB_INVALID 0 +#define XEN_VALTAB_MAX_PAGE 1 +#define XEN_VALTAB_CONRING_SIZE 2 + +/* + * Xen symbol crash table + * Note is a list in the form of: + * Machine word (32/64bit) Symbol ID. + * Symbol Address (64bit pointers). + */ +#define XEN_CRASHTABLE_SYM64TAB 0x3000002 + +typedef struct { unsigned long id; uint64_t addr; } sym64tab_t; + +#define XEN_SYMTAB_INVALID 0 +#define XEN_SYMTAB_CONRING 1 + + +#endif /* __XEN_PUBLIC_CRASHTABLES_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 8ef04a0f6241 -r 90208fe69bd4 xen/include/xen/console.h --- a/xen/include/xen/console.h +++ b/xen/include/xen/console.h @@ -9,6 +9,7 @@ #include #include +#include struct xen_sysctl_readconsole; long read_console_ring(struct xen_sysctl_readconsole *op); @@ -37,6 +38,9 @@ int console_steal(int handle, void (*fn) /* Give back stolen console. Takes the identifier returned by console_steal. */ void console_giveback(int id); +void console_write_val64tab(val64tab_t * valtab); +void console_write_sym64tab(sym64tab_t * symtab); + int console_suspend(void); int console_resume(void);