diff options
-rw-r--r-- | arch/x86/include/asm/xen/page.h | 6 | ||||
-rw-r--r-- | arch/x86/pci/xen.c | 10 | ||||
-rw-r--r-- | arch/x86/xen/Kconfig | 8 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 1 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 52 | ||||
-rw-r--r-- | arch/x86/xen/p2m.c | 128 | ||||
-rw-r--r-- | drivers/block/xen-blkback/blkback.c | 2 | ||||
-rw-r--r-- | drivers/xen/balloon.c | 12 | ||||
-rw-r--r-- | drivers/xen/events.c | 10 | ||||
-rw-r--r-- | drivers/xen/gntdev.c | 39 | ||||
-rw-r--r-- | drivers/xen/grant-table.c | 6 | ||||
-rw-r--r-- | drivers/xen/xen-selfballoon.c | 67 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_probe_backend.c | 2 | ||||
-rw-r--r-- | include/xen/balloon.h | 5 | ||||
-rw-r--r-- | include/xen/grant_table.h | 1 |
15 files changed, 238 insertions, 111 deletions
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 7ff4669580cf..c34f96c2f7a0 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/pgtable.h> | 12 | #include <asm/pgtable.h> |
13 | 13 | ||
14 | #include <xen/interface/xen.h> | 14 | #include <xen/interface/xen.h> |
15 | #include <xen/grant_table.h> | ||
15 | #include <xen/features.h> | 16 | #include <xen/features.h> |
16 | 17 | ||
17 | /* Xen machine address */ | 18 | /* Xen machine address */ |
@@ -48,14 +49,11 @@ extern unsigned long set_phys_range_identity(unsigned long pfn_s, | |||
48 | unsigned long pfn_e); | 49 | unsigned long pfn_e); |
49 | 50 | ||
50 | extern int m2p_add_override(unsigned long mfn, struct page *page, | 51 | extern int m2p_add_override(unsigned long mfn, struct page *page, |
51 | bool clear_pte); | 52 | struct gnttab_map_grant_ref *kmap_op); |
52 | extern int m2p_remove_override(struct page *page, bool clear_pte); | 53 | extern int m2p_remove_override(struct page *page, bool clear_pte); |
53 | extern struct page *m2p_find_override(unsigned long mfn); | 54 | extern struct page *m2p_find_override(unsigned long mfn); |
54 | extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); | 55 | extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); |
55 | 56 | ||
56 | #ifdef CONFIG_XEN_DEBUG_FS | ||
57 | extern int p2m_dump_show(struct seq_file *m, void *v); | ||
58 | #endif | ||
59 | static inline unsigned long pfn_to_mfn(unsigned long pfn) | 57 | static inline unsigned long pfn_to_mfn(unsigned long pfn) |
60 | { | 58 | { |
61 | unsigned long mfn; | 59 | unsigned long mfn; |
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 1017c7bee388..11a9301d52d4 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
@@ -175,8 +175,10 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
175 | "pcifront-msi-x" : | 175 | "pcifront-msi-x" : |
176 | "pcifront-msi", | 176 | "pcifront-msi", |
177 | DOMID_SELF); | 177 | DOMID_SELF); |
178 | if (irq < 0) | 178 | if (irq < 0) { |
179 | ret = irq; | ||
179 | goto free; | 180 | goto free; |
181 | } | ||
180 | i++; | 182 | i++; |
181 | } | 183 | } |
182 | kfree(v); | 184 | kfree(v); |
@@ -221,8 +223,10 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
221 | if (msg.data != XEN_PIRQ_MSI_DATA || | 223 | if (msg.data != XEN_PIRQ_MSI_DATA || |
222 | xen_irq_from_pirq(pirq) < 0) { | 224 | xen_irq_from_pirq(pirq) < 0) { |
223 | pirq = xen_allocate_pirq_msi(dev, msidesc); | 225 | pirq = xen_allocate_pirq_msi(dev, msidesc); |
224 | if (pirq < 0) | 226 | if (pirq < 0) { |
227 | irq = -ENODEV; | ||
225 | goto error; | 228 | goto error; |
229 | } | ||
226 | xen_msi_compose_msg(dev, pirq, &msg); | 230 | xen_msi_compose_msg(dev, pirq, &msg); |
227 | __write_msi_msg(msidesc, &msg); | 231 | __write_msi_msg(msidesc, &msg); |
228 | dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); | 232 | dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); |
@@ -244,7 +248,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
244 | error: | 248 | error: |
245 | dev_err(&dev->dev, | 249 | dev_err(&dev->dev, |
246 | "Xen PCI frontend has not registered MSI/MSI-X support!\n"); | 250 | "Xen PCI frontend has not registered MSI/MSI-X support!\n"); |
247 | return -ENODEV; | 251 | return irq; |
248 | } | 252 | } |
249 | 253 | ||
250 | #ifdef CONFIG_XEN_DOM0 | 254 | #ifdef CONFIG_XEN_DOM0 |
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 5cc821cb2e09..ae559fe91c25 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig | |||
@@ -49,11 +49,3 @@ config XEN_DEBUG_FS | |||
49 | help | 49 | help |
50 | Enable statistics output and various tuning options in debugfs. | 50 | Enable statistics output and various tuning options in debugfs. |
51 | Enabling this option may incur a significant performance overhead. | 51 | Enabling this option may incur a significant performance overhead. |
52 | |||
53 | config XEN_DEBUG | ||
54 | bool "Enable Xen debug checks" | ||
55 | depends on XEN | ||
56 | default n | ||
57 | help | ||
58 | Enable various WARN_ON checks in the Xen MMU code. | ||
59 | Enabling this option WILL incur a significant performance overhead. | ||
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 2d69617950f7..da8afd576a6b 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -251,6 +251,7 @@ static void __init xen_init_cpuid_mask(void) | |||
251 | ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ | 251 | ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ |
252 | (1 << X86_FEATURE_ACPI)); /* disable ACPI */ | 252 | (1 << X86_FEATURE_ACPI)); /* disable ACPI */ |
253 | ax = 1; | 253 | ax = 1; |
254 | cx = 0; | ||
254 | xen_cpuid(&ax, &bx, &cx, &dx); | 255 | xen_cpuid(&ax, &bx, &cx, &dx); |
255 | 256 | ||
256 | xsave_mask = | 257 | xsave_mask = |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 3dd53f997b11..87f6673b1207 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -495,41 +495,6 @@ static pte_t xen_make_pte(pteval_t pte) | |||
495 | } | 495 | } |
496 | PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte); | 496 | PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte); |
497 | 497 | ||
498 | #ifdef CONFIG_XEN_DEBUG | ||
499 | pte_t xen_make_pte_debug(pteval_t pte) | ||
500 | { | ||
501 | phys_addr_t addr = (pte & PTE_PFN_MASK); | ||
502 | phys_addr_t other_addr; | ||
503 | bool io_page = false; | ||
504 | pte_t _pte; | ||
505 | |||
506 | if (pte & _PAGE_IOMAP) | ||
507 | io_page = true; | ||
508 | |||
509 | _pte = xen_make_pte(pte); | ||
510 | |||
511 | if (!addr) | ||
512 | return _pte; | ||
513 | |||
514 | if (io_page && | ||
515 | (xen_initial_domain() || addr >= ISA_END_ADDRESS)) { | ||
516 | other_addr = pfn_to_mfn(addr >> PAGE_SHIFT) << PAGE_SHIFT; | ||
517 | WARN_ONCE(addr != other_addr, | ||
518 | "0x%lx is using VM_IO, but it is 0x%lx!\n", | ||
519 | (unsigned long)addr, (unsigned long)other_addr); | ||
520 | } else { | ||
521 | pteval_t iomap_set = (_pte.pte & PTE_FLAGS_MASK) & _PAGE_IOMAP; | ||
522 | other_addr = (_pte.pte & PTE_PFN_MASK); | ||
523 | WARN_ONCE((addr == other_addr) && (!io_page) && (!iomap_set), | ||
524 | "0x%lx is missing VM_IO (and wasn't fixed)!\n", | ||
525 | (unsigned long)addr); | ||
526 | } | ||
527 | |||
528 | return _pte; | ||
529 | } | ||
530 | PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte_debug); | ||
531 | #endif | ||
532 | |||
533 | static pgd_t xen_make_pgd(pgdval_t pgd) | 498 | static pgd_t xen_make_pgd(pgdval_t pgd) |
534 | { | 499 | { |
535 | pgd = pte_pfn_to_mfn(pgd); | 500 | pgd = pte_pfn_to_mfn(pgd); |
@@ -1992,9 +1957,6 @@ void __init xen_ident_map_ISA(void) | |||
1992 | 1957 | ||
1993 | static void __init xen_post_allocator_init(void) | 1958 | static void __init xen_post_allocator_init(void) |
1994 | { | 1959 | { |
1995 | #ifdef CONFIG_XEN_DEBUG | ||
1996 | pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug); | ||
1997 | #endif | ||
1998 | pv_mmu_ops.set_pte = xen_set_pte; | 1960 | pv_mmu_ops.set_pte = xen_set_pte; |
1999 | pv_mmu_ops.set_pmd = xen_set_pmd; | 1961 | pv_mmu_ops.set_pmd = xen_set_pmd; |
2000 | pv_mmu_ops.set_pud = xen_set_pud; | 1962 | pv_mmu_ops.set_pud = xen_set_pud; |
@@ -2404,17 +2366,3 @@ out: | |||
2404 | return err; | 2366 | return err; |
2405 | } | 2367 | } |
2406 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); | 2368 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); |
2407 | |||
2408 | #ifdef CONFIG_XEN_DEBUG_FS | ||
2409 | static int p2m_dump_open(struct inode *inode, struct file *filp) | ||
2410 | { | ||
2411 | return single_open(filp, p2m_dump_show, NULL); | ||
2412 | } | ||
2413 | |||
2414 | static const struct file_operations p2m_dump_fops = { | ||
2415 | .open = p2m_dump_open, | ||
2416 | .read = seq_read, | ||
2417 | .llseek = seq_lseek, | ||
2418 | .release = single_release, | ||
2419 | }; | ||
2420 | #endif /* CONFIG_XEN_DEBUG_FS */ | ||
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 58efeb9d5440..1b267e75158d 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -161,7 +161,9 @@ | |||
161 | #include <asm/xen/page.h> | 161 | #include <asm/xen/page.h> |
162 | #include <asm/xen/hypercall.h> | 162 | #include <asm/xen/hypercall.h> |
163 | #include <asm/xen/hypervisor.h> | 163 | #include <asm/xen/hypervisor.h> |
164 | #include <xen/grant_table.h> | ||
164 | 165 | ||
166 | #include "multicalls.h" | ||
165 | #include "xen-ops.h" | 167 | #include "xen-ops.h" |
166 | 168 | ||
167 | static void __init m2p_override_init(void); | 169 | static void __init m2p_override_init(void); |
@@ -676,7 +678,8 @@ static unsigned long mfn_hash(unsigned long mfn) | |||
676 | } | 678 | } |
677 | 679 | ||
678 | /* Add an MFN override for a particular page */ | 680 | /* Add an MFN override for a particular page */ |
679 | int m2p_add_override(unsigned long mfn, struct page *page, bool clear_pte) | 681 | int m2p_add_override(unsigned long mfn, struct page *page, |
682 | struct gnttab_map_grant_ref *kmap_op) | ||
680 | { | 683 | { |
681 | unsigned long flags; | 684 | unsigned long flags; |
682 | unsigned long pfn; | 685 | unsigned long pfn; |
@@ -692,16 +695,28 @@ int m2p_add_override(unsigned long mfn, struct page *page, bool clear_pte) | |||
692 | "m2p_add_override: pfn %lx not mapped", pfn)) | 695 | "m2p_add_override: pfn %lx not mapped", pfn)) |
693 | return -EINVAL; | 696 | return -EINVAL; |
694 | } | 697 | } |
695 | 698 | WARN_ON(PagePrivate(page)); | |
696 | page->private = mfn; | 699 | SetPagePrivate(page); |
700 | set_page_private(page, mfn); | ||
697 | page->index = pfn_to_mfn(pfn); | 701 | page->index = pfn_to_mfn(pfn); |
698 | 702 | ||
699 | if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) | 703 | if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) |
700 | return -ENOMEM; | 704 | return -ENOMEM; |
701 | 705 | ||
702 | if (clear_pte && !PageHighMem(page)) | 706 | if (kmap_op != NULL) { |
703 | /* Just zap old mapping for now */ | 707 | if (!PageHighMem(page)) { |
704 | pte_clear(&init_mm, address, ptep); | 708 | struct multicall_space mcs = |
709 | xen_mc_entry(sizeof(*kmap_op)); | ||
710 | |||
711 | MULTI_grant_table_op(mcs.mc, | ||
712 | GNTTABOP_map_grant_ref, kmap_op, 1); | ||
713 | |||
714 | xen_mc_issue(PARAVIRT_LAZY_MMU); | ||
715 | } | ||
716 | /* let's use dev_bus_addr to record the old mfn instead */ | ||
717 | kmap_op->dev_bus_addr = page->index; | ||
718 | page->index = (unsigned long) kmap_op; | ||
719 | } | ||
705 | spin_lock_irqsave(&m2p_override_lock, flags); | 720 | spin_lock_irqsave(&m2p_override_lock, flags); |
706 | list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); | 721 | list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); |
707 | spin_unlock_irqrestore(&m2p_override_lock, flags); | 722 | spin_unlock_irqrestore(&m2p_override_lock, flags); |
@@ -735,13 +750,56 @@ int m2p_remove_override(struct page *page, bool clear_pte) | |||
735 | spin_lock_irqsave(&m2p_override_lock, flags); | 750 | spin_lock_irqsave(&m2p_override_lock, flags); |
736 | list_del(&page->lru); | 751 | list_del(&page->lru); |
737 | spin_unlock_irqrestore(&m2p_override_lock, flags); | 752 | spin_unlock_irqrestore(&m2p_override_lock, flags); |
738 | set_phys_to_machine(pfn, page->index); | 753 | WARN_ON(!PagePrivate(page)); |
754 | ClearPagePrivate(page); | ||
739 | 755 | ||
740 | if (clear_pte && !PageHighMem(page)) | 756 | if (clear_pte) { |
741 | set_pte_at(&init_mm, address, ptep, | 757 | struct gnttab_map_grant_ref *map_op = |
742 | pfn_pte(pfn, PAGE_KERNEL)); | 758 | (struct gnttab_map_grant_ref *) page->index; |
743 | /* No tlb flush necessary because the caller already | 759 | set_phys_to_machine(pfn, map_op->dev_bus_addr); |
744 | * left the pte unmapped. */ | 760 | if (!PageHighMem(page)) { |
761 | struct multicall_space mcs; | ||
762 | struct gnttab_unmap_grant_ref *unmap_op; | ||
763 | |||
764 | /* | ||
765 | * It might be that we queued all the m2p grant table | ||
766 | * hypercalls in a multicall, then m2p_remove_override | ||
767 | * get called before the multicall has actually been | ||
768 | * issued. In this case handle is going to -1 because | ||
769 | * it hasn't been modified yet. | ||
770 | */ | ||
771 | if (map_op->handle == -1) | ||
772 | xen_mc_flush(); | ||
773 | /* | ||
774 | * Now if map_op->handle is negative it means that the | ||
775 | * hypercall actually returned an error. | ||
776 | */ | ||
777 | if (map_op->handle == GNTST_general_error) { | ||
778 | printk(KERN_WARNING "m2p_remove_override: " | ||
779 | "pfn %lx mfn %lx, failed to modify kernel mappings", | ||
780 | pfn, mfn); | ||
781 | return -1; | ||
782 | } | ||
783 | |||
784 | mcs = xen_mc_entry( | ||
785 | sizeof(struct gnttab_unmap_grant_ref)); | ||
786 | unmap_op = mcs.args; | ||
787 | unmap_op->host_addr = map_op->host_addr; | ||
788 | unmap_op->handle = map_op->handle; | ||
789 | unmap_op->dev_bus_addr = 0; | ||
790 | |||
791 | MULTI_grant_table_op(mcs.mc, | ||
792 | GNTTABOP_unmap_grant_ref, unmap_op, 1); | ||
793 | |||
794 | xen_mc_issue(PARAVIRT_LAZY_MMU); | ||
795 | |||
796 | set_pte_at(&init_mm, address, ptep, | ||
797 | pfn_pte(pfn, PAGE_KERNEL)); | ||
798 | __flush_tlb_single(address); | ||
799 | map_op->host_addr = 0; | ||
800 | } | ||
801 | } else | ||
802 | set_phys_to_machine(pfn, page->index); | ||
745 | 803 | ||
746 | return 0; | 804 | return 0; |
747 | } | 805 | } |
@@ -758,7 +816,7 @@ struct page *m2p_find_override(unsigned long mfn) | |||
758 | spin_lock_irqsave(&m2p_override_lock, flags); | 816 | spin_lock_irqsave(&m2p_override_lock, flags); |
759 | 817 | ||
760 | list_for_each_entry(p, bucket, lru) { | 818 | list_for_each_entry(p, bucket, lru) { |
761 | if (p->private == mfn) { | 819 | if (page_private(p) == mfn) { |
762 | ret = p; | 820 | ret = p; |
763 | break; | 821 | break; |
764 | } | 822 | } |
@@ -782,17 +840,21 @@ unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn) | |||
782 | EXPORT_SYMBOL_GPL(m2p_find_override_pfn); | 840 | EXPORT_SYMBOL_GPL(m2p_find_override_pfn); |
783 | 841 | ||
784 | #ifdef CONFIG_XEN_DEBUG_FS | 842 | #ifdef CONFIG_XEN_DEBUG_FS |
785 | 843 | #include <linux/debugfs.h> | |
786 | int p2m_dump_show(struct seq_file *m, void *v) | 844 | #include "debugfs.h" |
845 | static int p2m_dump_show(struct seq_file *m, void *v) | ||
787 | { | 846 | { |
788 | static const char * const level_name[] = { "top", "middle", | 847 | static const char * const level_name[] = { "top", "middle", |
789 | "entry", "abnormal" }; | 848 | "entry", "abnormal", "error"}; |
790 | static const char * const type_name[] = { "identity", "missing", | ||
791 | "pfn", "abnormal"}; | ||
792 | #define TYPE_IDENTITY 0 | 849 | #define TYPE_IDENTITY 0 |
793 | #define TYPE_MISSING 1 | 850 | #define TYPE_MISSING 1 |
794 | #define TYPE_PFN 2 | 851 | #define TYPE_PFN 2 |
795 | #define TYPE_UNKNOWN 3 | 852 | #define TYPE_UNKNOWN 3 |
853 | static const char * const type_name[] = { | ||
854 | [TYPE_IDENTITY] = "identity", | ||
855 | [TYPE_MISSING] = "missing", | ||
856 | [TYPE_PFN] = "pfn", | ||
857 | [TYPE_UNKNOWN] = "abnormal"}; | ||
796 | unsigned long pfn, prev_pfn_type = 0, prev_pfn_level = 0; | 858 | unsigned long pfn, prev_pfn_type = 0, prev_pfn_level = 0; |
797 | unsigned int uninitialized_var(prev_level); | 859 | unsigned int uninitialized_var(prev_level); |
798 | unsigned int uninitialized_var(prev_type); | 860 | unsigned int uninitialized_var(prev_type); |
@@ -856,4 +918,32 @@ int p2m_dump_show(struct seq_file *m, void *v) | |||
856 | #undef TYPE_PFN | 918 | #undef TYPE_PFN |
857 | #undef TYPE_UNKNOWN | 919 | #undef TYPE_UNKNOWN |
858 | } | 920 | } |
859 | #endif | 921 | |
922 | static int p2m_dump_open(struct inode *inode, struct file *filp) | ||
923 | { | ||
924 | return single_open(filp, p2m_dump_show, NULL); | ||
925 | } | ||
926 | |||
927 | static const struct file_operations p2m_dump_fops = { | ||
928 | .open = p2m_dump_open, | ||
929 | .read = seq_read, | ||
930 | .llseek = seq_lseek, | ||
931 | .release = single_release, | ||
932 | }; | ||
933 | |||
934 | static struct dentry *d_mmu_debug; | ||
935 | |||
936 | static int __init xen_p2m_debugfs(void) | ||
937 | { | ||
938 | struct dentry *d_xen = xen_init_debugfs(); | ||
939 | |||
940 | if (d_xen == NULL) | ||
941 | return -ENOMEM; | ||
942 | |||
943 | d_mmu_debug = debugfs_create_dir("mmu", d_xen); | ||
944 | |||
945 | debugfs_create_file("p2m", 0600, d_mmu_debug, NULL, &p2m_dump_fops); | ||
946 | return 0; | ||
947 | } | ||
948 | fs_initcall(xen_p2m_debugfs); | ||
949 | #endif /* CONFIG_XEN_DEBUG_FS */ | ||
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 2330a9ad5e95..1540792b1e54 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -396,7 +396,7 @@ static int xen_blkbk_map(struct blkif_request *req, | |||
396 | continue; | 396 | continue; |
397 | 397 | ||
398 | ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), | 398 | ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), |
399 | blkbk->pending_page(pending_req, i), false); | 399 | blkbk->pending_page(pending_req, i), NULL); |
400 | if (ret) { | 400 | if (ret) { |
401 | pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n", | 401 | pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n", |
402 | (unsigned long)map[i].dev_bus_addr, ret); | 402 | (unsigned long)map[i].dev_bus_addr, ret); |
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index fc43b53651d7..5876e1ae6c2d 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
@@ -501,20 +501,24 @@ EXPORT_SYMBOL_GPL(balloon_set_new_target); | |||
501 | * alloc_xenballooned_pages - get pages that have been ballooned out | 501 | * alloc_xenballooned_pages - get pages that have been ballooned out |
502 | * @nr_pages: Number of pages to get | 502 | * @nr_pages: Number of pages to get |
503 | * @pages: pages returned | 503 | * @pages: pages returned |
504 | * @highmem: highmem or lowmem pages | ||
504 | * @return 0 on success, error otherwise | 505 | * @return 0 on success, error otherwise |
505 | */ | 506 | */ |
506 | int alloc_xenballooned_pages(int nr_pages, struct page** pages) | 507 | int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem) |
507 | { | 508 | { |
508 | int pgno = 0; | 509 | int pgno = 0; |
509 | struct page* page; | 510 | struct page* page; |
510 | mutex_lock(&balloon_mutex); | 511 | mutex_lock(&balloon_mutex); |
511 | while (pgno < nr_pages) { | 512 | while (pgno < nr_pages) { |
512 | page = balloon_retrieve(true); | 513 | page = balloon_retrieve(highmem); |
513 | if (page) { | 514 | if (page && PageHighMem(page) == highmem) { |
514 | pages[pgno++] = page; | 515 | pages[pgno++] = page; |
515 | } else { | 516 | } else { |
516 | enum bp_state st; | 517 | enum bp_state st; |
517 | st = decrease_reservation(nr_pages - pgno, GFP_HIGHUSER); | 518 | if (page) |
519 | balloon_append(page); | ||
520 | st = decrease_reservation(nr_pages - pgno, | ||
521 | highmem ? GFP_HIGHUSER : GFP_USER); | ||
518 | if (st != BP_DONE) | 522 | if (st != BP_DONE) |
519 | goto out_undo; | 523 | goto out_undo; |
520 | } | 524 | } |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 7523719bf8a4..212a5c871bf4 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -432,7 +432,8 @@ static int __must_check xen_allocate_irq_dynamic(void) | |||
432 | 432 | ||
433 | irq = irq_alloc_desc_from(first, -1); | 433 | irq = irq_alloc_desc_from(first, -1); |
434 | 434 | ||
435 | xen_irq_init(irq); | 435 | if (irq >= 0) |
436 | xen_irq_init(irq); | ||
436 | 437 | ||
437 | return irq; | 438 | return irq; |
438 | } | 439 | } |
@@ -713,7 +714,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, | |||
713 | mutex_lock(&irq_mapping_update_lock); | 714 | mutex_lock(&irq_mapping_update_lock); |
714 | 715 | ||
715 | irq = xen_allocate_irq_dynamic(); | 716 | irq = xen_allocate_irq_dynamic(); |
716 | if (irq == -1) | 717 | if (irq < 0) |
717 | goto out; | 718 | goto out; |
718 | 719 | ||
719 | irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq, | 720 | irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq, |
@@ -729,7 +730,7 @@ out: | |||
729 | error_irq: | 730 | error_irq: |
730 | mutex_unlock(&irq_mapping_update_lock); | 731 | mutex_unlock(&irq_mapping_update_lock); |
731 | xen_free_irq(irq); | 732 | xen_free_irq(irq); |
732 | return -1; | 733 | return ret; |
733 | } | 734 | } |
734 | #endif | 735 | #endif |
735 | 736 | ||
@@ -779,7 +780,7 @@ int xen_irq_from_pirq(unsigned pirq) | |||
779 | mutex_lock(&irq_mapping_update_lock); | 780 | mutex_lock(&irq_mapping_update_lock); |
780 | 781 | ||
781 | list_for_each_entry(info, &xen_irq_list_head, list) { | 782 | list_for_each_entry(info, &xen_irq_list_head, list) { |
782 | if (info == NULL || info->type != IRQT_PIRQ) | 783 | if (info->type != IRQT_PIRQ) |
783 | continue; | 784 | continue; |
784 | irq = info->irq; | 785 | irq = info->irq; |
785 | if (info->u.pirq.pirq == pirq) | 786 | if (info->u.pirq.pirq == pirq) |
@@ -1670,6 +1671,7 @@ void __init xen_init_IRQ(void) | |||
1670 | 1671 | ||
1671 | evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), | 1672 | evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), |
1672 | GFP_KERNEL); | 1673 | GFP_KERNEL); |
1674 | BUG_ON(!evtchn_to_irq); | ||
1673 | for (i = 0; i < NR_EVENT_CHANNELS; i++) | 1675 | for (i = 0; i < NR_EVENT_CHANNELS; i++) |
1674 | evtchn_to_irq[i] = -1; | 1676 | evtchn_to_irq[i] = -1; |
1675 | 1677 | ||
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index f914b26cf0c2..880798aae2f2 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -83,6 +83,7 @@ struct grant_map { | |||
83 | struct ioctl_gntdev_grant_ref *grants; | 83 | struct ioctl_gntdev_grant_ref *grants; |
84 | struct gnttab_map_grant_ref *map_ops; | 84 | struct gnttab_map_grant_ref *map_ops; |
85 | struct gnttab_unmap_grant_ref *unmap_ops; | 85 | struct gnttab_unmap_grant_ref *unmap_ops; |
86 | struct gnttab_map_grant_ref *kmap_ops; | ||
86 | struct page **pages; | 87 | struct page **pages; |
87 | }; | 88 | }; |
88 | 89 | ||
@@ -116,19 +117,22 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | |||
116 | add->grants = kzalloc(sizeof(add->grants[0]) * count, GFP_KERNEL); | 117 | add->grants = kzalloc(sizeof(add->grants[0]) * count, GFP_KERNEL); |
117 | add->map_ops = kzalloc(sizeof(add->map_ops[0]) * count, GFP_KERNEL); | 118 | add->map_ops = kzalloc(sizeof(add->map_ops[0]) * count, GFP_KERNEL); |
118 | add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL); | 119 | add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL); |
120 | add->kmap_ops = kzalloc(sizeof(add->kmap_ops[0]) * count, GFP_KERNEL); | ||
119 | add->pages = kzalloc(sizeof(add->pages[0]) * count, GFP_KERNEL); | 121 | add->pages = kzalloc(sizeof(add->pages[0]) * count, GFP_KERNEL); |
120 | if (NULL == add->grants || | 122 | if (NULL == add->grants || |
121 | NULL == add->map_ops || | 123 | NULL == add->map_ops || |
122 | NULL == add->unmap_ops || | 124 | NULL == add->unmap_ops || |
125 | NULL == add->kmap_ops || | ||
123 | NULL == add->pages) | 126 | NULL == add->pages) |
124 | goto err; | 127 | goto err; |
125 | 128 | ||
126 | if (alloc_xenballooned_pages(count, add->pages)) | 129 | if (alloc_xenballooned_pages(count, add->pages, false /* lowmem */)) |
127 | goto err; | 130 | goto err; |
128 | 131 | ||
129 | for (i = 0; i < count; i++) { | 132 | for (i = 0; i < count; i++) { |
130 | add->map_ops[i].handle = -1; | 133 | add->map_ops[i].handle = -1; |
131 | add->unmap_ops[i].handle = -1; | 134 | add->unmap_ops[i].handle = -1; |
135 | add->kmap_ops[i].handle = -1; | ||
132 | } | 136 | } |
133 | 137 | ||
134 | add->index = 0; | 138 | add->index = 0; |
@@ -142,6 +146,7 @@ err: | |||
142 | kfree(add->grants); | 146 | kfree(add->grants); |
143 | kfree(add->map_ops); | 147 | kfree(add->map_ops); |
144 | kfree(add->unmap_ops); | 148 | kfree(add->unmap_ops); |
149 | kfree(add->kmap_ops); | ||
145 | kfree(add); | 150 | kfree(add); |
146 | return NULL; | 151 | return NULL; |
147 | } | 152 | } |
@@ -243,10 +248,35 @@ static int map_grant_pages(struct grant_map *map) | |||
243 | gnttab_set_unmap_op(&map->unmap_ops[i], addr, | 248 | gnttab_set_unmap_op(&map->unmap_ops[i], addr, |
244 | map->flags, -1 /* handle */); | 249 | map->flags, -1 /* handle */); |
245 | } | 250 | } |
251 | } else { | ||
252 | /* | ||
253 | * Setup the map_ops corresponding to the pte entries pointing | ||
254 | * to the kernel linear addresses of the struct pages. | ||
255 | * These ptes are completely different from the user ptes dealt | ||
256 | * with find_grant_ptes. | ||
257 | */ | ||
258 | for (i = 0; i < map->count; i++) { | ||
259 | unsigned level; | ||
260 | unsigned long address = (unsigned long) | ||
261 | pfn_to_kaddr(page_to_pfn(map->pages[i])); | ||
262 | pte_t *ptep; | ||
263 | u64 pte_maddr = 0; | ||
264 | BUG_ON(PageHighMem(map->pages[i])); | ||
265 | |||
266 | ptep = lookup_address(address, &level); | ||
267 | pte_maddr = arbitrary_virt_to_machine(ptep).maddr; | ||
268 | gnttab_set_map_op(&map->kmap_ops[i], pte_maddr, | ||
269 | map->flags | | ||
270 | GNTMAP_host_map | | ||
271 | GNTMAP_contains_pte, | ||
272 | map->grants[i].ref, | ||
273 | map->grants[i].domid); | ||
274 | } | ||
246 | } | 275 | } |
247 | 276 | ||
248 | pr_debug("map %d+%d\n", map->index, map->count); | 277 | pr_debug("map %d+%d\n", map->index, map->count); |
249 | err = gnttab_map_refs(map->map_ops, map->pages, map->count); | 278 | err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, |
279 | map->pages, map->count); | ||
250 | if (err) | 280 | if (err) |
251 | return err; | 281 | return err; |
252 | 282 | ||
@@ -462,13 +492,11 @@ static int gntdev_release(struct inode *inode, struct file *flip) | |||
462 | 492 | ||
463 | pr_debug("priv %p\n", priv); | 493 | pr_debug("priv %p\n", priv); |
464 | 494 | ||
465 | spin_lock(&priv->lock); | ||
466 | while (!list_empty(&priv->maps)) { | 495 | while (!list_empty(&priv->maps)) { |
467 | map = list_entry(priv->maps.next, struct grant_map, next); | 496 | map = list_entry(priv->maps.next, struct grant_map, next); |
468 | list_del(&map->next); | 497 | list_del(&map->next); |
469 | gntdev_put_map(map); | 498 | gntdev_put_map(map); |
470 | } | 499 | } |
471 | spin_unlock(&priv->lock); | ||
472 | 500 | ||
473 | if (use_ptemod) | 501 | if (use_ptemod) |
474 | mmu_notifier_unregister(&priv->mn, priv->mm); | 502 | mmu_notifier_unregister(&priv->mn, priv->mm); |
@@ -532,10 +560,11 @@ static long gntdev_ioctl_unmap_grant_ref(struct gntdev_priv *priv, | |||
532 | map = gntdev_find_map_index(priv, op.index >> PAGE_SHIFT, op.count); | 560 | map = gntdev_find_map_index(priv, op.index >> PAGE_SHIFT, op.count); |
533 | if (map) { | 561 | if (map) { |
534 | list_del(&map->next); | 562 | list_del(&map->next); |
535 | gntdev_put_map(map); | ||
536 | err = 0; | 563 | err = 0; |
537 | } | 564 | } |
538 | spin_unlock(&priv->lock); | 565 | spin_unlock(&priv->lock); |
566 | if (map) | ||
567 | gntdev_put_map(map); | ||
539 | return err; | 568 | return err; |
540 | } | 569 | } |
541 | 570 | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 4f44b347b24a..8c71ab801756 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -448,7 +448,8 @@ unsigned int gnttab_max_grant_frames(void) | |||
448 | EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); | 448 | EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); |
449 | 449 | ||
450 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | 450 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, |
451 | struct page **pages, unsigned int count) | 451 | struct gnttab_map_grant_ref *kmap_ops, |
452 | struct page **pages, unsigned int count) | ||
452 | { | 453 | { |
453 | int i, ret; | 454 | int i, ret; |
454 | pte_t *pte; | 455 | pte_t *pte; |
@@ -488,8 +489,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
488 | */ | 489 | */ |
489 | return -EOPNOTSUPP; | 490 | return -EOPNOTSUPP; |
490 | } | 491 | } |
491 | ret = m2p_add_override(mfn, pages[i], | 492 | ret = m2p_add_override(mfn, pages[i], &kmap_ops[i]); |
492 | map_ops[i].flags & GNTMAP_contains_pte); | ||
493 | if (ret) | 493 | if (ret) |
494 | return ret; | 494 | return ret; |
495 | } | 495 | } |
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c index 6ea852e25162..d93c70857e03 100644 --- a/drivers/xen/xen-selfballoon.c +++ b/drivers/xen/xen-selfballoon.c | |||
@@ -68,6 +68,8 @@ | |||
68 | */ | 68 | */ |
69 | 69 | ||
70 | #include <linux/kernel.h> | 70 | #include <linux/kernel.h> |
71 | #include <linux/bootmem.h> | ||
72 | #include <linux/swap.h> | ||
71 | #include <linux/mm.h> | 73 | #include <linux/mm.h> |
72 | #include <linux/mman.h> | 74 | #include <linux/mman.h> |
73 | #include <linux/module.h> | 75 | #include <linux/module.h> |
@@ -93,6 +95,15 @@ static unsigned int selfballoon_uphysteresis __read_mostly = 1; | |||
93 | /* In HZ, controls frequency of worker invocation. */ | 95 | /* In HZ, controls frequency of worker invocation. */ |
94 | static unsigned int selfballoon_interval __read_mostly = 5; | 96 | static unsigned int selfballoon_interval __read_mostly = 5; |
95 | 97 | ||
98 | /* | ||
99 | * Minimum usable RAM in MB for selfballooning target for balloon. | ||
100 | * If non-zero, it is added to totalreserve_pages and self-ballooning | ||
101 | * will not balloon below the sum. If zero, a piecewise linear function | ||
102 | * is calculated as a minimum and added to totalreserve_pages. Note that | ||
103 | * setting this value indiscriminately may cause OOMs and crashes. | ||
104 | */ | ||
105 | static unsigned int selfballoon_min_usable_mb; | ||
106 | |||
96 | static void selfballoon_process(struct work_struct *work); | 107 | static void selfballoon_process(struct work_struct *work); |
97 | static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process); | 108 | static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process); |
98 | 109 | ||
@@ -189,20 +200,23 @@ static int __init xen_selfballooning_setup(char *s) | |||
189 | __setup("selfballooning", xen_selfballooning_setup); | 200 | __setup("selfballooning", xen_selfballooning_setup); |
190 | #endif /* CONFIG_FRONTSWAP */ | 201 | #endif /* CONFIG_FRONTSWAP */ |
191 | 202 | ||
203 | #define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) | ||
204 | |||
192 | /* | 205 | /* |
193 | * Use current balloon size, the goal (vm_committed_as), and hysteresis | 206 | * Use current balloon size, the goal (vm_committed_as), and hysteresis |
194 | * parameters to set a new target balloon size | 207 | * parameters to set a new target balloon size |
195 | */ | 208 | */ |
196 | static void selfballoon_process(struct work_struct *work) | 209 | static void selfballoon_process(struct work_struct *work) |
197 | { | 210 | { |
198 | unsigned long cur_pages, goal_pages, tgt_pages; | 211 | unsigned long cur_pages, goal_pages, tgt_pages, floor_pages; |
212 | unsigned long useful_pages; | ||
199 | bool reset_timer = false; | 213 | bool reset_timer = false; |
200 | 214 | ||
201 | if (xen_selfballooning_enabled) { | 215 | if (xen_selfballooning_enabled) { |
202 | cur_pages = balloon_stats.current_pages; | 216 | cur_pages = totalram_pages; |
203 | tgt_pages = cur_pages; /* default is no change */ | 217 | tgt_pages = cur_pages; /* default is no change */ |
204 | goal_pages = percpu_counter_read_positive(&vm_committed_as) + | 218 | goal_pages = percpu_counter_read_positive(&vm_committed_as) + |
205 | balloon_stats.current_pages - totalram_pages; | 219 | totalreserve_pages; |
206 | #ifdef CONFIG_FRONTSWAP | 220 | #ifdef CONFIG_FRONTSWAP |
207 | /* allow space for frontswap pages to be repatriated */ | 221 | /* allow space for frontswap pages to be repatriated */ |
208 | if (frontswap_selfshrinking && frontswap_enabled) | 222 | if (frontswap_selfshrinking && frontswap_enabled) |
@@ -217,7 +231,26 @@ static void selfballoon_process(struct work_struct *work) | |||
217 | ((goal_pages - cur_pages) / | 231 | ((goal_pages - cur_pages) / |
218 | selfballoon_uphysteresis); | 232 | selfballoon_uphysteresis); |
219 | /* else if cur_pages == goal_pages, no change */ | 233 | /* else if cur_pages == goal_pages, no change */ |
220 | balloon_set_new_target(tgt_pages); | 234 | useful_pages = max_pfn - totalreserve_pages; |
235 | if (selfballoon_min_usable_mb != 0) | ||
236 | floor_pages = totalreserve_pages + | ||
237 | MB2PAGES(selfballoon_min_usable_mb); | ||
238 | /* piecewise linear function ending in ~3% slope */ | ||
239 | else if (useful_pages < MB2PAGES(16)) | ||
240 | floor_pages = max_pfn; /* not worth ballooning */ | ||
241 | else if (useful_pages < MB2PAGES(64)) | ||
242 | floor_pages = totalreserve_pages + MB2PAGES(16) + | ||
243 | ((useful_pages - MB2PAGES(16)) >> 1); | ||
244 | else if (useful_pages < MB2PAGES(512)) | ||
245 | floor_pages = totalreserve_pages + MB2PAGES(40) + | ||
246 | ((useful_pages - MB2PAGES(40)) >> 3); | ||
247 | else /* useful_pages >= MB2PAGES(512) */ | ||
248 | floor_pages = totalreserve_pages + MB2PAGES(99) + | ||
249 | ((useful_pages - MB2PAGES(99)) >> 5); | ||
250 | if (tgt_pages < floor_pages) | ||
251 | tgt_pages = floor_pages; | ||
252 | balloon_set_new_target(tgt_pages + | ||
253 | balloon_stats.current_pages - totalram_pages); | ||
221 | reset_timer = true; | 254 | reset_timer = true; |
222 | } | 255 | } |
223 | #ifdef CONFIG_FRONTSWAP | 256 | #ifdef CONFIG_FRONTSWAP |
@@ -340,6 +373,31 @@ static ssize_t store_selfballoon_uphys(struct sys_device *dev, | |||
340 | static SYSDEV_ATTR(selfballoon_uphysteresis, S_IRUGO | S_IWUSR, | 373 | static SYSDEV_ATTR(selfballoon_uphysteresis, S_IRUGO | S_IWUSR, |
341 | show_selfballoon_uphys, store_selfballoon_uphys); | 374 | show_selfballoon_uphys, store_selfballoon_uphys); |
342 | 375 | ||
376 | SELFBALLOON_SHOW(selfballoon_min_usable_mb, "%d\n", | ||
377 | selfballoon_min_usable_mb); | ||
378 | |||
379 | static ssize_t store_selfballoon_min_usable_mb(struct sys_device *dev, | ||
380 | struct sysdev_attribute *attr, | ||
381 | const char *buf, | ||
382 | size_t count) | ||
383 | { | ||
384 | unsigned long val; | ||
385 | int err; | ||
386 | |||
387 | if (!capable(CAP_SYS_ADMIN)) | ||
388 | return -EPERM; | ||
389 | err = strict_strtoul(buf, 10, &val); | ||
390 | if (err || val == 0) | ||
391 | return -EINVAL; | ||
392 | selfballoon_min_usable_mb = val; | ||
393 | return count; | ||
394 | } | ||
395 | |||
396 | static SYSDEV_ATTR(selfballoon_min_usable_mb, S_IRUGO | S_IWUSR, | ||
397 | show_selfballoon_min_usable_mb, | ||
398 | store_selfballoon_min_usable_mb); | ||
399 | |||
400 | |||
343 | #ifdef CONFIG_FRONTSWAP | 401 | #ifdef CONFIG_FRONTSWAP |
344 | SELFBALLOON_SHOW(frontswap_selfshrinking, "%d\n", frontswap_selfshrinking); | 402 | SELFBALLOON_SHOW(frontswap_selfshrinking, "%d\n", frontswap_selfshrinking); |
345 | 403 | ||
@@ -421,6 +479,7 @@ static struct attribute *selfballoon_attrs[] = { | |||
421 | &attr_selfballoon_interval.attr, | 479 | &attr_selfballoon_interval.attr, |
422 | &attr_selfballoon_downhysteresis.attr, | 480 | &attr_selfballoon_downhysteresis.attr, |
423 | &attr_selfballoon_uphysteresis.attr, | 481 | &attr_selfballoon_uphysteresis.attr, |
482 | &attr_selfballoon_min_usable_mb.attr, | ||
424 | #ifdef CONFIG_FRONTSWAP | 483 | #ifdef CONFIG_FRONTSWAP |
425 | &attr_frontswap_selfshrinking.attr, | 484 | &attr_frontswap_selfshrinking.attr, |
426 | &attr_frontswap_hysteresis.attr, | 485 | &attr_frontswap_hysteresis.attr, |
diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c index 60adf919d78d..32417b5064fd 100644 --- a/drivers/xen/xenbus/xenbus_probe_backend.c +++ b/drivers/xen/xenbus/xenbus_probe_backend.c | |||
@@ -104,8 +104,6 @@ static int xenbus_uevent_backend(struct device *dev, | |||
104 | 104 | ||
105 | xdev = to_xenbus_device(dev); | 105 | xdev = to_xenbus_device(dev); |
106 | bus = container_of(xdev->dev.bus, struct xen_bus_type, bus); | 106 | bus = container_of(xdev->dev.bus, struct xen_bus_type, bus); |
107 | if (xdev == NULL) | ||
108 | return -ENODEV; | ||
109 | 107 | ||
110 | if (add_uevent_var(env, "MODALIAS=xen-backend:%s", xdev->devicetype)) | 108 | if (add_uevent_var(env, "MODALIAS=xen-backend:%s", xdev->devicetype)) |
111 | return -ENOMEM; | 109 | return -ENOMEM; |
diff --git a/include/xen/balloon.h b/include/xen/balloon.h index 76f7538bb339..d29c153705bc 100644 --- a/include/xen/balloon.h +++ b/include/xen/balloon.h | |||
@@ -25,8 +25,9 @@ extern struct balloon_stats balloon_stats; | |||
25 | 25 | ||
26 | void balloon_set_new_target(unsigned long target); | 26 | void balloon_set_new_target(unsigned long target); |
27 | 27 | ||
28 | int alloc_xenballooned_pages(int nr_pages, struct page** pages); | 28 | int alloc_xenballooned_pages(int nr_pages, struct page **pages, |
29 | void free_xenballooned_pages(int nr_pages, struct page** pages); | 29 | bool highmem); |
30 | void free_xenballooned_pages(int nr_pages, struct page **pages); | ||
30 | 31 | ||
31 | struct sys_device; | 32 | struct sys_device; |
32 | #ifdef CONFIG_XEN_SELFBALLOONING | 33 | #ifdef CONFIG_XEN_SELFBALLOONING |
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index b1fab6b5b3ef..6b99bfbd785d 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h | |||
@@ -156,6 +156,7 @@ unsigned int gnttab_max_grant_frames(void); | |||
156 | #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) | 156 | #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) |
157 | 157 | ||
158 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | 158 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, |
159 | struct gnttab_map_grant_ref *kmap_ops, | ||
159 | struct page **pages, unsigned int count); | 160 | struct page **pages, unsigned int count); |
160 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | 161 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, |
161 | struct page **pages, unsigned int count); | 162 | struct page **pages, unsigned int count); |