@@ -1138,6 +1138,10 @@ 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;
+ break;
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>
@@ -1192,6 +1193,39 @@ 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 = iomem_permit_access(d, start_gfn, (start_gfn + nr));
+ if ( res )
+ {
+ printk(XENLOG_ERR "Unable to permit to dom%d access to"
+ " 0x%"PRIx64" - 0x%"PRIx64"\n",
+ d->domain_id,
+ start_gfn << PAGE_SHIFT, (start_gfn + nr) << PAGE_SHIFT);
+ return res;
+ }
+
+ res = map_mmio_regions(d, start_gfn, nr, mfn);
+ if ( res < 0 )
+ {
+ printk(XENLOG_ERR "Unable to map 0x%"PRIx64
+ " - 0x%"PRIx64" 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,
@@ -168,6 +168,11 @@ int unmap_regions(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 */
/* ` } */
/*