[PATCH v5 3/3] xen: add helpers to allocate unpopulated memory

2020-09-01 Thread Roger Pau Monne
To be used in order to create foreign mappings. This is based on the
ZONE_DEVICE facility which is used by persistent memory devices in
order to create struct pages and kernel virtual mappings for the IOMEM
areas of such devices. Note that on kernels without support for
ZONE_DEVICE Xen will fallback to use ballooned pages in order to
create foreign mappings.

The newly added helpers use the same parameters as the existing
{alloc/free}_xenballooned_pages functions, which allows for in-place
replacement of the callers. Once a memory region has been added to be
used as scratch mapping space it will no longer be released, and pages
returned are kept in a linked list. This allows to have a buffer of
pages and prevents resorting to frequent additions and removals of
regions.

If enabled (because ZONE_DEVICE is supported) the usage of the new
functionality untangles Xen balloon and RAM hotplug from the usage of
unpopulated physical memory ranges to map foreign pages, which is the
correct thing to do in order to avoid mappings of foreign pages depend
on memory hotplug.

Note the driver is currently not enabled on Arm platforms because it
would interfere with the identity mapping required on some platforms.

Signed-off-by: Roger Pau Monné 
---
Cc: Oleksandr Andrushchenko 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Boris Ostrovsky 
Cc: Juergen Gross 
Cc: Stefano Stabellini 
Cc: Dan Carpenter 
Cc: Roger Pau Monne 
Cc: Wei Liu 
Cc: Yan Yankovskyi 
Cc: dri-devel@lists.freedesktop.org
Cc: xen-de...@lists.xenproject.org
Cc: linux...@kvack.org
Cc: David Hildenbrand 
Cc: Michal Hocko 
Cc: Dan Williams 
---
Changes since v4:
 - Introduce a description for the option.
 - Force selection of ZONE_DEVICE on X86 and select
   XEN_UNPOPULATED_ALLOC if running on dom0 mode or having any
   backends.

Changes since v3:
 - Introduce a Kconfig option that gates the addition of the
   unpopulated alloc driver. This allows to easily disable it on Arm
   platforms.
 - Dropped Juergen RB due to the addition of the Kconfig option.
 - Switched from MEMORY_DEVICE_DEVDAX to MEMORY_DEVICE_GENERIC.

Changes since v2:
 - Drop BUILD_BUG_ON regarding PVMMU page sizes.
 - Use a SPDX license identifier.
 - Call fill with only the minimum required number of pages.
 - Include xen.h header in xen_drm_front_gem.c.
 - Use less generic function names.
 - Exit early from the init function if not a PV guest.
 - Don't use all caps for region name.
---
 drivers/gpu/drm/xen/xen_drm_front_gem.c |   9 +-
 drivers/xen/Kconfig |  11 ++
 drivers/xen/Makefile|   1 +
 drivers/xen/balloon.c   |   4 +-
 drivers/xen/grant-table.c   |   4 +-
 drivers/xen/privcmd.c   |   4 +-
 drivers/xen/unpopulated-alloc.c | 185 
 drivers/xen/xenbus/xenbus_client.c  |   6 +-
 drivers/xen/xlate_mmu.c |   4 +-
 include/xen/xen.h   |   9 ++
 10 files changed, 222 insertions(+), 15 deletions(-)
 create mode 100644 drivers/xen/unpopulated-alloc.c

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c 
b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index 39ff95b75357..534daf37c97e 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -18,6 +18,7 @@
 #include 
 
 #include 
+#include 
 
 #include "xen_drm_front.h"
 #include "xen_drm_front_gem.h"
@@ -99,8 +100,8 @@ static struct xen_gem_object *gem_create(struct drm_device 
*dev, size_t size)
 * allocate ballooned pages which will be used to map
 * grant references provided by the backend
 */
-   ret = alloc_xenballooned_pages(xen_obj->num_pages,
-  xen_obj->pages);
+   ret = xen_alloc_unpopulated_pages(xen_obj->num_pages,
+ xen_obj->pages);
if (ret < 0) {
DRM_ERROR("Cannot allocate %zu ballooned pages: %d\n",
  xen_obj->num_pages, ret);
@@ -152,8 +153,8 @@ void xen_drm_front_gem_free_object_unlocked(struct 
drm_gem_object *gem_obj)
} else {
if (xen_obj->pages) {
if (xen_obj->be_alloc) {
-   free_xenballooned_pages(xen_obj->num_pages,
-   xen_obj->pages);
+   xen_free_unpopulated_pages(xen_obj->num_pages,
+  xen_obj->pages);
gem_free_pages_array(xen_obj);
} else {
drm_gem_put_pages(_obj->base,
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index ea6c1e7e3e42..e38c33558d0d 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -325,4 +325,15 @

[PATCH v4 2/2] xen: add helpers to allocate unpopulated memory

2020-08-12 Thread Roger Pau Monne
To be used in order to create foreign mappings. This is based on the
ZONE_DEVICE facility which is used by persistent memory devices in
order to create struct pages and kernel virtual mappings for the IOMEM
areas of such devices. Note that on kernels without support for
ZONE_DEVICE Xen will fallback to use ballooned pages in order to
create foreign mappings.

The newly added helpers use the same parameters as the existing
{alloc/free}_xenballooned_pages functions, which allows for in-place
replacement of the callers. Once a memory region has been added to be
used as scratch mapping space it will no longer be released, and pages
returned are kept in a linked list. This allows to have a buffer of
pages and prevents resorting to frequent additions and removals of
regions.

If enabled (because ZONE_DEVICE is supported) the usage of the new
functionality untangles Xen balloon and RAM hotplug from the usage of
unpopulated physical memory ranges to map foreign pages, which is the
correct thing to do in order to avoid mappings of foreign pages depend
on memory hotplug.

Note the driver is currently not enabled on Arm platforms because it
would interfere with the identity mapping required on some platforms.

Signed-off-by: Roger Pau Monné 
---
Cc: Oleksandr Andrushchenko 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Boris Ostrovsky 
Cc: Juergen Gross 
Cc: Stefano Stabellini 
Cc: Dan Carpenter 
Cc: Roger Pau Monne 
Cc: Wei Liu 
Cc: Yan Yankovskyi 
Cc: dri-devel@lists.freedesktop.org
Cc: xen-de...@lists.xenproject.org
Cc: linux...@kvack.org
Cc: David Hildenbrand 
Cc: Michal Hocko 
Cc: Dan Williams 
---
Changes since v3:
 - Introduce a Kconfig option that gates the addition of the
   unpopulated alloc driver. This allows to easily disable it on Arm
   platforms.
 - Dropped Juergen RB due to the addition of the Kconfig option.
 - Switched from MEMORY_DEVICE_DEVDAX to MEMORY_DEVICE_GENERIC.

Changes since v2:
 - Drop BUILD_BUG_ON regarding PVMMU page sizes.
 - Use a SPDX license identifier.
 - Call fill with only the minimum required number of pages.
 - Include xen.h header in xen_drm_front_gem.c.
 - Use less generic function names.
 - Exit early from the init function if not a PV guest.
 - Don't use all caps for region name.
---
 drivers/gpu/drm/xen/xen_drm_front_gem.c |   9 +-
 drivers/xen/Kconfig |   4 +
 drivers/xen/Makefile|   1 +
 drivers/xen/balloon.c   |   4 +-
 drivers/xen/grant-table.c   |   4 +-
 drivers/xen/privcmd.c   |   4 +-
 drivers/xen/unpopulated-alloc.c | 185 
 drivers/xen/xenbus/xenbus_client.c  |   6 +-
 drivers/xen/xlate_mmu.c |   4 +-
 include/xen/xen.h   |   9 ++
 10 files changed, 215 insertions(+), 15 deletions(-)
 create mode 100644 drivers/xen/unpopulated-alloc.c

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c 
b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e094111..270e1bd3e4da 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -18,6 +18,7 @@
 #include 
 
 #include 
+#include 
 
 #include "xen_drm_front.h"
 #include "xen_drm_front_gem.h"
@@ -99,8 +100,8 @@ static struct xen_gem_object *gem_create(struct drm_device 
*dev, size_t size)
 * allocate ballooned pages which will be used to map
 * grant references provided by the backend
 */
-   ret = alloc_xenballooned_pages(xen_obj->num_pages,
-  xen_obj->pages);
+   ret = xen_alloc_unpopulated_pages(xen_obj->num_pages,
+ xen_obj->pages);
if (ret < 0) {
DRM_ERROR("Cannot allocate %zu ballooned pages: %d\n",
  xen_obj->num_pages, ret);
@@ -152,8 +153,8 @@ void xen_drm_front_gem_free_object_unlocked(struct 
drm_gem_object *gem_obj)
} else {
if (xen_obj->pages) {
if (xen_obj->be_alloc) {
-   free_xenballooned_pages(xen_obj->num_pages,
-   xen_obj->pages);
+   xen_free_unpopulated_pages(xen_obj->num_pages,
+  xen_obj->pages);
gem_free_pages_array(xen_obj);
} else {
drm_gem_put_pages(_obj->base,
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 1d339ef92422..018020b91baa 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -327,4 +327,8 @@ config XEN_HAVE_VPMU
 config XEN_FRONT_PGDIR_SHBUF
tristate
 
+config XEN_UNPOPULATED_ALLOC
+   bool
+   default y if ZONE_DEVICE && !ARM && !ARM64
+

[PATCH v3 4/4] xen: add helpers to allocate unpopulated memory

2020-07-27 Thread Roger Pau Monne
To be used in order to create foreign mappings. This is based on the
ZONE_DEVICE facility which is used by persistent memory devices in
order to create struct pages and kernel virtual mappings for the IOMEM
areas of such devices. Note that on kernels without support for
ZONE_DEVICE Xen will fallback to use ballooned pages in order to
create foreign mappings.

The newly added helpers use the same parameters as the existing
{alloc/free}_xenballooned_pages functions, which allows for in-place
replacement of the callers. Once a memory region has been added to be
used as scratch mapping space it will no longer be released, and pages
returned are kept in a linked list. This allows to have a buffer of
pages and prevents resorting to frequent additions and removals of
regions.

If enabled (because ZONE_DEVICE is supported) the usage of the new
functionality untangles Xen balloon and RAM hotplug from the usage of
unpopulated physical memory ranges to map foreign pages, which is the
correct thing to do in order to avoid mappings of foreign pages depend
on memory hotplug.

Signed-off-by: Roger Pau Monné 
---
I've not added a new memory_type type and just used
MEMORY_DEVICE_DEVDAX which seems to be what we want for such memory
regions. I'm unsure whether abusing this type is fine, or if I should
instead add a specific type, maybe MEMORY_DEVICE_GENERIC? I don't
think we should be using a specific Xen type at all.
---
Cc: Oleksandr Andrushchenko 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Boris Ostrovsky 
Cc: Juergen Gross 
Cc: Stefano Stabellini 
Cc: Dan Carpenter 
Cc: Roger Pau Monne 
Cc: Wei Liu 
Cc: Yan Yankovskyi 
Cc: dri-devel@lists.freedesktop.org
Cc: xen-de...@lists.xenproject.org
Cc: linux...@kvack.org
Cc: David Hildenbrand 
Cc: Michal Hocko 
Cc: Dan Williams 
---
Changes since v2:
 - Drop BUILD_BUG_ON regarding PVMMU page sizes.
 - Use a SPDX license identifier.
 - Call fill with only the minimum required number of pages.
 - Include xen.h header in xen_drm_front_gem.c.
 - Use less generic function names.
 - Exit early from the init function if not a PV guest.
 - Don't use all caps for region name.
---
 drivers/gpu/drm/xen/xen_drm_front_gem.c |   9 +-
 drivers/xen/Makefile|   1 +
 drivers/xen/balloon.c   |   4 +-
 drivers/xen/grant-table.c   |   4 +-
 drivers/xen/privcmd.c   |   4 +-
 drivers/xen/unpopulated-alloc.c | 185 
 drivers/xen/xenbus/xenbus_client.c  |   6 +-
 drivers/xen/xlate_mmu.c |   4 +-
 include/xen/xen.h   |   9 ++
 9 files changed, 211 insertions(+), 15 deletions(-)
 create mode 100644 drivers/xen/unpopulated-alloc.c

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c 
b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e094111..270e1bd3e4da 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -18,6 +18,7 @@
 #include 
 
 #include 
+#include 
 
 #include "xen_drm_front.h"
 #include "xen_drm_front_gem.h"
@@ -99,8 +100,8 @@ static struct xen_gem_object *gem_create(struct drm_device 
*dev, size_t size)
 * allocate ballooned pages which will be used to map
 * grant references provided by the backend
 */
-   ret = alloc_xenballooned_pages(xen_obj->num_pages,
-  xen_obj->pages);
+   ret = xen_alloc_unpopulated_pages(xen_obj->num_pages,
+ xen_obj->pages);
if (ret < 0) {
DRM_ERROR("Cannot allocate %zu ballooned pages: %d\n",
  xen_obj->num_pages, ret);
@@ -152,8 +153,8 @@ void xen_drm_front_gem_free_object_unlocked(struct 
drm_gem_object *gem_obj)
} else {
if (xen_obj->pages) {
if (xen_obj->be_alloc) {
-   free_xenballooned_pages(xen_obj->num_pages,
-   xen_obj->pages);
+   xen_free_unpopulated_pages(xen_obj->num_pages,
+  xen_obj->pages);
gem_free_pages_array(xen_obj);
} else {
drm_gem_put_pages(_obj->base,
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 0d322f3d90cd..788a5d9c8ef0 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -42,3 +42,4 @@ xen-gntdev-$(CONFIG_XEN_GNTDEV_DMABUF)+= 
gntdev-dmabuf.o
 xen-gntalloc-y := gntalloc.o
 xen-privcmd-y  := privcmd.o privcmd-buf.o
 obj-$(CONFIG_XEN_FRONT_PGDIR_SHBUF)+= xen-front-pgdir-shbuf.o
+obj-$(CONFIG_ZONE_DEVICE)  += unpopulated-alloc.o
diff --git a/drivers/xen/ball

[PATCH v2 4/4] xen: add helpers to allocate unpopulated memory

2020-07-26 Thread Roger Pau Monne
To be used in order to create foreign mappings. This is based on the
ZONE_DEVICE facility which is used by persistent memory devices in
order to create struct pages and kernel virtual mappings for the IOMEM
areas of such devices. Note that on kernels without support for
ZONE_DEVICE Xen will fallback to use ballooned pages in order to
create foreign mappings.

The newly added helpers use the same parameters as the existing
{alloc/free}_xenballooned_pages functions, which allows for in-place
replacement of the callers. Once a memory region has been added to be
used as scratch mapping space it will no longer be released, and pages
returned are kept in a linked list. This allows to have a buffer of
pages and prevents resorting to frequent additions and removals of
regions.

If enabled (because ZONE_DEVICE is supported) the usage of the new
functionality untangles Xen balloon and RAM hotplug from the usage of
unpopulated physical memory ranges to map foreign pages, which is the
correct thing to do in order to avoid mappings of foreign pages depend
on memory hotplug.

Signed-off-by: Roger Pau Monné 
---
I've not added a new memory_type type and just used
MEMORY_DEVICE_DEVDAX which seems to be what we want for such memory
regions. I'm unsure whether abusing this type is fine, or if I should
instead add a specific type, maybe MEMORY_DEVICE_GENERIC? I don't
think we should be using a specific Xen type at all.
---
Cc: Oleksandr Andrushchenko 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: Boris Ostrovsky 
Cc: Juergen Gross 
Cc: Stefano Stabellini 
Cc: Dan Carpenter 
Cc: Roger Pau Monne 
Cc: Wei Liu 
Cc: Yan Yankovskyi 
Cc: dri-devel@lists.freedesktop.org
Cc: xen-de...@lists.xenproject.org
Cc: linux...@kvack.org
Cc: David Hildenbrand 
Cc: Michal Hocko 
---
 drivers/gpu/drm/xen/xen_drm_front_gem.c |   8 +-
 drivers/xen/Makefile|   1 +
 drivers/xen/balloon.c   |   4 +-
 drivers/xen/grant-table.c   |   4 +-
 drivers/xen/privcmd.c   |   4 +-
 drivers/xen/unpopulated-alloc.c | 222 
 drivers/xen/xenbus/xenbus_client.c  |   6 +-
 drivers/xen/xlate_mmu.c |   4 +-
 include/xen/xen.h   |   8 +
 9 files changed, 246 insertions(+), 15 deletions(-)
 create mode 100644 drivers/xen/unpopulated-alloc.c

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c 
b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e094111..9dd06eae767a 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -99,8 +99,8 @@ static struct xen_gem_object *gem_create(struct drm_device 
*dev, size_t size)
 * allocate ballooned pages which will be used to map
 * grant references provided by the backend
 */
-   ret = alloc_xenballooned_pages(xen_obj->num_pages,
-  xen_obj->pages);
+   ret = xen_alloc_unpopulated_pages(xen_obj->num_pages,
+ xen_obj->pages);
if (ret < 0) {
DRM_ERROR("Cannot allocate %zu ballooned pages: %d\n",
  xen_obj->num_pages, ret);
@@ -152,8 +152,8 @@ void xen_drm_front_gem_free_object_unlocked(struct 
drm_gem_object *gem_obj)
} else {
if (xen_obj->pages) {
if (xen_obj->be_alloc) {
-   free_xenballooned_pages(xen_obj->num_pages,
-   xen_obj->pages);
+   xen_free_unpopulated_pages(xen_obj->num_pages,
+  xen_obj->pages);
gem_free_pages_array(xen_obj);
} else {
drm_gem_put_pages(_obj->base,
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 0d322f3d90cd..788a5d9c8ef0 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -42,3 +42,4 @@ xen-gntdev-$(CONFIG_XEN_GNTDEV_DMABUF)+= 
gntdev-dmabuf.o
 xen-gntalloc-y := gntalloc.o
 xen-privcmd-y  := privcmd.o privcmd-buf.o
 obj-$(CONFIG_XEN_FRONT_PGDIR_SHBUF)+= xen-front-pgdir-shbuf.o
+obj-$(CONFIG_ZONE_DEVICE)  += unpopulated-alloc.o
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index b1d8b028bf80..815ef10eb2ff 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -654,7 +654,7 @@ void free_xenballooned_pages(int nr_pages, struct page 
**pages)
 }
 EXPORT_SYMBOL(free_xenballooned_pages);
 
-#ifdef CONFIG_XEN_PV
+#if defined(CONFIG_XEN_PV) && !defined(CONFIG_ZONE_DEVICE)
 static void __init balloon_add_region(unsigned long start_pfn,
  unsigned long pages)
 {
@@ -708,7 +708,7 @@ static int __init