[Xen-devel] [replace tabs with spaces] convert tabs into spaces; preserving indentation

2017-01-09 Thread Eric DeVolder
Convert tabs into spaces; preserving indentation

No functional changes

Signed-off-by: Eric DeVolder 

---
 tools/libxc/xc_kexec.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tools/libxc/xc_kexec.c b/tools/libxc/xc_kexec.c
index 989e225192..59e2f076f4 100644
--- a/tools/libxc/xc_kexec.c
+++ b/tools/libxc/xc_kexec.c
@@ -27,8 +27,8 @@ int xc_kexec_exec(xc_interface *xch, int type)
 exec->type = type;
 
 ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
-  KEXEC_CMD_kexec,
-  HYPERCALL_BUFFER_AS_ARG(exec));
+   KEXEC_CMD_kexec,
+   HYPERCALL_BUFFER_AS_ARG(exec));
 
 out:
 xc_hypercall_buffer_free(xch, exec);
@@ -53,8 +53,8 @@ int xc_kexec_get_range(xc_interface *xch, int range,  int nr,
 get_range->nr = nr;
 
 ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
-  KEXEC_CMD_kexec_get_range,
-  HYPERCALL_BUFFER_AS_ARG(get_range));
+   KEXEC_CMD_kexec_get_range,
+   HYPERCALL_BUFFER_AS_ARG(get_range));
 
 *size = get_range->size;
 *start = get_range->start;
@@ -93,8 +93,8 @@ int xc_kexec_load(xc_interface *xch, uint8_t type, uint16_t 
arch,
 set_xen_guest_handle(load->segments.h, segments);
 
 ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
-  KEXEC_CMD_kexec_load,
-  HYPERCALL_BUFFER_AS_ARG(load));
+   KEXEC_CMD_kexec_load,
+   HYPERCALL_BUFFER_AS_ARG(load));
 
 out:
 xc_hypercall_buffer_free(xch, load);
@@ -118,8 +118,8 @@ int xc_kexec_unload(xc_interface *xch, int type)
 unload->type = type;
 
 ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
-  KEXEC_CMD_kexec_unload,
-  HYPERCALL_BUFFER_AS_ARG(unload));
+   KEXEC_CMD_kexec_unload,
+   HYPERCALL_BUFFER_AS_ARG(unload));
 
 out:
 xc_hypercall_buffer_free(xch, unload);
-- 
2.11.0


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] convert tabs into spaces; preserving indentation

2017-01-09 Thread Eric DeVolder
Convert tabs into spaces; preserving indentation

No functional changes

Signed-off-by: Eric DeVolder 

---
 tools/libxc/xc_kexec.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tools/libxc/xc_kexec.c b/tools/libxc/xc_kexec.c
index 989e225192..59e2f076f4 100644
--- a/tools/libxc/xc_kexec.c
+++ b/tools/libxc/xc_kexec.c
@@ -27,8 +27,8 @@ int xc_kexec_exec(xc_interface *xch, int type)
 exec->type = type;
 
 ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
-  KEXEC_CMD_kexec,
-  HYPERCALL_BUFFER_AS_ARG(exec));
+   KEXEC_CMD_kexec,
+   HYPERCALL_BUFFER_AS_ARG(exec));
 
 out:
 xc_hypercall_buffer_free(xch, exec);
@@ -53,8 +53,8 @@ int xc_kexec_get_range(xc_interface *xch, int range,  int nr,
 get_range->nr = nr;
 
 ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
-  KEXEC_CMD_kexec_get_range,
-  HYPERCALL_BUFFER_AS_ARG(get_range));
+   KEXEC_CMD_kexec_get_range,
+   HYPERCALL_BUFFER_AS_ARG(get_range));
 
 *size = get_range->size;
 *start = get_range->start;
@@ -93,8 +93,8 @@ int xc_kexec_load(xc_interface *xch, uint8_t type, uint16_t 
arch,
 set_xen_guest_handle(load->segments.h, segments);
 
 ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
-  KEXEC_CMD_kexec_load,
-  HYPERCALL_BUFFER_AS_ARG(load));
+   KEXEC_CMD_kexec_load,
+   HYPERCALL_BUFFER_AS_ARG(load));
 
 out:
 xc_hypercall_buffer_free(xch, load);
@@ -118,8 +118,8 @@ int xc_kexec_unload(xc_interface *xch, int type)
 unload->type = type;
 
 ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
-  KEXEC_CMD_kexec_unload,
-  HYPERCALL_BUFFER_AS_ARG(unload));
+   KEXEC_CMD_kexec_unload,
+   HYPERCALL_BUFFER_AS_ARG(unload));
 
 out:
 xc_hypercall_buffer_free(xch, unload);
-- 
2.11.0


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2] kexec: implement STATUS hypercall to check if image is loaded

2017-01-12 Thread Eric DeVolder
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.

Note: No need to check KEXEC_FLAG_IN_PROGRESS (and error out of
kexec_status()) as this flag is set only once by the first/only
cpu on the crash path.

Note: The __XEN_LATEST_INTERFACE_VERSION__ has been bumped to
0x00040900 due to the introduction of a new hypervisor call.

Note: This is just the Xen side of the hypercall, kexec-tools patch
to come separately.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
Reviewed-by: Daniel Kiper 
---
CC: Elena Ufimtseva 
CC: Daniel Kiper 

v0: Internal version.
v1: Dropped Reviewed-by, posting on xen-devel.
v2: Incorporated xen-devel feedback
---
 tools/libxc/include/xenctrl.h   | 10 ++
 tools/libxc/xc_kexec.c  | 24 
 xen/common/kexec.c  | 19 +++
 xen/include/public/kexec.h  | 13 +
 xen/include/public/xen-compat.h |  2 +-
 5 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 4ab0f57117..63c616ff6a 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2574,6 +2574,16 @@ 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 type can be either KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH.
+ * If zero is returned, that means no image is loaded for the type.
+ * If one is returned, that means an image is loaded for the type.
+ * Otherwise, negative return value indicates error.
+ */
+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 989e225192..a0a9fd3841 100644
--- a/tools/libxc/xc_kexec.c
+++ b/tools/libxc/xc_kexec.c
@@ -126,3 +126,27 @@ out:
 
 return ret;
 }
+
+int xc_kexec_status(xc_interface *xch, int type)
+{
+DECLARE_HYPERCALL_BUFFER(xen_kexec_status_t, status);
+int ret = -1;
+
+status = xc_hypercall_buffer_alloc(xch, status, sizeof(*status));
+if ( status == NULL )
+{
+PERROR("Could not alloc buffer for kexec status hypercall");
+goto out;
+}
+
+status->type = type;
+
+ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
+   KEXEC_CMD_kexec_status,
+   HYPERCALL_BUFFER_AS_ARG(status));
+
+out:
+xc_hypercall_buffer_free(xch, status);
+
+return ret;
+}
diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index c83d48fc79..aa808cb2f2 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -1169,6 +1169,22 @@ 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;
+
+if ( unlikely(copy_from_guest(&status, uarg, 1)) )
+return -EFAULT;
+
+/* No need to check KEXEC_FLAG_IN_PROGRESS. */
+
+if ( kexec_load_get_bits(status.type, &base, &bit) )
+return -EINVAL;
+
+return test_bit(bit, &kexec_flags);
+}
+
 static int do_kexec_op_internal(unsigned long op,
 XEN_GUEST_HANDLE_PARAM(void) uarg,
 bool_t compat)
@@ -1208,6 +1224,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 a6a0a88f4f..c200e8ceee 100644
--- a/xen/include/public/kexec.h
+++ b/xen/include/public/kexec.h
@@ -227,6 +227,19 @@ 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. A return value of
+ * zero indicates no image loaded. A return value of one
+ * indicates an image is loaded. A negative return value
+ * indicates an error.
+ *
+ * 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
diff --git a/xen/include/public/xen-compat.h b/xen/include/public/xen-compat.h
index dd8a5c0d0e..b67365340b 100644
--- a/xen/include/public/xen-compat.h
+++ b/xen/include/public/xen-compat.h
@@ -27,7 +27,7 @@
 #ifndef __XEN_PUBLIC_XEN_COMPAT_H__
 #define

[Xen-devel] [PATCH v3] kexec: implement STATUS hypercall to check if image is loaded

2017-01-17 Thread Eric DeVolder
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.

Note: No need to check KEXEC_FLAG_IN_PROGRESS (and error out of
kexec_status()) as this flag is set only once by the first/only
cpu on the crash path.

Note: This is just the Xen side of the hypercall, kexec-tools patch
to come separately.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
---
CC: Andrew Cooper 
CC: Elena Ufimtseva 
CC: Daniel Kiper 

v0: Internal version.
v1: Dropped Reviewed-by, posting on xen-devel.
v2: Incorporated xen-devel feedback, re-posted on xen-devel.
v3: Incorporated xen-devel feedback
---
 tools/libxc/include/xenctrl.h | 10 ++
 tools/libxc/xc_kexec.c| 24 
 xen/common/kexec.c| 19 +++
 xen/include/public/kexec.h| 13 +
 4 files changed, 66 insertions(+)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 4ab0f57..63c616f 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2574,6 +2574,16 @@ 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 type can be either KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH.
+ * If zero is returned, that means no image is loaded for the type.
+ * If one is returned, that means an image is loaded for the type.
+ * Otherwise, negative return value indicates error.
+ */
+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 59e2f07..a4e8966 100644
--- a/tools/libxc/xc_kexec.c
+++ b/tools/libxc/xc_kexec.c
@@ -126,3 +126,27 @@ out:
 
 return ret;
 }
+
+int xc_kexec_status(xc_interface *xch, int type)
+{
+DECLARE_HYPERCALL_BUFFER(xen_kexec_status_t, status);
+int ret = -1;
+
+status = xc_hypercall_buffer_alloc(xch, status, sizeof(*status));
+if ( status == NULL )
+{
+PERROR("Could not alloc buffer for kexec status hypercall");
+goto out;
+}
+
+status->type = type;
+
+ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
+   KEXEC_CMD_kexec_status,
+   HYPERCALL_BUFFER_AS_ARG(status));
+
+out:
+xc_hypercall_buffer_free(xch, status);
+
+return ret;
+}
diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index c83d48f..aa808cb 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -1169,6 +1169,22 @@ 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;
+
+if ( unlikely(copy_from_guest(&status, uarg, 1)) )
+return -EFAULT;
+
+/* No need to check KEXEC_FLAG_IN_PROGRESS. */
+
+if ( kexec_load_get_bits(status.type, &base, &bit) )
+return -EINVAL;
+
+return test_bit(bit, &kexec_flags);
+}
+
 static int do_kexec_op_internal(unsigned long op,
 XEN_GUEST_HANDLE_PARAM(void) uarg,
 bool_t compat)
@@ -1208,6 +1224,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..c200e8c 100644
--- a/xen/include/public/kexec.h
+++ b/xen/include/public/kexec.h
@@ -227,6 +227,19 @@ 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. A return value of
+ * zero indicates no image loaded. A return value of one
+ * indicates an image is loaded. A negative return value
+ * indicates an error.
+ *
+ * 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
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v4] kexec: implement STATUS hypercall to check if image is loaded

2017-01-18 Thread Eric DeVolder
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.

Note: No need to check KEXEC_FLAG_IN_PROGRESS (and error out of
kexec_status()) as this flag is set only once by the first/only
cpu on the crash path.

Note: In kexec_status(), the use of test_bit() can also return
EPERM, so the return value from test_bit() must be checked to
ensure that kexec_status() always returns 0, 1 or -1, per the
public header description.

Note: This is just the Xen side of the hypercall, kexec-tools patch
to come separately.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
---
CC: Andrew Cooper 
CC: Elena Ufimtseva 
CC: Daniel Kiper 

v0: Internal version.
v1: Dropped Reviewed-by, posting on xen-devel.
v2: Incorporated xen-devel feedback, re-posted on xen-devel.
v3: Incorporated xen-devel feedback, re-posted on xen-devel.
v4: Incorporated xen-devel feedback
---
 tools/libxc/include/xenctrl.h | 10 ++
 tools/libxc/xc_kexec.c| 24 
 xen/common/kexec.c| 19 +++
 xen/include/public/kexec.h| 14 ++
 4 files changed, 67 insertions(+)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 4ab0f57..63c616f 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2574,6 +2574,16 @@ 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 type can be either KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH.
+ * If zero is returned, that means no image is loaded for the type.
+ * If one is returned, that means an image is loaded for the type.
+ * Otherwise, negative return value indicates error.
+ */
+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 59e2f07..a4e8966 100644
--- a/tools/libxc/xc_kexec.c
+++ b/tools/libxc/xc_kexec.c
@@ -126,3 +126,27 @@ out:
 
 return ret;
 }
+
+int xc_kexec_status(xc_interface *xch, int type)
+{
+DECLARE_HYPERCALL_BUFFER(xen_kexec_status_t, status);
+int ret = -1;
+
+status = xc_hypercall_buffer_alloc(xch, status, sizeof(*status));
+if ( status == NULL )
+{
+PERROR("Could not alloc buffer for kexec status hypercall");
+goto out;
+}
+
+status->type = type;
+
+ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
+   KEXEC_CMD_kexec_status,
+   HYPERCALL_BUFFER_AS_ARG(status));
+
+out:
+xc_hypercall_buffer_free(xch, status);
+
+return ret;
+}
diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index c83d48f..40b76d5 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -1169,6 +1169,22 @@ 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;
+
+if ( unlikely(copy_from_guest(&status, uarg, 1)) )
+return -EFAULT;
+
+/* No need to check KEXEC_FLAG_IN_PROGRESS. */
+
+if ( kexec_load_get_bits(status.type, &base, &bit) )
+return -EINVAL;
+
+return (test_bit(bit, &kexec_flags) == 1);
+}
+
 static int do_kexec_op_internal(unsigned long op,
 XEN_GUEST_HANDLE_PARAM(void) uarg,
 bool_t compat)
@@ -1208,6 +1224,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..74ea981 100644
--- a/xen/include/public/kexec.h
+++ b/xen/include/public/kexec.h
@@ -227,6 +227,20 @@ 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. A return value of
+ * zero indicates no image loaded. A return value of one
+ * indicates an image is loaded. A negative return value
+ * indicates an error.
+ *
+ * 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
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v3] kexec: implement STATUS hypercall to check if image is loaded

2017-01-18 Thread Eric DeVolder

On 01/18/2017 04:47 AM, Wei Liu wrote:

On Wed, Jan 18, 2017 at 03:45:54AM -0700, Jan Beulich wrote:

On 18.01.17 at 11:37,  wrote:

On Wed, Jan 18, 2017 at 03:19:49AM -0700, Jan Beulich wrote:

On 17.01.17 at 18:29,  wrote:

--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -1169,6 +1169,22 @@ 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;
+
+if ( unlikely(copy_from_guest(&status, uarg, 1)) )
+return -EFAULT;
+
+/* No need to check KEXEC_FLAG_IN_PROGRESS. */
+
+if ( kexec_load_get_bits(status.type, &base, &bit) )
+return -EINVAL;
+
+return test_bit(bit, &kexec_flags);


In the public header you promise to return zero or one here (unless
an error occurs), which requires the use of !!. Please see x86's
implementation of the function for how/when there can actually be
other non-zero values returned here (in particular all ones, which
would resolve to -EPERM).


--- a/xen/include/public/kexec.h
+++ b/xen/include/public/kexec.h
@@ -227,6 +227,19 @@ 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. A return value of
+ * zero indicates no image loaded. A return value of one
+ * indicates an image is loaded. A negative return value
+ * indicates an error.
+ *
+ * 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 */


There was a blank line above here before your addition, and you
shouldn't eliminate it (making quickly scanning over the file harder).

I guess both items are simple enough to fix while committing.


Oops, I already committed this patch with Andrew's review. A follow-up
patch is appreciated. Thanks.


Well, I suppose that was directed at Eric ...



Yes. That was for Eric.

Wei.



Hi. I have made the two changes and recreated the entire patch.
It has been posted as v4.
If a delta patch against v3 was what was desired, then please
let me know and I'll provide.

Note my handling of the test_bit() scenario is to explicitly check
for return value of 1, so any value other than 1 returns 0.

Regards,
Eric


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] Followup corrections to kexec STATUS patch v3

2017-01-18 Thread Eric DeVolder
This contains the two corrections pointed out by Jan Beulich
for the kexec STATUS call just introduced.

Note: In kexec_status(), the use of test_bit() can also return
EPERM, so the return value from test_bit() must be checked to
ensure that kexec_status() always returns 0, 1 or -1, per the
public header description.

Note: My handling of the test_bit() scenario is to explicitly
check for return value of 1, so any value other than 1 causes
kexec_status to return 0.


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] kexec: ensure kexec_status() always returns 0 or 1

2017-01-18 Thread Eric DeVolder
The use of test_bit() can also return EPERM, so the
return value from test_bit() must be checked to
ensure that kexec_status() always returns 0, 1 or
-1, per the public header description.
---
 xen/common/kexec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index aa808cb..40b76d5 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -1182,7 +1182,7 @@ static int kexec_status(XEN_GUEST_HANDLE_PARAM(void) uarg)
 if ( kexec_load_get_bits(status.type, &base, &bit) )
 return -EINVAL;
 
-return test_bit(bit, &kexec_flags);
+return (test_bit(bit, &kexec_flags) == 1);
 }
 
 static int do_kexec_op_internal(unsigned long op,
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] Put back blank line for readability purposes.

2017-01-18 Thread Eric DeVolder
This blank line was accidentally removed during
the insertion of the kexec_status() declarations.
---
 xen/include/public/kexec.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xen/include/public/kexec.h b/xen/include/public/kexec.h
index c200e8c..74ea981 100644
--- a/xen/include/public/kexec.h
+++ b/xen/include/public/kexec.h
@@ -240,6 +240,7 @@ 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
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v4] kexec: implement STATUS hypercall to check if image is loaded

2017-01-18 Thread Eric DeVolder

On 01/18/2017 11:47 AM, Wei Liu wrote:

On Wed, Jan 18, 2017 at 11:46:13AM -0600, Eric DeVolder 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.

Note: No need to check KEXEC_FLAG_IN_PROGRESS (and error out of
kexec_status()) as this flag is set only once by the first/only
cpu on the crash path.

Note: In kexec_status(), the use of test_bit() can also return
EPERM, so the return value from test_bit() must be checked to
ensure that kexec_status() always returns 0, 1 or -1, per the
public header description.

Note: This is just the Xen side of the hypercall, kexec-tools patch
to come separately.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 


Your v3 is already applied to staging.

Please submit a patch on top of staging branch.

Wei.



Wei,
I just sent those, subject line 'Followup corrections to kexec STATUS'
eric


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] kexec: followup to STATUS patch v3 already in staging

2017-01-18 Thread Eric DeVolder
This contains the two corrections pointed out by Jan Beulich
for the kexec STATUS call just introduced.

Note: In kexec_status(), the use of test_bit() can also return
EPERM, so the return value from test_bit() must be checked to
ensure that kexec_status() always returns 0, 1 or -1, per the
public header description.

Note: My handling of the test_bit() scenario is to explicitly
check for return value of 1, so any value other than 1 causes
kexec_status to return 0.


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 2/2] kexec: ensure kexec_status() always returns 0 or 1

2017-01-18 Thread Eric DeVolder
The use of test_bit() can also return EPERM, so the
return value from test_bit() must be checked to
ensure that kexec_status() always returns 0, 1 or
-1, per the public header description.

Signed-off-by: Eric DeVolder 
---
 xen/common/kexec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index aa808cb..40b76d5 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -1182,7 +1182,7 @@ static int kexec_status(XEN_GUEST_HANDLE_PARAM(void) uarg)
 if ( kexec_load_get_bits(status.type, &base, &bit) )
 return -EINVAL;
 
-return test_bit(bit, &kexec_flags);
+return (test_bit(bit, &kexec_flags) == 1);
 }
 
 static int do_kexec_op_internal(unsigned long op,
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 1/2] Put back blank line for readability purposes.

2017-01-18 Thread Eric DeVolder
This blank line was accidentally removed during
the insertion of the kexec_status() declarations.

Signed-off-by: Eric DeVolder 
---
 xen/include/public/kexec.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xen/include/public/kexec.h b/xen/include/public/kexec.h
index c200e8c..74ea981 100644
--- a/xen/include/public/kexec.h
+++ b/xen/include/public/kexec.h
@@ -240,6 +240,7 @@ 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
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 1/1] kexec: ensure kexec_status() return bit value of 0 or 1

2017-01-19 Thread Eric DeVolder
When checking kexec_flags bit corresponding to the
requested image, ensure that 0 or 1 is returned.

Signed-off-by: Eric DeVolder 
---
 xen/common/kexec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index aa808cb..3da27bf 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -1182,7 +1182,8 @@ static int kexec_status(XEN_GUEST_HANDLE_PARAM(void) uarg)
 if ( kexec_load_get_bits(status.type, &base, &bit) )
 return -EINVAL;
 
-return test_bit(bit, &kexec_flags);
+/* Ensure return bit value of 0 or 1 */
+return !!test_bit(bit, &kexec_flags);
 }
 
 static int do_kexec_op_internal(unsigned long op,
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 0/1] Followup corrections for kexec_status()

2017-01-19 Thread Eric DeVolder
Jan,
This corrects the use of test_bit() in kexec_status().

Wei,
This patch is against the kexec_status() recently applied to staging.

Regards,
Eric


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2] kexec: implemented XEN KEXEC STATUS to determine if an image is loaded

2017-01-20 Thread Eric DeVolder
Instead of the scripts having to poke at various fields we can
provide that functionality via the -S parameter.

Returns 0 if the payload is loaded. Can be used in combination
with -l or -p to get the state of the proper kexec image.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
---
Note: The corresponding Xen changes have been committed
to the Xen staging branch. Follow this thread:
https://lists.xenproject.org/archives/html/xen-devel/2017-01/msg01570.html

CC: Andrew Cooper 
CC: ke...@lists.infradead.org
CC: xen-de...@lists.xenproject.org
CC: Daniel Kiper 

v0: First version (internal product).
v1: Posted on kexec mailing list. Changed -s to -S
v2: Incorporated feedback from kexec mailing list
---
 configure.ac  |  8 ++-
 kexec/kexec-xen.c | 26 +++
 kexec/kexec.8 |  6 ++
 kexec/kexec.c | 62 ---
 kexec/kexec.h |  5 -
 5 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3044185..c6e864b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -165,8 +165,14 @@ fi
 dnl find Xen control stack libraries
 if test "$with_xen" = yes ; then
AC_CHECK_HEADER(xenctrl.h,
-   [AC_CHECK_LIB(xenctrl, xc_kexec_load, ,
+   [AC_CHECK_LIB(xenctrl, xc_kexec_load, [ have_xenctrl_h=yes ],
AC_MSG_NOTICE([Xen support disabled]))])
+if test "$have_xenctrl_h" = yes ; then
+   AC_CHECK_LIB(xenctrl, xc_kexec_status,
+   AC_DEFINE(HAVE_KEXEC_CMD_STATUS, 1,
+   [The kexec_status call is available]),
+   AC_MSG_NOTICE([The kexec_status call is not available]))
+fi
 fi
 
 dnl ---Sanity checks
diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c
index 24a4191..2b448d3 100644
--- a/kexec/kexec-xen.c
+++ b/kexec/kexec-xen.c
@@ -105,6 +105,27 @@ int xen_kexec_unload(uint64_t kexec_flags)
return ret;
 }
 
+int xen_kexec_status(uint64_t kexec_flags)
+{
+   xc_interface *xch;
+   uint8_t type;
+   int ret = -1;
+
+#ifdef HAVE_KEXEC_CMD_STATUS
+   xch = xc_interface_open(NULL, NULL, 0);
+   if (!xch)
+   return -1;
+
+   type = (kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH : 
KEXEC_TYPE_DEFAULT;
+
+   ret = xc_kexec_status(xch, type);
+
+   xc_interface_close(xch);
+#endif
+
+   return ret;
+}
+
 void xen_kexec_exec(void)
 {
xc_interface *xch;
@@ -130,6 +151,11 @@ int xen_kexec_unload(uint64_t kexec_flags)
return -1;
 }
 
+int xen_kexec_status(uint64_t kexec_flags)
+{
+   return -1;
+}
+
 void xen_kexec_exec(void)
 {
 }
diff --git a/kexec/kexec.8 b/kexec/kexec.8
index 4d0c1d1..f4b39a6 100644
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -107,6 +107,12 @@ command:
 .B \-d\ (\-\-debug)
 Enable debugging messages.
 .TP
+.B \-S\ (\-\-status)
+Return 0 if the type (by default crash) is loaded. Can be used in conjuction
+with -l or -p to toggle the type. Note this option supersedes other options
+and it will
+.BR not\ load\ or\ unload\ the\ kernel.
+.TP
 .B \-e\ (\-\-exec)
 Run the currently loaded kernel. Note that it will reboot into the loaded 
kernel without calling shutdown(8).
 .TP
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 500e5a9..defbbe3 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -51,6 +51,9 @@
 #include "kexec-lzma.h"
 #include 
 
+#define KEXEC_LOADED_PATH "/sys/kernel/kexec_loaded"
+#define KEXEC_CRASH_LOADED_PATH "/sys/kernel/kexec_crash_loaded"
+
 unsigned long long mem_min = 0;
 unsigned long long mem_max = ULONG_MAX;
 static unsigned long kexec_flags = 0;
@@ -58,6 +61,8 @@ static unsigned long kexec_flags = 0;
 static unsigned long kexec_file_flags = 0;
 int kexec_debug = 0;
 
+static int kexec_loaded(const char *file);
+
 void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr)
 {
int i;
@@ -890,8 +895,6 @@ static int my_exec(void)
return -1;
 }
 
-static int kexec_loaded(void);
-
 static int load_jump_back_helper_image(unsigned long kexec_flags, void *entry)
 {
int result;
@@ -909,7 +912,7 @@ static int my_load_jump_back_helper(unsigned long 
kexec_flags, void *entry)
 {
int result;
 
-   if (kexec_loaded()) {
+   if (kexec_loaded(KEXEC_LOADED_PATH)) {
fprintf(stderr, "There is kexec kernel loaded, make sure "
"you are in kexeced kernel.\n");
return -1;
@@ -970,6 +973,7 @@ void usage(void)
   "  to original kernel.\n"
   " -s, --kexec-file-syscall Use file based syscall for kexec 
operation\n"
   " -d, --debug   Enable debugging to help spot a 
failure.\n"
+  " -S, --status Return 0 if the type (by default crash) 
is loaded.\n"
   "\n"
   &q

[Xen-devel] [PATCH v3] kexec: implemented XEN KEXEC STATUS to determine if an image is loaded

2017-01-24 Thread Eric DeVolder
Instead of the scripts having to poke at various fields we can
provide that functionality via the -S parameter.

kexec_loaded/kexec_crash_loaded exposes Linux kernel kexec/crash
state. It does not say anything about Xen kexec/crash state. So,
we need a special approach to get the latter. Though for
compatibility we provide similar functionality in kexec-tools
for the former.

This change enables the --status or -S option to work either
with or without Xen.

Returns 0 if the payload is loaded. Can be used in combination
with -l or -p to get the state of the proper kexec image.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
---
Note: The corresponding Xen changes have been committed
to the Xen staging branch. Follow this thread:
https://lists.xenproject.org/archives/html/xen-devel/2017-01/msg01570.html

CC: Andrew Cooper 
CC: ke...@lists.infradead.org
CC: xen-de...@lists.xenproject.org
CC: Daniel Kiper 

v0: First version (internal product).
v1: Posted on kexec mailing list. Changed -s to -S
v2: Incorporated feedback from kexec mailing list, posted on kexec mailing list
v3: Incorporated feedback from kexec mailing list
---
 configure.ac  |  8 ++-
 kexec/kexec-xen.c | 26 +++
 kexec/kexec.8 |  6 ++
 kexec/kexec.c | 62 ---
 kexec/kexec.h |  5 -
 5 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3044185..c6e864b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -165,8 +165,14 @@ fi
 dnl find Xen control stack libraries
 if test "$with_xen" = yes ; then
AC_CHECK_HEADER(xenctrl.h,
-   [AC_CHECK_LIB(xenctrl, xc_kexec_load, ,
+   [AC_CHECK_LIB(xenctrl, xc_kexec_load, [ have_xenctrl_h=yes ],
AC_MSG_NOTICE([Xen support disabled]))])
+if test "$have_xenctrl_h" = yes ; then
+   AC_CHECK_LIB(xenctrl, xc_kexec_status,
+   AC_DEFINE(HAVE_KEXEC_CMD_STATUS, 1,
+   [The kexec_status call is available]),
+   AC_MSG_NOTICE([The kexec_status call is not available]))
+fi
 fi
 
 dnl ---Sanity checks
diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c
index 24a4191..2b448d3 100644
--- a/kexec/kexec-xen.c
+++ b/kexec/kexec-xen.c
@@ -105,6 +105,27 @@ int xen_kexec_unload(uint64_t kexec_flags)
return ret;
 }
 
+int xen_kexec_status(uint64_t kexec_flags)
+{
+   xc_interface *xch;
+   uint8_t type;
+   int ret = -1;
+
+#ifdef HAVE_KEXEC_CMD_STATUS
+   xch = xc_interface_open(NULL, NULL, 0);
+   if (!xch)
+   return -1;
+
+   type = (kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH : 
KEXEC_TYPE_DEFAULT;
+
+   ret = xc_kexec_status(xch, type);
+
+   xc_interface_close(xch);
+#endif
+
+   return ret;
+}
+
 void xen_kexec_exec(void)
 {
xc_interface *xch;
@@ -130,6 +151,11 @@ int xen_kexec_unload(uint64_t kexec_flags)
return -1;
 }
 
+int xen_kexec_status(uint64_t kexec_flags)
+{
+   return -1;
+}
+
 void xen_kexec_exec(void)
 {
 }
diff --git a/kexec/kexec.8 b/kexec/kexec.8
index 4d0c1d1..f4b39a6 100644
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -107,6 +107,12 @@ command:
 .B \-d\ (\-\-debug)
 Enable debugging messages.
 .TP
+.B \-S\ (\-\-status)
+Return 0 if the type (by default crash) is loaded. Can be used in conjuction
+with -l or -p to toggle the type. Note this option supersedes other options
+and it will
+.BR not\ load\ or\ unload\ the\ kernel.
+.TP
 .B \-e\ (\-\-exec)
 Run the currently loaded kernel. Note that it will reboot into the loaded 
kernel without calling shutdown(8).
 .TP
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 500e5a9..defbbe3 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -51,6 +51,9 @@
 #include "kexec-lzma.h"
 #include 
 
+#define KEXEC_LOADED_PATH "/sys/kernel/kexec_loaded"
+#define KEXEC_CRASH_LOADED_PATH "/sys/kernel/kexec_crash_loaded"
+
 unsigned long long mem_min = 0;
 unsigned long long mem_max = ULONG_MAX;
 static unsigned long kexec_flags = 0;
@@ -58,6 +61,8 @@ static unsigned long kexec_flags = 0;
 static unsigned long kexec_file_flags = 0;
 int kexec_debug = 0;
 
+static int kexec_loaded(const char *file);
+
 void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr)
 {
int i;
@@ -890,8 +895,6 @@ static int my_exec(void)
return -1;
 }
 
-static int kexec_loaded(void);
-
 static int load_jump_back_helper_image(unsigned long kexec_flags, void *entry)
 {
int result;
@@ -909,7 +912,7 @@ static int my_load_jump_back_helper(unsigned long 
kexec_flags, void *entry)
 {
int result;
 
-   if (kexec_loaded()) {
+   if (kexec_loaded(KEXEC_LOADED_PATH)) {
fprintf(stderr, "There is kexec kernel loaded, make sure "
"you are in kexeced kernel.\n");
return -1;
@@ -970,6 +973,7 @@ vo

Re: [Xen-devel] [PATCH v3] kexec: implemented XEN KEXEC STATUS to determine if an image is loaded

2017-01-24 Thread Eric DeVolder

On 01/24/2017 01:16 PM, Daniel Kiper wrote:

On Tue, Jan 24, 2017 at 12:55:35PM -0600, Eric DeVolder wrote:

Instead of the scripts having to poke at various fields we can
provide that functionality via the -S parameter.

kexec_loaded/kexec_crash_loaded exposes Linux kernel kexec/crash
state. It does not say anything about Xen kexec/crash state. So,
we need a special approach to get the latter. Though for
compatibility we provide similar functionality in kexec-tools
for the former.

This change enables the --status or -S option to work either
with or without Xen.

Returns 0 if the payload is loaded. Can be used in combination
with -l or -p to get the state of the proper kexec image.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
---
Note: The corresponding Xen changes have been committed
to the Xen staging branch. Follow this thread:
https://lists.xenproject.org/archives/html/xen-devel/2017-01/msg01570.html

CC: Andrew Cooper 
CC: ke...@lists.infradead.org
CC: xen-de...@lists.xenproject.org
CC: Daniel Kiper 

v0: First version (internal product).
v1: Posted on kexec mailing list. Changed -s to -S
v2: Incorporated feedback from kexec mailing list, posted on kexec mailing list
v3: Incorporated feedback from kexec mailing list
---
 configure.ac  |  8 ++-
 kexec/kexec-xen.c | 26 +++
 kexec/kexec.8 |  6 ++
 kexec/kexec.c | 62 ---
 kexec/kexec.h |  5 -
 5 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3044185..c6e864b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -165,8 +165,14 @@ fi
 dnl find Xen control stack libraries
 if test "$with_xen" = yes ; then
AC_CHECK_HEADER(xenctrl.h,
-   [AC_CHECK_LIB(xenctrl, xc_kexec_load, ,
+   [AC_CHECK_LIB(xenctrl, xc_kexec_load, [ have_xenctrl_h=yes ],
AC_MSG_NOTICE([Xen support disabled]))])
+if test "$have_xenctrl_h" = yes ; then
+   AC_CHECK_LIB(xenctrl, xc_kexec_status,
+   AC_DEFINE(HAVE_KEXEC_CMD_STATUS, 1,
+   [The kexec_status call is available]),
+   AC_MSG_NOTICE([The kexec_status call is not available]))
+fi


I have a feeling that you have missed my comment. Please add two TABs
starting from "+if test "$have_xenctrl_h" = yes ; then" up to "+fi".
So, it should look more or less like this:

AC_MSG_NOTICE([Xen support disabled]))])
+   if test "$have_xenctrl_h" = yes ; then
+   AC_CHECK_LIB(xenctrl, xc_kexec_status,
...

If it is not needed or something like that please drop me a line.


The tabs are not needed for the configure to work properly.

If tabs are needed for readability/style purposes, I will
add them in. There is not any precedent of nesting in
the configure.ac file, so I am unsure what convention is
for this package.




 fi

 dnl ---Sanity checks
diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c
index 24a4191..2b448d3 100644
--- a/kexec/kexec-xen.c
+++ b/kexec/kexec-xen.c
@@ -105,6 +105,27 @@ int xen_kexec_unload(uint64_t kexec_flags)
return ret;
 }

+int xen_kexec_status(uint64_t kexec_flags)
+{
+   xc_interface *xch;
+   uint8_t type;
+   int ret = -1;
+
+#ifdef HAVE_KEXEC_CMD_STATUS
+   xch = xc_interface_open(NULL, NULL, 0);
+   if (!xch)
+   return -1;
+
+   type = (kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH : 
KEXEC_TYPE_DEFAULT;
+
+   ret = xc_kexec_status(xch, type);
+
+   xc_interface_close(xch);
+#endif
+
+   return ret;
+}
+
 void xen_kexec_exec(void)
 {
xc_interface *xch;
@@ -130,6 +151,11 @@ int xen_kexec_unload(uint64_t kexec_flags)
return -1;
 }

+int xen_kexec_status(uint64_t kexec_flags)
+{
+   return -1;
+}
+
 void xen_kexec_exec(void)
 {
 }
diff --git a/kexec/kexec.8 b/kexec/kexec.8
index 4d0c1d1..f4b39a6 100644
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -107,6 +107,12 @@ command:
 .B \-d\ (\-\-debug)
 Enable debugging messages.
 .TP
+.B \-S\ (\-\-status)
+Return 0 if the type (by default crash) is loaded. Can be used in conjuction
+with -l or -p to toggle the type. Note this option supersedes other options
+and it will
+.BR not\ load\ or\ unload\ the\ kernel.


Same as above. I think that you have missed my earlier comments.
I suppose that you can join "+and it will" and "+.BR not\ load\ or\
unload\ the\ kernel." into one line.


In that file, all dot directives start with the dot in the
first column. I did the same for the .BR in this statement.




+.TP
 .B \-e\ (\-\-exec)
 Run the currently loaded kernel. Note that it will reboot into the loaded 
kernel without calling shutdown(8).
 .TP
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 500e5a9..defbbe3 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -51,6 +51,9 @@
 #include "

Re: [Xen-devel] [PATCH v3] kexec: implemented XEN KEXEC STATUS to determine if an image is loaded

2017-01-24 Thread Eric DeVolder

On 01/24/2017 01:16 PM, Daniel Kiper wrote:

On Tue, Jan 24, 2017 at 12:55:35PM -0600, Eric DeVolder wrote:

Instead of the scripts having to poke at various fields we can
provide that functionality via the -S parameter.

kexec_loaded/kexec_crash_loaded exposes Linux kernel kexec/crash
state. It does not say anything about Xen kexec/crash state. So,
we need a special approach to get the latter. Though for
compatibility we provide similar functionality in kexec-tools
for the former.

This change enables the --status or -S option to work either
with or without Xen.

Returns 0 if the payload is loaded. Can be used in combination
with -l or -p to get the state of the proper kexec image.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
---
Note: The corresponding Xen changes have been committed
to the Xen staging branch. Follow this thread:
https://lists.xenproject.org/archives/html/xen-devel/2017-01/msg01570.html

CC: Andrew Cooper 
CC: ke...@lists.infradead.org
CC: xen-de...@lists.xenproject.org
CC: Daniel Kiper 

v0: First version (internal product).
v1: Posted on kexec mailing list. Changed -s to -S
v2: Incorporated feedback from kexec mailing list, posted on kexec mailing list
v3: Incorporated feedback from kexec mailing list
---
 configure.ac  |  8 ++-
 kexec/kexec-xen.c | 26 +++
 kexec/kexec.8 |  6 ++
 kexec/kexec.c | 62 ---
 kexec/kexec.h |  5 -
 5 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3044185..c6e864b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -165,8 +165,14 @@ fi
 dnl find Xen control stack libraries
 if test "$with_xen" = yes ; then
AC_CHECK_HEADER(xenctrl.h,
-   [AC_CHECK_LIB(xenctrl, xc_kexec_load, ,
+   [AC_CHECK_LIB(xenctrl, xc_kexec_load, [ have_xenctrl_h=yes ],
AC_MSG_NOTICE([Xen support disabled]))])
+if test "$have_xenctrl_h" = yes ; then
+   AC_CHECK_LIB(xenctrl, xc_kexec_status,
+   AC_DEFINE(HAVE_KEXEC_CMD_STATUS, 1,
+   [The kexec_status call is available]),
+   AC_MSG_NOTICE([The kexec_status call is not available]))
+fi


I have a feeling that you have missed my comment. Please add two TABs
starting from "+if test "$have_xenctrl_h" = yes ; then" up to "+fi".
So, it should look more or less like this:

AC_MSG_NOTICE([Xen support disabled]))])
+   if test "$have_xenctrl_h" = yes ; then
+   AC_CHECK_LIB(xenctrl, xc_kexec_status,
...

If it is not needed or something like that please drop me a line.


 fi

 dnl ---Sanity checks
diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c
index 24a4191..2b448d3 100644
--- a/kexec/kexec-xen.c
+++ b/kexec/kexec-xen.c
@@ -105,6 +105,27 @@ int xen_kexec_unload(uint64_t kexec_flags)
return ret;
 }

+int xen_kexec_status(uint64_t kexec_flags)
+{
+   xc_interface *xch;
+   uint8_t type;
+   int ret = -1;
+
+#ifdef HAVE_KEXEC_CMD_STATUS
+   xch = xc_interface_open(NULL, NULL, 0);
+   if (!xch)
+   return -1;
+
+   type = (kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH : 
KEXEC_TYPE_DEFAULT;
+
+   ret = xc_kexec_status(xch, type);
+
+   xc_interface_close(xch);
+#endif
+
+   return ret;
+}
+
 void xen_kexec_exec(void)
 {
xc_interface *xch;
@@ -130,6 +151,11 @@ int xen_kexec_unload(uint64_t kexec_flags)
return -1;
 }

+int xen_kexec_status(uint64_t kexec_flags)
+{
+   return -1;
+}
+
 void xen_kexec_exec(void)
 {
 }
diff --git a/kexec/kexec.8 b/kexec/kexec.8
index 4d0c1d1..f4b39a6 100644
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -107,6 +107,12 @@ command:
 .B \-d\ (\-\-debug)
 Enable debugging messages.
 .TP
+.B \-S\ (\-\-status)
+Return 0 if the type (by default crash) is loaded. Can be used in conjuction
+with -l or -p to toggle the type. Note this option supersedes other options
+and it will
+.BR not\ load\ or\ unload\ the\ kernel.


Same as above. I think that you have missed my earlier comments.
I suppose that you can join "+and it will" and "+.BR not\ load\ or\
unload\ the\ kernel." into one line.


+.TP
 .B \-e\ (\-\-exec)
 Run the currently loaded kernel. Note that it will reboot into the loaded 
kernel without calling shutdown(8).
 .TP
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 500e5a9..defbbe3 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -51,6 +51,9 @@
 #include "kexec-lzma.h"
 #include 

+#define KEXEC_LOADED_PATH "/sys/kernel/kexec_loaded"
+#define KEXEC_CRASH_LOADED_PATH "/sys/kernel/kexec_crash_loaded"
+
 unsigned long long mem_min = 0;
 unsigned long long mem_max = ULONG_MAX;
 static unsigned long kexec_flags = 0;
@@ -58,6 +61,8 @@ static unsigned long kexec_flags = 0;
 static unsigned long kexec_file_flags

[Xen-devel] [PATCH v4] kexec: implemented XEN KEXEC STATUS to determine if an image is loaded

2017-01-25 Thread Eric DeVolder
Instead of the scripts having to poke at various fields we can
provide that functionality via the -S parameter.

kexec_loaded/kexec_crash_loaded exposes Linux kernel kexec/crash
state. It does not say anything about Xen kexec/crash state. So,
we need a special approach to get the latter. Though for
compatibility we provide similar functionality in kexec-tools
for the former.

This change enables the --status or -S option to work either
with or without Xen.

Returns 0 if the payload is loaded. Can be used in combination
with -l or -p to get the state of the proper kexec image.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
---
CC: ke...@lists.infradead.org
CC: xen-de...@lists.xenproject.org
CC: Daniel Kiper 

v0: First version (internal product).
v1: Posted on kexec mailing list. Changed -s to -S
v2: Incorporated feedback from kexec mailing list, posted on kexec mailing list
v3: Incorporated feedback from kexec mailing list, posted on kexec mailing list
v4: Incorporated feedback from kexec mailing list
---
 configure.ac  |   8 +++-
 kexec/kexec-xen.c |  26 +
 kexec/kexec.8 |   6 +++
 kexec/kexec.c | 114 ++
 kexec/kexec.h |   5 ++-
 5 files changed, 123 insertions(+), 36 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3044185..53fffc3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -165,8 +165,14 @@ fi
 dnl find Xen control stack libraries
 if test "$with_xen" = yes ; then
AC_CHECK_HEADER(xenctrl.h,
-   [AC_CHECK_LIB(xenctrl, xc_kexec_load, ,
+   [AC_CHECK_LIB(xenctrl, xc_kexec_load, [ have_xenctrl_h=yes ],
AC_MSG_NOTICE([Xen support disabled]))])
+   if test "$have_xenctrl_h" = yes ; then
+   AC_CHECK_LIB(xenctrl, xc_kexec_status,
+   AC_DEFINE(HAVE_KEXEC_CMD_STATUS, 1,
+   [The kexec_status call is available]),
+   AC_MSG_NOTICE([The kexec_status call is not 
available]))
+   fi
 fi
 
 dnl ---Sanity checks
diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c
index 24a4191..2b448d3 100644
--- a/kexec/kexec-xen.c
+++ b/kexec/kexec-xen.c
@@ -105,6 +105,27 @@ int xen_kexec_unload(uint64_t kexec_flags)
return ret;
 }
 
+int xen_kexec_status(uint64_t kexec_flags)
+{
+   xc_interface *xch;
+   uint8_t type;
+   int ret = -1;
+
+#ifdef HAVE_KEXEC_CMD_STATUS
+   xch = xc_interface_open(NULL, NULL, 0);
+   if (!xch)
+   return -1;
+
+   type = (kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH : 
KEXEC_TYPE_DEFAULT;
+
+   ret = xc_kexec_status(xch, type);
+
+   xc_interface_close(xch);
+#endif
+
+   return ret;
+}
+
 void xen_kexec_exec(void)
 {
xc_interface *xch;
@@ -130,6 +151,11 @@ int xen_kexec_unload(uint64_t kexec_flags)
return -1;
 }
 
+int xen_kexec_status(uint64_t kexec_flags)
+{
+   return -1;
+}
+
 void xen_kexec_exec(void)
 {
 }
diff --git a/kexec/kexec.8 b/kexec/kexec.8
index 4d0c1d1..f4b39a6 100644
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -107,6 +107,12 @@ command:
 .B \-d\ (\-\-debug)
 Enable debugging messages.
 .TP
+.B \-S\ (\-\-status)
+Return 0 if the type (by default crash) is loaded. Can be used in conjuction
+with -l or -p to toggle the type. Note this option supersedes other options
+and it will
+.BR not\ load\ or\ unload\ the\ kernel.
+.TP
 .B \-e\ (\-\-exec)
 Run the currently loaded kernel. Note that it will reboot into the loaded 
kernel without calling shutdown(8).
 .TP
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 500e5a9..ec16247 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -51,6 +51,9 @@
 #include "kexec-lzma.h"
 #include 
 
+#define KEXEC_LOADED_PATH "/sys/kernel/kexec_loaded"
+#define KEXEC_CRASH_LOADED_PATH "/sys/kernel/kexec_crash_loaded"
+
 unsigned long long mem_min = 0;
 unsigned long long mem_max = ULONG_MAX;
 static unsigned long kexec_flags = 0;
@@ -890,8 +893,6 @@ static int my_exec(void)
return -1;
 }
 
-static int kexec_loaded(void);
-
 static int load_jump_back_helper_image(unsigned long kexec_flags, void *entry)
 {
int result;
@@ -902,6 +903,40 @@ static int load_jump_back_helper_image(unsigned long 
kexec_flags, void *entry)
return result;
 }
 
+static int kexec_loaded(const char *file)
+{
+   long ret = -1;
+   FILE *fp;
+   char *p;
+   char line[3];
+
+   /* No way to tell if an image is loaded under Xen, assume it is. */
+   if (xen_present())
+   return 1;
+
+   fp = fopen(file, "r");
+   if (fp == NULL)
+   return -1;
+
+   p = fgets(line, sizeof(line), fp);
+   fclose(fp);
+
+   if (p == NULL)
+   return -1;
+
+   ret = strtol(line, &p, 10);
+
+   /* Too long */
+   if (ret > INT_MAX)
+ 

[Xen-devel] [XEN KEXEC PATCH] Corrected comment typo "count not" to "could not"

2016-12-21 Thread Eric DeVolder
Fix cut-n-paste typo; changed the words "count not" to "could not".

No functional changes

Signed-off-by: Eric DeVolder 

---
 tools/libxc/xc_kexec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/libxc/xc_kexec.c b/tools/libxc/xc_kexec.c
index 1cceb5d2d6..989e225192 100644
--- a/tools/libxc/xc_kexec.c
+++ b/tools/libxc/xc_kexec.c
@@ -20,7 +20,7 @@ int xc_kexec_exec(xc_interface *xch, int type)
 exec = xc_hypercall_buffer_alloc(xch, exec, sizeof(*exec));
 if ( exec == NULL )
 {
-PERROR("Count not alloc bounce buffer for kexec_exec hypercall");
+PERROR("Could not alloc bounce buffer for kexec_exec hypercall");
 goto out;
 }
 
@@ -111,7 +111,7 @@ int xc_kexec_unload(xc_interface *xch, int type)
 unload = xc_hypercall_buffer_alloc(xch, unload, sizeof(*unload));
 if ( unload == NULL )
 {
-PERROR("Count not alloc buffer for kexec unload hypercall");
+PERROR("Could not alloc buffer for kexec unload hypercall");
 goto out;
 }
 
-- 
2.11.0


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] kexec: Add spinlock for the whole hypercall

2017-04-10 Thread Eric DeVolder
When we concurrently try to unload and load crash
images we eventually get:

 Xen call trace:
[] machine_kexec_add_page+0x3a0/0x3fa
[] machine_kexec_load+0xdb/0x107
[] kexec.c#kexec_load_slot+0x11/0x42
[] kexec.c#kexec_load+0x119/0x150
[] kexec.c#do_kexec_op_internal+0xab/0xcf
[] do_kexec_op+0xe/0x1e
[] pv_hypercall+0x20a/0x44a
[] cpufreq.c#test_all_events+0/0x30

 Pagetable walk from 820040088320:
  L4[0x104] = 0002979d1063 
  L3[0x001] = 0002979d0063 
  L2[0x000] = 0002979c7063 
  L1[0x088] = 80037a91ede97063 

The interesting thing is that the page bits (063) look legit.

The operation on which we blow up is us trying to write
in the L1 and finding that the L2 entry points to some
bizzare MFN. It stinks of a race, and it looks like
the issue is due to no concurrency locks when dealing
with the crash kernel space.

Specifically we concurrently call kimage_alloc_crash_control_page
which iterates over the kexec_crash_area.start -> kexec_crash_area.size
and once found:

  if ( page )
  {
  image->next_crash_page = hole_end;
  clear_domain_page(_mfn(page_to_mfn(page)));
  }

clears. Since the parameters of what MFN to use are provided
by the callers (and the area to search is bounded) the the 'page'
is probably the same. So #1 we concurrently clear the
'control_code_page'.

The next step is us passing this 'control_code_page' to
machine_kexec_add_page. This function requires the MFNs:
page_to_maddr(image->control_code_page).

And this would always return the same virtual address, as
the MFN of the control_code_page is inside of the
kexec_crash_area.start -> kexec_crash_area.size area.

Then machine_kexec_add_page updates the L1 .. which can be done
concurrently and on subsequent calls we mangle it up.

This is all a theory at this time, but testing reveals
that adding the spinlock at the kexec hypercall fixes
the crash.

An alternative solution would be to only add the spinlock
on paths that touch the CRASH region and not everything.

NOTE: The spinlock in kexec_swap_images() was removed as
this function is only reachable on the kexec call, which is
now entirely protected by a spinlock, thus the local spinlock
is no longer necessary.

NOTE: This patch follows 5c5216 (kexec: clear kexec_image slot
when unloading kexec image) to prevent crashes during
simultaneous load/unloads.

Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Eric DeVolder 
Reviewed-by: Daniel Kiper 
---
 xen/common/kexec.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 072cc8e..5bcc356 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -819,7 +819,6 @@ static int kexec_exec(XEN_GUEST_HANDLE_PARAM(void) uarg)
 static int kexec_swap_images(int type, struct kexec_image *new,
  struct kexec_image **old)
 {
-static DEFINE_SPINLOCK(kexec_lock);
 int base, bit, pos;
 int new_slot, old_slot;
 
@@ -831,8 +830,6 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 if ( kexec_load_get_bits(type, &base, &bit) )
 return -EINVAL;
 
-spin_lock(&kexec_lock);
-
 pos = (test_bit(bit, &kexec_flags) != 0);
 old_slot = base + pos;
 new_slot = base + !pos;
@@ -845,8 +842,6 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 clear_bit(old_slot, &kexec_flags);
 *old = kexec_image[old_slot];
 
-spin_unlock(&kexec_lock);
-
 return 0;
 }
 
@@ -1187,12 +1182,22 @@ static int do_kexec_op_internal(unsigned long op,
 XEN_GUEST_HANDLE_PARAM(void) uarg,
 bool_t compat)
 {
+static DEFINE_SPINLOCK(kexec_lock);
 int ret = -EINVAL;
 
 ret = xsm_kexec(XSM_PRIV);
 if ( ret )
 return ret;
 
+/*
+ * Because we write directly to the reserved memory
+ * region when loading crash kernels we need a spinlock here to
+ * prevent multiple crash kernels from attempting to load
+ * simultaneously, and to prevent a crash kernel from loading
+ * over the top of a in use crash kernel.
+ */
+spin_lock(&kexec_lock);
+
 switch ( op )
 {
 case KEXEC_CMD_kexec_get_range:
@@ -1227,6 +1232,8 @@ static int do_kexec_op_internal(unsigned long op,
 break;
 }
 
+spin_unlock(&kexec_lock);
+
 return ret;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2 1/2] kexec: use hypercall_create_continuation to protect KEXEC ops

2017-04-17 Thread Eric DeVolder
When we concurrently try to unload and load crash
images we eventually get:

 Xen call trace:
[] machine_kexec_add_page+0x3a0/0x3fa
[] machine_kexec_load+0xdb/0x107
[] kexec.c#kexec_load_slot+0x11/0x42
[] kexec.c#kexec_load+0x119/0x150
[] kexec.c#do_kexec_op_internal+0xab/0xcf
[] do_kexec_op+0xe/0x1e
[] pv_hypercall+0x20a/0x44a
[] cpufreq.c#test_all_events+0/0x30

 Pagetable walk from 820040088320:
  L4[0x104] = 0002979d1063 
  L3[0x001] = 0002979d0063 
  L2[0x000] = 0002979c7063 
  L1[0x088] = 80037a91ede97063 

The interesting thing is that the page bits (063) look legit.

The operation on which we blow up is us trying to write
in the L1 and finding that the L2 entry points to some
bizzare MFN. It stinks of a race, and it looks like
the issue is due to no concurrency locks when dealing
with the crash kernel space.

Specifically we concurrently call kimage_alloc_crash_control_page
which iterates over the kexec_crash_area.start -> kexec_crash_area.size
and once found:

  if ( page )
  {
  image->next_crash_page = hole_end;
  clear_domain_page(_mfn(page_to_mfn(page)));
  }

clears. Since the parameters of what MFN to use are provided
by the callers (and the area to search is bounded) the the 'page'
is probably the same. So #1 we concurrently clear the
'control_code_page'.

The next step is us passing this 'control_code_page' to
machine_kexec_add_page. This function requires the MFNs:
page_to_maddr(image->control_code_page).

And this would always return the same virtual address, as
the MFN of the control_code_page is inside of the
kexec_crash_area.start -> kexec_crash_area.size area.

Then machine_kexec_add_page updates the L1 .. which can be done
concurrently and on subsequent calls we mangle it up.

This is all a theory at this time, but testing reveals
that adding the hypercall_create_continuation() at the
kexec hypercall fixes the crash.

NOTE: This patch follows 5c5216 (kexec: clear kexec_image slot
when unloading kexec image) to prevent crashes during
simultaneous load/unloads.

NOTE: Consideration was given to using the existing flag
KEXEC_FLAG_IN_PROGRESS to denote a kexec hypercall in
progress. This, however, overloads the original intent of
the flag which is to denote that we are about-to/have made
the jump to the crash path. The overloading would lead to
failures in existing checks on this flag as the flag would
always be set at the top level in do_kexec_op_internal().
For this reason, the new flag KEXEC_FLAG_HC_IN_PROGRESS
was introduced.

While at it, fixed the #define mismatched spacing

Signed-off-by: Eric DeVolder 
Reviewed-by: Bhavesh Davda 
Reviewed-by: Konrad Rzeszutek Wilk 
---
v2: 04/17/2017
 - Patch titled 'kexec: use hypercall_create_continuation to protect KEXEC ops'
 - Jan Beulich directed me to use a continuation method instead
   of spinlock.
 - Incorporated feedback from Daniel Kiper 
 - Incorporated feedback from Konrad Wilk 

v1: 04/10/2017
 - Patch titled 'kexec: Add spinlock for the whole hypercall'
 - Used spinlock in do_kexec_op_internal()
---
 xen/common/kexec.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 072cc8e..3f96eb2 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -50,9 +50,10 @@ static cpumask_t crash_saved_cpus;
 
 static struct kexec_image *kexec_image[KEXEC_IMAGE_NR];
 
-#define KEXEC_FLAG_DEFAULT_POS   (KEXEC_IMAGE_NR + 0)
-#define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1)
-#define KEXEC_FLAG_IN_PROGRESS   (KEXEC_IMAGE_NR + 2)
+#define KEXEC_FLAG_DEFAULT_POS(KEXEC_IMAGE_NR + 0)
+#define KEXEC_FLAG_CRASH_POS  (KEXEC_IMAGE_NR + 1)
+#define KEXEC_FLAG_IN_PROGRESS(KEXEC_IMAGE_NR + 2)
+#define KEXEC_FLAG_HC_IN_PROGRESS (KEXEC_IMAGE_NR + 3)
 
 static unsigned long kexec_flags = 0; /* the lowest bits are for 
KEXEC_IMAGE... */
 
@@ -1193,6 +1194,9 @@ static int do_kexec_op_internal(unsigned long op,
 if ( ret )
 return ret;
 
+if ( test_and_set_bit(KEXEC_FLAG_HC_IN_PROGRESS, &kexec_flags))
+return hypercall_create_continuation(__HYPERVISOR_kexec_op, "lh", op, 
uarg);
+
 switch ( op )
 {
 case KEXEC_CMD_kexec_get_range:
@@ -1227,6 +1231,8 @@ static int do_kexec_op_internal(unsigned long op,
 break;
 }
 
+clear_bit(KEXEC_FLAG_HC_IN_PROGRESS, &kexec_flags);
+
 return ret;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2 0/2] kexec: Use hypercall_create_continuation to protect KEXEC ops

2017-04-17 Thread Eric DeVolder
During testing (using the script below) we found that multiple
invocations of kexec of unload/load are not safe.

This does not exist in classic Xen kernels in which the kexec-tools
did the kexec via Linux kernel syscall (which in turn made the
hypercall), as the Linux code has a mutex_trylock which would
inhibit multiple concurrent calls.

But with the kexec-tools utilizing xc_kexec_* that is no longer
the case and we need to protect against multiple concurrent
invocations.

Please see the patches and review at your convenience!

 try-crash.pl from bhavesh.da...@oracle.com 
#!/usr/bin/perl -w

use strict;
use warnings;
use threads;

sub threaded_task {
threads->create(sub {
my $thr_id = threads->self->tid;
#print "Starting load thread $thr_id\n";
system("/sbin/kexec  -p --command-line=\"placeholder 
root=/dev/mapper/nimbula-root ro rhbg console=tty0 console=hvc0 earlyprintk=xen 
nomodeset printk.time=1 irqpoll maxcpus=1 nr_cpus=1 reset_devices 
cgroup_disable=memory mce=off selinux=0 console=ttyS1,115200n8\" 
--initrd=/boot/initrd-4.1.12-61.1.9.el6uek.x86_64kdump.img 
/boot/vmlinuz-4.1.12-61.1.9.el6uek.x86_64");
#print "Ending load thread $thr_id\n";
threads->detach(); #End thread.
});
threads->create(sub {
my $thr_id = threads->self->tid;
#print "Starting unload thread $thr_id\n";
system("/sbin/kexec  -p -u");
#print "Ending unload thread $thr_id\n";
    threads->detach(); #End thread.
});
}

for my $i (0..99)
{
threaded_task();
}


Eric DeVolder (2):
  kexec: use hypercall_create_continuation to protect KEXEC ops
  kexec: remove spinlock now that all KEXEC hypercall ops are protected
at the top-level

 xen/common/kexec.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2 2/2] kexec: remove spinlock now that all KEXEC hypercall ops are protected at the top-level

2017-04-17 Thread Eric DeVolder
The spinlock in kexec_swap_images() was removed as
this function is only reachable on the kexec hypercall, which is
now protected at the top-level in do_kexec_op_internal(),
thus the local spinlock is no longer necessary.

Signed-off-by: Eric DeVolder 
Reviewed-by: Bhavesh Davda 
Reviewed-by: Konrad Rzeszutek Wilk 
---
 xen/common/kexec.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 3f96eb2..efecf60 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -820,7 +820,6 @@ static int kexec_exec(XEN_GUEST_HANDLE_PARAM(void) uarg)
 static int kexec_swap_images(int type, struct kexec_image *new,
  struct kexec_image **old)
 {
-static DEFINE_SPINLOCK(kexec_lock);
 int base, bit, pos;
 int new_slot, old_slot;
 
@@ -832,8 +831,6 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 if ( kexec_load_get_bits(type, &base, &bit) )
 return -EINVAL;
 
-spin_lock(&kexec_lock);
-
 pos = (test_bit(bit, &kexec_flags) != 0);
 old_slot = base + pos;
 new_slot = base + !pos;
@@ -846,8 +843,6 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 clear_bit(old_slot, &kexec_flags);
 *old = kexec_image[old_slot];
 
-spin_unlock(&kexec_lock);
-
 return 0;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v3 2/2] kexec: remove spinlock now that all KEXEC hypercall ops are protected at the top-level

2017-04-19 Thread Eric DeVolder
The spinlock in kexec_swap_images() was removed as
this function is only reachable on the kexec hypercall, which is
now protected at the top-level in do_kexec_op_internal(),
thus the local spinlock is no longer necessary.

Per recommendation from Jan Beulich and Andrew Cooper, I left
an ASSERT in place of the spin_lock().

Signed-off-by: Eric DeVolder 
Reviewed-by: Bhavesh Davda 
Reviewed-by: Konrad Rzeszutek Wilk 
---
v3:
 - Incorporated feedback from Jan Beulich and Andrew Cooper
   to leave an ASSERT where spin_lock() once was.

v2: 04/17/2017
 - Patch titled 'kexec: use hypercall_create_continuation to protect KEXEC ops'
 - Separated removal of spinlock in kexec_swap_images() into its own patch.

v1: 04/10/2017
 - Patch titled 'kexec: Add spinlock for the whole hypercall'
 - Removal of spinlock in kexec_swap_images() was part of other patch.
---
 xen/common/kexec.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 253c204..af32e58 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -820,7 +820,6 @@ static int kexec_exec(XEN_GUEST_HANDLE_PARAM(void) uarg)
 static int kexec_swap_images(int type, struct kexec_image *new,
  struct kexec_image **old)
 {
-static DEFINE_SPINLOCK(kexec_lock);
 int base, bit, pos;
 int new_slot, old_slot;
 
@@ -832,7 +831,7 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 if ( kexec_load_get_bits(type, &base, &bit) )
 return -EINVAL;
 
-spin_lock(&kexec_lock);
+ASSERT( !test_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags) );
 
 pos = (test_bit(bit, &kexec_flags) != 0);
 old_slot = base + pos;
@@ -846,8 +845,6 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 clear_bit(old_slot, &kexec_flags);
 *old = kexec_image[old_slot];
 
-spin_unlock(&kexec_lock);
-
 return 0;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v3 1/2] kexec: use hypercall_create_continuation to protect KEXEC ops

2017-04-19 Thread Eric DeVolder
When we concurrently try to unload and load crash
images we eventually get:

 Xen call trace:
[] machine_kexec_add_page+0x3a0/0x3fa
[] machine_kexec_load+0xdb/0x107
[] kexec.c#kexec_load_slot+0x11/0x42
[] kexec.c#kexec_load+0x119/0x150
[] kexec.c#do_kexec_op_internal+0xab/0xcf
[] do_kexec_op+0xe/0x1e
[] pv_hypercall+0x20a/0x44a
[] cpufreq.c#test_all_events+0/0x30

 Pagetable walk from 820040088320:
  L4[0x104] = 0002979d1063 
  L3[0x001] = 0002979d0063 
  L2[0x000] = 0002979c7063 
  L1[0x088] = 80037a91ede97063 

The interesting thing is that the page bits (063) look legit.

The operation on which we blow up is us trying to write
in the L1 and finding that the L2 entry points to some
bizzare MFN. It stinks of a race, and it looks like
the issue is due to no concurrency locks when dealing
with the crash kernel space.

Specifically we concurrently call kimage_alloc_crash_control_page
which iterates over the kexec_crash_area.start -> kexec_crash_area.size
and once found:

  if ( page )
  {
  image->next_crash_page = hole_end;
  clear_domain_page(_mfn(page_to_mfn(page)));
  }

clears. Since the parameters of what MFN to use are provided
by the callers (and the area to search is bounded) the the 'page'
is probably the same. So #1 we concurrently clear the
'control_code_page'.

The next step is us passing this 'control_code_page' to
machine_kexec_add_page. This function requires the MFNs:
page_to_maddr(image->control_code_page).

And this would always return the same virtual address, as
the MFN of the control_code_page is inside of the
kexec_crash_area.start -> kexec_crash_area.size area.

Then machine_kexec_add_page updates the L1 .. which can be done
concurrently and on subsequent calls we mangle it up.

This is all a theory at this time, but testing reveals
that adding the hypercall_create_continuation() at the
kexec hypercall fixes the crash.

NOTE: This patch follows 5c5216 (kexec: clear kexec_image slot
when unloading kexec image) to prevent crashes during
simultaneous load/unloads.

NOTE: Consideration was given to using the existing flag
KEXEC_FLAG_IN_PROGRESS to denote a kexec hypercall in
progress. This, however, overloads the original intent of
the flag which is to denote that we are about-to/have made
the jump to the crash path. The overloading would lead to
failures in existing checks on this flag as the flag would
always be set at the top level in do_kexec_op_internal().
For this reason, the new flag KEXEC_FLAG_HC_IN_PROGRESS
was introduced.

While at it, fixed the #define mismatched spacing

Signed-off-by: Eric DeVolder 
Reviewed-by: Bhavesh Davda 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Jan Beulich 
Reviewed-by: Andrew Cooper 
Reviewed-by: Daniel Kiper 
---
v3:
 - Incorporated feedback from Jan Beulich to change the
   name of the new flag to KEXEC_FLAG_IN_HYPERCALL

v2: 04/17/2017
 - Patch titled 'kexec: use hypercall_create_continuation to protect KEXEC ops'
 - Jan Beulich directed me to use a continuation method instead
   of spinlock.
 - Incorporated feedback from Daniel Kiper 
 - Incorporated feedback from Konrad Wilk 

v1: 04/10/2017
 - Patch titled 'kexec: Add spinlock for the whole hypercall'
 - Used spinlock in do_kexec_op_internal()
---
 xen/common/kexec.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 072cc8e..253c204 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -50,9 +50,10 @@ static cpumask_t crash_saved_cpus;
 
 static struct kexec_image *kexec_image[KEXEC_IMAGE_NR];
 
-#define KEXEC_FLAG_DEFAULT_POS   (KEXEC_IMAGE_NR + 0)
-#define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1)
-#define KEXEC_FLAG_IN_PROGRESS   (KEXEC_IMAGE_NR + 2)
+#define KEXEC_FLAG_DEFAULT_POS  (KEXEC_IMAGE_NR + 0)
+#define KEXEC_FLAG_CRASH_POS(KEXEC_IMAGE_NR + 1)
+#define KEXEC_FLAG_IN_PROGRESS  (KEXEC_IMAGE_NR + 2)
+#define KEXEC_FLAG_IN_HYPERCALL (KEXEC_IMAGE_NR + 3)
 
 static unsigned long kexec_flags = 0; /* the lowest bits are for 
KEXEC_IMAGE... */
 
@@ -1193,6 +1194,9 @@ static int do_kexec_op_internal(unsigned long op,
 if ( ret )
 return ret;
 
+if ( test_and_set_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags) )
+return hypercall_create_continuation(__HYPERVISOR_kexec_op, "lh", op, 
uarg);
+
 switch ( op )
 {
 case KEXEC_CMD_kexec_get_range:
@@ -1227,6 +1231,8 @@ static int do_kexec_op_internal(unsigned long op,
 break;
 }
 
+clear_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags);
+
 return ret;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v3 0/2] kexec: Use hypercall_create_continuation to protect KEXEC ops

2017-04-19 Thread Eric DeVolder
During testing (using the script below) we found that multiple
invocations of kexec of unload/load are not safe.

This does not exist in classic Xen kernels in which the kexec-tools
did the kexec via Linux kernel syscall (which in turn made the
hypercall), as the Linux code has a mutex_trylock which would
inhibit multiple concurrent calls.

But with the kexec-tools utilizing xc_kexec_* that is no longer
the case and we need to protect against multiple concurrent
invocations.

Please see the patches and review at your convenience!

 try-crash.pl from bhavesh.da...@oracle.com 
#!/usr/bin/perl -w

use strict;
use warnings;
use threads;

sub threaded_task {
threads->create(sub {
my $thr_id = threads->self->tid;
#print "Starting load thread $thr_id\n";
system("/sbin/kexec  -p --command-line=\"placeholder 
root=/dev/mapper/nimbula-root ro rhbg console=tty0 console=hvc0 earlyprintk=xen 
nomodeset printk.time=1 irqpoll maxcpus=1 nr_cpus=1 reset_devices 
cgroup_disable=memory mce=off selinux=0 console=ttyS1,115200n8\" 
--initrd=/boot/initrd-4.1.12-61.1.9.el6uek.x86_64kdump.img 
/boot/vmlinuz-4.1.12-61.1.9.el6uek.x86_64");
#print "Ending load thread $thr_id\n";
threads->detach(); #End thread.
});
threads->create(sub {
my $thr_id = threads->self->tid;
#print "Starting unload thread $thr_id\n";
system("/sbin/kexec  -p -u");
#print "Ending unload thread $thr_id\n";
    threads->detach(); #End thread.
});
}

for my $i (0..99)
{
threaded_task();
}


Eric DeVolder (2):
  kexec: use hypercall_create_continuation to protect KEXEC ops
  kexec: remove spinlock now that all KEXEC hypercall ops are protected
at the top-level

 xen/common/kexec.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v2 2/2] kexec: remove spinlock now that all KEXEC hypercall ops are protected at the top-level

2017-04-19 Thread Eric DeVolder

On 04/19/2017 08:37 AM, Jan Beulich wrote:

On 19.04.17 at 14:13,  wrote:

On Wed, Apr 19, 2017 at 05:20:50AM -0600, Jan Beulich wrote:

On 19.04.17 at 12:56,  wrote:

On Tue, Apr 18, 2017 at 04:49:48AM -0600, Jan Beulich wrote:

On 17.04.17 at 21:09,  wrote:

The spinlock in kexec_swap_images() was removed as
this function is only reachable on the kexec hypercall, which is
now protected at the top-level in do_kexec_op_internal(),
thus the local spinlock is no longer necessary.


But perhaps leave an ASSERT() there, making sure the in-hypercall
flag is set?


I am not sure why but if at all I think that we should also consider
other key kexec functions then. Or put ASSERT() into do_kexec_op_internal()
just before "switch ( op )".


The point of my placement suggestion was that the ASSERT()
effectively replaces the lock acquire - the places you name
didn't previously require any synchronization.


After the first patch of this series kexec_swap_images() cannot be
started twice in parallel. So, I do not see the point of ASSERT() here.
Or let's say we wish to have it to double check that "the in-hypercall
flag is set". AIUI, it is your original idea. However, then I think that
we should have an ASSERT() at least in kexec_load_slot() because parallel
loads make issues too. And we can go higher to feel more safe. That is
why I suggested do_kexec_op_internal() as the final resting place for
an ASSERT(). Simply it looks to me the safest approach. Am I missing
something?


The point you're missing is - why don't you then move the ASSERT()
yet one more level up, right next to where the flag is being set? IOW
what you suggest would imo rather mean not adding any assertion
at all.


I've just posted v3 of this patch with the ASSERT in lieu of the 
spin_lock().


Eric



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v2 1/2] kexec: use hypercall_create_continuation to protect KEXEC ops

2017-04-19 Thread Eric DeVolder

On 04/19/2017 06:48 AM, Andrew Cooper wrote:

On 19/04/17 12:00, Daniel Kiper wrote:

On Tue, Apr 18, 2017 at 04:48:06AM -0600, Jan Beulich wrote:

On 17.04.17 at 21:09,  wrote:

--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -50,9 +50,10 @@ static cpumask_t crash_saved_cpus;

 static struct kexec_image *kexec_image[KEXEC_IMAGE_NR];

-#define KEXEC_FLAG_DEFAULT_POS   (KEXEC_IMAGE_NR + 0)
-#define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1)
-#define KEXEC_FLAG_IN_PROGRESS   (KEXEC_IMAGE_NR + 2)
+#define KEXEC_FLAG_DEFAULT_POS(KEXEC_IMAGE_NR + 0)
+#define KEXEC_FLAG_CRASH_POS  (KEXEC_IMAGE_NR + 1)
+#define KEXEC_FLAG_IN_PROGRESS(KEXEC_IMAGE_NR + 2)
+#define KEXEC_FLAG_HC_IN_PROGRESS (KEXEC_IMAGE_NR + 3)

Perhaps KEXEC_FLAG_IN_HYPERCALL? Other than that (and this

Make sense for me.


Agreed.  (I can fix on commit).




clearly is subject to Andrew's opinion)
Reviewed-by: Jan Beulich 

Otherwise Reviewed-by: Daniel Kiper 


Reviewed-by: Andrew Cooper 

CC'ing Julien.  This is clearly a good bugfix for 4.9


I've just posted v3 of this patch with the flag name change.
Eric



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v3 2/2] kexec: remove spinlock now that all KEXEC hypercall ops are protected at the top-level

2017-04-19 Thread Eric DeVolder

On 04/19/2017 10:47 AM, Eric DeVolder wrote:

The spinlock in kexec_swap_images() was removed as
this function is only reachable on the kexec hypercall, which is
now protected at the top-level in do_kexec_op_internal(),
thus the local spinlock is no longer necessary.

Per recommendation from Jan Beulich and Andrew Cooper, I left
an ASSERT in place of the spin_lock().

Signed-off-by: Eric DeVolder 
Reviewed-by: Bhavesh Davda 
Reviewed-by: Konrad Rzeszutek Wilk 
---
v3:
 - Incorporated feedback from Jan Beulich and Andrew Cooper
   to leave an ASSERT where spin_lock() once was.

v2: 04/17/2017
 - Patch titled 'kexec: use hypercall_create_continuation to protect KEXEC ops'
 - Separated removal of spinlock in kexec_swap_images() into its own patch.

v1: 04/10/2017
 - Patch titled 'kexec: Add spinlock for the whole hypercall'
 - Removal of spinlock in kexec_swap_images() was part of other patch.
---
 xen/common/kexec.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 253c204..af32e58 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -820,7 +820,6 @@ static int kexec_exec(XEN_GUEST_HANDLE_PARAM(void) uarg)
 static int kexec_swap_images(int type, struct kexec_image *new,
  struct kexec_image **old)
 {
-static DEFINE_SPINLOCK(kexec_lock);
 int base, bit, pos;
 int new_slot, old_slot;

@@ -832,7 +831,7 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 if ( kexec_load_get_bits(type, &base, &bit) )
 return -EINVAL;

-spin_lock(&kexec_lock);
+ASSERT( !test_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags) );


There are two problems here: the spaces need to be eliminated, and more 
importantly, the sense/polarity of the expression is wrong, the '!' 
needs to be removed.




 pos = (test_bit(bit, &kexec_flags) != 0);
 old_slot = base + pos;
@@ -846,8 +845,6 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 clear_bit(old_slot, &kexec_flags);
 *old = kexec_image[old_slot];

-spin_unlock(&kexec_lock);
-
 return 0;
 }





___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v3 2/2] kexec: remove spinlock now that all KEXEC hypercall ops are protected at the top-level

2017-04-19 Thread Eric DeVolder

On 04/19/2017 11:21 AM, Jan Beulich wrote:

On 19.04.17 at 17:47,  wrote:

@@ -832,7 +831,7 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 if ( kexec_load_get_bits(type, &base, &bit) )
 return -EINVAL;

-spin_lock(&kexec_lock);
+ASSERT( !test_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags) );


Did you test this (in a debug build)? I ask because it looks to me that
you've inverted the condition.


You are correct, I inverted the condition. I had found this shortly 
after posting, and have corrected and have tested with Config.mk:debug=y


I will repost patch.

Thanks,
eric



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v4 2/2] kexec: remove spinlock now that all KEXEC hypercall ops are protected at the top-level

2017-04-19 Thread Eric DeVolder
The spinlock in kexec_swap_images() was removed as
this function is only reachable on the kexec hypercall, which is
now protected at the top-level in do_kexec_op_internal(),
thus the local spinlock is no longer necessary.

Per recommendation from Jan Beulich and Andrew Cooper, I left
an ASSERT in place of the spin_lock().

Signed-off-by: Eric DeVolder 
Reviewed-by: Bhavesh Davda 
Reviewed-by: Konrad Rzeszutek Wilk 
---
v4: 04/19/2017
 - Fix ASSERT to work properly. Tested with Config.mk:debug=y

v3: 04/19/2017
 - Incorporated feedback from Jan Beulich and Andrew Cooper
   to leave an ASSERT where spin_lock() once was.

v2: 04/17/2017
 - Patch titled 'kexec: use hypercall_create_continuation to protect KEXEC ops'
 - Separated removal of spinlock in kexec_swap_images() into its own patch.

v1: 04/10/2017
 - Patch titled 'kexec: Add spinlock for the whole hypercall'
 - Removal of spinlock in kexec_swap_images() was part of other patch.
---
 xen/common/kexec.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 253c204..96efa3b 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -820,7 +820,6 @@ static int kexec_exec(XEN_GUEST_HANDLE_PARAM(void) uarg)
 static int kexec_swap_images(int type, struct kexec_image *new,
  struct kexec_image **old)
 {
-static DEFINE_SPINLOCK(kexec_lock);
 int base, bit, pos;
 int new_slot, old_slot;
 
@@ -832,7 +831,7 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 if ( kexec_load_get_bits(type, &base, &bit) )
 return -EINVAL;
 
-spin_lock(&kexec_lock);
+ASSERT(test_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags));
 
 pos = (test_bit(bit, &kexec_flags) != 0);
 old_slot = base + pos;
@@ -846,8 +845,6 @@ static int kexec_swap_images(int type, struct kexec_image 
*new,
 clear_bit(old_slot, &kexec_flags);
 *old = kexec_image[old_slot];
 
-spin_unlock(&kexec_lock);
-
 return 0;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v4 0/2] kexec: Use hypercall_create_continuation to protect KEXEC ops

2017-04-19 Thread Eric DeVolder
During testing (using the script below) we found that multiple
invocations of kexec of unload/load are not safe.

This does not exist in classic Xen kernels in which the kexec-tools
did the kexec via Linux kernel syscall (which in turn made the
hypercall), as the Linux code has a mutex_trylock which would
inhibit multiple concurrent calls.

But with the kexec-tools utilizing xc_kexec_* that is no longer
the case and we need to protect against multiple concurrent
invocations.

Please see the patches and review at your convenience!

 try-crash.pl from bhavesh.da...@oracle.com 
#!/usr/bin/perl -w

use strict;
use warnings;
use threads;

sub threaded_task {
threads->create(sub {
my $thr_id = threads->self->tid;
#print "Starting load thread $thr_id\n";
system("/sbin/kexec  -p --command-line=\"placeholder 
root=/dev/mapper/nimbula-root ro rhbg console=tty0 console=hvc0 earlyprintk=xen 
nomodeset printk.time=1 irqpoll maxcpus=1 nr_cpus=1 reset_devices 
cgroup_disable=memory mce=off selinux=0 console=ttyS1,115200n8\" 
--initrd=/boot/initrd-4.1.12-61.1.9.el6uek.x86_64kdump.img 
/boot/vmlinuz-4.1.12-61.1.9.el6uek.x86_64");
#print "Ending load thread $thr_id\n";
threads->detach(); #End thread.
});
threads->create(sub {
my $thr_id = threads->self->tid;
#print "Starting unload thread $thr_id\n";
system("/sbin/kexec  -p -u");
#print "Ending unload thread $thr_id\n";
    threads->detach(); #End thread.
});
}

for my $i (0..99)
{
threaded_task();
}


Eric DeVolder (2):
  kexec: use hypercall_create_continuation to protect KEXEC ops
  kexec: remove spinlock now that all KEXEC hypercall ops are protected
at the top-level

 xen/common/kexec.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v4 1/2] kexec: use hypercall_create_continuation to protect KEXEC ops

2017-04-19 Thread Eric DeVolder
When we concurrently try to unload and load crash
images we eventually get:

 Xen call trace:
[] machine_kexec_add_page+0x3a0/0x3fa
[] machine_kexec_load+0xdb/0x107
[] kexec.c#kexec_load_slot+0x11/0x42
[] kexec.c#kexec_load+0x119/0x150
[] kexec.c#do_kexec_op_internal+0xab/0xcf
[] do_kexec_op+0xe/0x1e
[] pv_hypercall+0x20a/0x44a
[] cpufreq.c#test_all_events+0/0x30

 Pagetable walk from 820040088320:
  L4[0x104] = 0002979d1063 
  L3[0x001] = 0002979d0063 
  L2[0x000] = 0002979c7063 
  L1[0x088] = 80037a91ede97063 

The interesting thing is that the page bits (063) look legit.

The operation on which we blow up is us trying to write
in the L1 and finding that the L2 entry points to some
bizzare MFN. It stinks of a race, and it looks like
the issue is due to no concurrency locks when dealing
with the crash kernel space.

Specifically we concurrently call kimage_alloc_crash_control_page
which iterates over the kexec_crash_area.start -> kexec_crash_area.size
and once found:

  if ( page )
  {
  image->next_crash_page = hole_end;
  clear_domain_page(_mfn(page_to_mfn(page)));
  }

clears. Since the parameters of what MFN to use are provided
by the callers (and the area to search is bounded) the the 'page'
is probably the same. So #1 we concurrently clear the
'control_code_page'.

The next step is us passing this 'control_code_page' to
machine_kexec_add_page. This function requires the MFNs:
page_to_maddr(image->control_code_page).

And this would always return the same virtual address, as
the MFN of the control_code_page is inside of the
kexec_crash_area.start -> kexec_crash_area.size area.

Then machine_kexec_add_page updates the L1 .. which can be done
concurrently and on subsequent calls we mangle it up.

This is all a theory at this time, but testing reveals
that adding the hypercall_create_continuation() at the
kexec hypercall fixes the crash.

NOTE: This patch follows 5c5216 (kexec: clear kexec_image slot
when unloading kexec image) to prevent crashes during
simultaneous load/unloads.

NOTE: Consideration was given to using the existing flag
KEXEC_FLAG_IN_PROGRESS to denote a kexec hypercall in
progress. This, however, overloads the original intent of
the flag which is to denote that we are about-to/have made
the jump to the crash path. The overloading would lead to
failures in existing checks on this flag as the flag would
always be set at the top level in do_kexec_op_internal().
For this reason, the new flag KEXEC_FLAG_HC_IN_PROGRESS
was introduced.

While at it, fixed the #define mismatched spacing

Signed-off-by: Eric DeVolder 
Reviewed-by: Bhavesh Davda 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Jan Beulich 
Reviewed-by: Andrew Cooper 
Reviewed-by: Daniel Kiper 
---
v4: 04/19/2017
 - Unchanged

v3: 04/19/2017
 - Incorporated feedback from Jan Beulich to change the
   name of the new flag to KEXEC_FLAG_IN_HYPERCALL

v2: 04/17/2017
 - Patch titled 'kexec: use hypercall_create_continuation to protect KEXEC ops'
 - Jan Beulich directed me to use a continuation method instead
   of spinlock.
 - Incorporated feedback from Daniel Kiper 
 - Incorporated feedback from Konrad Wilk 

v1: 04/10/2017
 - Patch titled 'kexec: Add spinlock for the whole hypercall'
 - Used spinlock in do_kexec_op_internal()
---
 xen/common/kexec.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 072cc8e..253c204 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -50,9 +50,10 @@ static cpumask_t crash_saved_cpus;
 
 static struct kexec_image *kexec_image[KEXEC_IMAGE_NR];
 
-#define KEXEC_FLAG_DEFAULT_POS   (KEXEC_IMAGE_NR + 0)
-#define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1)
-#define KEXEC_FLAG_IN_PROGRESS   (KEXEC_IMAGE_NR + 2)
+#define KEXEC_FLAG_DEFAULT_POS  (KEXEC_IMAGE_NR + 0)
+#define KEXEC_FLAG_CRASH_POS(KEXEC_IMAGE_NR + 1)
+#define KEXEC_FLAG_IN_PROGRESS  (KEXEC_IMAGE_NR + 2)
+#define KEXEC_FLAG_IN_HYPERCALL (KEXEC_IMAGE_NR + 3)
 
 static unsigned long kexec_flags = 0; /* the lowest bits are for 
KEXEC_IMAGE... */
 
@@ -1193,6 +1194,9 @@ static int do_kexec_op_internal(unsigned long op,
 if ( ret )
 return ret;
 
+if ( test_and_set_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags) )
+return hypercall_create_continuation(__HYPERVISOR_kexec_op, "lh", op, 
uarg);
+
 switch ( op )
 {
 case KEXEC_CMD_kexec_get_range:
@@ -1227,6 +1231,8 @@ static int do_kexec_op_internal(unsigned long op,
 break;
 }
 
+clear_bit(KEXEC_FLAG_IN_HYPERCALL, &kexec_flags);
+
 return ret;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel