diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2013-12-11 11:58:42 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-12-13 11:20:30 -0500 |
commit | c1d15f5c8bc1170dafe16e988e55437245966dfe (patch) | |
tree | bb1c364882addcaa8ac053ed12ae7a501f54a3be /drivers/xen/balloon.c | |
parent | 380108d891acf8db5cf0d477176c7ed2b62b7928 (diff) |
xen/balloon: Seperate the auto-translate logic properly (v2)
The auto-xlat logic vs the non-xlat means that we don't need to for
auto-xlat guests (like PVH, HVM or ARM):
- use P2M
- use scratch page.
However the code in increase_reservation does modify the p2m for
auto_translate guests, but not in decrease_reservation.
Fix that by avoiding any p2m modifications in both increase_reservation
and decrease_reservation for auto_translated guests.
And also avoid allocating or using scratch pages for auto_translated guests.
Lastly, since !auto-xlat is really another way of saying 'xen_pv'
remove the redundant 'xen_pv_domain' check.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
[v2: Updated the description]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen/balloon.c')
-rw-r--r-- | drivers/xen/balloon.c | 63 |
1 files changed, 34 insertions, 29 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 | ||