@@ -4077,38 +4077,39 @@ intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
4077
4077
struct iommu_domain * parent ,
4078
4078
const struct iommu_user_data * user_data )
4079
4079
{
4080
+ struct device_domain_info * info = dev_iommu_priv_get (dev );
4081
+ bool dirty_tracking = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING ;
4082
+ bool nested_parent = flags & IOMMU_HWPT_ALLOC_NEST_PARENT ;
4083
+ struct intel_iommu * iommu = info -> iommu ;
4080
4084
struct iommu_domain * domain ;
4081
- struct intel_iommu * iommu ;
4082
- bool dirty_tracking ;
4085
+
4086
+ /* Must be NESTING domain */
4087
+ if (parent ) {
4088
+ if (!nested_supported (iommu ) || flags )
4089
+ return ERR_PTR (- EOPNOTSUPP );
4090
+ return intel_nested_domain_alloc (parent , user_data );
4091
+ }
4083
4092
4084
4093
if (flags &
4085
4094
(~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING )))
4086
4095
return ERR_PTR (- EOPNOTSUPP );
4087
-
4088
- if (parent || user_data )
4089
- return ERR_PTR (- EOPNOTSUPP );
4090
-
4091
- iommu = device_to_iommu (dev , NULL , NULL );
4092
- if (!iommu )
4093
- return ERR_PTR (- ENODEV );
4094
-
4095
- if ((flags & IOMMU_HWPT_ALLOC_NEST_PARENT ) && !nested_supported (iommu ))
4096
+ if (nested_parent && !nested_supported (iommu ))
4096
4097
return ERR_PTR (- EOPNOTSUPP );
4097
-
4098
- dirty_tracking = (flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING );
4099
- if (dirty_tracking && !ssads_supported (iommu ))
4098
+ if (user_data || (dirty_tracking && !ssads_supported (iommu )))
4100
4099
return ERR_PTR (- EOPNOTSUPP );
4101
4100
4102
4101
/*
4103
- * domain_alloc_user op needs to fully initialize a domain
4104
- * before return, so uses iommu_domain_alloc() here for
4105
- * simple.
4102
+ * domain_alloc_user op needs to fully initialize a domain before
4103
+ * return, so uses iommu_domain_alloc() here for simple.
4106
4104
*/
4107
4105
domain = iommu_domain_alloc (dev -> bus );
4108
4106
if (!domain )
4109
- domain = ERR_PTR (- ENOMEM );
4107
+ return ERR_PTR (- ENOMEM );
4108
+
4109
+ if (nested_parent )
4110
+ to_dmar_domain (domain )-> nested_parent = true;
4110
4111
4111
- if (! IS_ERR ( domain ) && dirty_tracking ) {
4112
+ if (dirty_tracking ) {
4112
4113
if (to_dmar_domain (domain )-> use_first_level ) {
4113
4114
iommu_domain_free (domain );
4114
4115
return ERR_PTR (- EOPNOTSUPP );
0 commit comments