diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-08-18 00:43:28 +0400 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2012-09-19 18:04:32 +0400 |
commit | aaee3116bff0cda7d0eb4e2723cc108d5c056988 (patch) | |
tree | 3b067d793f0ac4a81fa19977dc20a5d70b6c2bb7 /arch/x86/xen/setup.c | |
parent | a3aaee9f1070ccec4bf551af5b47b6037a939e1c (diff) | |
download | linux-aaee3116bff0cda7d0eb4e2723cc108d5c056988.tar.xz |
xen/setup: Fix one-off error when adding for-balloon PFNs to the P2M.
commit c96aae1f7f393387d160211f60398d58463a7e65 upstream.
When we are finished with return PFNs to the hypervisor, then
populate it back, and also mark the E820 MMIO and E820 gaps
as IDENTITY_FRAMEs, we then call P2M to set areas that can
be used for ballooning. We were off by one, and ended up
over-writting a P2M entry that most likely was an IDENTITY_FRAME.
For example:
1-1 mapping on 40000->40200
1-1 mapping on bc558->bc5ac
1-1 mapping on bc5b4->bc8c5
1-1 mapping on bc8c6->bcb7c
1-1 mapping on bcd00->100000
Released 614 pages of unused memory
Set 277889 page(s) to 1-1 mapping
Populating 40200-40466 pfn range: 614 pages added
=> here we set from 40466 up to bc559 P2M tree to be
INVALID_P2M_ENTRY. We should have done it up to bc558.
The end result is that if anybody is trying to construct
a PTE for PFN bc558 they end up with ~PAGE_PRESENT.
Reported-by-and-Tested-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r-- | arch/x86/xen/setup.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index b2c7179fa263..bb104b4e068a 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -78,9 +78,16 @@ static void __init xen_add_extra_mem(u64 start, u64 size) memblock_x86_reserve_range(start, start + size, "XEN EXTRA"); xen_max_p2m_pfn = PFN_DOWN(start + size); + for (pfn = PFN_DOWN(start); pfn < xen_max_p2m_pfn; pfn++) { + unsigned long mfn = pfn_to_mfn(pfn); + + if (WARN(mfn == pfn, "Trying to over-write 1-1 mapping (pfn: %lx)\n", pfn)) + continue; + WARN(mfn != INVALID_P2M_ENTRY, "Trying to remove %lx which has %lx mfn!\n", + pfn, mfn); - for (pfn = PFN_DOWN(start); pfn <= xen_max_p2m_pfn; pfn++) __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); + } } static unsigned long __init xen_release_chunk(unsigned long start, |