Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2
kexec-tools
kexec-tools-xen-present.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File kexec-tools-xen-present.diff of Package kexec-tools
From: Olaf Hering <ohering@novell.com> References: bnc#658413, bnc#694863 Subject: xen_present() should be named is_xen_pv() (includes also dom0). A hvm guest is like physical hardware and should not need special handling. Use code from xen-detect.c instead of stat() to distinguish hvm from pv because xenfs in a pv_ops kernel generates /proc/xen/capabilities unconditionally. --- kexec/crashdump-xen.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) Index: kexec-tools-2.0.2/kexec/crashdump-xen.c =================================================================== --- kexec-tools-2.0.2.orig/kexec/crashdump-xen.c +++ kexec-tools-2.0.2/kexec/crashdump-xen.c @@ -10,6 +10,8 @@ #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> +#include <setjmp.h> +#include <signal.h> #include "kexec.h" #include "crashdump.h" #include "kexec-syscall.h" @@ -25,14 +27,102 @@ struct crash_note_info { unsigned long length; }; -int xen_phys_cpus = 0; -struct crash_note_info *xen_phys_notes; +static int xen_phys_cpus; +static struct crash_note_info *xen_phys_notes; -int xen_present(void) +/* based on code from xen-detect.c */ +static int is_dom0; +#if defined(__i386__) || defined(__x86_64__) +static jmp_buf xen_sigill_jmp; +void xen_sigill_handler(int sig) +{ + longjmp(xen_sigill_jmp, 1); +} + +static void xen_cpuid(uint32_t idx, uint32_t *regs, int pv_context) +{ +#ifdef __i386__ + /* Use the stack to avoid reg constraint failures with some gcc flags */ + asm volatile ( + "push %%eax; push %%ebx; push %%ecx; push %%edx\n\t" + "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid\n\t" + "mov %%eax,(%2); mov %%ebx,4(%2)\n\t" + "mov %%ecx,8(%2); mov %%edx,12(%2)\n\t" + "pop %%edx; pop %%ecx; pop %%ebx; pop %%eax\n\t" + : : "a" (idx), "c" (pv_context), "S" (regs) : "memory" ); +#else + asm volatile ( + "test %5,%5 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid\n\t" + : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) + : "0" (idx), "1" (pv_context), "2" (0) ); +#endif +} + +static int check_for_xen(int pv_context) { - struct stat buf; + uint32_t regs[4]; + char signature[13]; + uint32_t base; + + for (base = 0x40000000; base < 0x40010000; base += 0x100) + { + xen_cpuid(base, regs, pv_context); + + *(uint32_t *)(signature + 0) = regs[1]; + *(uint32_t *)(signature + 4) = regs[2]; + *(uint32_t *)(signature + 8) = regs[3]; + signature[12] = '\0'; + + if (strcmp("XenVMMXenVMM", signature) == 0 && regs[0] >= (base + 2)) + goto found; + } + + return 0; + +found: + xen_cpuid(base + 1, regs, pv_context); + return regs[0]; +} - return stat("/proc/xen", &buf) == 0; +static int xen_detect_pv_guest(void) +{ + struct sigaction act, oldact; + int is_pv = -1; + + if (setjmp(xen_sigill_jmp)) + return is_pv; + + memset(&act, 0, sizeof(act)); + act.sa_handler = xen_sigill_handler; + sigemptyset (&act.sa_mask); + if (sigaction(SIGILL, &act, &oldact)) + return is_pv; + if (check_for_xen(1)) + is_pv = 1; + sigaction(SIGILL, &oldact, NULL); + return is_pv; +} +#else +static int xen_detect_pv_guest(void) +{ + return 1; +} +#endif + +/* + * Return 1 if its a PV guest. + * This includes dom0, which is the only PV guest where kexec/kdump works. + * HVM guests have to be handled as native hardware. + */ +int xen_present(void) +{ + if (!is_dom0) { + if (access("/proc/xen", F_OK) == 0) + is_dom0 = xen_detect_pv_guest(); + else + is_dom0 = -1; + } + return is_dom0 > 0; } unsigned long xen_architecture(struct crash_elf_info *elf_info)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor