> 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