qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] ipmi: check ibe status before ibe outlen at ipmi_bm


From: xinhua.Cao
Subject: [Qemu-devel] [PATCH] ipmi: check ibe status before ibe outlen at ipmi_bmc_extern_handle_command
Date: Thu, 16 Nov 2017 13:25:11 +0800

When we always kill vm's ipmi_sim program. qemu will do handling chr_event
to reconnect ipmi_sim. handling chain is chr_event -> continue_send ->
qemu_chr_fe_write. if ipmi_sim program was killed again. then qemu_chr_fe_write
will failed. then ibe's outlen and outbuf will not cleared. so if vcpu handle
a ipmi_bmc_extern_handle_command. qemu aborted. here is backtrace.

(gdb) bt
0  0x00007f3d9f4181d7 in raise () from /usr/lib64/libc.so.6
1  0x00007f3d9f4198c8 in abort () from /usr/lib64/libc.so.6
2  0x0000000000635c20 in ipmi_bmc_extern_handle_command (b=<optimized out>,
   cmd=0x4290198 "\030\001\004\001", cmd_len=2,
   max_cmd_len=300, msg_id=39 '\'') at hw/ipmi/ipmi_bmc_extern.c:586
3  0x0000000000636e1d in ipmi_kcs_signal (ii=0x428fea0, ik=<optimized out>)
   at hw/ipmi/isa_ipmi_kcs.c:126
4  0x000000000047341a in memory_region_write_accessor (mr=0x428ff60, addr=0,
   value=<optimized out>, size=1, shift=<optimized out>, mask=<optimized out>,
   attrs=...) at /root/rpmbuild/BUILD/qemu-kvm-2.8.1/memory.c:527
5  0x000000000047221f in access_with_adjusted_size (address@hidden,
   address@hidden, address@hidden,
   access_size_min=<optimized out>, access_size_max=<optimized out>,
   address@hidden <memory_region_write_accessor>,
   address@hidden, address@hidden)
   at /root/rpmbuild/BUILD/qemu-kvm-2.8.1/memory.c:593
6  0x0000000000473e4d in memory_region_dispatch_write (address@hidden,
   address@hidden, data=1, address@hidden, address@hidden) at
   /root/rpmbuild/BUILD/qemu-kvm-2.8.1/memory.c:1334
7  0x000000000042c2ed in address_space_write_continue (address@hidden
   <address_space_io>, address@hidden, attrs=..., address@hidden,
   address@hidden <Address 0x7f3da59fe000 out of bounds>, address@hidden,
   addr1=0, l=1, mr=0x428ff60) at 
/root/rpmbuild/BUILD/qemu-kvm-2.8.1/exec.c:2998
8  0x000000000042de66 in address_space_write (as=0xecb400 <address_space_io>,
   addr=3234, attrs=...,buf=0x7f3da59fe000 <Address 0x7f3da59fe000 out of 
bounds>,
   len=1) at /root/rpmbuild/BUILD/qemu-kvm-2.8.1/exec.c:3043
9  0x000000000042e34d in address_space_rw (as=<optimized out>, address@hidden,
   attrs=..., address@hidden, address@hidden <Address 0x7f3da59fe000
   out of bounds>, address@hidden, address@hidden)
   at /root/rpmbuild/BUILD/qemu-kvm-2.8.1/exec.c:3145
10 0x000000000046b751 in kvm_handle_io (port=3234, address@hidden,
   data=<optimized out>, direction=<optimized out>, size=1, count=1)
   at /root/rpmbuild/BUILD/qemu-kvm-2.8.1/kvm_all.c:1822
11 0x000000000046f4a7 in kvm_cpu_exec (address@hidden)
   at /root/rpmbuild/BUILD/qemu-kvm-2.8.1/kvm_all.c:1980
12 0x0000000000459cf5 in qemu_kvm_cpu_thread_fn (address@hidden)
   at /root/rpmbuild/BUILD/qemu-kvm-2.8.1/cpus.c:1072
13 0x0000000000848818 in thread_entry_for_hotfix (pthread_cb=<optimized out>)
   at uvp/hotpatch/qemu_hotpatch_helper.c:502
14 0x00007f3d9f7acdc5 in start_thread () from /usr/lib64/libpthread.so.0
15 0x00007f3d9f4da6fd in clone () from /usr/lib64/libc.so.6

we check ibe status before ibe outlen at ipmi_bmc_extern_handle_command to fix 
this abort.
---
 hw/ipmi/ipmi_bmc_extern.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index abab3bb..7a49050 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -192,13 +192,6 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
     uint8_t err = 0, csum;
     unsigned int i;
 
-    if (ibe->outlen) {
-        /* We already have a command queued.  Shouldn't ever happen. */
-        fprintf(stderr, "IPMI KCS: Got command when not finished with the"
-                " previous command\n");
-        abort();
-    }
-
     /* If it's too short or it was truncated, return an error. */
     if (cmd_len < 2) {
         err = IPMI_CC_REQUEST_DATA_LENGTH_INVALID;
@@ -206,7 +199,10 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
         err = IPMI_CC_REQUEST_DATA_TRUNCATED;
     } else if (!ibe->connected) {
         err = IPMI_CC_BMC_INIT_IN_PROGRESS;
+    } else if (ibe->wdt_state.trans_fail) {
+        err = IPMI_CC_BMC_INIT_IN_PROGRESS;
     }
+
     if (err) {
         IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
         unsigned char rsp[3];
@@ -218,6 +214,12 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
         goto out;
     }
 
+    if (ibe->outlen) {
+        /* We already have a command queued.  Shouldn't ever happen. */
+        QEMU_LOG(LOG_ERR, "IPMI KCS: Got command when not finished with the 
previous command\n");
+        abort();
+    }
+
     addchar(ibe, msg_id);
     for (i = 0; i < cmd_len; i++) {
         addchar(ibe, cmd[i]);
@@ -390,6 +392,7 @@ static void chr_event(void *opaque, int event)
 
     switch (event) {
     case CHR_EVENT_OPENED:
+        QEMU_LOG(LOG_INFO, "open ipmi device\n");
         ibe->connected = true;
         ibe->outpos = 0;
         ibe->outlen = 0;
-- 
2.8.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]