Skip to content

Commit

Permalink
xen/balloon: flush persistent kmaps in correct position
Browse files Browse the repository at this point in the history
Xen balloon driver will update ballooned out pages' P2M entries to point
to scratch page for PV guests. In 24f6937 ("xen/balloon: don't alloc
page while non-preemptible", kmap_flush_unused was moved after updating
P2M table. In that case for 32 bit PV guest we might end up with

  P2M    X -----> S  (S is mfn of balloon scratch page)
  M2P    Y -----> X  (Y is mfn in persistent kmap entry)

kmap_flush_unused() iterates through all the PTEs in the kmap address
space, using pte_to_page() to obtain the page. If the p2m and the m2p
are inconsistent the incorrect page is returned.  This will clear
page->address on the wrong page which may cause subsequent oopses if
that page is currently kmap'ed.

Move the flush back between get_page and __set_phys_to_machine to fix
this.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Cc: stable@vger.kernel.org # 3.12+
  • Loading branch information
Wei Liu authored and David Vrabel committed Mar 25, 2014
1 parent b098d67 commit 09ed3d5
Showing 1 changed file with 18 additions and 6 deletions.
24 changes: 18 additions & 6 deletions drivers/xen/balloon.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,25 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
state = BP_EAGAIN;
break;
}
scrub_page(page);

pfn = page_to_pfn(page);
frame_list[i] = pfn_to_mfn(pfn);
frame_list[i] = page_to_pfn(page);
}

scrub_page(page);
/*
* Ensure that ballooned highmem pages don't have kmaps.
*
* Do this before changing the p2m as kmap_flush_unused()
* reads PTEs to obtain pages (and hence needs the original
* p2m entry).
*/
kmap_flush_unused();

/* Update direct mapping, invalidate P2M, and add to balloon. */
for (i = 0; i < nr_pages; i++) {
pfn = frame_list[i];
frame_list[i] = pfn_to_mfn(pfn);
page = pfn_to_page(pfn);

#ifdef CONFIG_XEN_HAVE_PVMMU
/*
Expand All @@ -429,11 +443,9 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
}
#endif

balloon_append(pfn_to_page(pfn));
balloon_append(page);
}

/* Ensure that ballooned highmem pages don't have kmaps. */
kmap_flush_unused();
flush_tlb_all();

set_xen_guest_handle(reservation.extent_start, frame_list);
Expand Down

0 comments on commit 09ed3d5

Please sign in to comment.