Skip to content

Commit 68beef5

Browse files
committed
Merge tag 'for-linus-5.9-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross: "A small series for fixing a problem with Xen PVH guests when running as backends (e.g. as dom0). Mapping other guests' memory is now working via ZONE_DEVICE, thus not requiring to abuse the memory hotplug functionality for that purpose" * tag 'for-linus-5.9-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen: add helpers to allocate unpopulated memory memremap: rename MEMORY_DEVICE_DEVDAX to MEMORY_DEVICE_GENERIC xen/balloon: add header guard
2 parents dd9fb9b + 9e2369c commit 68beef5

File tree

14 files changed

+229
-22
lines changed

14 files changed

+229
-22
lines changed

drivers/dax/device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ int dev_dax_probe(struct device *dev)
429429
return -EBUSY;
430430
}
431431

432-
dev_dax->pgmap.type = MEMORY_DEVICE_DEVDAX;
432+
dev_dax->pgmap.type = MEMORY_DEVICE_GENERIC;
433433
addr = devm_memremap_pages(dev, &dev_dax->pgmap);
434434
if (IS_ERR(addr))
435435
return PTR_ERR(addr);

drivers/gpu/drm/xen/xen_drm_front_gem.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <drm/drm_probe_helper.h>
1919

2020
#include <xen/balloon.h>
21+
#include <xen/xen.h>
2122

2223
#include "xen_drm_front.h"
2324
#include "xen_drm_front_gem.h"
@@ -99,8 +100,8 @@ static struct xen_gem_object *gem_create(struct drm_device *dev, size_t size)
99100
* allocate ballooned pages which will be used to map
100101
* grant references provided by the backend
101102
*/
102-
ret = alloc_xenballooned_pages(xen_obj->num_pages,
103-
xen_obj->pages);
103+
ret = xen_alloc_unpopulated_pages(xen_obj->num_pages,
104+
xen_obj->pages);
104105
if (ret < 0) {
105106
DRM_ERROR("Cannot allocate %zu ballooned pages: %d\n",
106107
xen_obj->num_pages, ret);
@@ -152,8 +153,8 @@ void xen_drm_front_gem_free_object_unlocked(struct drm_gem_object *gem_obj)
152153
} else {
153154
if (xen_obj->pages) {
154155
if (xen_obj->be_alloc) {
155-
free_xenballooned_pages(xen_obj->num_pages,
156-
xen_obj->pages);
156+
xen_free_unpopulated_pages(xen_obj->num_pages,
157+
xen_obj->pages);
157158
gem_free_pages_array(xen_obj);
158159
} else {
159160
drm_gem_put_pages(&xen_obj->base,

drivers/xen/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,4 +325,14 @@ config XEN_HAVE_VPMU
325325
config XEN_FRONT_PGDIR_SHBUF
326326
tristate
327327

328+
config XEN_UNPOPULATED_ALLOC
329+
bool "Use unpopulated memory ranges for guest mappings"
330+
depends on X86 && ZONE_DEVICE
331+
default XEN_BACKEND || XEN_GNTDEV || XEN_DOM0
332+
help
333+
Use unpopulated memory ranges in order to create mappings for guest
334+
memory regions, including grant maps and foreign pages. This avoids
335+
having to balloon out RAM regions in order to obtain physical memory
336+
space to create such mappings.
337+
328338
endmenu

drivers/xen/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ xen-gntdev-$(CONFIG_XEN_GNTDEV_DMABUF) += gntdev-dmabuf.o
4141
xen-gntalloc-y := gntalloc.o
4242
xen-privcmd-y := privcmd.o privcmd-buf.o
4343
obj-$(CONFIG_XEN_FRONT_PGDIR_SHBUF) += xen-front-pgdir-shbuf.o
44+
obj-$(CONFIG_XEN_UNPOPULATED_ALLOC) += unpopulated-alloc.o

drivers/xen/balloon.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ void free_xenballooned_pages(int nr_pages, struct page **pages)
653653
}
654654
EXPORT_SYMBOL(free_xenballooned_pages);
655655

656-
#ifdef CONFIG_XEN_PV
656+
#if defined(CONFIG_XEN_PV) && !defined(CONFIG_XEN_UNPOPULATED_ALLOC)
657657
static void __init balloon_add_region(unsigned long start_pfn,
658658
unsigned long pages)
659659
{
@@ -707,7 +707,7 @@ static int __init balloon_init(void)
707707
register_sysctl_table(xen_root);
708708
#endif
709709

710-
#ifdef CONFIG_XEN_PV
710+
#if defined(CONFIG_XEN_PV) && !defined(CONFIG_XEN_UNPOPULATED_ALLOC)
711711
{
712712
int i;
713713

drivers/xen/grant-table.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ int gnttab_alloc_pages(int nr_pages, struct page **pages)
801801
{
802802
int ret;
803803

804-
ret = alloc_xenballooned_pages(nr_pages, pages);
804+
ret = xen_alloc_unpopulated_pages(nr_pages, pages);
805805
if (ret < 0)
806806
return ret;
807807

@@ -836,7 +836,7 @@ EXPORT_SYMBOL_GPL(gnttab_pages_clear_private);
836836
void gnttab_free_pages(int nr_pages, struct page **pages)
837837
{
838838
gnttab_pages_clear_private(nr_pages, pages);
839-
free_xenballooned_pages(nr_pages, pages);
839+
xen_free_unpopulated_pages(nr_pages, pages);
840840
}
841841
EXPORT_SYMBOL_GPL(gnttab_free_pages);
842842

drivers/xen/privcmd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ static int alloc_empty_pages(struct vm_area_struct *vma, int numpgs)
424424
if (pages == NULL)
425425
return -ENOMEM;
426426

427-
rc = alloc_xenballooned_pages(numpgs, pages);
427+
rc = xen_alloc_unpopulated_pages(numpgs, pages);
428428
if (rc != 0) {
429429
pr_warn("%s Could not alloc %d pfns rc:%d\n", __func__,
430430
numpgs, rc);
@@ -895,7 +895,7 @@ static void privcmd_close(struct vm_area_struct *vma)
895895

896896
rc = xen_unmap_domain_gfn_range(vma, numgfns, pages);
897897
if (rc == 0)
898-
free_xenballooned_pages(numpgs, pages);
898+
xen_free_unpopulated_pages(numpgs, pages);
899899
else
900900
pr_crit("unable to unmap MFN range: leaking %d pages. rc=%d\n",
901901
numpgs, rc);

drivers/xen/unpopulated-alloc.c

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

drivers/xen/xenbus/xenbus_client.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ static int xenbus_map_ring_hvm(struct xenbus_device *dev,
621621
bool leaked = false;
622622
unsigned int nr_pages = XENBUS_PAGES(nr_grefs);
623623

624-
err = alloc_xenballooned_pages(nr_pages, node->hvm.pages);
624+
err = xen_alloc_unpopulated_pages(nr_pages, node->hvm.pages);
625625
if (err)
626626
goto out_err;
627627

@@ -662,7 +662,7 @@ static int xenbus_map_ring_hvm(struct xenbus_device *dev,
662662
addr, nr_pages);
663663
out_free_ballooned_pages:
664664
if (!leaked)
665-
free_xenballooned_pages(nr_pages, node->hvm.pages);
665+
xen_free_unpopulated_pages(nr_pages, node->hvm.pages);
666666
out_err:
667667
return err;
668668
}
@@ -858,7 +858,7 @@ static int xenbus_unmap_ring_hvm(struct xenbus_device *dev, void *vaddr)
858858
info.addrs);
859859
if (!rv) {
860860
vunmap(vaddr);
861-
free_xenballooned_pages(nr_pages, node->hvm.pages);
861+
xen_free_unpopulated_pages(nr_pages, node->hvm.pages);
862862
}
863863
else
864864
WARN(1, "Leaking %p, size %u page(s)\n", vaddr, nr_pages);

drivers/xen/xlate_mmu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
232232
kfree(pages);
233233
return -ENOMEM;
234234
}
235-
rc = alloc_xenballooned_pages(nr_pages, pages);
235+
rc = xen_alloc_unpopulated_pages(nr_pages, pages);
236236
if (rc) {
237237
pr_warn("%s Couldn't balloon alloc %ld pages rc:%d\n", __func__,
238238
nr_pages, rc);
@@ -249,7 +249,7 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
249249
if (!vaddr) {
250250
pr_warn("%s Couldn't map %ld pages rc:%d\n", __func__,
251251
nr_pages, rc);
252-
free_xenballooned_pages(nr_pages, pages);
252+
xen_free_unpopulated_pages(nr_pages, pages);
253253
kfree(pages);
254254
kfree(pfns);
255255
return -ENOMEM;

include/linux/memremap.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@ struct vmem_altmap {
4646
* wakeup is used to coordinate physical address space management (ex:
4747
* fs truncate/hole punch) vs pinned pages (ex: device dma).
4848
*
49-
* MEMORY_DEVICE_DEVDAX:
49+
* MEMORY_DEVICE_GENERIC:
5050
* Host memory that has similar access semantics as System RAM i.e. DMA
51-
* coherent and supports page pinning. In contrast to
52-
* MEMORY_DEVICE_FS_DAX, this memory is access via a device-dax
53-
* character device.
51+
* coherent and supports page pinning. This is for example used by DAX devices
52+
* that expose memory using a character device.
5453
*
5554
* MEMORY_DEVICE_PCI_P2PDMA:
5655
* Device memory residing in a PCI BAR intended for use with Peer-to-Peer
@@ -60,7 +59,7 @@ enum memory_type {
6059
/* 0 is reserved to catch uninitialized type fields */
6160
MEMORY_DEVICE_PRIVATE = 1,
6261
MEMORY_DEVICE_FS_DAX,
63-
MEMORY_DEVICE_DEVDAX,
62+
MEMORY_DEVICE_GENERIC,
6463
MEMORY_DEVICE_PCI_P2PDMA,
6564
};
6665

include/xen/balloon.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
/******************************************************************************
33
* Xen balloon functionality
44
*/
5+
#ifndef _XEN_BALLOON_H
6+
#define _XEN_BALLOON_H
57

68
#define RETRY_UNLIMITED 0
79

@@ -34,3 +36,5 @@ static inline void xen_balloon_init(void)
3436
{
3537
}
3638
#endif
39+
40+
#endif /* _XEN_BALLOON_H */

include/xen/xen.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,13 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
5252
extern u64 xen_saved_max_mem_size;
5353
#endif
5454

55+
#ifdef CONFIG_XEN_UNPOPULATED_ALLOC
56+
int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages);
57+
void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages);
58+
#else
59+
#define xen_alloc_unpopulated_pages alloc_xenballooned_pages
60+
#define xen_free_unpopulated_pages free_xenballooned_pages
61+
#include <xen/balloon.h>
62+
#endif
63+
5564
#endif /* _XEN_XEN_H */

0 commit comments

Comments
 (0)