diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-28 13:52:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-28 13:52:05 -0400 |
commit | 81250437a55044edf16d2cc484da4fb837489317 (patch) | |
tree | 07f12a763928ed767fd39be4c6d35bfc28d30aea | |
parent | 75c5a52da3fc2a06abb6c6192bdf5d680e56d37d (diff) | |
parent | 5926f87fdaad4be3ed10cec563bf357915e55a86 (diff) |
Merge tag 'stable/for-linus-3.14-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull Xen bugfixes from David Vrabel:
"Fix two bugs that cause x86 PV guest crashes.
1. Ballooning a 32-bit guest would eventually crash it.
2. Revert a broken fix for a regression with NUMA_BALACING. The bad
fix caused PV guests to crash after migration. This is not ideal
but unpicking the madness that is _PAGE_NUMA == _PAGE_PROTNONE will
take a while longer"
* tag 'stable/for-linus-3.14-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
Revert "xen: properly account for _PAGE_NUMA during xen pte translations"
xen/balloon: flush persistent kmaps in correct position
-rw-r--r-- | arch/x86/include/asm/pgtable.h | 14 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 4 | ||||
-rw-r--r-- | drivers/xen/balloon.c | 24 |
3 files changed, 22 insertions, 20 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 5ad38ad07890..bbc8b12fa443 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -445,20 +445,10 @@ static inline int pte_same(pte_t a, pte_t b) | |||
445 | return a.pte == b.pte; | 445 | return a.pte == b.pte; |
446 | } | 446 | } |
447 | 447 | ||
448 | static inline int pteval_present(pteval_t pteval) | ||
449 | { | ||
450 | /* | ||
451 | * Yes Linus, _PAGE_PROTNONE == _PAGE_NUMA. Expressing it this | ||
452 | * way clearly states that the intent is that protnone and numa | ||
453 | * hinting ptes are considered present for the purposes of | ||
454 | * pagetable operations like zapping, protection changes, gup etc. | ||
455 | */ | ||
456 | return pteval & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_NUMA); | ||
457 | } | ||
458 | |||
459 | static inline int pte_present(pte_t a) | 448 | static inline int pte_present(pte_t a) |
460 | { | 449 | { |
461 | return pteval_present(pte_flags(a)); | 450 | return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE | |
451 | _PAGE_NUMA); | ||
462 | } | 452 | } |
463 | 453 | ||
464 | #define pte_accessible pte_accessible | 454 | #define pte_accessible pte_accessible |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 256282e7888b..2423ef04ffea 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -365,7 +365,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | |||
365 | /* Assume pteval_t is equivalent to all the other *val_t types. */ | 365 | /* Assume pteval_t is equivalent to all the other *val_t types. */ |
366 | static pteval_t pte_mfn_to_pfn(pteval_t val) | 366 | static pteval_t pte_mfn_to_pfn(pteval_t val) |
367 | { | 367 | { |
368 | if (pteval_present(val)) { | 368 | if (val & _PAGE_PRESENT) { |
369 | unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; | 369 | unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; |
370 | unsigned long pfn = mfn_to_pfn(mfn); | 370 | unsigned long pfn = mfn_to_pfn(mfn); |
371 | 371 | ||
@@ -381,7 +381,7 @@ static pteval_t pte_mfn_to_pfn(pteval_t val) | |||
381 | 381 | ||
382 | static pteval_t pte_pfn_to_mfn(pteval_t val) | 382 | static pteval_t pte_pfn_to_mfn(pteval_t val) |
383 | { | 383 | { |
384 | if (pteval_present(val)) { | 384 | if (val & _PAGE_PRESENT) { |
385 | unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; | 385 | unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; |
386 | pteval_t flags = val & PTE_FLAGS_MASK; | 386 | pteval_t flags = val & PTE_FLAGS_MASK; |
387 | unsigned long mfn; | 387 | unsigned long mfn; |
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 37d06ea624aa..61a6ac8fa8fc 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
@@ -399,11 +399,25 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) | |||
399 | state = BP_EAGAIN; | 399 | state = BP_EAGAIN; |
400 | break; | 400 | break; |
401 | } | 401 | } |
402 | scrub_page(page); | ||
402 | 403 | ||
403 | pfn = page_to_pfn(page); | 404 | frame_list[i] = page_to_pfn(page); |
404 | frame_list[i] = pfn_to_mfn(pfn); | 405 | } |
405 | 406 | ||
406 | scrub_page(page); | 407 | /* |
408 | * Ensure that ballooned highmem pages don't have kmaps. | ||
409 | * | ||
410 | * Do this before changing the p2m as kmap_flush_unused() | ||
411 | * reads PTEs to obtain pages (and hence needs the original | ||
412 | * p2m entry). | ||
413 | */ | ||
414 | kmap_flush_unused(); | ||
415 | |||
416 | /* Update direct mapping, invalidate P2M, and add to balloon. */ | ||
417 | for (i = 0; i < nr_pages; i++) { | ||
418 | pfn = frame_list[i]; | ||
419 | frame_list[i] = pfn_to_mfn(pfn); | ||
420 | page = pfn_to_page(pfn); | ||
407 | 421 | ||
408 | #ifdef CONFIG_XEN_HAVE_PVMMU | 422 | #ifdef CONFIG_XEN_HAVE_PVMMU |
409 | /* | 423 | /* |
@@ -429,11 +443,9 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) | |||
429 | } | 443 | } |
430 | #endif | 444 | #endif |
431 | 445 | ||
432 | balloon_append(pfn_to_page(pfn)); | 446 | balloon_append(page); |
433 | } | 447 | } |
434 | 448 | ||
435 | /* Ensure that ballooned highmem pages don't have kmaps. */ | ||
436 | kmap_flush_unused(); | ||
437 | flush_tlb_all(); | 449 | flush_tlb_all(); |
438 | 450 | ||
439 | set_xen_guest_handle(reservation.extent_start, frame_list); | 451 | set_xen_guest_handle(reservation.extent_start, frame_list); |