@@ -1138,6 +1138,9 @@ int xenmem_add_to_physmap_one(
rcu_unlock_domain(od);
break;
}
+ case XENMAPSPACE_dev_mmio:
+ rc = map_dev_mmio_region(d, gpfn, 1, idx);
+ return rc;
default:
return -ENOSYS;
@@ -7,6 +7,7 @@
#include <xen/bitops.h>
#include <xen/vm_event.h>
#include <xen/mem_access.h>
+#include <xen/iocap.h>
#include <public/vm_event.h>
#include <asm/flushtlb.h>
#include <asm/gic.h>
@@ -1270,6 +1271,28 @@ int unmap_mmio_regions(struct domain *d,
d->arch.p2m.default_access);
}
+int map_dev_mmio_region(struct domain *d,
+ unsigned long start_gfn,
+ unsigned long nr,
+ unsigned long mfn)
+{
+ int res;
+
+ if(!iomem_access_permitted(d, start_gfn, start_gfn + nr))
+ return 0;
+
+ res = map_mmio_regions(d, start_gfn, nr, mfn);
+ if ( res < 0 )
+ {
+ printk(XENLOG_ERR "Unable to map 0x%lx - 0x%lx in domain %d\n",
+ start_gfn << PAGE_SHIFT, (start_gfn + nr) << PAGE_SHIFT,
+ d->domain_id);
+ return res;
+ }
+
+ return 0;
+}
+
int guest_physmap_add_entry(struct domain *d,
unsigned long gpfn,
unsigned long mfn,
@@ -980,6 +980,14 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
if ( d == NULL )
return -ESRCH;
+ /*
+ * XENMAPSPACE_dev_mmio mapping is only supported for hardware Domain
+ * to map this kind of space to itself.
+ */
+ if ( (xatp.space == XENMAPSPACE_dev_mmio) &&
+ (!is_hardware_domain(current->domain) || (d != current->domain)) )
+ return -EACCES;
+
rc = xsm_add_to_physmap(XSM_TARGET, current->domain, d);
if ( rc )
{
@@ -1024,6 +1032,14 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
if ( d == NULL )
return -ESRCH;
+ /*
+ * XENMAPSPACE_dev_mmio mapping is only supported for hardware Domain
+ * to map this kind of space to itself.
+ */
+ if ( (xatpb.space == XENMAPSPACE_dev_mmio) &&
+ (!is_hardware_domain(current->domain) || (d != current->domain)) )
+ return -EACCES;
+
rc = xsm_add_to_physmap(XSM_TARGET, current->domain, d);
if ( rc )
{
@@ -154,6 +154,11 @@ int unmap_regions_rw(struct domain *d,
unsigned long nr_mfns,
unsigned long mfn);
+int map_dev_mmio_region(struct domain *d,
+ unsigned long start_gfn,
+ unsigned long nr,
+ unsigned long mfn);
+
int guest_physmap_add_entry(struct domain *d,
unsigned long gfn,
unsigned long mfn,
@@ -220,6 +220,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
#define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap only. */
#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
* XENMEM_add_to_physmap_batch only. */
+#define XENMAPSPACE_dev_mmio 5 /* device mmio region */
/* ` } */
/*