Message ID | 1479161573-12671-2-git-send-email-konrad.wilk@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Nov 14, 2016 at 05:12:52PM -0500, Konrad Rzeszutek Wilk wrote: > The tools that use kexec are asynchronous in nature and do > not keep state changes. As such provide an hypercall to find > out whether an image has been loaded for either type. > > Note: No need to modify XSM as it has one size fits all > check and does not check for subcommands. > > Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> > --- > v0: Internal version. > v1: Dropped Reviewed-by, posting on xen-devel. > > CC: Elena Ufimtseva <elena.ufimtseva@oracle.com> > CC: Daniel Kiper <daniel.kiper@oracle.com> > --- > tools/libxc/include/xenctrl.h | 8 ++++++++ > tools/libxc/xc_kexec.c | 27 +++++++++++++++++++++++++++ > xen/common/kexec.c | 25 +++++++++++++++++++++++++ > xen/include/public/kexec.h | 11 +++++++++++ > 4 files changed, 71 insertions(+) > > diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h > index 2c83544..aa5d798 100644 > --- a/tools/libxc/include/xenctrl.h > +++ b/tools/libxc/include/xenctrl.h > @@ -2574,6 +2574,14 @@ int xc_kexec_load(xc_interface *xch, uint8_t type, uint16_t arch, > */ > int xc_kexec_unload(xc_interface *xch, int type); > > +/* > + * Find out whether the image has been succesfully loaded. > + * > + * The can be either KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH. > + * If zero is returned that means the image is loaded for the type. > + */ > +int xc_kexec_status(xc_interface *xch, int type); > + > typedef xenpf_resource_entry_t xc_resource_entry_t; > > /* > diff --git a/tools/libxc/xc_kexec.c b/tools/libxc/xc_kexec.c > index 1cceb5d..95d36ff 100644 > --- a/tools/libxc/xc_kexec.c > +++ b/tools/libxc/xc_kexec.c > @@ -126,3 +126,30 @@ out: > > return ret; > } > + > +int xc_kexec_status(xc_interface *xch, int type) > +{ > + DECLARE_HYPERCALL; > + DECLARE_HYPERCALL_BUFFER(xen_kexec_status_t, status); > + int ret = -1; > + > + status = xc_hypercall_buffer_alloc(xch, status, sizeof(*status)); > + if ( status == NULL ) > + { > + PERROR("Count not alloc buffer for kexec status hypercall"); Could not? It looks that you copied this from existing code. Could you send separate patch fixing this issue in two other places too? > + goto out; > + } > + > + status->type = type; > + > + hypercall.op = __HYPERVISOR_kexec_op; > + hypercall.arg[0] = KEXEC_CMD_kexec_status; > + hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(status); > + > + ret = do_xen_hypercall(xch, &hypercall); > + > +out: > + xc_hypercall_buffer_free(xch, status); > + > + return ret; > +} > diff --git a/xen/common/kexec.c b/xen/common/kexec.c > index c83d48f..1148f85 100644 > --- a/xen/common/kexec.c > +++ b/xen/common/kexec.c > @@ -1169,6 +1169,28 @@ static int kexec_unload(XEN_GUEST_HANDLE_PARAM(void) uarg) > return kexec_do_unload(&unload); > } > > +static int kexec_status(XEN_GUEST_HANDLE_PARAM(void) uarg) > +{ > + xen_kexec_status_t status; > + int base, bit, pos; > + > + if ( unlikely(copy_from_guest(&status, uarg, 1)) ) > + return -EFAULT; > + > + if ( test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags) ) > + return -EBUSY; > + > + if ( kexec_load_get_bits(status.type, &base, &bit) ) > + return -EINVAL; > + > + pos = (test_bit(bit, &kexec_flags) != 0); > + > + if ( !test_bit(base + pos, &kexec_flags) ) > + return -ENOENT; > + > + return 0; > +} > + > static int do_kexec_op_internal(unsigned long op, > XEN_GUEST_HANDLE_PARAM(void) uarg, > bool_t compat) > @@ -1208,6 +1230,9 @@ static int do_kexec_op_internal(unsigned long op, > case KEXEC_CMD_kexec_unload: > ret = kexec_unload(uarg); > break; > + case KEXEC_CMD_kexec_status: > + ret = kexec_status(uarg); > + break; > } > > return ret; > diff --git a/xen/include/public/kexec.h b/xen/include/public/kexec.h > index a6a0a88..29dcb5d 100644 > --- a/xen/include/public/kexec.h > +++ b/xen/include/public/kexec.h > @@ -227,6 +227,17 @@ typedef struct xen_kexec_unload { > } xen_kexec_unload_t; > DEFINE_XEN_GUEST_HANDLE(xen_kexec_unload_t); > > +/* > + * Figure out whether we have an image loaded. An return value of > + * zero indicates success while XEN_ENODEV implies no image loaded. It seems to me that you thought about -ENOENT instead of XEN_ENODEV. If you fix both things then Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> Daniel
On 14/11/16 22:12, Konrad Rzeszutek Wilk wrote: > The tools that use kexec are asynchronous in nature and do > not keep state changes. As such provide an hypercall to find > out whether an image has been loaded for either type. > > Note: No need to modify XSM as it has one size fits all > check and does not check for subcommands. [...] > --- a/tools/libxc/include/xenctrl.h > +++ b/tools/libxc/include/xenctrl.h > @@ -2574,6 +2574,14 @@ int xc_kexec_load(xc_interface *xch, uint8_t type, uint16_t arch, > */ > int xc_kexec_unload(xc_interface *xch, int type); > > +/* > + * Find out whether the image has been succesfully loaded. > + * > + * The can be either KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH. > + * If zero is returned that means the image is loaded for the type. Suggest return 0 if an image is not loaded, 1 if an image is loaded, but I'll leave this for the toolstack maintainers to decide. > --- a/xen/common/kexec.c > +++ b/xen/common/kexec.c > @@ -1169,6 +1169,28 @@ static int kexec_unload(XEN_GUEST_HANDLE_PARAM(void) uarg) > return kexec_do_unload(&unload); > } > > +static int kexec_status(XEN_GUEST_HANDLE_PARAM(void) uarg) > +{ > + xen_kexec_status_t status; > + int base, bit, pos; > + > + if ( unlikely(copy_from_guest(&status, uarg, 1)) ) > + return -EFAULT; > + > + if ( test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags) ) > + return -EBUSY; No need to check in progress here. > + > + if ( kexec_load_get_bits(status.type, &base, &bit) ) > + return -EINVAL; > + > + pos = (test_bit(bit, &kexec_flags) != 0); > + > + if ( !test_bit(base + pos, &kexec_flags) ) > + return -ENOENT; return !!test_bit(...); It also occurs to be that this testing of bits races with kexec_swap_image(). This race also affects kexec_exec(). > static int do_kexec_op_internal(unsigned long op, > XEN_GUEST_HANDLE_PARAM(void) uarg, > bool_t compat) > @@ -1208,6 +1230,9 @@ static int do_kexec_op_internal(unsigned long op, > case KEXEC_CMD_kexec_unload: > ret = kexec_unload(uarg); > break; > + case KEXEC_CMD_kexec_status: > + ret = kexec_status(uarg); > + break; Tabs! > --- a/xen/include/public/kexec.h > +++ b/xen/include/public/kexec.h > @@ -227,6 +227,17 @@ typedef struct xen_kexec_unload { > } xen_kexec_unload_t; > DEFINE_XEN_GUEST_HANDLE(xen_kexec_unload_t); > > +/* > + * Figure out whether we have an image loaded. An return value of > + * zero indicates success while XEN_ENODEV implies no image loaded. > + * > + * Type must be one of KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH. Return 0 if no image is loaded. 1 if an image is loaded and -ve on an error. David
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 2c83544..aa5d798 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -2574,6 +2574,14 @@ int xc_kexec_load(xc_interface *xch, uint8_t type, uint16_t arch, */ int xc_kexec_unload(xc_interface *xch, int type); +/* + * Find out whether the image has been succesfully loaded. + * + * The can be either KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH. + * If zero is returned that means the image is loaded for the type. + */ +int xc_kexec_status(xc_interface *xch, int type); + typedef xenpf_resource_entry_t xc_resource_entry_t; /* diff --git a/tools/libxc/xc_kexec.c b/tools/libxc/xc_kexec.c index 1cceb5d..95d36ff 100644 --- a/tools/libxc/xc_kexec.c +++ b/tools/libxc/xc_kexec.c @@ -126,3 +126,30 @@ out: return ret; } + +int xc_kexec_status(xc_interface *xch, int type) +{ + DECLARE_HYPERCALL; + DECLARE_HYPERCALL_BUFFER(xen_kexec_status_t, status); + int ret = -1; + + status = xc_hypercall_buffer_alloc(xch, status, sizeof(*status)); + if ( status == NULL ) + { + PERROR("Count not alloc buffer for kexec status hypercall"); + goto out; + } + + status->type = type; + + hypercall.op = __HYPERVISOR_kexec_op; + hypercall.arg[0] = KEXEC_CMD_kexec_status; + hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(status); + + ret = do_xen_hypercall(xch, &hypercall); + +out: + xc_hypercall_buffer_free(xch, status); + + return ret; +} diff --git a/xen/common/kexec.c b/xen/common/kexec.c index c83d48f..1148f85 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -1169,6 +1169,28 @@ static int kexec_unload(XEN_GUEST_HANDLE_PARAM(void) uarg) return kexec_do_unload(&unload); } +static int kexec_status(XEN_GUEST_HANDLE_PARAM(void) uarg) +{ + xen_kexec_status_t status; + int base, bit, pos; + + if ( unlikely(copy_from_guest(&status, uarg, 1)) ) + return -EFAULT; + + if ( test_bit(KEXEC_FLAG_IN_PROGRESS, &kexec_flags) ) + return -EBUSY; + + if ( kexec_load_get_bits(status.type, &base, &bit) ) + return -EINVAL; + + pos = (test_bit(bit, &kexec_flags) != 0); + + if ( !test_bit(base + pos, &kexec_flags) ) + return -ENOENT; + + return 0; +} + static int do_kexec_op_internal(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) uarg, bool_t compat) @@ -1208,6 +1230,9 @@ static int do_kexec_op_internal(unsigned long op, case KEXEC_CMD_kexec_unload: ret = kexec_unload(uarg); break; + case KEXEC_CMD_kexec_status: + ret = kexec_status(uarg); + break; } return ret; diff --git a/xen/include/public/kexec.h b/xen/include/public/kexec.h index a6a0a88..29dcb5d 100644 --- a/xen/include/public/kexec.h +++ b/xen/include/public/kexec.h @@ -227,6 +227,17 @@ typedef struct xen_kexec_unload { } xen_kexec_unload_t; DEFINE_XEN_GUEST_HANDLE(xen_kexec_unload_t); +/* + * Figure out whether we have an image loaded. An return value of + * zero indicates success while XEN_ENODEV implies no image loaded. + * + * Type must be one of KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH. + */ +#define KEXEC_CMD_kexec_status 6 +typedef struct xen_kexec_status { + uint8_t type; +} xen_kexec_status_t; +DEFINE_XEN_GUEST_HANDLE(xen_kexec_status_t); #else /* __XEN_INTERFACE_VERSION__ < 0x00040400 */ #define KEXEC_CMD_kexec_load KEXEC_CMD_kexec_load_v1
The tools that use kexec are asynchronous in nature and do not keep state changes. As such provide an hypercall to find out whether an image has been loaded for either type. Note: No need to modify XSM as it has one size fits all check and does not check for subcommands. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> --- v0: Internal version. v1: Dropped Reviewed-by, posting on xen-devel. CC: Elena Ufimtseva <elena.ufimtseva@oracle.com> CC: Daniel Kiper <daniel.kiper@oracle.com> --- tools/libxc/include/xenctrl.h | 8 ++++++++ tools/libxc/xc_kexec.c | 27 +++++++++++++++++++++++++++ xen/common/kexec.c | 25 +++++++++++++++++++++++++ xen/include/public/kexec.h | 11 +++++++++++ 4 files changed, 71 insertions(+)