> On 09/08/2016 10:04, Xulei (Stone) wrote: > > Following your suggestion, i'm now sure it is caused by missing SMI. > > I have tried adding dprintf() like this: > > > > --- 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 failed case 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===== > > > > So, it's obviously that after outb(0x01, PORT_SMI_STATUS), bios does > > not handle_smi, so PORT_SMI_STATUS is always 0x01. What's more, when > > this problem happens, rebooting vm cannot restore it any more. My vm > > is always stuck at the same place until i destroy it. > > > > And I have already tried kernel commit c43203cab1e which still can not > > solve this problem. > > Any idea, Kevin and Paolo? > > 0xb2 is handled within QEMU, so it may be useful to make sure that QEMU is > sending the KVM_SMI ioctl. From there the best tool is still KVM tracing and > printk. I suggest replacing the dprintf with a simple outb like outb(0x21, > 0x402) (before) and outb(0x23, 0x402) (after). They show as "!" and "#" in > the > trace, and they are easy to spot in the KVM trace.
Following your suggestion, I found this problem may be caused by the flag of HF_SMM_MASK. I'm now sure QEMU is sending the KVM_SMI ioctl, and kmod already handles this ioctl. I add printk in inject_pending_event(), like this: /* try to inject new event if pending */ + if(get_smi) + printk(KERN_INFO "is_smm:%d\n", is_smm(vcpu)); + if (vcpu->arch.smi_pending && !is_smm(vcpu)) { vcpu->arch.smi_pending = false; process_smi(vcpu); } Then I found that the normal output is (is_smm is 0): 2016-08-11T09:44:45.090078+08:00|info|kernel[-]|[1269634.151054get smi ioctl from qemu 2016-08-11T09:44:45.090097+08:00|info|kernel[-]|[1269634.151056in process_smi_request 2016-08-11T09:44:45.090114+08:00|info|kernel[-]|[1269634.151057is_smm:0 2016-08-11T09:44:45.090131+08:00|info|kernel[-]|[1269634.151058process smi 2016-08-11T09:44:45.090914+08:00|info|kernel[-]|[1269634.151575get smi ioctl from qemu 2016-08-11T09:44:45.090947+08:00|info|kernel[-]|[1269634.151578in process_smi_request 2016-08-11T09:44:45.090972+08:00|info|kernel[-]|[1269634.151579is_smm:0 When problem occurs the output is (is_smm is 1): 2016-08-11T10:07:11.755982+08:00|info|kernel[-]|[1270981.916056get smi ioctl from qemu 2016-08-11T10:07:11.756035+08:00|info|kernel[-]|[1270981.916062in process_smi_request 2016-08-11T10:07:11.756078+08:00|info|kernel[-]|[1270981.916064is_smm:1 2016-08-11T10:07:13.896977+08:00|info|kernel[-]|[1270984.058117get smi ioctl from qemu 2016-08-11T10:07:13.897063+08:00|info|kernel[-]|[1270984.058121in process_smi_request 2016-08-11T10:07:13.897091+08:00|info|kernel[-]|[1270984.058123is_smm:1 So, it seems kvm cannot set HF_SMM_MASK flag correctly when we continuously reset VM. Any futher suggestion? Paolo :) > Paolo