On Thu, Mar 22, 2018 at 11:40:46AM +0800, Zhe Liu wrote:
Hi! Recently, I encountered a seabios hanging problem. When I try to inject an MSI-X interrupt along with SMI in qemu like below: *************** patch below********************* diff --git a/target-i386/kvm.c b/target-i386/kvm.c- a/target-i386/kvm.c
--- a/target-i386/kvm.c +++ b/target-i386/kvm.c
@@ -104,6 +104,7 @@ static uint32_t num_architectural_pmu_counters; static int has_xsave; static int has_xcrs; static int has_pit_state2; +static int msi_count;
static bool has_msr_mcg_ext_ctl;
@@ -2870,12 +2871, 26 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) DPRINTF("inject SMI\n");
- MSIMessage msg = {.address = 0x0, .data = 0x4062};
- if (msi_count == 1) {
- ret = kvm_irqchip_send_msi(kvm_state, msg);
- if (ret <0) {
- QEMU_LOG(LOG_ALERT, "MSI lost %s\n", strerror(-ret));
- }
- }
- msi_count++;
ret = kvm_vcpu_ioctl(cpu, KVM_SMI); if (ret < 0) **************patch above*************************
Then, when the vm will hang when booting. There will be only one line in the vnc displayer: "Guest has not initialized the display(yet)"
I went through the codes(kvm qemu seabios), and I found the check_irqs function in seabios will allow interrupt for a while. When the interrupt triggered, the vcpu will lookup the seabios IDT table and jump to the interrupt handler.
However, in ivt_init(void), the entries from 0x60 to 0x66 will be cleared, which is configured by the patch below.
https://github.com/coreboot/seabios/commit/b164d2c1b8ff2dd764dcf064e2624dd4a...
So the vcpu will jump to an undefined entry instead of the default entry.
========================================================================= I removed the patch, and the bug seems to disappear. I wonder if this is an approprite solution.
This doesn't seem like a SeaBIOS issue. The real-mode handlers installed at 0x60-0x66 are intended for software interrupts; not for hardware raised interrupts.
I don't know why the machine irq routing would deliver a hardware interrupt to that vector, but I suspect that is what needs to be looked at.
-Kevin
So the vcpu will jump to an un This doesn't seem like a SeaBIOS issue. >The real-mode handlers installed at 0x60-0x66 are intended for >software interrupts; not for hardware raised interrupts.
Dear Kevin, Thanks for getting back to me. Your replay helps me a lot. And there are two things I want to make clear. 1. > The real-mode handlers installed at 0x60-0x66 are intended for software interrupts. During the booting of the vm seabios, which modules will raise the software interrupts? (Qemu? KVM? VirtualMachine?) 2. In src/post.c: init_ivt, the handlers for 0x60-0x66 is set to none as below. for (i=0x60; i<=0x66; i++) SET_IVT(i, SEGOFF(0, 0)); If I change the handlers of 0x60-0x66 to default handler, which is "iret" directly, is there some side effects?
2018-03-27 0:33 GMT+08:00 Kevin O'Connor kevin@koconnor.net:
On Thu, Mar 22, 2018 at 11:40:46AM +0800, Zhe Liu wrote:
Hi! Recently, I encountered a seabios hanging problem. When I try to inject
an
MSI-X interrupt along with SMI in qemu like below: *************** patch below********************* diff --git a/target-i386/kvm.c b/target-i386/kvm.c- a/target-i386/kvm.c
--- a/target-i386/kvm.c +++ b/target-i386/kvm.c
@@ -104,6 +104,7 @@ static uint32_t num_architectural_pmu_counters; static int has_xsave; static int has_xcrs; static int has_pit_state2; +static int msi_count;
static bool has_msr_mcg_ext_ctl;
@@ -2870,12 +2871, 26 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) DPRINTF("inject SMI\n");
- MSIMessage msg = {.address = 0x0, .data = 0x4062};
- if (msi_count == 1) {
- ret = kvm_irqchip_send_msi(kvm_state, msg);
- if (ret <0) {
- QEMU_LOG(LOG_ALERT, "MSI lost %s\n", strerror(-ret));
- }
- }
- msi_count++;
ret = kvm_vcpu_ioctl(cpu, KVM_SMI); if (ret < 0) **************patch above*************************
Then, when the vm will hang when booting. There will be only one line in the vnc displayer: "Guest has not initialized the display(yet)"
I went through the codes(kvm qemu seabios), and I found the check_irqs function in seabios will allow interrupt for a while. When the interrupt triggered, the vcpu will lookup the seabios IDT table and jump to the interrupt handler.
However, in ivt_init(void), the entries from 0x60 to 0x66 will be
cleared,
which is configured by the patch below.
https://github.com/coreboot/seabios/commit/b164d2c1b8ff2dd76
4dcf064e2624dd4aa78c112
So the vcpu will jump to an undefined entry instead of the default entry.
============================================================
=============
I removed the patch, and the bug seems to disappear. I wonder if this is
an
approprite solution.
This doesn't seem like a SeaBIOS issue. The real-mode handlers installed at 0x60-0x66 are intended for software interrupts; not for hardware raised interrupts.
I don't know why the machine irq routing would deliver a hardware interrupt to that vector, but I suspect that is what needs to be looked at.
-Kevin