Merge branch 'stable/128gb.v5.1' into stable/for-linus-3.7
* stable/128gb.v5.1: xen/mmu: If the revector fails, don't attempt to revector anything else. xen/p2m: When revectoring deal with holes in the P2M array. xen/mmu: Release just the MFN list, not MFN list and part of pagetables. xen/mmu: Remove from __ka space PMD entries for pagetables. xen/mmu: Copy and revector the P2M tree. xen/p2m: Add logic to revector a P2M tree to use __va leafs. xen/mmu: Recycle the Xen provided L4, L3, and L2 pages xen/mmu: For 64-bit do not call xen_map_identity_early xen/mmu: use copy_page instead of memcpy. xen/mmu: Provide comments describing the _ka and _va aliasing issue xen/mmu: The xen_setup_kernel_pagetable doesn't need to return anything. Revert "xen/x86: Workaround 64-bit hypervisor and 32-bit initial domain." and "xen/x86: Use memblock_reserve for sensitive areas." xen/x86: Workaround 64-bit hypervisor and 32-bit initial domain. xen/x86: Use memblock_reserve for sensitive areas. xen/p2m: Fix the comment describing the P2M tree. Conflicts: arch/x86/xen/mmu.c The pagetable_init is the old xen_pagetable_setup_done and xen_pagetable_setup_start rolled in one. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
*
|
||||
* P2M_PER_PAGE depends on the architecture, as a mfn is always
|
||||
* unsigned long (8 bytes on 64-bit, 4 bytes on 32), leading to
|
||||
* 512 and 1024 entries respectively.
|
||||
* 512 and 1024 entries respectively.
|
||||
*
|
||||
* In short, these structures contain the Machine Frame Number (MFN) of the PFN.
|
||||
*
|
||||
@@ -139,11 +139,11 @@
|
||||
* / | ~0, ~0, .... |
|
||||
* | \---------------/
|
||||
* |
|
||||
* p2m_missing p2m_missing
|
||||
* /------------------\ /------------\
|
||||
* | [p2m_mid_missing]+---->| ~0, ~0, ~0 |
|
||||
* | [p2m_mid_missing]+---->| ..., ~0 |
|
||||
* \------------------/ \------------/
|
||||
* p2m_mid_missing p2m_missing
|
||||
* /-----------------\ /------------\
|
||||
* | [p2m_missing] +---->| ~0, ~0, ~0 |
|
||||
* | [p2m_missing] +---->| ..., ~0 |
|
||||
* \-----------------/ \------------/
|
||||
*
|
||||
* where ~0 is INVALID_P2M_ENTRY. IDENTITY is (PFN | IDENTITY_BIT)
|
||||
*/
|
||||
@@ -396,7 +396,85 @@ void __init xen_build_dynamic_phys_to_machine(void)
|
||||
|
||||
m2p_override_init();
|
||||
}
|
||||
#ifdef CONFIG_X86_64
|
||||
#include <linux/bootmem.h>
|
||||
unsigned long __init xen_revector_p2m_tree(void)
|
||||
{
|
||||
unsigned long va_start;
|
||||
unsigned long va_end;
|
||||
unsigned long pfn;
|
||||
unsigned long pfn_free = 0;
|
||||
unsigned long *mfn_list = NULL;
|
||||
unsigned long size;
|
||||
|
||||
va_start = xen_start_info->mfn_list;
|
||||
/*We copy in increments of P2M_PER_PAGE * sizeof(unsigned long),
|
||||
* so make sure it is rounded up to that */
|
||||
size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long));
|
||||
va_end = va_start + size;
|
||||
|
||||
/* If we were revectored already, don't do it again. */
|
||||
if (va_start <= __START_KERNEL_map && va_start >= __PAGE_OFFSET)
|
||||
return 0;
|
||||
|
||||
mfn_list = alloc_bootmem_align(size, PAGE_SIZE);
|
||||
if (!mfn_list) {
|
||||
pr_warn("Could not allocate space for a new P2M tree!\n");
|
||||
return xen_start_info->mfn_list;
|
||||
}
|
||||
/* Fill it out with INVALID_P2M_ENTRY value */
|
||||
memset(mfn_list, 0xFF, size);
|
||||
|
||||
for (pfn = 0; pfn < ALIGN(MAX_DOMAIN_PAGES, P2M_PER_PAGE); pfn += P2M_PER_PAGE) {
|
||||
unsigned topidx = p2m_top_index(pfn);
|
||||
unsigned mididx;
|
||||
unsigned long *mid_p;
|
||||
|
||||
if (!p2m_top[topidx])
|
||||
continue;
|
||||
|
||||
if (p2m_top[topidx] == p2m_mid_missing)
|
||||
continue;
|
||||
|
||||
mididx = p2m_mid_index(pfn);
|
||||
mid_p = p2m_top[topidx][mididx];
|
||||
if (!mid_p)
|
||||
continue;
|
||||
if ((mid_p == p2m_missing) || (mid_p == p2m_identity))
|
||||
continue;
|
||||
|
||||
if ((unsigned long)mid_p == INVALID_P2M_ENTRY)
|
||||
continue;
|
||||
|
||||
/* The old va. Rebase it on mfn_list */
|
||||
if (mid_p >= (unsigned long *)va_start && mid_p <= (unsigned long *)va_end) {
|
||||
unsigned long *new;
|
||||
|
||||
if (pfn_free > (size / sizeof(unsigned long))) {
|
||||
WARN(1, "Only allocated for %ld pages, but we want %ld!\n",
|
||||
size / sizeof(unsigned long), pfn_free);
|
||||
return 0;
|
||||
}
|
||||
new = &mfn_list[pfn_free];
|
||||
|
||||
copy_page(new, mid_p);
|
||||
p2m_top[topidx][mididx] = &mfn_list[pfn_free];
|
||||
p2m_top_mfn_p[topidx][mididx] = virt_to_mfn(&mfn_list[pfn_free]);
|
||||
|
||||
pfn_free += P2M_PER_PAGE;
|
||||
|
||||
}
|
||||
/* This should be the leafs allocated for identity from _brk. */
|
||||
}
|
||||
return (unsigned long)mfn_list;
|
||||
|
||||
}
|
||||
#else
|
||||
unsigned long __init xen_revector_p2m_tree(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
unsigned long get_phys_to_machine(unsigned long pfn)
|
||||
{
|
||||
unsigned topidx, mididx, idx;
|
||||
@@ -430,7 +508,7 @@ static void free_p2m_page(void *p)
|
||||
free_page((unsigned long)p);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Fully allocate the p2m structure for a given pfn. We need to check
|
||||
* that both the top and mid levels are allocated, and make sure the
|
||||
* parallel mfn tree is kept in sync. We may race with other cpus, so
|
||||
|
Reference in New Issue
Block a user