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.
Paolo