kexec-tools/kexec-tools-xen-balloon-up.patch
Tony Jones 080f64dafa Accepting request 500203 from home:tiwai:branches:Kernel:kdump
- Update to version 2.0.14 (bsc#1039937, FATE#320672, FATE#320671)
  Changelog: http://git.kernel.org/cgit/utils/kernel/kexec/kexec-tools.git/log/?id=refs/tags/v2.0.13..v2.0.14
- Backport upstream fixes  (bsc#1039937, FATE#320672, FATE#320671)
  0001-kexec-tools-2.0.14.git.patch
  0002-ppc64-Reduce-number-of-ELF-LOAD-segments.patch
  0003-kexec-Increase-the-upper-limit-for-RAM-segments.patch
  0004-alpha-add-missing-__NR_kexec_load-definition.patch
  0005-kexec-implemented-XEN-KEXEC-STATUS-to-determine-if-a.patch
  0006-kexec-Remove-redundant-space-from-help-message.patch
  0007-purgatory-Add-purgatory.map-and-purgatory.ro.sym-to-.patch
  0008-kexec-Add-option-to-get-crash-kernel-region-size.patch
  0009-crashdump-arm-Add-get_crash_kernel_load_range-functi.patch
  0010-crashdump-arm64-Add-get_crash_kernel_load_range-func.patch
  0011-crashdump-cris-Add-get_crash_kernel_load_range-funct.patch
  0012-crashdump-ia64-Add-get_crash_kernel_load_range-funct.patch
  0013-crashdump-m68k-Add-get_crash_kernel_load_range-funct.patch
  0014-crashdump-mips-Add-get_crash_kernel_load_range-funct.patch
  0015-crashdump-ppc-Add-get_crash_kernel_load_range-functi.patch
  0016-crashdump-ppc64-Add-get_crash_kernel_load_range-func.patch
  0017-crashdump-s390-Add-get_crash_kernel_load_range-funct.patch
  0018-crashdump-sh-Add-get_crash_kernel_load_range-functio.patch
  0019-gitignore-add-two-generated-files-in-purgatory.patch
  0020-Only-print-debug-message-when-failed-to-serach-for-k.patch
  0021-build_mem_phdrs-check-if-p_paddr-is-invalid.patch
  0022-uImage-fix-realloc-pointer-confusion.patch
  0023-uImage-Fix-uImage_load-for-little-endian-machines.patch
  0024-uImage-Add-new-IH_ARCH_xxx-definitions.patch
  0025-uImage-use-char-instead-of-unsigned-char-for-uImage_.patch
  0026-uImage-use-char-instead-of-unsigned-char-for-uImage_.patch
  0027-arm64-add-uImage-support.patch

OBS-URL: https://build.opensuse.org/request/show/500203
OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/kexec-tools?expand=0&rev=83
2017-05-31 20:00:34 +00:00

226 lines
5.0 KiB
Diff

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/kexec.c | 6 ++
kexec/kexec.h | 1
3 files changed, 119 insertions(+), 6 deletions(-)
--- a/kexec/crashdump-xen.c
+++ b/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)
{
@@ -84,29 +96,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
/*
@@ -125,6 +226,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;
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1240,6 +1240,7 @@ int main(int argc, char *argv[])
int do_shutdown = 1;
int do_sync = 1, skip_sync = 0;
int do_ifdown = 0, skip_ifdown = 0;
+ int do_balloon = 0;
int do_unload = 0;
int do_reuse_initrd = 0;
int do_kexec_file_syscall = 0;
@@ -1298,6 +1299,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:
@@ -1318,6 +1320,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:
@@ -1482,6 +1485,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();
}
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -316,6 +316,7 @@ int xen_kexec_load(struct kexec_info *in
int xen_kexec_unload(uint64_t kexec_flags);
void xen_kexec_exec(void);
int xen_kexec_status(uint64_t kexec_flags);
+int xen_balloon_up(void);
extern unsigned long long get_kernel_sym(const char *text);