|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4/6] xen/hypercall: Cope with -ERESTART on more hypercall paths
These hypercalls each use continue_hypercall_on_cpu(), whose API is about to
switch to use -ERESTART. Update the soon-to-be affected paths to cope,
folding existing contination logic where applicable.
In addition:
* For platform op and sysctl, insert a cpu_relax() into what is otherwise a
tight spinlock loop, and make the continuation logic common at the
epilogue.
* Contrary to the comment in the code, kexec_exec() does return in the
KEXEC_REBOOT case, needs to pass ret back to the caller.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Julien Grall <julien@xxxxxxx>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
---
xen/arch/x86/platform_hypercall.c | 14 ++++++++++++--
xen/common/compat/domain.c | 9 ++++-----
xen/common/domain.c | 8 ++++----
xen/common/kexec.c | 20 ++++++++++++++++----
xen/common/sysctl.c | 13 +++++++++++--
5 files changed, 47 insertions(+), 17 deletions(-)
diff --git a/xen/arch/x86/platform_hypercall.c
b/xen/arch/x86/platform_hypercall.c
index b19f6ec4ed..c0c209baac 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -201,9 +201,12 @@ ret_t
do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
* with this vcpu.
*/
while ( !spin_trylock(&xenpf_lock) )
+ {
+ cpu_relax();
+
if ( hypercall_preempt_check() )
- return hypercall_create_continuation(
- __HYPERVISOR_platform_op, "h", u_xenpf_op);
+ goto create_continuation;
+ }
switch ( op->cmd )
{
@@ -816,6 +819,13 @@ ret_t
do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
out:
spin_unlock(&xenpf_lock);
+ if ( ret == -ERESTART )
+ {
+ create_continuation:
+ ret = hypercall_create_continuation(__HYPERVISOR_platform_op,
+ "h", u_xenpf_op);
+ }
+
return ret;
}
diff --git a/xen/common/compat/domain.c b/xen/common/compat/domain.c
index 11c6afc463..1a14403672 100644
--- a/xen/common/compat/domain.c
+++ b/xen/common/compat/domain.c
@@ -79,11 +79,6 @@ int compat_vcpu_op(int cmd, unsigned int vcpuid,
XEN_GUEST_HANDLE_PARAM(void) ar
xfree(ctxt);
}
-
- if ( rc == -ERESTART )
- rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
- cmd, vcpuid, arg);
-
break;
}
@@ -130,6 +125,10 @@ int compat_vcpu_op(int cmd, unsigned int vcpuid,
XEN_GUEST_HANDLE_PARAM(void) ar
break;
}
+ if ( rc == -ERESTART )
+ rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
+ cmd, vcpuid, arg);
+
return rc;
}
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 865a1cb9d7..ab7e4d09c0 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -1422,10 +1422,6 @@ long do_vcpu_op(int cmd, unsigned int vcpuid,
XEN_GUEST_HANDLE_PARAM(void) arg)
return -EINVAL;
rc = arch_initialise_vcpu(v, arg);
- if ( rc == -ERESTART )
- rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
- cmd, vcpuid, arg);
-
break;
case VCPUOP_up:
@@ -1598,6 +1594,10 @@ long do_vcpu_op(int cmd, unsigned int vcpuid,
XEN_GUEST_HANDLE_PARAM(void) arg)
break;
}
+ if ( rc == -ERESTART )
+ rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
+ cmd, vcpuid, arg);
+
return rc;
}
diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index a262cc5a18..2fca75cec0 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -842,7 +842,7 @@ static int kexec_exec(XEN_GUEST_HANDLE_PARAM(void) uarg)
break;
}
- return -EINVAL; /* never reached */
+ return ret;
}
static int kexec_swap_images(int type, struct kexec_image *new,
@@ -1220,7 +1220,7 @@ static int do_kexec_op_internal(unsigned long op,
return ret;
if ( test_and_set_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags) )
- return hypercall_create_continuation(__HYPERVISOR_kexec_op, "lh", op,
uarg);
+ return -ERESTART;
switch ( op )
{
@@ -1263,13 +1263,25 @@ static int do_kexec_op_internal(unsigned long op,
long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) uarg)
{
- return do_kexec_op_internal(op, uarg, 0);
+ int ret = do_kexec_op_internal(op, uarg, 0);
+
+ if ( ret == -ERESTART )
+ ret = hypercall_create_continuation(__HYPERVISOR_kexec_op,
+ "lh", op, uarg);
+
+ return ret;
}
#ifdef CONFIG_COMPAT
int compat_kexec_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) uarg)
{
- return do_kexec_op_internal(op, uarg, 1);
+ int ret = do_kexec_op_internal(op, uarg, 1);
+
+ if ( ret == -ERESTART )
+ ret = hypercall_create_continuation(__HYPERVISOR_kexec_op,
+ "lh", op, uarg);
+
+ return ret;
}
#endif
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index f88a285e7f..7b55047bb9 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -51,9 +51,12 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
* with this vcpu.
*/
while ( !spin_trylock(&sysctl_lock) )
+ {
+ cpu_relax();
+
if ( hypercall_preempt_check() )
- return hypercall_create_continuation(
- __HYPERVISOR_sysctl, "h", u_sysctl);
+ goto create_continuation;
+ }
switch ( op->cmd )
{
@@ -516,6 +519,12 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t)
u_sysctl)
__copy_to_guest(u_sysctl, op, 1) )
ret = -EFAULT;
+ if ( ret == -ERESTART )
+ {
+ create_continuation:
+ ret = hypercall_create_continuation(__HYPERVISOR_sysctl, "h",
u_sysctl);
+ }
+
return ret;
}
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |