All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] add MEMORY_FAILURE event
@ 2020-09-30 10:04 zhenwei pi
  2020-09-30 10:04 ` [PATCH v3 1/3] target-i386: seperate MCIP & MCE_MASK error reason zhenwei pi
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: zhenwei pi @ 2020-09-30 10:04 UTC (permalink / raw)
  To: pbonzini, peter.maydell; +Cc: qemu-devel, zhenwei pi

v2->v3:
Use g_strdup_printf instead of snprintf.
Declear memory failure event as 3 parts: 'recipient', 'action', 'flags'.
Wrapper function emit_guest_memory_failure&emit_hypervisor_memory_failure.

v1->v2:
Suggested by Peter Maydell, rename events to make them
architecture-neutral:
'PC-RAM' -> 'guest-memory'
'guest-triple-fault' -> 'guest-mce-fatal'

Suggested by Paolo, add more fields in event:
'action-required': boolean type to distinguish a guest-mce is AR/AO.
'recursive': boolean type. set true if: previous MCE in processing
             in guest, another AO MCE occurs.

v1:
Although QEMU could catch signal BUS to handle hardware memory
corrupted event, sadly, QEMU just prints a little log and try to fix
it silently.

In these patches, introduce a 'MEMORY_FAILURE' event with 4 detailed
actions of QEMU, then uplayer could know what situaction QEMU hit and
did. And further step we can do: if a host server hits a 'hypervisor-ignore'
or 'guest-mce', scheduler could migrate VM to another host; if hitting
'hypervisor-stop' or 'guest-triple-fault', scheduler could select other
healthy servers to launch VM.

Zhenwei Pi (3):
  target-i386: seperate MCIP & MCE_MASK error reason
  qapi/run-state.json: introduce memory failure event
  target-i386: post memory failure event to uplayer

 qapi/run-state.json  | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 target/i386/helper.c | 47 ++++++++++++++++++++++-------
 target/i386/kvm.c    | 13 +++++++-
 3 files changed, 134 insertions(+), 11 deletions(-)

-- 
2.11.0



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/3] target-i386: seperate MCIP & MCE_MASK error reason
  2020-09-30 10:04 [PATCH v3 0/3] add MEMORY_FAILURE event zhenwei pi
@ 2020-09-30 10:04 ` zhenwei pi
  2020-09-30 10:04 ` [PATCH v3 2/3] qapi/run-state.json: introduce memory failure event zhenwei pi
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: zhenwei pi @ 2020-09-30 10:04 UTC (permalink / raw)
  To: pbonzini, peter.maydell; +Cc: qemu-devel, zhenwei pi

Previously we can only get a simple string "Triple fault" in qemu
log. Add detailed message for the two reasons to describe why qemu
has to reset the guest.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
 target/i386/helper.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/target/i386/helper.c b/target/i386/helper.c
index 70be53e2c3..17e1684ff9 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -857,6 +857,8 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *cenv = &cpu->env;
     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
+    g_autofree char *msg = NULL;
+    bool need_reset = false;
 
     cpu_synchronize_state(cs);
 
@@ -894,16 +896,25 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
             return;
         }
 
-        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
-            !(cenv->cr[4] & CR4_MCE_MASK)) {
-            monitor_printf(params->mon,
-                           "CPU %d: Previous MCE still in progress, raising"
-                           " triple fault\n",
-                           cs->cpu_index);
-            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
+        if (cenv->mcg_status & MCG_STATUS_MCIP) {
+            need_reset = true;
+            msg = g_strdup_printf("CPU %d: Previous MCE still in progress, "
+                                  "raising triple fault", cs->cpu_index);
+        }
+
+        if (!(cenv->cr[4] & CR4_MCE_MASK)) {
+            need_reset = true;
+            msg = g_strdup_printf("CPU %d: MCE capability is not enabled, "
+                                  "raising triple fault", cs->cpu_index);
+        }
+
+        if (need_reset) {
+            monitor_printf(params->mon, "%s", msg);
+            qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
             return;
         }
+
         if (banks[1] & MCI_STATUS_VAL) {
             params->status |= MCI_STATUS_OVER;
         }
-- 
2.11.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/3] qapi/run-state.json: introduce memory failure event
  2020-09-30 10:04 [PATCH v3 0/3] add MEMORY_FAILURE event zhenwei pi
  2020-09-30 10:04 ` [PATCH v3 1/3] target-i386: seperate MCIP & MCE_MASK error reason zhenwei pi
@ 2020-09-30 10:04 ` zhenwei pi
  2020-09-30 10:04 ` [PATCH v3 3/3] target-i386: post memory failure event to uplayer zhenwei pi
  2020-10-01 17:28 ` [PATCH v3 0/3] add MEMORY_FAILURE event Paolo Bonzini
  3 siblings, 0 replies; 5+ messages in thread
From: zhenwei pi @ 2020-09-30 10:04 UTC (permalink / raw)
  To: pbonzini, peter.maydell; +Cc: qemu-devel, zhenwei pi

Introduce memory failure events for hyperviso/guest . Then uplayer
could know when/why/what happened during hitting a hardware memory
failure.

Suggested by Peter Maydell, rename events name&description to make
them architecture-neutral; and suggested by Paolo, add more info to
distinguish a mce is AR/AO, previous mce is still processing in
guest or not.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
 qapi/run-state.json | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/qapi/run-state.json b/qapi/run-state.json
index 7cc9f96a5b..d795dc21fc 100644
--- a/qapi/run-state.json
+++ b/qapi/run-state.json
@@ -475,3 +475,88 @@
            'psw-mask': 'uint64',
            'psw-addr': 'uint64',
            'reason': 'S390CrashReason' } }
+
+##
+# @MEMORY_FAILURE:
+#
+# Emitted when a memory failure occurs on host side.
+#
+# @recipient: recipient is defined as @MemoryFailureRecipient.
+#
+# @action: action that has been taken. action is defined as @MemoryFailureAction.
+#
+# @flags: flags for MemoryFailureAction. action is defined as @MemoryFailureFlags.
+#
+# Since: 5.2
+#
+# Example:
+#
+# <- { "event": "MEMORY_FAILURE",
+#      "data": { "action": "guest-mce" } }
+#
+##
+{ 'event': 'MEMORY_FAILURE',
+  'data': { 'recipient': 'MemoryFailureRecipient',
+            'action': 'MemoryFailureAction',
+            'flags': 'MemoryFailureFlags'} }
+
+##
+# @MemoryFailureRecipient:
+#
+# Hardware memory failure occurs, handled by recipient.
+#
+# @hypervisor: memory failure at QEMU process address space.
+#              (none guest memory, but used by QEMU itself).
+#
+# @guest: memory failure at guest memory,
+#
+# Since: 5.2
+#
+##
+{ 'enum': 'MemoryFailureRecipient',
+  'data': [ 'hypervisor',
+            'guest' ] }
+
+
+##
+# @MemoryFailureAction:
+#
+# Hardware memory failure occurs, action by QEMU.
+#
+# @ignore: action optional memory failure which could be ignored.
+#
+# @inject: memory failure at guest memory, and guest enables MCE handling
+#          mechanism, QEMU injects MCE to guest successfully.
+#
+# @fatal: action required memory failure occurs. If recipient is hypervior, QEMU
+#         hits a fatal error and exits later. And if recipient is guest, QEMU
+#         tries to inject MCE to guest, but guest is not ready to handle MCE
+#         (typical cases: guest has no MCE mechanism, or guest disables MCE,
+#         or during previous MCE still in processing, an AR MCE occurs). QEMU
+#         has to raise a fault and shutdown/reset. Also see detailed info in
+#         QEMU log.
+#
+# Since: 5.2
+#
+##
+{ 'enum': 'MemoryFailureAction',
+  'data': [ 'ignore',
+            'inject',
+            'fatal' ] }
+
+##
+# @MemoryFailureFlags:
+#
+# Structure of flags for each memory failure event.
+#
+# @action-required: describe a MCE event as AR/AO.
+#
+# @recursive: previous MCE in processing in guest, another AO MCE
+#             occurs, set recursive as true.
+#
+# Since: 5.2
+#
+##
+{ 'struct': 'MemoryFailureFlags',
+  'data': { 'action-required': 'bool',
+            'recursive': 'bool'} }
-- 
2.11.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 3/3] target-i386: post memory failure event to uplayer
  2020-09-30 10:04 [PATCH v3 0/3] add MEMORY_FAILURE event zhenwei pi
  2020-09-30 10:04 ` [PATCH v3 1/3] target-i386: seperate MCIP & MCE_MASK error reason zhenwei pi
  2020-09-30 10:04 ` [PATCH v3 2/3] qapi/run-state.json: introduce memory failure event zhenwei pi
@ 2020-09-30 10:04 ` zhenwei pi
  2020-10-01 17:28 ` [PATCH v3 0/3] add MEMORY_FAILURE event Paolo Bonzini
  3 siblings, 0 replies; 5+ messages in thread
From: zhenwei pi @ 2020-09-30 10:04 UTC (permalink / raw)
  To: pbonzini, peter.maydell; +Cc: qemu-devel, zhenwei pi

Post memory failure event to uplayer to handle hardware memory
corrupted event. Rather than simple QEMU log, QEMU could report more
effective message to uplayer. For example, guest crashes by MCE,
selecting another host server is a better choice.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
 target/i386/helper.c | 24 ++++++++++++++++++++----
 target/i386/kvm.c    | 13 ++++++++++++-
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/target/i386/helper.c b/target/i386/helper.c
index 17e1684ff9..2a184c4835 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -18,6 +18,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/qapi-events-run-state.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "qemu/qemu-print.h"
@@ -851,6 +852,15 @@ typedef struct MCEInjectionParams {
     int flags;
 } MCEInjectionParams;
 
+static void emit_guest_memory_failure(MemoryFailureAction action, bool ar,
+                                      bool recursive)
+{
+    MemoryFailureFlags mff = {.action_required = ar, .recursive = recursive};
+
+    qapi_event_send_memory_failure(MEMORY_FAILURE_RECIPIENT_GUEST, action,
+                                   &mff);
+}
+
 static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
 {
     MCEInjectionParams *params = data.host_ptr;
@@ -859,16 +869,18 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
     g_autofree char *msg = NULL;
     bool need_reset = false;
+    bool recursive;
+    bool ar = !!(params->status & MCI_STATUS_AR);
 
     cpu_synchronize_state(cs);
+    recursive = !!(cenv->mcg_status & MCG_STATUS_MCIP);
 
     /*
      * If there is an MCE exception being processed, ignore this SRAO MCE
      * unless unconditional injection was requested.
      */
-    if (!(params->flags & MCE_INJECT_UNCOND_AO)
-        && !(params->status & MCI_STATUS_AR)
-        && (cenv->mcg_status & MCG_STATUS_MCIP)) {
+    if (!(params->flags & MCE_INJECT_UNCOND_AO) && !ar && recursive) {
+        emit_guest_memory_failure(MEMORY_FAILURE_ACTION_IGNORE, ar, recursive);
         return;
     }
 
@@ -896,7 +908,7 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
             return;
         }
 
-        if (cenv->mcg_status & MCG_STATUS_MCIP) {
+        if (recursive) {
             need_reset = true;
             msg = g_strdup_printf("CPU %d: Previous MCE still in progress, "
                                   "raising triple fault", cs->cpu_index);
@@ -909,6 +921,8 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
         }
 
         if (need_reset) {
+            emit_guest_memory_failure(MEMORY_FAILURE_ACTION_FATAL, ar,
+                                      recursive);
             monitor_printf(params->mon, "%s", msg);
             qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
@@ -934,6 +948,8 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
     } else {
         banks[1] |= MCI_STATUS_OVER;
     }
+
+    emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
 }
 
 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 9efb07e7c8..923749f5d8 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -13,6 +13,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/qapi-events-run-state.h"
 #include "qapi/error.h"
 #include <sys/ioctl.h>
 #include <sys/utsname.h>
@@ -575,8 +576,17 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
                        (MCM_ADDR_PHYS << 6) | 0xc, flags);
 }
 
+static void emit_hypervisor_memory_failure(MemoryFailureAction action, bool ar)
+{
+    MemoryFailureFlags mff = {.action_required = ar, .recursive = false};
+
+    qapi_event_send_memory_failure(MEMORY_FAILURE_RECIPIENT_HYPERVISOR, action,
+                                   &mff);
+}
+
 static void hardware_memory_error(void *host_addr)
 {
+    emit_hypervisor_memory_failure(MEMORY_FAILURE_ACTION_FATAL, true);
     error_report("QEMU got Hardware memory error at addr %p", host_addr);
     exit(1);
 }
@@ -631,7 +641,8 @@ void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
         hardware_memory_error(addr);
     }
 
-    /* Hope we are lucky for AO MCE */
+    /* Hope we are lucky for AO MCE, just notify a event */
+    emit_hypervisor_memory_failure(MEMORY_FAILURE_ACTION_IGNORE, false);
 }
 
 static void kvm_reset_exception(CPUX86State *env)
-- 
2.11.0



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 0/3] add MEMORY_FAILURE event
  2020-09-30 10:04 [PATCH v3 0/3] add MEMORY_FAILURE event zhenwei pi
                   ` (2 preceding siblings ...)
  2020-09-30 10:04 ` [PATCH v3 3/3] target-i386: post memory failure event to uplayer zhenwei pi
@ 2020-10-01 17:28 ` Paolo Bonzini
  3 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2020-10-01 17:28 UTC (permalink / raw)
  To: zhenwei pi, peter.maydell; +Cc: qemu-devel

On 30/09/20 12:04, zhenwei pi wrote:
> v2->v3:
> Use g_strdup_printf instead of snprintf.
> Declear memory failure event as 3 parts: 'recipient', 'action', 'flags'.
> Wrapper function emit_guest_memory_failure&emit_hypervisor_memory_failure.

Queued, thanks.  I took the liberty of adding a fourth value to
MemoryFailureAction, "reset", since "fatal" was used for two different
actions.

Paolo

> v1->v2:
> Suggested by Peter Maydell, rename events to make them
> architecture-neutral:
> 'PC-RAM' -> 'guest-memory'
> 'guest-triple-fault' -> 'guest-mce-fatal'
> 
> Suggested by Paolo, add more fields in event:
> 'action-required': boolean type to distinguish a guest-mce is AR/AO.
> 'recursive': boolean type. set true if: previous MCE in processing
>              in guest, another AO MCE occurs.
> 
> v1:
> Although QEMU could catch signal BUS to handle hardware memory
> corrupted event, sadly, QEMU just prints a little log and try to fix
> it silently.
> 
> In these patches, introduce a 'MEMORY_FAILURE' event with 4 detailed
> actions of QEMU, then uplayer could know what situaction QEMU hit and
> did. And further step we can do: if a host server hits a 'hypervisor-ignore'
> or 'guest-mce', scheduler could migrate VM to another host; if hitting
> 'hypervisor-stop' or 'guest-triple-fault', scheduler could select other
> healthy servers to launch VM.
> 
> Zhenwei Pi (3):
>   target-i386: seperate MCIP & MCE_MASK error reason
>   qapi/run-state.json: introduce memory failure event
>   target-i386: post memory failure event to uplayer
> 
>  qapi/run-state.json  | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  target/i386/helper.c | 47 ++++++++++++++++++++++-------
>  target/i386/kvm.c    | 13 +++++++-
>  3 files changed, 134 insertions(+), 11 deletions(-)
> 



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-10-01 17:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-30 10:04 [PATCH v3 0/3] add MEMORY_FAILURE event zhenwei pi
2020-09-30 10:04 ` [PATCH v3 1/3] target-i386: seperate MCIP & MCE_MASK error reason zhenwei pi
2020-09-30 10:04 ` [PATCH v3 2/3] qapi/run-state.json: introduce memory failure event zhenwei pi
2020-09-30 10:04 ` [PATCH v3 3/3] target-i386: post memory failure event to uplayer zhenwei pi
2020-10-01 17:28 ` [PATCH v3 0/3] add MEMORY_FAILURE event Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.