Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'stable/xen-swiotlb-0.8.6' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen

* 'stable/xen-swiotlb-0.8.6' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
x86: Detect whether we should use Xen SWIOTLB.
pci-swiotlb-xen: Add glue code to setup dma_ops utilizing xen_swiotlb_* functions.
swiotlb-xen: SWIOTLB library for Xen PV guest with PCI passthrough.
xen/mmu: inhibit vmap aliases rather than trying to clear them out
vmap: add flag to allow lazy unmap to be disabled at runtime
xen: Add xen_create_contiguous_region
xen: Rename the balloon lock
xen: Allow unprivileged Xen domains to create iomap pages
xen: use _PAGE_IOMAP in ioremap to do machine mappings

Fix up trivial conflicts (adding both xen swiotlb and xen pci platform
driver setup close to each other) in drivers/xen/{Kconfig,Makefile} and
include/xen/xen-ops.h

+1024 -24
+2 -6
arch/x86/include/asm/xen/page.h
··· 112 112 */ 113 113 static inline unsigned long mfn_to_local_pfn(unsigned long mfn) 114 114 { 115 - extern unsigned long max_mapnr; 116 115 unsigned long pfn = mfn_to_pfn(mfn); 117 - if ((pfn < max_mapnr) 118 - && !xen_feature(XENFEAT_auto_translated_physmap) 119 - && (get_phys_to_machine(pfn) != mfn)) 120 - return max_mapnr; /* force !pfn_valid() */ 121 - /* XXX fixme; not true with sparsemem */ 116 + if (get_phys_to_machine(pfn) != mfn) 117 + return -1; /* force !pfn_valid() */ 122 118 return pfn; 123 119 } 124 120
+14
arch/x86/include/asm/xen/swiotlb-xen.h
··· 1 + #ifndef _ASM_X86_SWIOTLB_XEN_H 2 + #define _ASM_X86_SWIOTLB_XEN_H 3 + 4 + #ifdef CONFIG_SWIOTLB_XEN 5 + extern int xen_swiotlb; 6 + extern int __init pci_xen_swiotlb_detect(void); 7 + extern void __init pci_xen_swiotlb_init(void); 8 + #else 9 + #define xen_swiotlb (0) 10 + static inline int __init pci_xen_swiotlb_detect(void) { return 0; } 11 + static inline void __init pci_xen_swiotlb_init(void) { } 12 + #endif 13 + 14 + #endif /* _ASM_X86_SWIOTLB_XEN_H */
+5 -2
arch/x86/kernel/pci-dma.c
··· 13 13 #include <asm/calgary.h> 14 14 #include <asm/amd_iommu.h> 15 15 #include <asm/x86_init.h> 16 + #include <asm/xen/swiotlb-xen.h> 16 17 17 18 static int forbid_dac __read_mostly; 18 19 ··· 133 132 /* free the range so iommu could get some range less than 4G */ 134 133 dma32_free_bootmem(); 135 134 136 - if (pci_swiotlb_detect()) 135 + if (pci_xen_swiotlb_detect() || pci_swiotlb_detect()) 137 136 goto out; 138 137 139 138 gart_iommu_hole_init(); ··· 145 144 /* needs to be called after gart_iommu_hole_init */ 146 145 amd_iommu_detect(); 147 146 out: 147 + pci_xen_swiotlb_init(); 148 + 148 149 pci_swiotlb_init(); 149 150 } 150 151 ··· 299 296 #endif 300 297 x86_init.iommu.iommu_init(); 301 298 302 - if (swiotlb) { 299 + if (swiotlb || xen_swiotlb) { 303 300 printk(KERN_INFO "PCI-DMA: " 304 301 "Using software bounce buffering for IO (SWIOTLB)\n"); 305 302 swiotlb_print_info();
+1
arch/x86/xen/Makefile
··· 18 18 obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o 19 19 obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o 20 20 21 + obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o
+4
arch/x86/xen/enlighten.c
··· 1172 1172 1173 1173 pgd = (pgd_t *)xen_start_info->pt_base; 1174 1174 1175 + if (!xen_initial_domain()) 1176 + __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD); 1177 + 1178 + __supported_pte_mask |= _PAGE_IOMAP; 1175 1179 /* Don't do the full vcpu_info placement stuff until we have a 1176 1180 possible map and a non-dummy shared_info. */ 1177 1181 per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
+288 -5
arch/x86/xen/mmu.c
··· 42 42 #include <linux/highmem.h> 43 43 #include <linux/debugfs.h> 44 44 #include <linux/bug.h> 45 + #include <linux/vmalloc.h> 45 46 #include <linux/module.h> 46 47 #include <linux/gfp.h> 47 48 ··· 52 51 #include <asm/mmu_context.h> 53 52 #include <asm/setup.h> 54 53 #include <asm/paravirt.h> 54 + #include <asm/e820.h> 55 55 #include <asm/linkage.h> 56 + #include <asm/page.h> 56 57 57 58 #include <asm/xen/hypercall.h> 58 59 #include <asm/xen/hypervisor.h> 59 60 61 + #include <xen/xen.h> 60 62 #include <xen/page.h> 61 63 #include <xen/interface/xen.h> 62 64 #include <xen/interface/hvm/hvm_op.h> 63 65 #include <xen/interface/version.h> 66 + #include <xen/interface/memory.h> 64 67 #include <xen/hvc-console.h> 65 68 66 69 #include "multicalls.h" ··· 72 67 #include "debugfs.h" 73 68 74 69 #define MMU_UPDATE_HISTO 30 70 + 71 + /* 72 + * Protects atomic reservation decrease/increase against concurrent increases. 73 + * Also protects non-atomic updates of current_pages and driver_pages, and 74 + * balloon lists. 75 + */ 76 + DEFINE_SPINLOCK(xen_reservation_lock); 75 77 76 78 #ifdef CONFIG_XEN_DEBUG_FS 77 79 ··· 390 378 return PagePinned(page); 391 379 } 392 380 381 + static bool xen_iomap_pte(pte_t pte) 382 + { 383 + return pte_flags(pte) & _PAGE_IOMAP; 384 + } 385 + 386 + static void xen_set_iomap_pte(pte_t *ptep, pte_t pteval) 387 + { 388 + struct multicall_space mcs; 389 + struct mmu_update *u; 390 + 391 + mcs = xen_mc_entry(sizeof(*u)); 392 + u = mcs.args; 393 + 394 + /* ptep might be kmapped when using 32-bit HIGHPTE */ 395 + u->ptr = arbitrary_virt_to_machine(ptep).maddr; 396 + u->val = pte_val_ma(pteval); 397 + 398 + MULTI_mmu_update(mcs.mc, mcs.args, 1, NULL, DOMID_IO); 399 + 400 + xen_mc_issue(PARAVIRT_LAZY_MMU); 401 + } 402 + 393 403 static void xen_extend_mmu_update(const struct mmu_update *update) 394 404 { 395 405 struct multicall_space mcs; ··· 488 454 void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, 489 455 pte_t *ptep, pte_t pteval) 490 456 { 457 + if (xen_iomap_pte(pteval)) { 458 + xen_set_iomap_pte(ptep, pteval); 459 + goto out; 460 + } 461 + 491 462 ADD_STATS(set_pte_at, 1); 492 463 // ADD_STATS(set_pte_at_pinned, xen_page_pinned(ptep)); 493 464 ADD_STATS(set_pte_at_current, mm == current->mm); ··· 563 524 return val; 564 525 } 565 526 527 + static pteval_t iomap_pte(pteval_t val) 528 + { 529 + if (val & _PAGE_PRESENT) { 530 + unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; 531 + pteval_t flags = val & PTE_FLAGS_MASK; 532 + 533 + /* We assume the pte frame number is a MFN, so 534 + just use it as-is. */ 535 + val = ((pteval_t)pfn << PAGE_SHIFT) | flags; 536 + } 537 + 538 + return val; 539 + } 540 + 566 541 pteval_t xen_pte_val(pte_t pte) 567 542 { 543 + if (xen_initial_domain() && (pte.pte & _PAGE_IOMAP)) 544 + return pte.pte; 545 + 568 546 return pte_mfn_to_pfn(pte.pte); 569 547 } 570 548 PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val); ··· 594 538 595 539 pte_t xen_make_pte(pteval_t pte) 596 540 { 597 - pte = pte_pfn_to_mfn(pte); 541 + phys_addr_t addr = (pte & PTE_PFN_MASK); 542 + 543 + /* 544 + * Unprivileged domains are allowed to do IOMAPpings for 545 + * PCI passthrough, but not map ISA space. The ISA 546 + * mappings are just dummy local mappings to keep other 547 + * parts of the kernel happy. 548 + */ 549 + if (unlikely(pte & _PAGE_IOMAP) && 550 + (xen_initial_domain() || addr >= ISA_END_ADDRESS)) { 551 + pte = iomap_pte(pte); 552 + } else { 553 + pte &= ~_PAGE_IOMAP; 554 + pte = pte_pfn_to_mfn(pte); 555 + } 556 + 598 557 return native_make_pte(pte); 599 558 } 600 559 PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte); ··· 665 594 666 595 void xen_set_pte(pte_t *ptep, pte_t pte) 667 596 { 597 + if (xen_iomap_pte(pte)) { 598 + xen_set_iomap_pte(ptep, pte); 599 + return; 600 + } 601 + 668 602 ADD_STATS(pte_update, 1); 669 603 // ADD_STATS(pte_update_pinned, xen_page_pinned(ptep)); 670 604 ADD_STATS(pte_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU); ··· 686 610 #ifdef CONFIG_X86_PAE 687 611 void xen_set_pte_atomic(pte_t *ptep, pte_t pte) 688 612 { 613 + if (xen_iomap_pte(pte)) { 614 + xen_set_iomap_pte(ptep, pte); 615 + return; 616 + } 617 + 689 618 set_64bit((u64 *)ptep, native_pte_val(pte)); 690 619 } 691 620 ··· 1017 936 read-only, and can be pinned. */ 1018 937 static void __xen_pgd_pin(struct mm_struct *mm, pgd_t *pgd) 1019 938 { 1020 - vm_unmap_aliases(); 1021 - 1022 939 xen_mc_batch(); 1023 940 1024 941 if (__xen_pgd_walk(mm, pgd, xen_pin_page, USER_LIMIT)) { ··· 1580 1501 if (PagePinned(virt_to_page(mm->pgd))) { 1581 1502 SetPagePinned(page); 1582 1503 1583 - vm_unmap_aliases(); 1584 1504 if (!PageHighMem(page)) { 1585 1505 make_lowmem_page_readonly(__va(PFN_PHYS((unsigned long)pfn))); 1586 1506 if (level == PT_PTE && USE_SPLIT_PTLOCKS) ··· 1890 1812 pte = pfn_pte(phys, prot); 1891 1813 break; 1892 1814 1893 - default: 1815 + case FIX_PARAVIRT_BOOTMAP: 1816 + /* This is an MFN, but it isn't an IO mapping from the 1817 + IO domain */ 1894 1818 pte = mfn_pte(phys, prot); 1819 + break; 1820 + 1821 + default: 1822 + /* By default, set_fixmap is used for hardware mappings */ 1823 + pte = mfn_pte(phys, __pgprot(pgprot_val(prot) | _PAGE_IOMAP)); 1895 1824 break; 1896 1825 } 1897 1826 ··· 2025 1940 x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start; 2026 1941 x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done; 2027 1942 pv_mmu_ops = xen_mmu_ops; 1943 + 1944 + vmap_lazy_unmap = false; 2028 1945 } 1946 + 1947 + /* Protected by xen_reservation_lock. */ 1948 + #define MAX_CONTIG_ORDER 9 /* 2MB */ 1949 + static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER]; 1950 + 1951 + #define VOID_PTE (mfn_pte(0, __pgprot(0))) 1952 + static void xen_zap_pfn_range(unsigned long vaddr, unsigned int order, 1953 + unsigned long *in_frames, 1954 + unsigned long *out_frames) 1955 + { 1956 + int i; 1957 + struct multicall_space mcs; 1958 + 1959 + xen_mc_batch(); 1960 + for (i = 0; i < (1UL<<order); i++, vaddr += PAGE_SIZE) { 1961 + mcs = __xen_mc_entry(0); 1962 + 1963 + if (in_frames) 1964 + in_frames[i] = virt_to_mfn(vaddr); 1965 + 1966 + MULTI_update_va_mapping(mcs.mc, vaddr, VOID_PTE, 0); 1967 + set_phys_to_machine(virt_to_pfn(vaddr), INVALID_P2M_ENTRY); 1968 + 1969 + if (out_frames) 1970 + out_frames[i] = virt_to_pfn(vaddr); 1971 + } 1972 + xen_mc_issue(0); 1973 + } 1974 + 1975 + /* 1976 + * Update the pfn-to-mfn mappings for a virtual address range, either to 1977 + * point to an array of mfns, or contiguously from a single starting 1978 + * mfn. 1979 + */ 1980 + static void xen_remap_exchanged_ptes(unsigned long vaddr, int order, 1981 + unsigned long *mfns, 1982 + unsigned long first_mfn) 1983 + { 1984 + unsigned i, limit; 1985 + unsigned long mfn; 1986 + 1987 + xen_mc_batch(); 1988 + 1989 + limit = 1u << order; 1990 + for (i = 0; i < limit; i++, vaddr += PAGE_SIZE) { 1991 + struct multicall_space mcs; 1992 + unsigned flags; 1993 + 1994 + mcs = __xen_mc_entry(0); 1995 + if (mfns) 1996 + mfn = mfns[i]; 1997 + else 1998 + mfn = first_mfn + i; 1999 + 2000 + if (i < (limit - 1)) 2001 + flags = 0; 2002 + else { 2003 + if (order == 0) 2004 + flags = UVMF_INVLPG | UVMF_ALL; 2005 + else 2006 + flags = UVMF_TLB_FLUSH | UVMF_ALL; 2007 + } 2008 + 2009 + MULTI_update_va_mapping(mcs.mc, vaddr, 2010 + mfn_pte(mfn, PAGE_KERNEL), flags); 2011 + 2012 + set_phys_to_machine(virt_to_pfn(vaddr), mfn); 2013 + } 2014 + 2015 + xen_mc_issue(0); 2016 + } 2017 + 2018 + /* 2019 + * Perform the hypercall to exchange a region of our pfns to point to 2020 + * memory with the required contiguous alignment. Takes the pfns as 2021 + * input, and populates mfns as output. 2022 + * 2023 + * Returns a success code indicating whether the hypervisor was able to 2024 + * satisfy the request or not. 2025 + */ 2026 + static int xen_exchange_memory(unsigned long extents_in, unsigned int order_in, 2027 + unsigned long *pfns_in, 2028 + unsigned long extents_out, 2029 + unsigned int order_out, 2030 + unsigned long *mfns_out, 2031 + unsigned int address_bits) 2032 + { 2033 + long rc; 2034 + int success; 2035 + 2036 + struct xen_memory_exchange exchange = { 2037 + .in = { 2038 + .nr_extents = extents_in, 2039 + .extent_order = order_in, 2040 + .extent_start = pfns_in, 2041 + .domid = DOMID_SELF 2042 + }, 2043 + .out = { 2044 + .nr_extents = extents_out, 2045 + .extent_order = order_out, 2046 + .extent_start = mfns_out, 2047 + .address_bits = address_bits, 2048 + .domid = DOMID_SELF 2049 + } 2050 + }; 2051 + 2052 + BUG_ON(extents_in << order_in != extents_out << order_out); 2053 + 2054 + rc = HYPERVISOR_memory_op(XENMEM_exchange, &exchange); 2055 + success = (exchange.nr_exchanged == extents_in); 2056 + 2057 + BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0))); 2058 + BUG_ON(success && (rc != 0)); 2059 + 2060 + return success; 2061 + } 2062 + 2063 + int xen_create_contiguous_region(unsigned long vstart, unsigned int order, 2064 + unsigned int address_bits) 2065 + { 2066 + unsigned long *in_frames = discontig_frames, out_frame; 2067 + unsigned long flags; 2068 + int success; 2069 + 2070 + /* 2071 + * Currently an auto-translated guest will not perform I/O, nor will 2072 + * it require PAE page directories below 4GB. Therefore any calls to 2073 + * this function are redundant and can be ignored. 2074 + */ 2075 + 2076 + if (xen_feature(XENFEAT_auto_translated_physmap)) 2077 + return 0; 2078 + 2079 + if (unlikely(order > MAX_CONTIG_ORDER)) 2080 + return -ENOMEM; 2081 + 2082 + memset((void *) vstart, 0, PAGE_SIZE << order); 2083 + 2084 + spin_lock_irqsave(&xen_reservation_lock, flags); 2085 + 2086 + /* 1. Zap current PTEs, remembering MFNs. */ 2087 + xen_zap_pfn_range(vstart, order, in_frames, NULL); 2088 + 2089 + /* 2. Get a new contiguous memory extent. */ 2090 + out_frame = virt_to_pfn(vstart); 2091 + success = xen_exchange_memory(1UL << order, 0, in_frames, 2092 + 1, order, &out_frame, 2093 + address_bits); 2094 + 2095 + /* 3. Map the new extent in place of old pages. */ 2096 + if (success) 2097 + xen_remap_exchanged_ptes(vstart, order, NULL, out_frame); 2098 + else 2099 + xen_remap_exchanged_ptes(vstart, order, in_frames, 0); 2100 + 2101 + spin_unlock_irqrestore(&xen_reservation_lock, flags); 2102 + 2103 + return success ? 0 : -ENOMEM; 2104 + } 2105 + EXPORT_SYMBOL_GPL(xen_create_contiguous_region); 2106 + 2107 + void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order) 2108 + { 2109 + unsigned long *out_frames = discontig_frames, in_frame; 2110 + unsigned long flags; 2111 + int success; 2112 + 2113 + if (xen_feature(XENFEAT_auto_translated_physmap)) 2114 + return; 2115 + 2116 + if (unlikely(order > MAX_CONTIG_ORDER)) 2117 + return; 2118 + 2119 + memset((void *) vstart, 0, PAGE_SIZE << order); 2120 + 2121 + spin_lock_irqsave(&xen_reservation_lock, flags); 2122 + 2123 + /* 1. Find start MFN of contiguous extent. */ 2124 + in_frame = virt_to_mfn(vstart); 2125 + 2126 + /* 2. Zap current PTEs. */ 2127 + xen_zap_pfn_range(vstart, order, NULL, out_frames); 2128 + 2129 + /* 3. Do the exchange for non-contiguous MFNs. */ 2130 + success = xen_exchange_memory(1, order, &in_frame, 1UL << order, 2131 + 0, out_frames, 0); 2132 + 2133 + /* 4. Map new pages in place of old pages. */ 2134 + if (success) 2135 + xen_remap_exchanged_ptes(vstart, order, out_frames, 0); 2136 + else 2137 + xen_remap_exchanged_ptes(vstart, order, NULL, in_frame); 2138 + 2139 + spin_unlock_irqrestore(&xen_reservation_lock, flags); 2140 + } 2141 + EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region); 2029 2142 2030 2143 #ifdef CONFIG_XEN_PVHVM 2031 2144 static void xen_hvm_exit_mmap(struct mm_struct *mm)
+58
arch/x86/xen/pci-swiotlb-xen.c
··· 1 + /* Glue code to lib/swiotlb-xen.c */ 2 + 3 + #include <linux/dma-mapping.h> 4 + #include <xen/swiotlb-xen.h> 5 + 6 + #include <asm/xen/hypervisor.h> 7 + #include <xen/xen.h> 8 + 9 + int xen_swiotlb __read_mostly; 10 + 11 + static struct dma_map_ops xen_swiotlb_dma_ops = { 12 + .mapping_error = xen_swiotlb_dma_mapping_error, 13 + .alloc_coherent = xen_swiotlb_alloc_coherent, 14 + .free_coherent = xen_swiotlb_free_coherent, 15 + .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, 16 + .sync_single_for_device = xen_swiotlb_sync_single_for_device, 17 + .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu, 18 + .sync_sg_for_device = xen_swiotlb_sync_sg_for_device, 19 + .map_sg = xen_swiotlb_map_sg_attrs, 20 + .unmap_sg = xen_swiotlb_unmap_sg_attrs, 21 + .map_page = xen_swiotlb_map_page, 22 + .unmap_page = xen_swiotlb_unmap_page, 23 + .dma_supported = xen_swiotlb_dma_supported, 24 + }; 25 + 26 + /* 27 + * pci_xen_swiotlb_detect - set xen_swiotlb to 1 if necessary 28 + * 29 + * This returns non-zero if we are forced to use xen_swiotlb (by the boot 30 + * option). 31 + */ 32 + int __init pci_xen_swiotlb_detect(void) 33 + { 34 + 35 + /* If running as PV guest, either iommu=soft, or swiotlb=force will 36 + * activate this IOMMU. If running as PV privileged, activate it 37 + * irregardlesss. 38 + */ 39 + if ((xen_initial_domain() || swiotlb || swiotlb_force) && 40 + (xen_pv_domain())) 41 + xen_swiotlb = 1; 42 + 43 + /* If we are running under Xen, we MUST disable the native SWIOTLB. 44 + * Don't worry about swiotlb_force flag activating the native, as 45 + * the 'swiotlb' flag is the only one turning it on. */ 46 + if (xen_pv_domain()) 47 + swiotlb = 0; 48 + 49 + return xen_swiotlb; 50 + } 51 + 52 + void __init pci_xen_swiotlb_init(void) 53 + { 54 + if (xen_swiotlb) { 55 + xen_swiotlb_init(1); 56 + dma_ops = &xen_swiotlb_dma_ops; 57 + } 58 + }
+5
drivers/xen/Kconfig
··· 71 71 initializing xenbus and grant_table when running in a Xen HVM 72 72 domain. As a consequence this driver is required to run any Xen PV 73 73 frontend on Xen HVM. 74 + 75 + config SWIOTLB_XEN 76 + def_bool y 77 + depends on SWIOTLB 78 + 74 79 endmenu
+1
drivers/xen/Makefile
··· 11 11 obj-$(CONFIG_XENFS) += xenfs/ 12 12 obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o 13 13 obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o 14 + obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o
+4 -11
drivers/xen/balloon.c
··· 85 85 86 86 static int register_balloon(struct sys_device *sysdev); 87 87 88 - /* 89 - * Protects atomic reservation decrease/increase against concurrent increases. 90 - * Also protects non-atomic updates of current_pages and driver_pages, and 91 - * balloon lists. 92 - */ 93 - static DEFINE_SPINLOCK(balloon_lock); 94 - 95 88 static struct balloon_stats balloon_stats; 96 89 97 90 /* We increase/decrease in batches which fit in a page */ ··· 203 210 if (nr_pages > ARRAY_SIZE(frame_list)) 204 211 nr_pages = ARRAY_SIZE(frame_list); 205 212 206 - spin_lock_irqsave(&balloon_lock, flags); 213 + spin_lock_irqsave(&xen_reservation_lock, flags); 207 214 208 215 page = balloon_first_page(); 209 216 for (i = 0; i < nr_pages; i++) { ··· 247 254 balloon_stats.current_pages += rc; 248 255 249 256 out: 250 - spin_unlock_irqrestore(&balloon_lock, flags); 257 + spin_unlock_irqrestore(&xen_reservation_lock, flags); 251 258 252 259 return rc < 0 ? rc : rc != nr_pages; 253 260 } ··· 292 299 kmap_flush_unused(); 293 300 flush_tlb_all(); 294 301 295 - spin_lock_irqsave(&balloon_lock, flags); 302 + spin_lock_irqsave(&xen_reservation_lock, flags); 296 303 297 304 /* No more mappings: invalidate P2M and add to balloon. */ 298 305 for (i = 0; i < nr_pages; i++) { ··· 308 315 309 316 balloon_stats.current_pages -= nr_pages; 310 317 311 - spin_unlock_irqrestore(&balloon_lock, flags); 318 + spin_unlock_irqrestore(&xen_reservation_lock, flags); 312 319 313 320 return need_sleep; 314 321 }
+515
drivers/xen/swiotlb-xen.c
··· 1 + /* 2 + * Copyright 2010 3 + * by Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> 4 + * 5 + * This code provides a IOMMU for Xen PV guests with PCI passthrough. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License v2.0 as published by 9 + * the Free Software Foundation 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * PV guests under Xen are running in an non-contiguous memory architecture. 17 + * 18 + * When PCI pass-through is utilized, this necessitates an IOMMU for 19 + * translating bus (DMA) to virtual and vice-versa and also providing a 20 + * mechanism to have contiguous pages for device drivers operations (say DMA 21 + * operations). 22 + * 23 + * Specifically, under Xen the Linux idea of pages is an illusion. It 24 + * assumes that pages start at zero and go up to the available memory. To 25 + * help with that, the Linux Xen MMU provides a lookup mechanism to 26 + * translate the page frame numbers (PFN) to machine frame numbers (MFN) 27 + * and vice-versa. The MFN are the "real" frame numbers. Furthermore 28 + * memory is not contiguous. Xen hypervisor stitches memory for guests 29 + * from different pools, which means there is no guarantee that PFN==MFN 30 + * and PFN+1==MFN+1. Lastly with Xen 4.0, pages (in debug mode) are 31 + * allocated in descending order (high to low), meaning the guest might 32 + * never get any MFN's under the 4GB mark. 33 + * 34 + */ 35 + 36 + #include <linux/bootmem.h> 37 + #include <linux/dma-mapping.h> 38 + #include <xen/swiotlb-xen.h> 39 + #include <xen/page.h> 40 + #include <xen/xen-ops.h> 41 + /* 42 + * Used to do a quick range check in swiotlb_tbl_unmap_single and 43 + * swiotlb_tbl_sync_single_*, to see if the memory was in fact allocated by this 44 + * API. 45 + */ 46 + 47 + static char *xen_io_tlb_start, *xen_io_tlb_end; 48 + static unsigned long xen_io_tlb_nslabs; 49 + /* 50 + * Quick lookup value of the bus address of the IOTLB. 51 + */ 52 + 53 + u64 start_dma_addr; 54 + 55 + static dma_addr_t xen_phys_to_bus(phys_addr_t paddr) 56 + { 57 + return phys_to_machine(XPADDR(paddr)).maddr;; 58 + } 59 + 60 + static phys_addr_t xen_bus_to_phys(dma_addr_t baddr) 61 + { 62 + return machine_to_phys(XMADDR(baddr)).paddr; 63 + } 64 + 65 + static dma_addr_t xen_virt_to_bus(void *address) 66 + { 67 + return xen_phys_to_bus(virt_to_phys(address)); 68 + } 69 + 70 + static int check_pages_physically_contiguous(unsigned long pfn, 71 + unsigned int offset, 72 + size_t length) 73 + { 74 + unsigned long next_mfn; 75 + int i; 76 + int nr_pages; 77 + 78 + next_mfn = pfn_to_mfn(pfn); 79 + nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT; 80 + 81 + for (i = 1; i < nr_pages; i++) { 82 + if (pfn_to_mfn(++pfn) != ++next_mfn) 83 + return 0; 84 + } 85 + return 1; 86 + } 87 + 88 + static int range_straddles_page_boundary(phys_addr_t p, size_t size) 89 + { 90 + unsigned long pfn = PFN_DOWN(p); 91 + unsigned int offset = p & ~PAGE_MASK; 92 + 93 + if (offset + size <= PAGE_SIZE) 94 + return 0; 95 + if (check_pages_physically_contiguous(pfn, offset, size)) 96 + return 0; 97 + return 1; 98 + } 99 + 100 + static int is_xen_swiotlb_buffer(dma_addr_t dma_addr) 101 + { 102 + unsigned long mfn = PFN_DOWN(dma_addr); 103 + unsigned long pfn = mfn_to_local_pfn(mfn); 104 + phys_addr_t paddr; 105 + 106 + /* If the address is outside our domain, it CAN 107 + * have the same virtual address as another address 108 + * in our domain. Therefore _only_ check address within our domain. 109 + */ 110 + if (pfn_valid(pfn)) { 111 + paddr = PFN_PHYS(pfn); 112 + return paddr >= virt_to_phys(xen_io_tlb_start) && 113 + paddr < virt_to_phys(xen_io_tlb_end); 114 + } 115 + return 0; 116 + } 117 + 118 + static int max_dma_bits = 32; 119 + 120 + static int 121 + xen_swiotlb_fixup(void *buf, size_t size, unsigned long nslabs) 122 + { 123 + int i, rc; 124 + int dma_bits; 125 + 126 + dma_bits = get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT) + PAGE_SHIFT; 127 + 128 + i = 0; 129 + do { 130 + int slabs = min(nslabs - i, (unsigned long)IO_TLB_SEGSIZE); 131 + 132 + do { 133 + rc = xen_create_contiguous_region( 134 + (unsigned long)buf + (i << IO_TLB_SHIFT), 135 + get_order(slabs << IO_TLB_SHIFT), 136 + dma_bits); 137 + } while (rc && dma_bits++ < max_dma_bits); 138 + if (rc) 139 + return rc; 140 + 141 + i += slabs; 142 + } while (i < nslabs); 143 + return 0; 144 + } 145 + 146 + void __init xen_swiotlb_init(int verbose) 147 + { 148 + unsigned long bytes; 149 + int rc; 150 + 151 + xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT); 152 + xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE); 153 + 154 + bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT; 155 + 156 + /* 157 + * Get IO TLB memory from any location. 158 + */ 159 + xen_io_tlb_start = alloc_bootmem(bytes); 160 + if (!xen_io_tlb_start) 161 + panic("Cannot allocate SWIOTLB buffer"); 162 + 163 + xen_io_tlb_end = xen_io_tlb_start + bytes; 164 + /* 165 + * And replace that memory with pages under 4GB. 166 + */ 167 + rc = xen_swiotlb_fixup(xen_io_tlb_start, 168 + bytes, 169 + xen_io_tlb_nslabs); 170 + if (rc) 171 + goto error; 172 + 173 + start_dma_addr = xen_virt_to_bus(xen_io_tlb_start); 174 + swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose); 175 + 176 + return; 177 + error: 178 + panic("DMA(%d): Failed to exchange pages allocated for DMA with Xen! "\ 179 + "We either don't have the permission or you do not have enough"\ 180 + "free memory under 4GB!\n", rc); 181 + } 182 + 183 + void * 184 + xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, 185 + dma_addr_t *dma_handle, gfp_t flags) 186 + { 187 + void *ret; 188 + int order = get_order(size); 189 + u64 dma_mask = DMA_BIT_MASK(32); 190 + unsigned long vstart; 191 + 192 + /* 193 + * Ignore region specifiers - the kernel's ideas of 194 + * pseudo-phys memory layout has nothing to do with the 195 + * machine physical layout. We can't allocate highmem 196 + * because we can't return a pointer to it. 197 + */ 198 + flags &= ~(__GFP_DMA | __GFP_HIGHMEM); 199 + 200 + if (dma_alloc_from_coherent(hwdev, size, dma_handle, &ret)) 201 + return ret; 202 + 203 + vstart = __get_free_pages(flags, order); 204 + ret = (void *)vstart; 205 + 206 + if (hwdev && hwdev->coherent_dma_mask) 207 + dma_mask = dma_alloc_coherent_mask(hwdev, flags); 208 + 209 + if (ret) { 210 + if (xen_create_contiguous_region(vstart, order, 211 + fls64(dma_mask)) != 0) { 212 + free_pages(vstart, order); 213 + return NULL; 214 + } 215 + memset(ret, 0, size); 216 + *dma_handle = virt_to_machine(ret).maddr; 217 + } 218 + return ret; 219 + } 220 + EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent); 221 + 222 + void 223 + xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, 224 + dma_addr_t dev_addr) 225 + { 226 + int order = get_order(size); 227 + 228 + if (dma_release_from_coherent(hwdev, order, vaddr)) 229 + return; 230 + 231 + xen_destroy_contiguous_region((unsigned long)vaddr, order); 232 + free_pages((unsigned long)vaddr, order); 233 + } 234 + EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent); 235 + 236 + 237 + /* 238 + * Map a single buffer of the indicated size for DMA in streaming mode. The 239 + * physical address to use is returned. 240 + * 241 + * Once the device is given the dma address, the device owns this memory until 242 + * either xen_swiotlb_unmap_page or xen_swiotlb_dma_sync_single is performed. 243 + */ 244 + dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, 245 + unsigned long offset, size_t size, 246 + enum dma_data_direction dir, 247 + struct dma_attrs *attrs) 248 + { 249 + phys_addr_t phys = page_to_phys(page) + offset; 250 + dma_addr_t dev_addr = xen_phys_to_bus(phys); 251 + void *map; 252 + 253 + BUG_ON(dir == DMA_NONE); 254 + /* 255 + * If the address happens to be in the device's DMA window, 256 + * we can safely return the device addr and not worry about bounce 257 + * buffering it. 258 + */ 259 + if (dma_capable(dev, dev_addr, size) && 260 + !range_straddles_page_boundary(phys, size) && !swiotlb_force) 261 + return dev_addr; 262 + 263 + /* 264 + * Oh well, have to allocate and map a bounce buffer. 265 + */ 266 + map = swiotlb_tbl_map_single(dev, start_dma_addr, phys, size, dir); 267 + if (!map) 268 + return DMA_ERROR_CODE; 269 + 270 + dev_addr = xen_virt_to_bus(map); 271 + 272 + /* 273 + * Ensure that the address returned is DMA'ble 274 + */ 275 + if (!dma_capable(dev, dev_addr, size)) 276 + panic("map_single: bounce buffer is not DMA'ble"); 277 + 278 + return dev_addr; 279 + } 280 + EXPORT_SYMBOL_GPL(xen_swiotlb_map_page); 281 + 282 + /* 283 + * Unmap a single streaming mode DMA translation. The dma_addr and size must 284 + * match what was provided for in a previous xen_swiotlb_map_page call. All 285 + * other usages are undefined. 286 + * 287 + * After this call, reads by the cpu to the buffer are guaranteed to see 288 + * whatever the device wrote there. 289 + */ 290 + static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr, 291 + size_t size, enum dma_data_direction dir) 292 + { 293 + phys_addr_t paddr = xen_bus_to_phys(dev_addr); 294 + 295 + BUG_ON(dir == DMA_NONE); 296 + 297 + /* NOTE: We use dev_addr here, not paddr! */ 298 + if (is_xen_swiotlb_buffer(dev_addr)) { 299 + swiotlb_tbl_unmap_single(hwdev, phys_to_virt(paddr), size, dir); 300 + return; 301 + } 302 + 303 + if (dir != DMA_FROM_DEVICE) 304 + return; 305 + 306 + /* 307 + * phys_to_virt doesn't work with hihgmem page but we could 308 + * call dma_mark_clean() with hihgmem page here. However, we 309 + * are fine since dma_mark_clean() is null on POWERPC. We can 310 + * make dma_mark_clean() take a physical address if necessary. 311 + */ 312 + dma_mark_clean(phys_to_virt(paddr), size); 313 + } 314 + 315 + void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, 316 + size_t size, enum dma_data_direction dir, 317 + struct dma_attrs *attrs) 318 + { 319 + xen_unmap_single(hwdev, dev_addr, size, dir); 320 + } 321 + EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_page); 322 + 323 + /* 324 + * Make physical memory consistent for a single streaming mode DMA translation 325 + * after a transfer. 326 + * 327 + * If you perform a xen_swiotlb_map_page() but wish to interrogate the buffer 328 + * using the cpu, yet do not wish to teardown the dma mapping, you must 329 + * call this function before doing so. At the next point you give the dma 330 + * address back to the card, you must first perform a 331 + * xen_swiotlb_dma_sync_for_device, and then the device again owns the buffer 332 + */ 333 + static void 334 + xen_swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, 335 + size_t size, enum dma_data_direction dir, 336 + enum dma_sync_target target) 337 + { 338 + phys_addr_t paddr = xen_bus_to_phys(dev_addr); 339 + 340 + BUG_ON(dir == DMA_NONE); 341 + 342 + /* NOTE: We use dev_addr here, not paddr! */ 343 + if (is_xen_swiotlb_buffer(dev_addr)) { 344 + swiotlb_tbl_sync_single(hwdev, phys_to_virt(paddr), size, dir, 345 + target); 346 + return; 347 + } 348 + 349 + if (dir != DMA_FROM_DEVICE) 350 + return; 351 + 352 + dma_mark_clean(phys_to_virt(paddr), size); 353 + } 354 + 355 + void 356 + xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, 357 + size_t size, enum dma_data_direction dir) 358 + { 359 + xen_swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU); 360 + } 361 + EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_cpu); 362 + 363 + void 364 + xen_swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, 365 + size_t size, enum dma_data_direction dir) 366 + { 367 + xen_swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE); 368 + } 369 + EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device); 370 + 371 + /* 372 + * Map a set of buffers described by scatterlist in streaming mode for DMA. 373 + * This is the scatter-gather version of the above xen_swiotlb_map_page 374 + * interface. Here the scatter gather list elements are each tagged with the 375 + * appropriate dma address and length. They are obtained via 376 + * sg_dma_{address,length}(SG). 377 + * 378 + * NOTE: An implementation may be able to use a smaller number of 379 + * DMA address/length pairs than there are SG table elements. 380 + * (for example via virtual mapping capabilities) 381 + * The routine returns the number of addr/length pairs actually 382 + * used, at most nents. 383 + * 384 + * Device ownership issues as mentioned above for xen_swiotlb_map_page are the 385 + * same here. 386 + */ 387 + int 388 + xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, 389 + int nelems, enum dma_data_direction dir, 390 + struct dma_attrs *attrs) 391 + { 392 + struct scatterlist *sg; 393 + int i; 394 + 395 + BUG_ON(dir == DMA_NONE); 396 + 397 + for_each_sg(sgl, sg, nelems, i) { 398 + phys_addr_t paddr = sg_phys(sg); 399 + dma_addr_t dev_addr = xen_phys_to_bus(paddr); 400 + 401 + if (swiotlb_force || 402 + !dma_capable(hwdev, dev_addr, sg->length) || 403 + range_straddles_page_boundary(paddr, sg->length)) { 404 + void *map = swiotlb_tbl_map_single(hwdev, 405 + start_dma_addr, 406 + sg_phys(sg), 407 + sg->length, dir); 408 + if (!map) { 409 + /* Don't panic here, we expect map_sg users 410 + to do proper error handling. */ 411 + xen_swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir, 412 + attrs); 413 + sgl[0].dma_length = 0; 414 + return DMA_ERROR_CODE; 415 + } 416 + sg->dma_address = xen_virt_to_bus(map); 417 + } else 418 + sg->dma_address = dev_addr; 419 + sg->dma_length = sg->length; 420 + } 421 + return nelems; 422 + } 423 + EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs); 424 + 425 + int 426 + xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, 427 + enum dma_data_direction dir) 428 + { 429 + return xen_swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL); 430 + } 431 + EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg); 432 + 433 + /* 434 + * Unmap a set of streaming mode DMA translations. Again, cpu read rules 435 + * concerning calls here are the same as for swiotlb_unmap_page() above. 436 + */ 437 + void 438 + xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, 439 + int nelems, enum dma_data_direction dir, 440 + struct dma_attrs *attrs) 441 + { 442 + struct scatterlist *sg; 443 + int i; 444 + 445 + BUG_ON(dir == DMA_NONE); 446 + 447 + for_each_sg(sgl, sg, nelems, i) 448 + xen_unmap_single(hwdev, sg->dma_address, sg->dma_length, dir); 449 + 450 + } 451 + EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_sg_attrs); 452 + 453 + void 454 + xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, 455 + enum dma_data_direction dir) 456 + { 457 + return xen_swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL); 458 + } 459 + EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_sg); 460 + 461 + /* 462 + * Make physical memory consistent for a set of streaming mode DMA translations 463 + * after a transfer. 464 + * 465 + * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules 466 + * and usage. 467 + */ 468 + static void 469 + xen_swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl, 470 + int nelems, enum dma_data_direction dir, 471 + enum dma_sync_target target) 472 + { 473 + struct scatterlist *sg; 474 + int i; 475 + 476 + for_each_sg(sgl, sg, nelems, i) 477 + xen_swiotlb_sync_single(hwdev, sg->dma_address, 478 + sg->dma_length, dir, target); 479 + } 480 + 481 + void 482 + xen_swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, 483 + int nelems, enum dma_data_direction dir) 484 + { 485 + xen_swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU); 486 + } 487 + EXPORT_SYMBOL_GPL(xen_swiotlb_sync_sg_for_cpu); 488 + 489 + void 490 + xen_swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, 491 + int nelems, enum dma_data_direction dir) 492 + { 493 + xen_swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); 494 + } 495 + EXPORT_SYMBOL_GPL(xen_swiotlb_sync_sg_for_device); 496 + 497 + int 498 + xen_swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) 499 + { 500 + return !dma_addr; 501 + } 502 + EXPORT_SYMBOL_GPL(xen_swiotlb_dma_mapping_error); 503 + 504 + /* 505 + * Return whether the given device DMA address mask can be supported 506 + * properly. For example, if your device can only drive the low 24-bits 507 + * during bus mastering, then you would pass 0x00ffffff as the mask to 508 + * this function. 509 + */ 510 + int 511 + xen_swiotlb_dma_supported(struct device *hwdev, u64 mask) 512 + { 513 + return xen_virt_to_bus(xen_io_tlb_end - 1) <= mask; 514 + } 515 + EXPORT_SYMBOL_GPL(xen_swiotlb_dma_supported);
+2
include/linux/vmalloc.h
··· 7 7 8 8 struct vm_area_struct; /* vma defining user mapping in mm_types.h */ 9 9 10 + extern bool vmap_lazy_unmap; 11 + 10 12 /* bits in flags of vmalloc's vm_struct below */ 11 13 #define VM_IOREMAP 0x00000001 /* ioremap() and friends */ 12 14 #define VM_ALLOC 0x00000002 /* vmalloc() */
+50
include/xen/interface/memory.h
··· 9 9 #ifndef __XEN_PUBLIC_MEMORY_H__ 10 10 #define __XEN_PUBLIC_MEMORY_H__ 11 11 12 + #include <linux/spinlock.h> 13 + 12 14 /* 13 15 * Increase or decrease the specified domain's memory reservation. Returns a 14 16 * -ve errcode on failure, or the # extents successfully allocated or freed. ··· 54 52 }; 55 53 DEFINE_GUEST_HANDLE_STRUCT(xen_memory_reservation); 56 54 55 + /* 56 + * An atomic exchange of memory pages. If return code is zero then 57 + * @out.extent_list provides GMFNs of the newly-allocated memory. 58 + * Returns zero on complete success, otherwise a negative error code. 59 + * On complete success then always @nr_exchanged == @in.nr_extents. 60 + * On partial success @nr_exchanged indicates how much work was done. 61 + */ 62 + #define XENMEM_exchange 11 63 + struct xen_memory_exchange { 64 + /* 65 + * [IN] Details of memory extents to be exchanged (GMFN bases). 66 + * Note that @in.address_bits is ignored and unused. 67 + */ 68 + struct xen_memory_reservation in; 69 + 70 + /* 71 + * [IN/OUT] Details of new memory extents. 72 + * We require that: 73 + * 1. @in.domid == @out.domid 74 + * 2. @in.nr_extents << @in.extent_order == 75 + * @out.nr_extents << @out.extent_order 76 + * 3. @in.extent_start and @out.extent_start lists must not overlap 77 + * 4. @out.extent_start lists GPFN bases to be populated 78 + * 5. @out.extent_start is overwritten with allocated GMFN bases 79 + */ 80 + struct xen_memory_reservation out; 81 + 82 + /* 83 + * [OUT] Number of input extents that were successfully exchanged: 84 + * 1. The first @nr_exchanged input extents were successfully 85 + * deallocated. 86 + * 2. The corresponding first entries in the output extent list correctly 87 + * indicate the GMFNs that were successfully exchanged. 88 + * 3. All other input and output extents are untouched. 89 + * 4. If not all input exents are exchanged then the return code of this 90 + * command will be non-zero. 91 + * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER! 92 + */ 93 + unsigned long nr_exchanged; 94 + }; 95 + 96 + DEFINE_GUEST_HANDLE_STRUCT(xen_memory_exchange); 57 97 /* 58 98 * Returns the maximum machine frame number of mapped RAM in this system. 59 99 * This command always succeeds (it never returns an error code). ··· 186 142 }; 187 143 DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list); 188 144 145 + 146 + /* 147 + * Prevent the balloon driver from changing the memory reservation 148 + * during a driver critical region. 149 + */ 150 + extern spinlock_t xen_reservation_lock; 189 151 #endif /* __XEN_PUBLIC_MEMORY_H__ */
+65
include/xen/swiotlb-xen.h
··· 1 + #ifndef __LINUX_SWIOTLB_XEN_H 2 + #define __LINUX_SWIOTLB_XEN_H 3 + 4 + #include <linux/swiotlb.h> 5 + 6 + extern void xen_swiotlb_init(int verbose); 7 + 8 + extern void 9 + *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, 10 + dma_addr_t *dma_handle, gfp_t flags); 11 + 12 + extern void 13 + xen_swiotlb_free_coherent(struct device *hwdev, size_t size, 14 + void *vaddr, dma_addr_t dma_handle); 15 + 16 + extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, 17 + unsigned long offset, size_t size, 18 + enum dma_data_direction dir, 19 + struct dma_attrs *attrs); 20 + 21 + extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, 22 + size_t size, enum dma_data_direction dir, 23 + struct dma_attrs *attrs); 24 + /* 25 + extern int 26 + xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, 27 + enum dma_data_direction dir); 28 + 29 + extern void 30 + xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, 31 + enum dma_data_direction dir); 32 + */ 33 + extern int 34 + xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, 35 + int nelems, enum dma_data_direction dir, 36 + struct dma_attrs *attrs); 37 + 38 + extern void 39 + xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, 40 + int nelems, enum dma_data_direction dir, 41 + struct dma_attrs *attrs); 42 + 43 + extern void 44 + xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, 45 + size_t size, enum dma_data_direction dir); 46 + 47 + extern void 48 + xen_swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, 49 + int nelems, enum dma_data_direction dir); 50 + 51 + extern void 52 + xen_swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, 53 + size_t size, enum dma_data_direction dir); 54 + 55 + extern void 56 + xen_swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, 57 + int nelems, enum dma_data_direction dir); 58 + 59 + extern int 60 + xen_swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); 61 + 62 + extern int 63 + xen_swiotlb_dma_supported(struct device *hwdev, u64 mask); 64 + 65 + #endif /* __LINUX_SWIOTLB_XEN_H */
+6
include/xen/xen-ops.h
··· 17 17 18 18 int xen_setup_shutdown_event(void); 19 19 20 + extern unsigned long *xen_contiguous_bitmap; 21 + int xen_create_contiguous_region(unsigned long vstart, unsigned int order, 22 + unsigned int address_bits); 23 + 24 + void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order); 25 + 20 26 #endif /* INCLUDE_XEN_OPS_H */
+4
mm/vmalloc.c
··· 31 31 #include <asm/tlbflush.h> 32 32 #include <asm/shmparam.h> 33 33 34 + bool vmap_lazy_unmap __read_mostly = true; 34 35 35 36 /*** Page table manipulation functions ***/ 36 37 ··· 502 501 static unsigned long lazy_max_pages(void) 503 502 { 504 503 unsigned int log; 504 + 505 + if (!vmap_lazy_unmap) 506 + return 0; 505 507 506 508 log = fls(num_online_cpus()); 507 509