diff mbox

[QUESTION] stuck in SeaBIOS because of losing a SMI

Message ID 8E78D212B8C25246BE4CE7EA0E645FE53EFD8C@SZXEMI504-MBS.china.huawei.com
State New
Headers show

Commit Message

Xulei (Stone, Euler) Aug. 3, 2016, 9:43 a.m. UTC
Hi, all:
Recently I use a shell script to continuously reset a vm to see what may happen.
After one day, the vm is stuck. Looking from the following seabios log and
kvm trace log, it seems like losing a SMI or SeaBIOS can not handle a SMI.
This problem is reproducible on my machine (SeaBIOS 1.9.1, Qemu 2.6.0,
Kmod 4.4.11).

2016-08-03 16:23:15init smm
2016-08-03 16:23:15before SMI====
2016-08-03 16:23:15after SMI=====     <----always stuck here, unless i destroy it

As above, it is obviously that if bios doesn't handle_smi, PORT_SMI_STATUS is
always 0x01. smm_relocate_and_restore() will always in the while loop.

Why does bios handle_smi at this point, is this a kvm bug? or SeaBIOS bug?

--------------
Xulei (Stone)

Comments

Paolo Bonzini Aug. 3, 2016, 10:32 a.m. UTC | #1
On 03/08/2016 11:43, Xulei (Stone) wrote:
> Hi, all:
> Recently I use a shell script to continuously reset a vm to see what may happen.
> After one day, the vm is stuck. Looking from the following seabios log and
> kvm trace log, it seems like losing a SMI or SeaBIOS can not handle a SMI.
> This problem is reproducible on my machine (SeaBIOS 1.9.1, Qemu 2.6.0,
> Kmod 4.4.11).

Thanks for the report!

The more interesting part of the trace would be around the pio_write at
0xb2.  Also please try kernel commit c43203cab1e, which just went into 4.8.

Paolo

> ==================my shell script===
> #!/bin/bash
> while((1))
> do
> virsh reset VMNAME
> sleep 1
> done
> 
> ==================kvm trace log===
> CPU 0/KVM-13843 [020] d... 1025056.813494: kvm_entry: vcpu 0
> CPU 0/KVM-13843 [020] .... 1025056.813495: kvm_exit: reason IO_INSTRUCTION rip 0xef10e info b30048 0
> CPU 0/KVM-13843 [020] .... 1025056.813495: kvm_emulate_insn: 0:ef10e:e4 b3 (prot32)
> CPU 0/KVM-13843 [020] .... 1025056.813496: kvm_userspace_exit: reason KVM_EXIT_IO (2)
> CPU 0/KVM-13843 [020] .... 1025056.813496: kvm_fpu: unload
> CPU 0/KVM-13843 [020] .... 1025056.813497: kvm_pio: pio_read at 0xb3 size 1 count 1 val 0x1
> CPU 0/KVM-13843 [020] .... 1025056.813497: kvm_fpu: load
> CPU 0/KVM-13843 [020] d... 1025056.813497: kvm_entry: vcpu 0
> CPU 0/KVM-13843 [020] .... 1025056.813498: kvm_exit: reason IO_INSTRUCTION rip 0xef10e info b30048 0
> CPU 0/KVM-13843 [020] .... 1025056.813498: kvm_emulate_insn: 0:ef10e:e4 b3 (prot32)
> CPU 0/KVM-13843 [020] .... 1025056.813499: kvm_userspace_exit: reason KVM_EXIT_IO (2)
> CPU 0/KVM-13843 [020] .... 1025056.813499: kvm_fpu: unload
> CPU 0/KVM-13843 [020] .... 1025056.813500: kvm_pio: pio_read at 0xb3 size 1 count 1 val 0x1
> CPU 0/KVM-13843 [020] .... 1025056.813500: kvm_fpu: load
> 
> ==================my seabios log===
> --- a/roms/seabios/src/fw/smm.c
> +++ b/roms/seabios/src/fw/smm.c
> @@ -65,7 +65,8 @@ handle_smi(u16 cs)
>      u8 cmd = inb(PORT_SMI_CMD);
>      struct smm_layout *smm = MAKE_FLATPTR(cs, 0);
>      u32 rev = smm->cpu.i32.smm_rev & SMM_REV_MASK;
> -    dprintf(DEBUG_HDL_smi, "handle_smi cmd=%x smbase=%p\n", cmd, smm);
> +    if(cmd == 0x00) {
> +    	dprintf(1, "handle_smi cmd=%x smbase=%p\n", cmd, smm);
> +    }
>  
>      if (smm == (void*)BUILD_SMM_INIT_ADDR) {
>          // relocate SMBASE to 0xa0000
> @@ -147,14 +148,14 @@ smm_relocate_and_restore(void)
>  {
>      /* init APM status port */
>      outb(0x01, PORT_SMI_STATUS);
> +   dprintf(1,"before SMI====\n");
> 
>      /* raise an SMI interrupt */
>      outb(0x00, PORT_SMI_CMD);
> +    dprintf(1,"after SMI=====\n");
> 
>      /* wait until SMM code executed */
>      while (inb(PORT_SMI_STATUS) != 0x00)
>          ;
> +   dprintf(1,"smm code executes complete====\n");
> 
> And the log output like this:
> 2016-08-03 16:23:15PCI: Using 00:02.0 for primary VGA
> 2016-08-03 16:23:15smm_device_setup start
> 2016-08-03 16:23:15init smm
> 2016-08-03 16:23:15before SMI====
> 2016-08-03 16:23:15after SMI=====     <----always stuck here, unless i destroy it
> 
> As above, it is obviously that if bios doesn't handle_smi, PORT_SMI_STATUS is
> always 0x01. smm_relocate_and_restore() will always in the while loop.
> 
> Why does bios handle_smi at this point, is this a kvm bug? or SeaBIOS bug?
> 
> --------------
> Xulei (Stone)
>
diff mbox

Patch

==================my shell script===
#!/bin/bash
while((1))
do
virsh reset VMNAME
sleep 1
done

==================kvm trace log===
CPU 0/KVM-13843 [020] d... 1025056.813494: kvm_entry: vcpu 0
CPU 0/KVM-13843 [020] .... 1025056.813495: kvm_exit: reason IO_INSTRUCTION rip 0xef10e info b30048 0
CPU 0/KVM-13843 [020] .... 1025056.813495: kvm_emulate_insn: 0:ef10e:e4 b3 (prot32)
CPU 0/KVM-13843 [020] .... 1025056.813496: kvm_userspace_exit: reason KVM_EXIT_IO (2)
CPU 0/KVM-13843 [020] .... 1025056.813496: kvm_fpu: unload
CPU 0/KVM-13843 [020] .... 1025056.813497: kvm_pio: pio_read at 0xb3 size 1 count 1 val 0x1
CPU 0/KVM-13843 [020] .... 1025056.813497: kvm_fpu: load
CPU 0/KVM-13843 [020] d... 1025056.813497: kvm_entry: vcpu 0
CPU 0/KVM-13843 [020] .... 1025056.813498: kvm_exit: reason IO_INSTRUCTION rip 0xef10e info b30048 0
CPU 0/KVM-13843 [020] .... 1025056.813498: kvm_emulate_insn: 0:ef10e:e4 b3 (prot32)
CPU 0/KVM-13843 [020] .... 1025056.813499: kvm_userspace_exit: reason KVM_EXIT_IO (2)
CPU 0/KVM-13843 [020] .... 1025056.813499: kvm_fpu: unload
CPU 0/KVM-13843 [020] .... 1025056.813500: kvm_pio: pio_read at 0xb3 size 1 count 1 val 0x1
CPU 0/KVM-13843 [020] .... 1025056.813500: kvm_fpu: load

==================my seabios log===
--- a/roms/seabios/src/fw/smm.c
+++ b/roms/seabios/src/fw/smm.c
@@ -65,7 +65,8 @@  handle_smi(u16 cs)
     u8 cmd = inb(PORT_SMI_CMD);
     struct smm_layout *smm = MAKE_FLATPTR(cs, 0);
     u32 rev = smm->cpu.i32.smm_rev & SMM_REV_MASK;
-    dprintf(DEBUG_HDL_smi, "handle_smi cmd=%x smbase=%p\n", cmd, smm);
+    if(cmd == 0x00) {
+    	dprintf(1, "handle_smi cmd=%x smbase=%p\n", cmd, smm);
+    }
 
     if (smm == (void*)BUILD_SMM_INIT_ADDR) {
         // relocate SMBASE to 0xa0000
@@ -147,14 +148,14 @@  smm_relocate_and_restore(void)
 {
     /* init APM status port */
     outb(0x01, PORT_SMI_STATUS);
+   dprintf(1,"before SMI====\n");

     /* raise an SMI interrupt */
     outb(0x00, PORT_SMI_CMD);
+    dprintf(1,"after SMI=====\n");

     /* wait until SMM code executed */
     while (inb(PORT_SMI_STATUS) != 0x00)
         ;
+   dprintf(1,"smm code executes complete====\n");

And the log output like this:
2016-08-03 16:23:15PCI: Using 00:02.0 for primary VGA
2016-08-03 16:23:15smm_device_setup start