aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/balloon.c147
1 files changed, 3 insertions, 144 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index cdec2d843e4c..fff987b10e0f 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -226,9 +226,8 @@ static int increase_reservation(unsigned long nr_pages)
226 } 226 }
227 227
228 set_xen_guest_handle(reservation.extent_start, frame_list); 228 set_xen_guest_handle(reservation.extent_start, frame_list);
229 reservation.nr_extents = nr_pages; 229 reservation.nr_extents = nr_pages;
230 rc = HYPERVISOR_memory_op( 230 rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
231 XENMEM_populate_physmap, &reservation);
232 if (rc < nr_pages) { 231 if (rc < nr_pages) {
233 if (rc > 0) { 232 if (rc > 0) {
234 int ret; 233 int ret;
@@ -236,7 +235,7 @@ static int increase_reservation(unsigned long nr_pages)
236 /* We hit the Xen hard limit: reprobe. */ 235 /* We hit the Xen hard limit: reprobe. */
237 reservation.nr_extents = rc; 236 reservation.nr_extents = rc;
238 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, 237 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
239 &reservation); 238 &reservation);
240 BUG_ON(ret != rc); 239 BUG_ON(ret != rc);
241 } 240 }
242 if (rc >= 0) 241 if (rc >= 0)
@@ -464,130 +463,6 @@ static void balloon_exit(void)
464 463
465module_exit(balloon_exit); 464module_exit(balloon_exit);
466 465
467static void balloon_update_driver_allowance(long delta)
468{
469 unsigned long flags;
470
471 spin_lock_irqsave(&balloon_lock, flags);
472 balloon_stats.driver_pages += delta;
473 spin_unlock_irqrestore(&balloon_lock, flags);
474}
475
476static int dealloc_pte_fn(
477 pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
478{
479 unsigned long mfn = pte_mfn(*pte);
480 int ret;
481 struct xen_memory_reservation reservation = {
482 .nr_extents = 1,
483 .extent_order = 0,
484 .domid = DOMID_SELF
485 };
486 set_xen_guest_handle(reservation.extent_start, &mfn);
487 set_pte_at(&init_mm, addr, pte, __pte_ma(0ull));
488 set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
489 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
490 BUG_ON(ret != 1);
491 return 0;
492}
493
494static struct page **alloc_empty_pages_and_pagevec(int nr_pages)
495{
496 unsigned long vaddr, flags;
497 struct page *page, **pagevec;
498 int i, ret;
499
500 pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL);
501 if (pagevec == NULL)
502 return NULL;
503
504 for (i = 0; i < nr_pages; i++) {
505 page = pagevec[i] = alloc_page(GFP_KERNEL);
506 if (page == NULL)
507 goto err;
508
509 vaddr = (unsigned long)page_address(page);
510
511 scrub_page(page);
512
513 spin_lock_irqsave(&balloon_lock, flags);
514
515 if (xen_feature(XENFEAT_auto_translated_physmap)) {
516 unsigned long gmfn = page_to_pfn(page);
517 struct xen_memory_reservation reservation = {
518 .nr_extents = 1,
519 .extent_order = 0,
520 .domid = DOMID_SELF
521 };
522 set_xen_guest_handle(reservation.extent_start, &gmfn);
523 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
524 &reservation);
525 if (ret == 1)
526 ret = 0; /* success */
527 } else {
528 ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,
529 dealloc_pte_fn, NULL);
530 }
531
532 if (ret != 0) {
533 spin_unlock_irqrestore(&balloon_lock, flags);
534 __free_page(page);
535 goto err;
536 }
537
538 totalram_pages = --balloon_stats.current_pages;
539
540 spin_unlock_irqrestore(&balloon_lock, flags);
541 }
542
543 out:
544 schedule_work(&balloon_worker);
545 flush_tlb_all();
546 return pagevec;
547
548 err:
549 spin_lock_irqsave(&balloon_lock, flags);
550 while (--i >= 0)
551 balloon_append(pagevec[i]);
552 spin_unlock_irqrestore(&balloon_lock, flags);
553 kfree(pagevec);
554 pagevec = NULL;
555 goto out;
556}
557
558static void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
559{
560 unsigned long flags;
561 int i;
562
563 if (pagevec == NULL)
564 return;
565
566 spin_lock_irqsave(&balloon_lock, flags);
567 for (i = 0; i < nr_pages; i++) {
568 BUG_ON(page_count(pagevec[i]) != 1);
569 balloon_append(pagevec[i]);
570 }
571 spin_unlock_irqrestore(&balloon_lock, flags);
572
573 kfree(pagevec);
574
575 schedule_work(&balloon_worker);
576}
577
578static void balloon_release_driver_page(struct page *page)
579{
580 unsigned long flags;
581
582 spin_lock_irqsave(&balloon_lock, flags);
583 balloon_append(page);
584 balloon_stats.driver_pages--;
585 spin_unlock_irqrestore(&balloon_lock, flags);
586
587 schedule_work(&balloon_worker);
588}
589
590
591#define BALLOON_SHOW(name, format, args...) \ 466#define BALLOON_SHOW(name, format, args...) \
592 static ssize_t show_##name(struct sys_device *dev, \ 467 static ssize_t show_##name(struct sys_device *dev, \
593 struct sysdev_attribute *attr, \ 468 struct sysdev_attribute *attr, \
@@ -691,20 +566,4 @@ static int register_balloon(struct sys_device *sysdev)
691 return error; 566 return error;
692} 567}
693 568
694static void unregister_balloon(struct sys_device *sysdev)
695{
696 int i;
697
698 sysfs_remove_group(&sysdev->kobj, &balloon_info_group);
699 for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++)
700 sysdev_remove_file(sysdev, balloon_attrs[i]);
701 sysdev_unregister(sysdev);
702 sysdev_class_unregister(&balloon_sysdev_class);
703}
704
705static void balloon_sysfs_exit(void)
706{
707 unregister_balloon(&balloon_sysdev);
708}
709
710MODULE_LICENSE("GPL"); 569MODULE_LICENSE("GPL");