x86: map portion of kexec crash area that is within the direct map area

Commit 7113a45451 (kexec/x86: do not map
crash kernel area) causes fatal page faults when loading a crash
image.  The attempt to zero the first control page allocated from the
crash region will fault as the VA return by map_domain_page() has no
mapping.

The fault will occur on non-debug builds of Xen when the crash area is
below 5 TiB (which will be most systems).

The assumption that the crash area mapping was not used is incorrect.
map_domain_page() is used when loading an image and building the
image's page tables to temporarily map the crash area, thus the
mapping is required if the crash area is in the direct map area.

Reintroduce the mapping, but only the portions of the crash area that
are within the direct map area.

Reported-by: Don Slutz <dslutz@verizon.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Tested-by: Don Slutz <dslutz@verizon.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Daniel Kiper <daniel.kiper@oracle.com>

This is really just a band aid - kexec shouldn't rely on the crash area
being always mapped when in the direct mapping range (and it didn't use
to in its previous form). That's primarily because map_domain_page()
(needed when the area is outside the direct mapping range) may be
unusable when wanting to kexec due to a crash, but also because in the
case of PFN compression the kexec range (if specified on the command
line) could fall into a hole between used memory ranges (while we're
currently only ignoring memory at the top of the physical address
space, it's pretty clear that sooner or later we will want that
selection to become more sophisticated in order to maximize the memory
made use of).

Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
David Vrabel authored and Jan Beulich committed 2014-01-10 17:46:33 +01:00
1 parent 3dbab7a8bf
commit 0896bd8bea
1 file changed
+11
+11
View File
@@ -1098,6 +1098,17 @@ void __init __start_xen(unsigned long mbi_p)
PFN_UP(mod[i].mod_end), PAGE_HYPERVISOR);
}
if ( kexec_crash_area.size )
{
unsigned long s = PFN_DOWN(kexec_crash_area.start);
unsigned long e = min(s + PFN_UP(kexec_crash_area.size),
PFN_UP(__pa(HYPERVISOR_VIRT_END - 1)));
if ( e > s )
map_pages_to_xen((unsigned long)__va(kexec_crash_area.start),
s, e - s, PAGE_HYPERVISOR);
}
xen_virt_end = ((unsigned long)_end + (1UL << L2_PAGETABLE_SHIFT) - 1) &
~((1UL << L2_PAGETABLE_SHIFT) - 1);
destroy_xen_mappings(xen_virt_end, XEN_VIRT_START + BOOTSTRAP_MAP_BASE);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.