diff mbox series

[v4] xen/iommu: cleanup iommu related domctl handling

Message ID 20220420055736.27901-1-jgross@suse.com (mailing list archive)
State New, archived
Headers show
Series [v4] xen/iommu: cleanup iommu related domctl handling | expand

Commit Message

Jürgen Groß April 20, 2022, 5:57 a.m. UTC
Today iommu_do_domctl() is being called from arch_do_domctl() in the
"default:" case of a switch statement. This has led already to crashes
due to unvalidated parameters.

Fix that by moving the call of iommu_do_domctl() to the main switch
statement of do_domctl().

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V3:
- new patch
V4:
- add iommu_do_domctl() stub for !CONFIG_HAS_PASSTHROUGH (Andrew Cooper,
  Jan Beulich)
---
 xen/arch/arm/domctl.c   | 11 +----------
 xen/arch/x86/domctl.c   |  2 +-
 xen/common/domctl.c     |  7 +++++++
 xen/include/xen/iommu.h | 12 +++++++++---
 4 files changed, 18 insertions(+), 14 deletions(-)

Comments

Jan Beulich April 20, 2022, 6:11 a.m. UTC | #1
On 20.04.2022 07:57, Juergen Gross wrote:
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -341,8 +341,17 @@ struct domain_iommu {
>  /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
>  #ifdef CONFIG_HAS_PASSTHROUGH
>  #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
> +
> +int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
> +                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
>  #else
>  #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
> +
> +static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
> +                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
> +{
> +    return -ENOSYS;
> +}

As said in reply to Andrew as well as in a number or earlier occasions,
I firmly think that this wants to be -EOPNOTSUPP, not -ENOSYS. Views
here may differ of course, but in the absence of objections I consider
this easy enough to adjust while committing. If, of course, the
approach finds a majority in the first place - as indicated before I
don't view it as very desirable to enumerate all the IOMMU related
domctl-s in the common handler.

FTAOD I can accept x86'es arch_do_domctl() returning -ENOSYS, but only
for the purpose of not altering the pre-existing error code which would
be returned if making it there.

Jan
Jürgen Groß April 20, 2022, 6:22 a.m. UTC | #2
On 20.04.22 08:11, Jan Beulich wrote:
> On 20.04.2022 07:57, Juergen Gross wrote:
>> --- a/xen/include/xen/iommu.h
>> +++ b/xen/include/xen/iommu.h
>> @@ -341,8 +341,17 @@ struct domain_iommu {
>>   /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
>>   #ifdef CONFIG_HAS_PASSTHROUGH
>>   #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
>> +
>> +int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>> +                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
>>   #else
>>   #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
>> +
>> +static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>> +                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>> +{
>> +    return -ENOSYS;
>> +}
> 
> As said in reply to Andrew as well as in a number or earlier occasions,
> I firmly think that this wants to be -EOPNOTSUPP, not -ENOSYS. Views

In libxl there is an explicit check for ENOSYS being returned for
assigning/deassigning a device, same in the xc python bindings.


Juergen
Jan Beulich April 20, 2022, 6:27 a.m. UTC | #3
On 20.04.2022 08:22, Juergen Gross wrote:
> On 20.04.22 08:11, Jan Beulich wrote:
>> On 20.04.2022 07:57, Juergen Gross wrote:
>>> --- a/xen/include/xen/iommu.h
>>> +++ b/xen/include/xen/iommu.h
>>> @@ -341,8 +341,17 @@ struct domain_iommu {
>>>   /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
>>>   #ifdef CONFIG_HAS_PASSTHROUGH
>>>   #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
>>> +
>>> +int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>> +                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
>>>   #else
>>>   #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
>>> +
>>> +static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>> +                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>>> +{
>>> +    return -ENOSYS;
>>> +}
>>
>> As said in reply to Andrew as well as in a number or earlier occasions,
>> I firmly think that this wants to be -EOPNOTSUPP, not -ENOSYS. Views
> 
> In libxl there is an explicit check for ENOSYS being returned for
> assigning/deassigning a device, same in the xc python bindings.

Urgh.

Jan
Andrew Cooper April 21, 2022, 5:47 p.m. UTC | #4
On 20/04/2022 07:27, Jan Beulich wrote:
> On 20.04.2022 08:22, Juergen Gross wrote:
>> On 20.04.22 08:11, Jan Beulich wrote:
>>> On 20.04.2022 07:57, Juergen Gross wrote:
>>>> --- a/xen/include/xen/iommu.h
>>>> +++ b/xen/include/xen/iommu.h
>>>> @@ -341,8 +341,17 @@ struct domain_iommu {
>>>>   /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
>>>>   #ifdef CONFIG_HAS_PASSTHROUGH
>>>>   #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
>>>> +
>>>> +int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>>> +                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
>>>>   #else
>>>>   #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
>>>> +
>>>> +static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>>> +                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>>>> +{
>>>> +    return -ENOSYS;
>>>> +}
>>> As said in reply to Andrew as well as in a number or earlier occasions,
>>> I firmly think that this wants to be -EOPNOTSUPP, not -ENOSYS. Views
>> In libxl there is an explicit check for ENOSYS being returned for
>> assigning/deassigning a device, same in the xc python bindings.
> Urgh.

Honestly, I wasn't particularly happy with your push to swap ENOSYS out
for EOPNOTSUPP.  This shows plainly why it's a bad move.

An end user doesn't give two hoots about the distinction between
hypercall not supported and subops not supported; they care about
whether Xen can perform the requested action or not.  ENOSYS is the more
common way of signalling this, and having only one errno value to check
is better for everyone involved.

~Andrew
Andrew Cooper April 21, 2022, 5:51 p.m. UTC | #5
On 20/04/2022 06:57, Juergen Gross wrote:
> Today iommu_do_domctl() is being called from arch_do_domctl() in the
> "default:" case of a switch statement. This has led already to crashes
> due to unvalidated parameters.
>
> Fix that by moving the call of iommu_do_domctl() to the main switch
> statement of do_domctl().
>
> Signed-off-by: Juergen Gross <jgross@suse.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Jan Beulich April 22, 2022, 7:09 a.m. UTC | #6
On 21.04.2022 19:47, Andrew Cooper wrote:
> On 20/04/2022 07:27, Jan Beulich wrote:
>> On 20.04.2022 08:22, Juergen Gross wrote:
>>> On 20.04.22 08:11, Jan Beulich wrote:
>>>> On 20.04.2022 07:57, Juergen Gross wrote:
>>>>> --- a/xen/include/xen/iommu.h
>>>>> +++ b/xen/include/xen/iommu.h
>>>>> @@ -341,8 +341,17 @@ struct domain_iommu {
>>>>>   /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
>>>>>   #ifdef CONFIG_HAS_PASSTHROUGH
>>>>>   #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
>>>>> +
>>>>> +int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>>>> +                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
>>>>>   #else
>>>>>   #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
>>>>> +
>>>>> +static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>>>> +                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>>>>> +{
>>>>> +    return -ENOSYS;
>>>>> +}
>>>> As said in reply to Andrew as well as in a number or earlier occasions,
>>>> I firmly think that this wants to be -EOPNOTSUPP, not -ENOSYS. Views
>>> In libxl there is an explicit check for ENOSYS being returned for
>>> assigning/deassigning a device, same in the xc python bindings.
>> Urgh.
> 
> Honestly, I wasn't particularly happy with your push to swap ENOSYS out
> for EOPNOTSUPP.  This shows plainly why it's a bad move.
> 
> An end user doesn't give two hoots about the distinction between
> hypercall not supported and subops not supported; they care about
> whether Xen can perform the requested action or not.  ENOSYS is the more
> common way of signalling this, and having only one errno value to check
> is better for everyone involved.

End users are of little interest here. Code looking for ENOSYS is what
is of interest, when the meaning of ENOSYS is quite well defined as
"system call not implemented" (which we merely extend to "hypercall").
Anything smaller scope than a major hypercall cannot possibly be
"hypercall not implemented". Code caring about knowing one vs the
other should not be misguided, and code looking for one when the other
is meant is simply flawed.

Jan
Andrew Cooper April 22, 2022, 7:01 p.m. UTC | #7
On 22/04/2022 08:09, Jan Beulich wrote:
> On 21.04.2022 19:47, Andrew Cooper wrote:
>> On 20/04/2022 07:27, Jan Beulich wrote:
>>> On 20.04.2022 08:22, Juergen Gross wrote:
>>>> On 20.04.22 08:11, Jan Beulich wrote:
>>>>> On 20.04.2022 07:57, Juergen Gross wrote:
>>>>>> --- a/xen/include/xen/iommu.h
>>>>>> +++ b/xen/include/xen/iommu.h
>>>>>> @@ -341,8 +341,17 @@ struct domain_iommu {
>>>>>>   /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
>>>>>>   #ifdef CONFIG_HAS_PASSTHROUGH
>>>>>>   #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
>>>>>> +
>>>>>> +int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>>>>> +                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
>>>>>>   #else
>>>>>>   #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
>>>>>> +
>>>>>> +static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>>>>> +                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>>>>>> +{
>>>>>> +    return -ENOSYS;
>>>>>> +}
>>>>> As said in reply to Andrew as well as in a number or earlier occasions,
>>>>> I firmly think that this wants to be -EOPNOTSUPP, not -ENOSYS. Views
>>>> In libxl there is an explicit check for ENOSYS being returned for
>>>> assigning/deassigning a device, same in the xc python bindings.
>>> Urgh.
>> Honestly, I wasn't particularly happy with your push to swap ENOSYS out
>> for EOPNOTSUPP.  This shows plainly why it's a bad move.
>>
>> An end user doesn't give two hoots about the distinction between
>> hypercall not supported and subops not supported; they care about
>> whether Xen can perform the requested action or not.  ENOSYS is the more
>> common way of signalling this, and having only one errno value to check
>> is better for everyone involved.
> End users are of little interest here. Code looking for ENOSYS is what
> is of interest, when the meaning of ENOSYS is quite well defined as
> "system call not implemented"

POSIX specifies it as "Functionality not supported" which is why other
compliment systems use it for smaller granularity than a system call.

~Andrew
Stefano Stabellini April 22, 2022, 11:41 p.m. UTC | #8
On Wed, 20 Apr 2022, Juergen Gross wrote:
> Today iommu_do_domctl() is being called from arch_do_domctl() in the
> "default:" case of a switch statement. This has led already to crashes
> due to unvalidated parameters.
> 
> Fix that by moving the call of iommu_do_domctl() to the main switch
> statement of do_domctl().
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>

For the ARM side:

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>


I have no opinion on the ENOSYS vs EOPNOTSUPP discussion.



> ---
> V3:
> - new patch
> V4:
> - add iommu_do_domctl() stub for !CONFIG_HAS_PASSTHROUGH (Andrew Cooper,
>   Jan Beulich)
> ---
>  xen/arch/arm/domctl.c   | 11 +----------
>  xen/arch/x86/domctl.c   |  2 +-
>  xen/common/domctl.c     |  7 +++++++
>  xen/include/xen/iommu.h | 12 +++++++++---
>  4 files changed, 18 insertions(+), 14 deletions(-)
> 
> diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
> index 6245af6d0b..1baf25c3d9 100644
> --- a/xen/arch/arm/domctl.c
> +++ b/xen/arch/arm/domctl.c
> @@ -176,16 +176,7 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
>          return rc;
>      }
>      default:
> -    {
> -        int rc;
> -
> -        rc = subarch_do_domctl(domctl, d, u_domctl);
> -
> -        if ( rc == -ENOSYS )
> -            rc = iommu_do_domctl(domctl, d, u_domctl);
> -
> -        return rc;
> -    }
> +        return subarch_do_domctl(domctl, d, u_domctl);
>      }
>  }
>  
> diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
> index a6aae500a3..c9699bb868 100644
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -1380,7 +1380,7 @@ long arch_do_domctl(
>          break;
>  
>      default:
> -        ret = iommu_do_domctl(domctl, d, u_domctl);
> +        ret = -ENOSYS;
>          break;
>      }
>  
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index 5879117580..0a866e3132 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -871,6 +871,13 @@ long cf_check do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>              copyback = 1;
>          break;
>  
> +    case XEN_DOMCTL_assign_device:
> +    case XEN_DOMCTL_test_assign_device:
> +    case XEN_DOMCTL_deassign_device:
> +    case XEN_DOMCTL_get_device_group:
> +        ret = iommu_do_domctl(op, d, u_domctl);
> +        break;
> +
>      default:
>          ret = arch_do_domctl(op, d, u_domctl);
>          break;
> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
> index 3a83981464..c6bbb65bbf 100644
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -341,8 +341,17 @@ struct domain_iommu {
>  /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
>  #ifdef CONFIG_HAS_PASSTHROUGH
>  #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
> +
> +int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
> +                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
>  #else
>  #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
> +
> +static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
> +                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
> +{
> +    return -ENOSYS;
> +}
>  #endif
>  
>  int __must_check iommu_suspend(void);
> @@ -356,9 +365,6 @@ int iommu_do_pci_domctl(struct xen_domctl *, struct domain *d,
>                          XEN_GUEST_HANDLE_PARAM(xen_domctl_t));
>  #endif
>  
> -int iommu_do_domctl(struct xen_domctl *, struct domain *d,
> -                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t));
> -
>  void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev);
>  
>  /*
> -- 
> 2.34.1
>
Jürgen Groß April 23, 2022, 5:55 a.m. UTC | #9
On 22.04.22 21:01, Andrew Cooper wrote:
> On 22/04/2022 08:09, Jan Beulich wrote:
>> On 21.04.2022 19:47, Andrew Cooper wrote:
>>> On 20/04/2022 07:27, Jan Beulich wrote:
>>>> On 20.04.2022 08:22, Juergen Gross wrote:
>>>>> On 20.04.22 08:11, Jan Beulich wrote:
>>>>>> On 20.04.2022 07:57, Juergen Gross wrote:
>>>>>>> --- a/xen/include/xen/iommu.h
>>>>>>> +++ b/xen/include/xen/iommu.h
>>>>>>> @@ -341,8 +341,17 @@ struct domain_iommu {
>>>>>>>    /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
>>>>>>>    #ifdef CONFIG_HAS_PASSTHROUGH
>>>>>>>    #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
>>>>>>> +
>>>>>>> +int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>>>>>> +                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
>>>>>>>    #else
>>>>>>>    #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
>>>>>>> +
>>>>>>> +static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
>>>>>>> +                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>>>>>>> +{
>>>>>>> +    return -ENOSYS;
>>>>>>> +}
>>>>>> As said in reply to Andrew as well as in a number or earlier occasions,
>>>>>> I firmly think that this wants to be -EOPNOTSUPP, not -ENOSYS. Views
>>>>> In libxl there is an explicit check for ENOSYS being returned for
>>>>> assigning/deassigning a device, same in the xc python bindings.
>>>> Urgh.
>>> Honestly, I wasn't particularly happy with your push to swap ENOSYS out
>>> for EOPNOTSUPP.  This shows plainly why it's a bad move.
>>>
>>> An end user doesn't give two hoots about the distinction between
>>> hypercall not supported and subops not supported; they care about
>>> whether Xen can perform the requested action or not.  ENOSYS is the more
>>> common way of signalling this, and having only one errno value to check
>>> is better for everyone involved.
>> End users are of little interest here. Code looking for ENOSYS is what
>> is of interest, when the meaning of ENOSYS is quite well defined as
>> "system call not implemented"
> 
> POSIX specifies it as "Functionality not supported" which is why other
> compliment systems use it for smaller granularity than a system call.

Thinking a little bit more about this topic, I'd like to return ENOSYS.

EOPNOTSUPP should be returned in case an operation is not suitable
for the given parameter combination (e.g. an IOMMU related operation
for a guest not being subject to IOMMU handling). The same operation
can be successful on the given system with other parameter combinations.

ENOSYS should be returned if the current hypervisor doesn't support the
requested operation (hypercall or hypercall + sub-op) on the given system
at all. The high level caller (e.g. a user of libxc) doesn't care, whether
a requested operation is a dedicated hypercall or a sub-op of a hypercall.
The only interesting aspect is whether the operation is unavailable, or
just failing due to the current situation.


Juergen
diff mbox series

Patch

diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index 6245af6d0b..1baf25c3d9 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -176,16 +176,7 @@  long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
         return rc;
     }
     default:
-    {
-        int rc;
-
-        rc = subarch_do_domctl(domctl, d, u_domctl);
-
-        if ( rc == -ENOSYS )
-            rc = iommu_do_domctl(domctl, d, u_domctl);
-
-        return rc;
-    }
+        return subarch_do_domctl(domctl, d, u_domctl);
     }
 }
 
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index a6aae500a3..c9699bb868 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1380,7 +1380,7 @@  long arch_do_domctl(
         break;
 
     default:
-        ret = iommu_do_domctl(domctl, d, u_domctl);
+        ret = -ENOSYS;
         break;
     }
 
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 5879117580..0a866e3132 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -871,6 +871,13 @@  long cf_check do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             copyback = 1;
         break;
 
+    case XEN_DOMCTL_assign_device:
+    case XEN_DOMCTL_test_assign_device:
+    case XEN_DOMCTL_deassign_device:
+    case XEN_DOMCTL_get_device_group:
+        ret = iommu_do_domctl(op, d, u_domctl);
+        break;
+
     default:
         ret = arch_do_domctl(op, d, u_domctl);
         break;
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index 3a83981464..c6bbb65bbf 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -341,8 +341,17 @@  struct domain_iommu {
 /* Does the IOMMU pagetable need to be kept synchronized with the P2M */
 #ifdef CONFIG_HAS_PASSTHROUGH
 #define need_iommu_pt_sync(d)     (dom_iommu(d)->need_sync)
+
+int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
+                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
 #else
 #define need_iommu_pt_sync(d)     ({ (void)(d); false; })
+
+static inline int iommu_do_domctl(struct xen_domctl *domctl, struct domain *d,
+                                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
+{
+    return -ENOSYS;
+}
 #endif
 
 int __must_check iommu_suspend(void);
@@ -356,9 +365,6 @@  int iommu_do_pci_domctl(struct xen_domctl *, struct domain *d,
                         XEN_GUEST_HANDLE_PARAM(xen_domctl_t));
 #endif
 
-int iommu_do_domctl(struct xen_domctl *, struct domain *d,
-                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t));
-
 void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev);
 
 /*