1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/errno.h> 3 #include <linux/gfp.h> 4 #include <linux/kernel.h> 5 #include <linux/mm.h> 6 #include <linux/memremap.h> 7 #include <linux/slab.h> 8 9 #include <asm/page.h> 10 11 #include <xen/page.h> 12 #include <xen/xen.h> 13 14 static DEFINE_MUTEX(list_lock); 15 static LIST_HEAD(page_list); 16 static unsigned int list_count; 17 18 static int fill_list(unsigned int nr_pages) 19 { 20 struct dev_pagemap *pgmap; 21 struct resource *res; 22 void *vaddr; 23 unsigned int i, alloc_pages = round_up(nr_pages, PAGES_PER_SECTION); 24 int ret = -ENOMEM; 25 26 res = kzalloc(sizeof(*res), GFP_KERNEL); 27 if (!res) 28 return -ENOMEM; 29 30 pgmap = kzalloc(sizeof(*pgmap), GFP_KERNEL); 31 if (!pgmap) 32 goto err_pgmap; 33 34 pgmap->type = MEMORY_DEVICE_GENERIC; 35 res->name = "Xen scratch"; 36 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; 37 38 ret = allocate_resource(&iomem_resource, res, 39 alloc_pages * PAGE_SIZE, 0, -1, 40 PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); 41 if (ret < 0) { 42 pr_err("Cannot allocate new IOMEM resource\n"); 43 goto err_resource; 44 } 45 46 pgmap->range = (struct range) { 47 .start = res->start, 48 .end = res->end, 49 }; 50 pgmap->nr_range = 1; 51 pgmap->owner = res; 52 53 #ifdef CONFIG_XEN_HAVE_PVMMU 54 /* 55 * memremap will build page tables for the new memory so 56 * the p2m must contain invalid entries so the correct 57 * non-present PTEs will be written. 58 * 59 * If a failure occurs, the original (identity) p2m entries 60 * are not restored since this region is now known not to 61 * conflict with any devices. 62 */ 63 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 64 xen_pfn_t pfn = PFN_DOWN(res->start); 65 66 for (i = 0; i < alloc_pages; i++) { 67 if (!set_phys_to_machine(pfn + i, INVALID_P2M_ENTRY)) { 68 pr_warn("set_phys_to_machine() failed, no memory added\n"); 69 ret = -ENOMEM; 70 goto err_memremap; 71 } 72 } 73 } 74 #endif 75 76 vaddr = memremap_pages(pgmap, NUMA_NO_NODE); 77 if (IS_ERR(vaddr)) { 78 pr_err("Cannot remap memory range\n"); 79 ret = PTR_ERR(vaddr); 80 goto err_memremap; 81 } 82 83 for (i = 0; i < alloc_pages; i++) { 84 struct page *pg = virt_to_page(vaddr + PAGE_SIZE * i); 85 86 BUG_ON(!virt_addr_valid(vaddr + PAGE_SIZE * i)); 87 list_add(&pg->lru, &page_list); 88 list_count++; 89 } 90 91 return 0; 92 93 err_memremap: 94 release_resource(res); 95 err_resource: 96 kfree(pgmap); 97 err_pgmap: 98 kfree(res); 99 return ret; 100 } 101 102 /** 103 * xen_alloc_unpopulated_pages - alloc unpopulated pages 104 * @nr_pages: Number of pages 105 * @pages: pages returned 106 * @return 0 on success, error otherwise 107 */ 108 int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages) 109 { 110 unsigned int i; 111 int ret = 0; 112 113 mutex_lock(&list_lock); 114 if (list_count < nr_pages) { 115 ret = fill_list(nr_pages - list_count); 116 if (ret) 117 goto out; 118 } 119 120 for (i = 0; i < nr_pages; i++) { 121 struct page *pg = list_first_entry_or_null(&page_list, 122 struct page, 123 lru); 124 125 BUG_ON(!pg); 126 list_del(&pg->lru); 127 list_count--; 128 pages[i] = pg; 129 130 #ifdef CONFIG_XEN_HAVE_PVMMU 131 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 132 ret = xen_alloc_p2m_entry(page_to_pfn(pg)); 133 if (ret < 0) { 134 unsigned int j; 135 136 for (j = 0; j <= i; j++) { 137 list_add(&pages[j]->lru, &page_list); 138 list_count++; 139 } 140 goto out; 141 } 142 } 143 #endif 144 } 145 146 out: 147 mutex_unlock(&list_lock); 148 return ret; 149 } 150 EXPORT_SYMBOL(xen_alloc_unpopulated_pages); 151 152 /** 153 * xen_free_unpopulated_pages - return unpopulated pages 154 * @nr_pages: Number of pages 155 * @pages: pages to return 156 */ 157 void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages) 158 { 159 unsigned int i; 160 161 mutex_lock(&list_lock); 162 for (i = 0; i < nr_pages; i++) { 163 list_add(&pages[i]->lru, &page_list); 164 list_count++; 165 } 166 mutex_unlock(&list_lock); 167 } 168 EXPORT_SYMBOL(xen_free_unpopulated_pages); 169 170 #ifdef CONFIG_XEN_PV 171 static int __init init(void) 172 { 173 unsigned int i; 174 175 if (!xen_domain()) 176 return -ENODEV; 177 178 if (!xen_pv_domain()) 179 return 0; 180 181 /* 182 * Initialize with pages from the extra memory regions (see 183 * arch/x86/xen/setup.c). 184 */ 185 for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { 186 unsigned int j; 187 188 for (j = 0; j < xen_extra_mem[i].n_pfns; j++) { 189 struct page *pg = 190 pfn_to_page(xen_extra_mem[i].start_pfn + j); 191 192 list_add(&pg->lru, &page_list); 193 list_count++; 194 } 195 } 196 197 return 0; 198 } 199 subsys_initcall(init); 200 #endif 201