From patchwork Tue Nov 26 12:03:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11262017 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CEF796C1 for ; Tue, 26 Nov 2019 12:05:07 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AC1DA2073F for ; Tue, 26 Nov 2019 12:05:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="DPuLksMh" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AC1DA2073F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iZZZf-0002IX-7h; Tue, 26 Nov 2019 12:04:07 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iZZZe-0002IN-4p for xen-devel@lists.xenproject.org; Tue, 26 Nov 2019 12:04:06 +0000 X-Inumbo-ID: d6ab1fa0-1044-11ea-a39f-12813bfff9fa Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id d6ab1fa0-1044-11ea-a39f-12813bfff9fa; Tue, 26 Nov 2019 12:04:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1574769844; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=h/iuozQJW1O4FqIa7Nx7Z47sjsCmC5q0fa/egETCNg4=; b=DPuLksMhMtc0OcCt3RnoTyAk0lWzxcO6L9abpIsvCK0KLuUynrzkrXaF uYuoB9KU6Jy3cF39vqHucjE/0mDN/ROqp3yHMSQAhBfVtC2mEZs7MfqvT W67TA7pNc3C7IrgOyH7fiCGswske5/hXl7MUZ+92c3WwXZZgKOErloMDd g=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa1.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa1.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa1.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: vOS1mDKnpqUq8Q3PVtN6XQq/G/LQa8TQZFFs6es2KrXgmbPAZmIg8/bY0T60vnd0Ezm8KCbdNo hxf+QuL2tJoGriqF22iIDBTn+zhbmGJLHixWxVP2Mm9nIQBpgiM+bV48wH1WV7RfY25jW4Uzhc azfdziSavidJIIkRJcGATR0t60NGMcjA0wWhg7zxAIR3Yf+GmBDcSuU37WZyjCHiHXyFfSOi/i ybn8tV5u5ohu6W4IKynUntzroQh3RuzWHJaYlFUZf6EEW5P/+lZSJ8iZzYEI31d3Ew4sNpmTtl Pdk= X-SBRS: 2.7 X-MesageID: 8964952 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,245,1571716800"; d="scan'208";a="8964952" From: Andrew Cooper To: Xen-devel Date: Tue, 26 Nov 2019 12:03:55 +0000 Message-ID: <20191126120357.13398-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191126120357.13398-1-andrew.cooper3@citrix.com> References: <20191126120357.13398-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v2 1/3] x86/vtx: Fix fault semantics for early task switch failures X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" The VT-x task switch handler adds inst_len to %rip before calling hvm_task_switch(), which is problematic in two ways: 1) Early faults (i.e. ones delivered in the context of the old task) get delivered with trap semantics, and break restartibility. 2) The addition isn't truncated to 32 bits. In the corner case of a task switch instruction crossing the 4G->0 boundary taking an early fault (with trap semantics), a VMEntry failure will occur due to %rip being out of range. Instead, pass the instruction length into hvm_task_switch() and write it into the outgoing TSS only, leaving %rip in its original location. For now, pass 0 on the SVM side. This highlights a separate preexisting bug which will be addressed in the following patch. While adjusting call sites, drop the unnecessary uint16_t cast. Signed-off-by: Andrew Cooper Reviewed-by: Roger Pau Monné Acked-by: Jan Beulich Reviewed-by: Kevin Tian --- xen/arch/x86/hvm/hvm.c | 4 ++-- xen/arch/x86/hvm/svm/svm.c | 2 +- xen/arch/x86/hvm/vmx/vmx.c | 4 ++-- xen/include/asm-x86/hvm/hvm.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 818e705fd1..7f556171bd 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2913,7 +2913,7 @@ void hvm_prepare_vm86_tss(struct vcpu *v, uint32_t base, uint32_t limit) void hvm_task_switch( uint16_t tss_sel, enum hvm_task_switch_reason taskswitch_reason, - int32_t errcode) + int32_t errcode, unsigned int insn_len) { struct vcpu *v = current; struct cpu_user_regs *regs = guest_cpu_user_regs(); @@ -2987,7 +2987,7 @@ void hvm_task_switch( if ( taskswitch_reason == TSW_iret ) eflags &= ~X86_EFLAGS_NT; - tss.eip = regs->eip; + tss.eip = regs->eip + insn_len; tss.eflags = eflags; tss.eax = regs->eax; tss.ecx = regs->ecx; diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 4eb6b0e4c7..049b800e20 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2794,7 +2794,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) */ vmcb->eventinj.bytes = 0; - hvm_task_switch((uint16_t)vmcb->exitinfo1, reason, errcode); + hvm_task_switch(vmcb->exitinfo1, reason, errcode, 0); break; } diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index a71df71bc1..7450cbe40d 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -3962,8 +3962,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) __vmread(IDT_VECTORING_ERROR_CODE, &ecode); else ecode = -1; - regs->rip += inst_len; - hvm_task_switch((uint16_t)exit_qualification, reasons[source], ecode); + + hvm_task_switch(exit_qualification, reasons[source], ecode, inst_len); break; } case EXIT_REASON_CPUID: diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index f86af09898..4cce59bb31 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -297,7 +297,7 @@ void hvm_set_rdtsc_exiting(struct domain *d, bool_t enable); enum hvm_task_switch_reason { TSW_jmp, TSW_iret, TSW_call_or_int }; void hvm_task_switch( uint16_t tss_sel, enum hvm_task_switch_reason taskswitch_reason, - int32_t errcode); + int32_t errcode, unsigned int insn_len); enum hvm_access_type { hvm_access_insn_fetch,