[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 |