Merge branches 'stable/p2m-identity.v4.9.1' and 'stable/e820' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
* 'stable/p2m-identity.v4.9.1' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen/m2p: Check whether the MFN has IDENTITY_FRAME bit set.. xen/m2p: No need to catch exceptions when we know that there is no RAM xen/debug: WARN_ON when identity PFN has no _PAGE_IOMAP flag set. xen/debugfs: Add 'p2m' file for printing out the P2M layout. xen/setup: Set identity mapping for non-RAM E820 and E820 gaps. xen/mmu: WARN_ON when racing to swap middle leaf. xen/mmu: Set _PAGE_IOMAP if PFN is an identity PFN. xen/mmu: Add the notion of identity (1-1) mapping. xen: Mark all initial reserved pages for the balloon as INVALID_P2M_ENTRY. * 'stable/e820' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen/e820: Don't mark balloon memory as E820_UNUSABLE when running as guest and fix overflow. xen/setup: Inhibit resource API from using System RAM E820 gaps as PCI mem gaps.
This commit is contained in:
@ -52,6 +52,8 @@ phys_addr_t xen_extra_mem_start, xen_extra_mem_size;
|
||||
|
||||
static __init void xen_add_extra_mem(unsigned long pages)
|
||||
{
|
||||
unsigned long pfn;
|
||||
|
||||
u64 size = (u64)pages * PAGE_SIZE;
|
||||
u64 extra_start = xen_extra_mem_start + xen_extra_mem_size;
|
||||
|
||||
@ -66,6 +68,9 @@ static __init void xen_add_extra_mem(unsigned long pages)
|
||||
xen_extra_mem_size += size;
|
||||
|
||||
xen_max_p2m_pfn = PFN_DOWN(extra_start + size);
|
||||
|
||||
for (pfn = PFN_DOWN(extra_start); pfn <= xen_max_p2m_pfn; pfn++)
|
||||
__set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
|
||||
}
|
||||
|
||||
static unsigned long __init xen_release_chunk(phys_addr_t start_addr,
|
||||
@ -104,7 +109,7 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr,
|
||||
WARN(ret != 1, "Failed to release memory %lx-%lx err=%d\n",
|
||||
start, end, ret);
|
||||
if (ret == 1) {
|
||||
set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
|
||||
__set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
|
||||
len++;
|
||||
}
|
||||
}
|
||||
@ -138,12 +143,55 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
|
||||
return released;
|
||||
}
|
||||
|
||||
static unsigned long __init xen_set_identity(const struct e820entry *list,
|
||||
ssize_t map_size)
|
||||
{
|
||||
phys_addr_t last = xen_initial_domain() ? 0 : ISA_END_ADDRESS;
|
||||
phys_addr_t start_pci = last;
|
||||
const struct e820entry *entry;
|
||||
unsigned long identity = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0, entry = list; i < map_size; i++, entry++) {
|
||||
phys_addr_t start = entry->addr;
|
||||
phys_addr_t end = start + entry->size;
|
||||
|
||||
if (start < last)
|
||||
start = last;
|
||||
|
||||
if (end <= start)
|
||||
continue;
|
||||
|
||||
/* Skip over the 1MB region. */
|
||||
if (last > end)
|
||||
continue;
|
||||
|
||||
if (entry->type == E820_RAM) {
|
||||
if (start > start_pci)
|
||||
identity += set_phys_range_identity(
|
||||
PFN_UP(start_pci), PFN_DOWN(start));
|
||||
|
||||
/* Without saving 'last' we would gooble RAM too
|
||||
* at the end of the loop. */
|
||||
last = end;
|
||||
start_pci = end;
|
||||
continue;
|
||||
}
|
||||
start_pci = min(start, start_pci);
|
||||
last = end;
|
||||
}
|
||||
if (last > start_pci)
|
||||
identity += set_phys_range_identity(
|
||||
PFN_UP(start_pci), PFN_DOWN(last));
|
||||
return identity;
|
||||
}
|
||||
/**
|
||||
* machine_specific_memory_setup - Hook for machine specific memory setup.
|
||||
**/
|
||||
char * __init xen_memory_setup(void)
|
||||
{
|
||||
static struct e820entry map[E820MAX] __initdata;
|
||||
static struct e820entry map_raw[E820MAX] __initdata;
|
||||
|
||||
unsigned long max_pfn = xen_start_info->nr_pages;
|
||||
unsigned long long mem_end;
|
||||
@ -151,6 +199,7 @@ char * __init xen_memory_setup(void)
|
||||
struct xen_memory_map memmap;
|
||||
unsigned long extra_pages = 0;
|
||||
unsigned long extra_limit;
|
||||
unsigned long identity_pages = 0;
|
||||
int i;
|
||||
int op;
|
||||
|
||||
@ -176,6 +225,7 @@ char * __init xen_memory_setup(void)
|
||||
}
|
||||
BUG_ON(rc);
|
||||
|
||||
memcpy(map_raw, map, sizeof(map));
|
||||
e820.nr_map = 0;
|
||||
xen_extra_mem_start = mem_end;
|
||||
for (i = 0; i < memmap.nr_entries; i++) {
|
||||
@ -194,6 +244,15 @@ char * __init xen_memory_setup(void)
|
||||
end -= delta;
|
||||
|
||||
extra_pages += PFN_DOWN(delta);
|
||||
/*
|
||||
* Set RAM below 4GB that is not for us to be unusable.
|
||||
* This prevents "System RAM" address space from being
|
||||
* used as potential resource for I/O address (happens
|
||||
* when 'allocate_resource' is called).
|
||||
*/
|
||||
if (delta &&
|
||||
(xen_initial_domain() && end < 0x100000000ULL))
|
||||
e820_add_region(end, delta, E820_UNUSABLE);
|
||||
}
|
||||
|
||||
if (map[i].size > 0 && end > xen_extra_mem_start)
|
||||
@ -251,6 +310,13 @@ char * __init xen_memory_setup(void)
|
||||
|
||||
xen_add_extra_mem(extra_pages);
|
||||
|
||||
/*
|
||||
* Set P2M for all non-RAM pages and E820 gaps to be identity
|
||||
* type PFNs. We supply it with the non-sanitized version
|
||||
* of the E820.
|
||||
*/
|
||||
identity_pages = xen_set_identity(map_raw, memmap.nr_entries);
|
||||
printk(KERN_INFO "Set %ld page(s) to 1-1 mapping.\n", identity_pages);
|
||||
return "Xen";
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user