Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote: > On 10/07/2017 17:48, Nadav Amit wrote: >>>> Any proposal is a great appreciated. :) >> I don’t see a (very) easy solution. The code was (apparently) never built to >> deal with a task switch during an instruction emulation. >> >> AFAIU kvm_task_switch() expects information about the task-switch from the >> CPU “task-switch assist” mechanisms, and this information (or even the fact >> that a task-switch is needed due to an exception) are unavailable from the >> instruction emulator. The instruction emulator itself does not know to >> emulate task-switches, e.g., during far CALL and JMP. >> >> A complete solution is therefore complicated and requires some work. Your >> specific problem may be addressed by detecting the injection of an exception >> while having invalid guest state in vm86 in vmx_queue_exception() or in >> handle_invalid_guest_state(), and emulating the “task-switch assist” >> mechanism. > > I agree, the right solution would be to read the IDT in > vmx_queue_exception if vmx->emulation_required, and inject the exception > manually. It would be an extension of what > kvm_inject_realmode_interrupt already does. I take it back. While everything I said is true, there is no reason for the guest state to be invalid in vm86, at least in the unit-test. It appears that the task-switch emulation updates rflags (and vm86 flag) only after the segments are loaded, causing vmx->emulation_required to be set, when in fact emulation is not needed. And indeed adding in the end of handle_task_switch(): vmx->emulation_required = emulation_required(vcpu); solves the problem for me.