--- /dev/null
+From ef3a575baf53571dc405ee4028e26f50856898e7 Mon Sep 17 00:00:00 2001
+From: Roger Pau Monne <roger.pau@citrix.com>
+Date: Tue, 12 Jan 2021 12:53:58 +0100
+Subject: xen/privcmd: allow fetching resource sizes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+commit ef3a575baf53571dc405ee4028e26f50856898e7 upstream.
+
+Allow issuing an IOCTL_PRIVCMD_MMAP_RESOURCE ioctl with num = 0 and
+addr = 0 in order to fetch the size of a specific resource.
+
+Add a shortcut to the default map resource path, since fetching the
+size requires no address to be passed in, and thus no VMA to setup.
+
+This is missing from the initial implementation, and causes issues
+when mapping resources that don't have fixed or known sizes.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Cc: stable@vger.kernel.org # >= 4.18
+Link: https://lore.kernel.org/r/20210112115358.23346-1-roger.pau@citrix.com
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/xen/privcmd.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -724,14 +724,15 @@ static long privcmd_ioctl_restrict(struc
+ return 0;
+ }
+
+-static long privcmd_ioctl_mmap_resource(struct file *file, void __user *udata)
++static long privcmd_ioctl_mmap_resource(struct file *file,
++ struct privcmd_mmap_resource __user *udata)
+ {
+ struct privcmd_data *data = file->private_data;
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ struct privcmd_mmap_resource kdata;
+ xen_pfn_t *pfns = NULL;
+- struct xen_mem_acquire_resource xdata;
++ struct xen_mem_acquire_resource xdata = { };
+ int rc;
+
+ if (copy_from_user(&kdata, udata, sizeof(kdata)))
+@@ -741,6 +742,22 @@ static long privcmd_ioctl_mmap_resource(
+ if (data->domid != DOMID_INVALID && data->domid != kdata.dom)
+ return -EPERM;
+
++ /* Both fields must be set or unset */
++ if (!!kdata.addr != !!kdata.num)
++ return -EINVAL;
++
++ xdata.domid = kdata.dom;
++ xdata.type = kdata.type;
++ xdata.id = kdata.id;
++
++ if (!kdata.addr && !kdata.num) {
++ /* Query the size of the resource. */
++ rc = HYPERVISOR_memory_op(XENMEM_acquire_resource, &xdata);
++ if (rc)
++ return rc;
++ return __put_user(xdata.nr_frames, &udata->num);
++ }
++
+ down_write(&mm->mmap_sem);
+
+ vma = find_vma(mm, kdata.addr);
+@@ -775,10 +792,6 @@ static long privcmd_ioctl_mmap_resource(
+ } else
+ vma->vm_private_data = PRIV_VMA_LOCKED;
+
+- memset(&xdata, 0, sizeof(xdata));
+- xdata.domid = kdata.dom;
+- xdata.type = kdata.type;
+- xdata.id = kdata.id;
+ xdata.frame = kdata.idx;
+ xdata.nr_frames = kdata.num;
+ set_xen_guest_handle(xdata.frame_list, pfns);