File libxc.do_domctl.EFAULT-retry.patch of Package xen.26345

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)
 {
openSUSE Build Service is sponsored by