Accepting request 125015 from home:olh:branches:Kernel:kdump
Without theses changes from sles11sp2 installation in a Xen HVM guest can not work in factory because the installer uses kexec to boot into second stage.. - Fix xen cpuid() inline asm to not clobber stack's red zone See xen-unstable changeset 24344:72f4e4cb7440 - Balloon up in a Xen PVonHVM guest before kexec (bnc#694863) - Update xen_present check for xenfs in pv_ops kernel (bnc#694863) - Change xen_present hv check (bnc#658413) OBS-URL: https://build.opensuse.org/request/show/125015 OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/kexec-tools?expand=0&rev=21
This commit is contained in:
parent
660ec8c794
commit
c8c1a9440a
231
kexec-tools-xen-balloon-up.patch
Normal file
231
kexec-tools-xen-balloon-up.patch
Normal file
@ -0,0 +1,231 @@
|
||||
Reference: bnc#694863
|
||||
|
||||
A PVonHVM guest can not kexec if balloon driver gave some memory back to hypervisor.
|
||||
Disable ballooning before doing kexec.
|
||||
|
||||
---
|
||||
kexec/crashdump-xen.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
kexec/crashdump.h | 1
|
||||
kexec/kexec.c | 6 ++
|
||||
3 files changed, 119 insertions(+), 6 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
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <sys/select.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <setjmp.h>
|
||||
@@ -30,9 +31,20 @@ struct crash_note_info {
|
||||
static int xen_phys_cpus;
|
||||
static struct crash_note_info *xen_phys_notes;
|
||||
|
||||
+#define XEN_MEM0_DIR "/sys/devices/system/xen_memory/xen_memory0"
|
||||
+#define XEN_MEM0_TARGET XEN_MEM0_DIR "/target_kb"
|
||||
+#define XEN_MEM0_LOW XEN_MEM0_DIR "/info/low_kb"
|
||||
+#define XEN_MEM0_HIGH XEN_MEM0_DIR "/info/high_kb"
|
||||
+
|
||||
/* based on code from xen-detect.c */
|
||||
static int is_dom0;
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
+enum {
|
||||
+ XEN_PV = 1,
|
||||
+ XEN_HVM = 2,
|
||||
+ XEN_NONE = 3,
|
||||
+};
|
||||
+static int guest_type;
|
||||
static jmp_buf xen_sigill_jmp;
|
||||
void xen_sigill_handler(int sig)
|
||||
{
|
||||
@@ -81,29 +93,118 @@ found:
|
||||
return regs[0];
|
||||
}
|
||||
|
||||
-static int xen_detect_pv_guest(void)
|
||||
+static void xen_detect_guest_type(void)
|
||||
{
|
||||
struct sigaction act, oldact;
|
||||
- int is_pv = -1;
|
||||
+
|
||||
+ guest_type = XEN_NONE;
|
||||
+ if (check_for_xen(0)) {
|
||||
+ guest_type = XEN_HVM;
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
if (setjmp(xen_sigill_jmp))
|
||||
- return is_pv;
|
||||
+ return;
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = xen_sigill_handler;
|
||||
sigemptyset (&act.sa_mask);
|
||||
if (sigaction(SIGILL, &act, &oldact))
|
||||
- return is_pv;
|
||||
+ return;
|
||||
if (check_for_xen(1))
|
||||
- is_pv = 1;
|
||||
+ guest_type = XEN_PV;
|
||||
sigaction(SIGILL, &oldact, NULL);
|
||||
- return is_pv;
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static int xen_detect_pv_guest(void)
|
||||
+{
|
||||
+ if (!guest_type)
|
||||
+ xen_detect_guest_type();
|
||||
+
|
||||
+ return guest_type == XEN_PV ? 1 : -1;
|
||||
}
|
||||
+
|
||||
+static int do_balloon_up(void)
|
||||
+{
|
||||
+ char line[123];
|
||||
+ FILE *f;
|
||||
+ int done = 0, seen_lo, seen_hi;
|
||||
+ long long lo, hi, prev_lo = 0, prev_hi = 0;
|
||||
+
|
||||
+ if (!guest_type)
|
||||
+ xen_detect_guest_type();
|
||||
+
|
||||
+ if (guest_type != XEN_HVM)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Nothing to do if no balloon driver */
|
||||
+ f = fopen(XEN_MEM0_TARGET, "w");
|
||||
+ if (!f)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Balloon up to maximum, the guest can not exceed its max_memkb */
|
||||
+ printf("Ballooning up in PVonHVM guest.\n");
|
||||
+ snprintf(line, sizeof(line), "%llu", -1LL);
|
||||
+ fwrite(line, strlen(line), 1, f);
|
||||
+ fclose(f);
|
||||
+
|
||||
+ do {
|
||||
+ struct timeval timeout = {.tv_usec = 654321, };
|
||||
+ seen_lo = seen_hi = 0;
|
||||
+ lo = hi = -1;
|
||||
+
|
||||
+ /* Wait for balloon driver to reach maximum */
|
||||
+ if (select(0, NULL, NULL, NULL, &timeout) < 0) {
|
||||
+ perror("select");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Check ballooned low mem */
|
||||
+ f = fopen(XEN_MEM0_LOW, "r");
|
||||
+ if (!f)
|
||||
+ break;
|
||||
+ if (fscanf(f, "%lld", &lo) == 1)
|
||||
+ seen_lo = 1;
|
||||
+ fclose(f);
|
||||
+
|
||||
+ /* Check ballooned high mem */
|
||||
+ f = fopen(XEN_MEM0_HIGH, "r");
|
||||
+ if (!f)
|
||||
+ break;
|
||||
+ if (fscanf(f, "%lld", &hi) == 1)
|
||||
+ seen_hi = 1;
|
||||
+ fclose(f);
|
||||
+
|
||||
+ /* Print progress if current values changed */
|
||||
+ if ((seen_lo || seen_hi) && (hi || lo) && (lo != prev_lo || hi != prev_hi)) {
|
||||
+ printf("h: %lld, l: %lld\n", hi, lo);
|
||||
+ if (seen_lo && lo != prev_lo)
|
||||
+ prev_lo = lo;
|
||||
+ if (seen_hi && hi != prev_hi)
|
||||
+ prev_hi = hi;
|
||||
+ }
|
||||
+
|
||||
+ /* Exit loop if nothing is ballooned anymore */
|
||||
+ if (seen_lo && seen_hi && hi == 0 && lo == 0)
|
||||
+ done = 1;
|
||||
+
|
||||
+ } while (!done);
|
||||
+
|
||||
+ printf("%s.\n", done ? "Done" : "Not done");
|
||||
+ return !done;
|
||||
+}
|
||||
+
|
||||
#else
|
||||
static int xen_detect_pv_guest(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
+static int do_balloon_up(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -122,6 +223,11 @@ int xen_present(void)
|
||||
return is_dom0 > 0;
|
||||
}
|
||||
|
||||
+int xen_balloon_up(void)
|
||||
+{
|
||||
+ return do_balloon_up();
|
||||
+}
|
||||
+
|
||||
unsigned long xen_architecture(struct crash_elf_info *elf_info)
|
||||
{
|
||||
unsigned long machine = elf_info->machine;
|
||||
Index: kexec-tools-2.0.2/kexec/crashdump.h
|
||||
===================================================================
|
||||
--- kexec-tools-2.0.2.orig/kexec/crashdump.h
|
||||
+++ kexec-tools-2.0.2/kexec/crashdump.h
|
||||
@@ -50,6 +50,7 @@ unsigned long phys_to_virt(struct crash_
|
||||
unsigned long paddr);
|
||||
|
||||
int xen_present(void);
|
||||
+int xen_balloon_up(void);
|
||||
unsigned long xen_architecture(struct crash_elf_info *elf_info);
|
||||
int xen_get_nr_phys_cpus(void);
|
||||
int xen_get_note(int cpu, uint64_t *addr, uint64_t *len);
|
||||
Index: kexec-tools-2.0.2/kexec/kexec.c
|
||||
===================================================================
|
||||
--- kexec-tools-2.0.2.orig/kexec/kexec.c
|
||||
+++ kexec-tools-2.0.2/kexec/kexec.c
|
||||
@@ -1048,6 +1048,7 @@ int main(int argc, char *argv[])
|
||||
int do_shutdown = 1;
|
||||
int do_sync = 1;
|
||||
int do_ifdown = 0;
|
||||
+ int do_balloon = 0;
|
||||
int do_unload = 0;
|
||||
int do_reuse_initrd = 0;
|
||||
void *entry = 0;
|
||||
@@ -1082,6 +1083,7 @@ int main(int argc, char *argv[])
|
||||
do_shutdown = 0;
|
||||
do_sync = 1;
|
||||
do_ifdown = 1;
|
||||
+ do_balloon = 1;
|
||||
do_exec = 1;
|
||||
break;
|
||||
case OPT_LOAD:
|
||||
@@ -1100,6 +1102,7 @@ int main(int argc, char *argv[])
|
||||
do_shutdown = 0;
|
||||
do_sync = 1;
|
||||
do_ifdown = 1;
|
||||
+ do_balloon = 1;
|
||||
do_exec = 1;
|
||||
break;
|
||||
case OPT_LOAD_JUMP_BACK_HELPER:
|
||||
@@ -1222,6 +1225,9 @@ int main(int argc, char *argv[])
|
||||
if ((result == 0) && do_ifdown) {
|
||||
ifdown();
|
||||
}
|
||||
+ if ((result == 0) && do_balloon) {
|
||||
+ result = xen_balloon_up();
|
||||
+ }
|
||||
if ((result == 0) && do_exec) {
|
||||
result = my_exec();
|
||||
}
|
133
kexec-tools-xen-present.diff
Normal file
133
kexec-tools-xen-present.diff
Normal file
@ -0,0 +1,133 @@
|
||||
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)
|
@ -1,3 +1,16 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Jun 14 16:23:58 CEST 2012 - ohering@suse.de
|
||||
|
||||
- Fix xen cpuid() inline asm to not clobber stack's red zone
|
||||
See xen-unstable changeset 24344:72f4e4cb7440
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jun 14 11:26:16 CEST 2012 - ohering@suse.de
|
||||
|
||||
- Balloon up in a Xen PVonHVM guest before kexec (bnc#694863)
|
||||
- Update xen_present check for xenfs in pv_ops kernel (bnc#694863)
|
||||
- Change xen_present hv check (bnc#658413)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Apr 20 16:19:26 UTC 2012 - rschweikert@suse.com
|
||||
|
||||
|
@ -37,6 +37,8 @@ Patch0: %{name}-no-vga-output.diff
|
||||
Patch1: %{name}-xen-static.diff
|
||||
Patch2: gcc-no-undefined-flag-fix.patch
|
||||
Patch3: kexec-fix-strncat.patch
|
||||
Patch4: kexec-tools-xen-present.diff
|
||||
Patch5: kexec-tools-xen-balloon-up.patch
|
||||
Url: ftp://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.bz2
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
#!BuildIgnore: fop
|
||||
@ -74,6 +76,8 @@ Authors:
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
|
||||
%build
|
||||
# disable as-needed
|
||||
|
Loading…
Reference in New Issue
Block a user