@@ -2507,7 +2507,7 @@ static int __init handle_device(struct domain *d, struct dt_device_node *dev,
return res;
}
- if ( dt_device_is_protected(dev) )
+ if ( device_is_protected(dt_to_dev(dev)) )
{
dt_dprintk("%s setup iommu\n", dt_node_full_name(dev));
res = iommu_assign_dt_device(d, dev);
@@ -3007,7 +3007,7 @@ static int __init handle_passthrough_prop(struct kernel_info *kinfo,
return res;
/* If xen_force, we allow assignment of devices without IOMMU protection. */
- if ( xen_force && !dt_device_is_protected(node) )
+ if ( xen_force && !device_is_protected(dt_to_dev(node)) )
return 0;
return iommu_assign_dt_device(kinfo->d, node);
@@ -1,6 +1,8 @@
#ifndef __ASM_ARM_DEVICE_H
#define __ASM_ARM_DEVICE_H
+#include <xen/types.h>
+
enum device_type
{
DEV_DT,
@@ -20,6 +22,7 @@ struct device
#endif
struct dev_archdata archdata;
struct iommu_fwspec *iommu_fwspec; /* per-device IOMMU instance data */
+ bool is_protected; /* Shows that device is protected by IOMMU */
};
typedef struct device device_t;
@@ -94,6 +97,16 @@ int device_init(struct dt_device_node *dev, enum device_class class,
*/
enum device_class device_get_class(const struct dt_device_node *dev);
+static inline void device_set_protected(struct device *device)
+{
+ device->is_protected = true;
+}
+
+static inline bool device_is_protected(const struct device *device)
+{
+ return device->is_protected;
+}
+
#define DT_DEVICE_START(_name, _namestr, _class) \
static const struct device_desc __dev_desc_##_name __used \
__section(".dev.info") = { \
@@ -1874,7 +1874,7 @@ static unsigned long __init unflatten_dt_node(const void *fdt,
/* By default dom0 owns the device */
np->used_by = 0;
/* By default the device is not protected */
- np->is_protected = false;
+ np->dev.is_protected = false;
INIT_LIST_HEAD(&np->domain_list);
if ( new_format )
@@ -1288,14 +1288,8 @@ static int ipmmu_add_device(u8 devfn, struct device *dev)
if ( !to_ipmmu(dev) )
return -ENODEV;
- if ( dt_device_is_protected(dev_to_dt(dev)) )
- {
- dev_err(dev, "Already added to IPMMU\n");
- return -EEXIST;
- }
-
/* Let Xen know that the master device is protected by an IOMMU. */
- dt_device_set_protected(dev_to_dt(dev));
+ device_set_protected(dev);
dev_info(dev, "Added master device (IPMMU %s micro-TLBs %u)\n",
dev_name(fwspec->iommu_dev), fwspec->num_ids);
@@ -1521,13 +1521,8 @@ static int arm_smmu_add_device(u8 devfn, struct device *dev)
*/
arm_smmu_enable_pasid(master);
- if (dt_device_is_protected(dev_to_dt(dev))) {
- dev_err(dev, "Already added to SMMUv3\n");
- return -EEXIST;
- }
-
/* Let Xen know that the master device is protected by an IOMMU. */
- dt_device_set_protected(dev_to_dt(dev));
+ device_set_protected(dev);
dev_info(dev, "Added master device (SMMUv3 %s StreamIds %u)\n",
dev_name(fwspec->iommu_dev), fwspec->num_ids);
@@ -838,7 +838,7 @@ static int arm_smmu_dt_add_device_legacy(struct arm_smmu_device *smmu,
master->of_node = dev_node;
/* Xen: Let Xen know that the device is protected by an SMMU */
- dt_device_set_protected(dev_node);
+ device_set_protected(dev);
for (i = 0; i < fwspec->num_ids; ++i) {
if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) &&
@@ -34,7 +34,7 @@ int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev)
if ( !is_iommu_enabled(d) )
return -EINVAL;
- if ( !dt_device_is_protected(dev) )
+ if ( !device_is_protected(dt_to_dev(dev)) )
return -EINVAL;
spin_lock(&dtdevs_lock);
@@ -65,7 +65,7 @@ int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
if ( !is_iommu_enabled(d) )
return -EINVAL;
- if ( !dt_device_is_protected(dev) )
+ if ( !device_is_protected(dt_to_dev(dev)) )
return -EINVAL;
spin_lock(&dtdevs_lock);
@@ -87,7 +87,7 @@ static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
{
bool_t assigned = 0;
- if ( !dt_device_is_protected(dev) )
+ if ( !device_is_protected(dt_to_dev(dev)) )
return 0;
spin_lock(&dtdevs_lock);
@@ -141,12 +141,15 @@ int iommu_add_dt_device(struct dt_device_node *np)
return -EINVAL;
/*
- * The device may already have been registered. As there is no harm in
- * it just return success early.
+ * This is needed in case a device has both the iommus property and
+ * also appears in the mmu-masters list.
*/
- if ( dev_iommu_fwspec_get(dev) )
+ if ( device_is_protected(dev) )
return 0;
+ if ( dev_iommu_fwspec_get(dev) )
+ return -EEXIST;
+
/*
* According to the Documentation/devicetree/bindings/iommu/iommu.txt
* from Linux.
@@ -90,9 +90,6 @@ struct dt_device_node {
struct dt_device_node *next; /* TODO: Remove it. Only use to know the last children */
struct dt_device_node *allnext;
- /* IOMMU specific fields */
- bool is_protected;
-
/* HACK: Remove this if there is a need of space */
bool_t static_evtchn_created;
@@ -302,16 +299,6 @@ static inline domid_t dt_device_used_by(const struct dt_device_node *device)
return device->used_by;
}
-static inline void dt_device_set_protected(struct dt_device_node *device)
-{
- device->is_protected = true;
-}
-
-static inline bool dt_device_is_protected(const struct dt_device_node *device)
-{
- return device->is_protected;
-}
-
static inline bool_t dt_property_name_is_equal(const struct dt_property *pp,
const char *name)
{