File libxc.do_domctl.EFAULT-retry.patch of Package xen.19016
based on commit 988d66cb78c35c620c2a0eb01bac842e4e99bf0e
tools/libxc: retry hypercall in case of EFAULT
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -224,7 +224,7 @@ int xc_get_pfn_type_batch(xc_interface *
domctl.domain = dom;
domctl.u.getpageframeinfo3.num = num;
set_xen_guest_handle(domctl.u.getpageframeinfo3.array, arr);
- rc = do_domctl(xch, &domctl);
+ rc = do_domctl_retry(xch, &domctl, 3);
xc_hypercall_bounce_post(xch, arr);
return rc;
}
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -262,9 +262,10 @@ out1:
return ret;
}
-static inline int do_domctl(xc_interface *xch, struct xen_domctl *domctl)
+static inline int do_domctl_retry_efault(xc_interface *xch, struct xen_domctl *domctl, unsigned int retries)
{
int ret = -1;
+ unsigned int retry_cnt = 0;
DECLARE_HYPERCALL_BOUNCE(domctl, sizeof(*domctl), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION;
@@ -275,8 +276,12 @@ static inline int do_domctl(xc_interface
goto out1;
}
+ do {
ret = xencall1(xch->xcall, __HYPERVISOR_domctl,
HYPERCALL_BUFFER_AS_ARG(domctl));
+ if ( ret < 0 && errno == EFAULT && retries )
+ PERROR("domctl failed during attempt %u/%u", retry_cnt + 1, retries + 1);
+ } while ( ret < 0 && errno == EFAULT && retry_cnt++ < retries);
if ( ret < 0 )
{
if ( errno == EACCES )
@@ -288,6 +293,15 @@ static inline int do_domctl(xc_interface
out1:
return ret;
}
+static inline int do_domctl(xc_interface *xch, struct xen_domctl *domctl)
+{
+ return do_domctl_retry_efault(xch, domctl, 0);
+}
+
+static inline int do_domctl_retry(xc_interface *xch, struct xen_domctl *domctl, unsigned int n)
+{
+ return do_domctl_retry_efault(xch, domctl, n);
+}
static inline int do_sysctl(xc_interface *xch, struct xen_sysctl *sysctl)
{