git: 658860e2d070 - main - xen/privcmd: implement the map resource ioctl
Roger Pau Monné
royger at FreeBSD.org
Mon Jan 11 15:36:10 UTC 2021
The branch main has been updated by royger:
URL: https://cgit.FreeBSD.org/src/commit/?id=658860e2d07065b4203bb3e7779bee0512c65c92
commit 658860e2d07065b4203bb3e7779bee0512c65c92
Author: Roger Pau Monne <roger.pau at citrix.com>
AuthorDate: 2020-06-23 09:36:19 +0000
Commit: Roger Pau Monné <royger at FreeBSD.org>
CommitDate: 2021-01-11 15:15:00 +0000
xen/privcmd: implement the map resource ioctl
The interface is mostly the same as the Linux ioctl, so that we don't
need to modify the user-space libraries that make use of it.
The ioctl is just a proxy for the XENMEM_acquire_resource hypercall.
Sponsored by: Citrix Systems R&D
---
sys/dev/xen/privcmd/privcmd.c | 52 +++++++++++++++++++++++++++++++++++++++++++
sys/xen/privcmd.h | 15 +++++++++++++
2 files changed, 67 insertions(+)
diff --git a/sys/dev/xen/privcmd/privcmd.c b/sys/dev/xen/privcmd/privcmd.c
index 78fb32444931..c31c31bcfe41 100644
--- a/sys/dev/xen/privcmd/privcmd.c
+++ b/sys/dev/xen/privcmd/privcmd.c
@@ -372,7 +372,59 @@ mmap_out:
break;
}
+ case IOCTL_PRIVCMD_MMAP_RESOURCE: {
+ struct ioctl_privcmd_mmapresource *mmap;
+ struct xen_mem_acquire_resource adq;
+ xen_pfn_t *gpfns;
+ struct privcmd_map *umap;
+
+ mmap = (struct ioctl_privcmd_mmapresource *)arg;
+
+ bzero(&adq, sizeof(adq));
+
+ adq.domid = mmap->dom;
+ adq.type = mmap->type;
+ adq.id = mmap->id;
+
+ /* Shortcut for getting the resource size. */
+ if (mmap->addr == 0 && mmap->num == 0) {
+ error = HYPERVISOR_memory_op(XENMEM_acquire_resource,
+ &adq);
+ if (error != 0) {
+ error = xen_translate_error(error);
+ break;
+ }
+ error = copyout(&adq.nr_frames, &mmap->num,
+ sizeof(mmap->num));
+ break;
+ }
+ umap = setup_virtual_area(td, mmap->addr, mmap->num);
+ if (umap == NULL) {
+ error = EINVAL;
+ break;
+ }
+
+ adq.nr_frames = mmap->num;
+ adq.frame = mmap->idx;
+
+ gpfns = malloc(sizeof(*gpfns) * mmap->num, M_PRIVCMD, M_WAITOK);
+ for (i = 0; i < mmap->num; i++)
+ gpfns[i] = atop(umap->phys_base_addr) + i;
+ set_xen_guest_handle(adq.frame_list, gpfns);
+
+ error = HYPERVISOR_memory_op(XENMEM_acquire_resource, &adq);
+ if (error != 0)
+ error = xen_translate_error(error);
+ else
+ umap->mapped = true;
+
+ free(gpfns, M_PRIVCMD);
+ if (!umap->mapped)
+ free(umap->err, M_PRIVCMD);
+
+ break;
+ }
default:
error = ENOSYS;
break;
diff --git a/sys/xen/privcmd.h b/sys/xen/privcmd.h
index a3cc4e110e41..ac2d0c00b845 100644
--- a/sys/xen/privcmd.h
+++ b/sys/xen/privcmd.h
@@ -50,9 +50,24 @@ struct ioctl_privcmd_mmapbatch {
int *err; /* array of error codes */
};
+struct ioctl_privcmd_mmapresource {
+ domid_t dom; /* target domain */
+ unsigned int type; /* type of resource to map */
+ unsigned int id; /* type-specific resource identifier */
+ unsigned int idx; /* the index of the initial frame to be mapped */
+ unsigned long num; /* number of frames of the resource to be mapped */
+ unsigned long addr; /* physical address to map into */
+ /*
+ * Note: issuing an ioctl with num = addr = 0 will return the size of
+ * the resource.
+ */
+};
+
#define IOCTL_PRIVCMD_HYPERCALL \
_IOWR('E', 0, struct ioctl_privcmd_hypercall)
#define IOCTL_PRIVCMD_MMAPBATCH \
_IOWR('E', 1, struct ioctl_privcmd_mmapbatch)
+#define IOCTL_PRIVCMD_MMAP_RESOURCE \
+ _IOW('E', 2, struct ioctl_privcmd_mmapresource)
#endif /* !__XEN_PRIVCMD_H__ */
More information about the dev-commits-src-all
mailing list