Hello community,

here is the log from the commit of package kexec-tools for openSUSE:Factory 
checked in at 2012-06-25 12:33:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kexec-tools (Old)
 and      /work/SRC/openSUSE:Factory/.kexec-tools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kexec-tools", Maintainer is "to...@suse.com"

Changes:
--------
--- /work/SRC/openSUSE:Factory/kexec-tools/kexec-tools.changes  2012-05-21 
07:27:58.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.kexec-tools.new/kexec-tools.changes     
2012-06-25 12:33:32.000000000 +0200
@@ -1,0 +2,13 @@
+Thu Jun 14 16:23:58 CEST 2012 - oher...@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 - oher...@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)
+
+-------------------------------------------------------------------

New:
----
  kexec-tools-xen-balloon-up.patch
  kexec-tools-xen-present.diff

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kexec-tools.spec ++++++
--- /var/tmp/diff_new_pack.zmr6iC/_old  2012-06-25 12:33:34.000000000 +0200
+++ /var/tmp/diff_new_pack.zmr6iC/_new  2012-06-25 12:33:34.000000000 +0200
@@ -37,6 +37,8 @@
 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 @@
 %patch1 -p1
 %patch2 -p1
 %patch3 -p1
+%patch4 -p1
+%patch5 -p1
 
 %build
 # disable as-needed

++++++ kexec-tools-xen-balloon-up.patch ++++++
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();
        }
++++++ kexec-tools-xen-present.diff ++++++
From: Olaf Hering <oher...@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)
-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to