diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-12-20 12:34:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-12-20 12:34:54 -0500 |
commit | 4203d0eb3acc459d1e7737193b5684e71185dca7 (patch) | |
tree | 357734dc414c22e87cd676dd1ff3feead64defc9 /drivers/xen | |
parent | 5263f0a88076ab32b3120356645734918bdc1700 (diff) | |
parent | c1d15f5c8bc1170dafe16e988e55437245966dfe (diff) |
Merge tag 'stable/for-linus-3.13-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull Xen bugfixes from Konrad Rzeszutek Wilk:
- Fix balloon driver for auto-translate guests (PVHVM, ARM) to not use
scratch pages.
- Fix block API header for ARM32 and ARM64 to have proper layout
- On ARM when mapping guests, stick on PTE_SPECIAL
- When using SWIOTLB under ARM, don't call swiotlb functions twice
- When unmapping guests memory and if we fail, don't return pages which
failed to be unmapped.
- Grant driver was using the wrong address on ARM.
* tag 'stable/for-linus-3.13-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xen/balloon: Seperate the auto-translate logic properly (v2)
xen/block: Correctly define structures in public headers on ARM32 and ARM64
arm: xen: foreign mapping PTEs are special.
xen/arm64: do not call the swiotlb functions twice
xen: privcmd: do not return pages which we have failed to unmap
XEN: Grant table address, xen_hvm_resume_frames, is a phys_addr not a pfn
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/balloon.c | 63 | ||||
-rw-r--r-- | drivers/xen/grant-table.c | 3 | ||||
-rw-r--r-- | drivers/xen/privcmd.c | 9 |
3 files changed, 43 insertions, 32 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 55ea73f7c70b..4c02e2b94103 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
@@ -350,17 +350,19 @@ static enum bp_state increase_reservation(unsigned long nr_pages) | |||
350 | 350 | ||
351 | pfn = page_to_pfn(page); | 351 | pfn = page_to_pfn(page); |
352 | 352 | ||
353 | set_phys_to_machine(pfn, frame_list[i]); | ||
354 | |||
355 | #ifdef CONFIG_XEN_HAVE_PVMMU | 353 | #ifdef CONFIG_XEN_HAVE_PVMMU |
356 | /* Link back into the page tables if not highmem. */ | 354 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { |
357 | if (xen_pv_domain() && !PageHighMem(page)) { | 355 | set_phys_to_machine(pfn, frame_list[i]); |
358 | int ret; | 356 | |
359 | ret = HYPERVISOR_update_va_mapping( | 357 | /* Link back into the page tables if not highmem. */ |
360 | (unsigned long)__va(pfn << PAGE_SHIFT), | 358 | if (!PageHighMem(page)) { |
361 | mfn_pte(frame_list[i], PAGE_KERNEL), | 359 | int ret; |
362 | 0); | 360 | ret = HYPERVISOR_update_va_mapping( |
363 | BUG_ON(ret); | 361 | (unsigned long)__va(pfn << PAGE_SHIFT), |
362 | mfn_pte(frame_list[i], PAGE_KERNEL), | ||
363 | 0); | ||
364 | BUG_ON(ret); | ||
365 | } | ||
364 | } | 366 | } |
365 | #endif | 367 | #endif |
366 | 368 | ||
@@ -378,7 +380,6 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) | |||
378 | enum bp_state state = BP_DONE; | 380 | enum bp_state state = BP_DONE; |
379 | unsigned long pfn, i; | 381 | unsigned long pfn, i; |
380 | struct page *page; | 382 | struct page *page; |
381 | struct page *scratch_page; | ||
382 | int ret; | 383 | int ret; |
383 | struct xen_memory_reservation reservation = { | 384 | struct xen_memory_reservation reservation = { |
384 | .address_bits = 0, | 385 | .address_bits = 0, |
@@ -411,27 +412,29 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) | |||
411 | 412 | ||
412 | scrub_page(page); | 413 | scrub_page(page); |
413 | 414 | ||
415 | #ifdef CONFIG_XEN_HAVE_PVMMU | ||
414 | /* | 416 | /* |
415 | * Ballooned out frames are effectively replaced with | 417 | * Ballooned out frames are effectively replaced with |
416 | * a scratch frame. Ensure direct mappings and the | 418 | * a scratch frame. Ensure direct mappings and the |
417 | * p2m are consistent. | 419 | * p2m are consistent. |
418 | */ | 420 | */ |
419 | scratch_page = get_balloon_scratch_page(); | ||
420 | #ifdef CONFIG_XEN_HAVE_PVMMU | ||
421 | if (xen_pv_domain() && !PageHighMem(page)) { | ||
422 | ret = HYPERVISOR_update_va_mapping( | ||
423 | (unsigned long)__va(pfn << PAGE_SHIFT), | ||
424 | pfn_pte(page_to_pfn(scratch_page), | ||
425 | PAGE_KERNEL_RO), 0); | ||
426 | BUG_ON(ret); | ||
427 | } | ||
428 | #endif | ||
429 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | 421 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { |
430 | unsigned long p; | 422 | unsigned long p; |
423 | struct page *scratch_page = get_balloon_scratch_page(); | ||
424 | |||
425 | if (!PageHighMem(page)) { | ||
426 | ret = HYPERVISOR_update_va_mapping( | ||
427 | (unsigned long)__va(pfn << PAGE_SHIFT), | ||
428 | pfn_pte(page_to_pfn(scratch_page), | ||
429 | PAGE_KERNEL_RO), 0); | ||
430 | BUG_ON(ret); | ||
431 | } | ||
431 | p = page_to_pfn(scratch_page); | 432 | p = page_to_pfn(scratch_page); |
432 | __set_phys_to_machine(pfn, pfn_to_mfn(p)); | 433 | __set_phys_to_machine(pfn, pfn_to_mfn(p)); |
434 | |||
435 | put_balloon_scratch_page(); | ||
433 | } | 436 | } |
434 | put_balloon_scratch_page(); | 437 | #endif |
435 | 438 | ||
436 | balloon_append(pfn_to_page(pfn)); | 439 | balloon_append(pfn_to_page(pfn)); |
437 | } | 440 | } |
@@ -627,15 +630,17 @@ static int __init balloon_init(void) | |||
627 | if (!xen_domain()) | 630 | if (!xen_domain()) |
628 | return -ENODEV; | 631 | return -ENODEV; |
629 | 632 | ||
630 | for_each_online_cpu(cpu) | 633 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { |
631 | { | 634 | for_each_online_cpu(cpu) |
632 | per_cpu(balloon_scratch_page, cpu) = alloc_page(GFP_KERNEL); | 635 | { |
633 | if (per_cpu(balloon_scratch_page, cpu) == NULL) { | 636 | per_cpu(balloon_scratch_page, cpu) = alloc_page(GFP_KERNEL); |
634 | pr_warn("Failed to allocate balloon_scratch_page for cpu %d\n", cpu); | 637 | if (per_cpu(balloon_scratch_page, cpu) == NULL) { |
635 | return -ENOMEM; | 638 | pr_warn("Failed to allocate balloon_scratch_page for cpu %d\n", cpu); |
639 | return -ENOMEM; | ||
640 | } | ||
636 | } | 641 | } |
642 | register_cpu_notifier(&balloon_cpu_notifier); | ||
637 | } | 643 | } |
638 | register_cpu_notifier(&balloon_cpu_notifier); | ||
639 | 644 | ||
640 | pr_info("Initialising balloon driver\n"); | 645 | pr_info("Initialising balloon driver\n"); |
641 | 646 | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 028387192b60..aa846a48f400 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -1176,7 +1176,8 @@ static int gnttab_setup(void) | |||
1176 | gnttab_shared.addr = xen_remap(xen_hvm_resume_frames, | 1176 | gnttab_shared.addr = xen_remap(xen_hvm_resume_frames, |
1177 | PAGE_SIZE * max_nr_gframes); | 1177 | PAGE_SIZE * max_nr_gframes); |
1178 | if (gnttab_shared.addr == NULL) { | 1178 | if (gnttab_shared.addr == NULL) { |
1179 | pr_warn("Failed to ioremap gnttab share frames!\n"); | 1179 | pr_warn("Failed to ioremap gnttab share frames (addr=0x%08lx)!\n", |
1180 | xen_hvm_resume_frames); | ||
1180 | return -ENOMEM; | 1181 | return -ENOMEM; |
1181 | } | 1182 | } |
1182 | } | 1183 | } |
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 8e74590fa1bb..569a13b9e856 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c | |||
@@ -533,12 +533,17 @@ static void privcmd_close(struct vm_area_struct *vma) | |||
533 | { | 533 | { |
534 | struct page **pages = vma->vm_private_data; | 534 | struct page **pages = vma->vm_private_data; |
535 | int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 535 | int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
536 | int rc; | ||
536 | 537 | ||
537 | if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages) | 538 | if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages) |
538 | return; | 539 | return; |
539 | 540 | ||
540 | xen_unmap_domain_mfn_range(vma, numpgs, pages); | 541 | rc = xen_unmap_domain_mfn_range(vma, numpgs, pages); |
541 | free_xenballooned_pages(numpgs, pages); | 542 | if (rc == 0) |
543 | free_xenballooned_pages(numpgs, pages); | ||
544 | else | ||
545 | pr_crit("unable to unmap MFN range: leaking %d pages. rc=%d\n", | ||
546 | numpgs, rc); | ||
542 | kfree(pages); | 547 | kfree(pages); |
543 | } | 548 | } |
544 | 549 | ||