Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754293AbdGJT0V (ORCPT ); Mon, 10 Jul 2017 15:26:21 -0400 Received: from mail-pg0-f67.google.com ([74.125.83.67]:32809 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751994AbdGJT0T (ORCPT ); Mon, 10 Jul 2017 15:26:19 -0400 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: Re: RFC: Task switch emulation fails for VM86 mode From: Nadav Amit In-Reply-To: Date: Mon, 10 Jul 2017 12:26:16 -0700 Cc: Radim Krcmar , kvm , "linux-kernel@vger.kernel.org" , Jan Kiszka Message-Id: <06163BE3-B69A-477C-8F5F-CAF0DE71DCC9@gmail.com> References: To: Paolo Bonzini , Wanpeng Li X-Mailer: Apple Mail (2.3273) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by nfs id v6AJQZai010171 Content-Length: 1668 Lines: 36 Paolo Bonzini 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.