@@ -738,13 +738,23 @@ __gnttab_map_grant_ref(
!(old_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
{
if ( wrc == 0 )
- err = iommu_map_page(ld, frame, frame,
- IOMMUF_readable|IOMMUF_writable);
+ {
+ if ( is_domain_direct_mapped(ld) )
+ err = arch_grant_map_page_identity(ld, frame, 1);
+ else
+ err = iommu_map_page(ld, frame, frame,
+ IOMMUF_readable|IOMMUF_writable);
+ }
}
else if ( act_pin && !old_pin )
{
if ( (wrc + rdc) == 0 )
- err = iommu_map_page(ld, frame, frame, IOMMUF_readable);
+ {
+ if ( is_domain_direct_mapped(ld) )
+ err = arch_grant_map_page_identity(ld, frame, 0);
+ else
+ err = iommu_map_page(ld, frame, frame, IOMMUF_readable);
+ }
}
if ( err )
{
@@ -941,9 +951,19 @@ __gnttab_unmap_common(
int err = 0;
mapcount(lgt, rd, op->frame, &wrc, &rdc);
if ( (wrc + rdc) == 0 )
- err = iommu_unmap_page(ld, op->frame);
+ {
+ if ( is_domain_direct_mapped(ld) )
+ err = arch_grant_unmap_page_identity(ld, op->frame);
+ else
+ err = iommu_unmap_page(ld, op->frame);
+ }
else if ( wrc == 0 )
- err = iommu_map_page(ld, op->frame, op->frame, IOMMUF_readable);
+ {
+ if ( is_domain_direct_mapped(ld) )
+ err = arch_grant_map_page_identity(ld, op->frame, 0);
+ else
+ err = iommu_map_page(ld, op->frame, op->frame, IOMMUF_readable);
+ }
if ( err )
{
rc = GNTST_general_error;
@@ -325,6 +325,8 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
break;
}
#endif
+ if ( is_domain_direct_mapped(d) )
+ fi.submap |= 1U << XENFEAT_grant_map_identity;
break;
default:
return -EINVAL;
@@ -1536,37 +1536,6 @@ static void arm_smmu_iommu_domain_teardown(struct domain *d)
xfree(smmu_domain);
}
-static int arm_smmu_map_page(struct domain *d, unsigned long gfn,
- unsigned long mfn, unsigned int flags)
-{
- /* Grant mappings can be used for DMA requests. The dev_bus_addr returned by
- * the hypercall is the MFN (not the IPA). For device protected by
- * an IOMMU, Xen needs to add a 1:1 mapping in the domain p2m to
- * allow DMA request to work.
- * This is only valid when the domain is directed mapped. Hence this
- * function should only be used by gnttab code with gfn == mfn.
- */
- BUG_ON(!is_domain_direct_mapped(d));
- BUG_ON(mfn != gfn);
-
- /* We only support readable and writable flags */
- if ( !(flags & (IOMMUF_readable | IOMMUF_writable)) )
- return -EINVAL;
-
- return arch_grant_map_page_identity(d, mfn, flags & IOMMUF_writable);
-}
-
-static int arm_smmu_unmap_page(struct domain *d, unsigned long gfn)
-{
- /* This function should only be used by gnttab code when the domain
- * is direct mapped
- */
- if ( !is_domain_direct_mapped(d) )
- return -EINVAL;
-
- return arch_grant_unmap_page_identity(d, gfn);
-}
-
static const struct iommu_ops arm_smmu_iommu_ops = {
.init = arm_smmu_iommu_domain_init,
.hwdom_init = arm_smmu_iommu_hwdom_init,
@@ -1575,8 +1544,6 @@ static const struct iommu_ops arm_smmu_iommu_ops = {
.iotlb_flush_all = arm_smmu_iotlb_flush_all,
.assign_dt_device = arm_smmu_attach_dev,
.reassign_dt_device = arm_smmu_reassign_dt_dev,
- .map_page = arm_smmu_map_page,
- .unmap_page = arm_smmu_unmap_page,
};
static int __init smmu_init(struct dt_device_node *dev,
@@ -33,8 +33,7 @@ static inline int replace_grant_supported(void)
( ((i >= nr_grant_frames(d->grant_table)) && \
(i < max_nr_grant_frames)) ? 0 : (d->arch.grant_table_gpfn[i]))
-#define gnttab_need_iommu_mapping(d) \
- (is_domain_direct_mapped(d) && need_iommu(d))
+#define gnttab_need_iommu_mapping(d) (is_domain_direct_mapped(d))
#endif /* __ASM_GRANT_TABLE_H__ */
/*
@@ -94,6 +94,9 @@
/* operation as Dom0 is supported */
#define XENFEAT_dom0 11
+/* Xen also maps grant references at pfn = mfn */
+#define XENFEAT_grant_map_identity 12
+
#define XENFEAT_NR_SUBMAPS 1
#endif /* __XEN_PUBLIC_FEATURES_H__ */