5859155d6b
57580bbd-kexec-allow-relaxed-placement-via-cmdline.patch - Upstream patches from Jan 575e9ca0-nested-vmx-Validate-host-VMX-MSRs-before-accessing-them.patch 57640448-xen-sched-use-default-scheduler-upon-an-invalid-sched.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=442
145 lines
5.1 KiB
Diff
145 lines
5.1 KiB
Diff
References: bsc#900418
|
|
|
|
# Commit cd42ccb27f4e364b6e75b6fecb06bb99ad8da988
|
|
# Date 2016-06-08 14:12:45 +0200
|
|
# Author Jan Beulich <jbeulich@suse.com>
|
|
# Committer Jan Beulich <jbeulich@suse.com>
|
|
kexec: allow relaxed placement specification via command line
|
|
|
|
Rather than just allowing a fixed address or fully automatic placement,
|
|
also allow for specifying an upper bound. Especially on EFI systems,
|
|
where firmware memory use is commonly less predictable than on legacy
|
|
BIOS ones, this makes success of the reservation more likely when
|
|
automatic placement is not an option (e.g. because of special DMA
|
|
restrictions of devices involved in actually carrying out the dump).
|
|
|
|
Also take the opportunity to actually add text to the "crashkernel"
|
|
entry in the command line option doc.
|
|
|
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
|
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
Reviewed-by: David Vrabel <david.vrabel@citrix.com>
|
|
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
|
|
--- a/docs/misc/xen-command-line.markdown
|
|
+++ b/docs/misc/xen-command-line.markdown
|
|
@@ -458,7 +458,18 @@ Specify the maximum address to allocate
|
|
combination with the `low_crashinfo` command line option.
|
|
|
|
### crashkernel
|
|
-> `= <ramsize-range>:<size>[,...][@<offset>]`
|
|
+> `= <ramsize-range>:<size>[,...][{@,<}<offset>]`
|
|
+> `= <size>[{@,<}<offset>]`
|
|
+
|
|
+Specify sizes and optionally placement of the crash kernel reservation
|
|
+area. The `<ramsize-range>:<size>` pairs indicate how much memory to
|
|
+set aside for a crash kernel (`<size>`) for a given range of installed
|
|
+RAM (`<ramsize-range>`). Each `<ramsize-range>` is of the form
|
|
+`<start>-[<end>]`.
|
|
+
|
|
+A trailing `@<offset>` specifies the exact address this area should be
|
|
+placed at, whereas `<` in place of `@` just specifies an upper bound of
|
|
+the address range the area should fall into.
|
|
|
|
### credit2\_balance\_over
|
|
> `= <integer>`
|
|
--- a/xen/arch/x86/setup.c
|
|
+++ b/xen/arch/x86/setup.c
|
|
@@ -1044,13 +1044,23 @@ void __init noreturn __start_xen(unsigne
|
|
}
|
|
|
|
#ifdef CONFIG_KEXEC
|
|
- /* Don't overlap with modules. */
|
|
- e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size),
|
|
- mod, mbi->mods_count, -1);
|
|
- if ( !kexec_crash_area.start && (s < e) )
|
|
+ /*
|
|
+ * Looking backwards from the crash area limit, find a large
|
|
+ * enough range that does not overlap with modules.
|
|
+ */
|
|
+ while ( !kexec_crash_area.start )
|
|
{
|
|
- e = (e - kexec_crash_area.size) & PAGE_MASK;
|
|
- kexec_crash_area.start = e;
|
|
+ /* Don't overlap with modules. */
|
|
+ e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size),
|
|
+ mod, mbi->mods_count, -1);
|
|
+ if ( s >= e )
|
|
+ break;
|
|
+ if ( e > kexec_crash_area_limit )
|
|
+ {
|
|
+ e = kexec_crash_area_limit & PAGE_MASK;
|
|
+ continue;
|
|
+ }
|
|
+ kexec_crash_area.start = (e - kexec_crash_area.size) & PAGE_MASK;
|
|
}
|
|
#endif
|
|
}
|
|
--- a/xen/common/kexec.c
|
|
+++ b/xen/common/kexec.c
|
|
@@ -60,6 +60,7 @@ static unsigned char vmcoreinfo_data[VMC
|
|
static size_t vmcoreinfo_size = 0;
|
|
|
|
xen_kexec_reserve_t kexec_crash_area;
|
|
+paddr_t __initdata kexec_crash_area_limit = ~(paddr_t)0;
|
|
static struct {
|
|
u64 start, end;
|
|
unsigned long size;
|
|
@@ -86,7 +87,7 @@ static void *crash_heap_current = NULL,
|
|
/*
|
|
* Parse command lines in the format
|
|
*
|
|
- * crashkernel=<ramsize-range>:<size>[,...][@<offset>]
|
|
+ * crashkernel=<ramsize-range>:<size>[,...][{@,<}<address>]
|
|
*
|
|
* with <ramsize-range> being of form
|
|
*
|
|
@@ -94,7 +95,7 @@ static void *crash_heap_current = NULL,
|
|
*
|
|
* as well as the legacy ones in the format
|
|
*
|
|
- * crashkernel=<size>[@<offset>]
|
|
+ * crashkernel=<size>[{@,<}<address>]
|
|
*/
|
|
static void __init parse_crashkernel(const char *str)
|
|
{
|
|
@@ -109,7 +110,7 @@ static void __init parse_crashkernel(con
|
|
{
|
|
printk(XENLOG_WARNING "crashkernel: too many ranges\n");
|
|
cur = NULL;
|
|
- str = strchr(str, '@');
|
|
+ str = strpbrk(str, "@<");
|
|
break;
|
|
}
|
|
|
|
@@ -154,9 +155,16 @@ static void __init parse_crashkernel(con
|
|
}
|
|
else
|
|
kexec_crash_area.size = parse_size_and_unit(cur = str, &str);
|
|
- if ( cur != str && *str == '@' )
|
|
- kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str);
|
|
- if ( cur == str )
|
|
+ if ( cur != str )
|
|
+ {
|
|
+ if ( *str == '@' )
|
|
+ kexec_crash_area.start = parse_size_and_unit(cur = str + 1, &str);
|
|
+ else if ( *str == '<' )
|
|
+ kexec_crash_area_limit = parse_size_and_unit(cur = str + 1, &str);
|
|
+ else
|
|
+ printk(XENLOG_WARNING "crashkernel: '%s' ignored\n", str);
|
|
+ }
|
|
+ if ( cur && cur == str )
|
|
printk(XENLOG_WARNING "crashkernel: memory value expected\n");
|
|
}
|
|
custom_param("crashkernel", parse_crashkernel);
|
|
--- a/xen/include/xen/kexec.h
|
|
+++ b/xen/include/xen/kexec.h
|
|
@@ -14,6 +14,7 @@ typedef struct xen_kexec_reserve {
|
|
} xen_kexec_reserve_t;
|
|
|
|
extern xen_kexec_reserve_t kexec_crash_area;
|
|
+extern paddr_t kexec_crash_area_limit;
|
|
|
|
extern bool_t kexecing;
|
|
|