From patchwork Thu Dec 24 18:23:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 7919791 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CE0F19F1AF for ; Thu, 24 Dec 2015 18:27:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D4C242047B for ; Thu, 24 Dec 2015 18:27:07 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AC1952046F for ; Thu, 24 Dec 2015 18:27:06 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aCAY4-0000mI-6l; Thu, 24 Dec 2015 18:23:36 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aCAY3-0000mD-2s for xen-devel@lists.xen.org; Thu, 24 Dec 2015 18:23:35 +0000 Received: from [193.109.254.147] by server-6.bemta-14.messagelabs.com id 33/AE-16618-6283C765; Thu, 24 Dec 2015 18:23:34 +0000 X-Env-Sender: prvs=793a85e9f=Andrew.Cooper3@citrix.com X-Msg-Ref: server-8.tower-27.messagelabs.com!1450981412!9353991!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 4467 invoked from network); 24 Dec 2015 18:23:33 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-8.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 24 Dec 2015 18:23:33 -0000 X-IronPort-AV: E=Sophos;i="5.20,474,1444694400"; d="scan'208";a="327394517" From: Andrew Cooper To: Xen-devel Date: Thu, 24 Dec 2015 18:23:04 +0000 Message-ID: <1450981384-2966-1-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-DLP: MIA1 Cc: Andrew Cooper , Kevin Tian , Jun Nakajima , Jan Beulich Subject: [Xen-devel] [PATCH] x86/vmx: Fix injection of #DB traps following XSA-165 X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Most debug exceptions are traps rather than faults. Blindly re-injecting them as hardware exception causes the instruction pointer in the exception frame to point at the target instruct, rather than after it. This in turn breaks debuggers in the guests. Introduce a helper which copies VM_EXIT_INTR_INTO to VM_ENTRY_INTR_INFO, and use it to mirror the intercepted interrupt back to the guest. As part of doing so, introduce vmx_intr_info_t with a bitfield representation of an INTR_INFO field. Signed-off-by: Andrew Cooper --- CC: Jan Beulich CC: Jun Nakajima CC: Kevin Tian --- xen/arch/x86/hvm/vmx/vmx.c | 33 ++++++++++++++++++++++++++++++--- xen/include/asm-x86/hvm/vmx/vmx.h | 12 ++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index b918b8a..aacf07a 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2877,6 +2877,34 @@ static int vmx_handle_eoi_write(void) return 0; } +/* + * Propagate VM_EXIT_INTR_INFO to VM_ENTRY_INTR_INFO. Used to mirror an + * intercepted exception back to the guest as if Xen hadn't intercepted it. + * + * It is the callers responsibility to ensure that this function is only used + * in the context of an appropriate vmexit. + */ +static void vmx_propagate_intr(void) +{ + vmx_intr_info_t intr; + unsigned long tmp; + + __vmread(VM_EXIT_INTR_INFO, &intr.raw); + + ASSERT(intr.valid); + + __vmwrite(VM_ENTRY_INTR_INFO, intr.raw); + + if ( intr.ec_valid ) + { + __vmread(VM_EXIT_INTR_ERROR_CODE, &tmp); + __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, tmp); + } + + __vmread(VM_EXIT_INSTRUCTION_LEN, &tmp); + __vmwrite(VM_ENTRY_INSTRUCTION_LEN, tmp); +} + static void vmx_idtv_reinject(unsigned long idtv_info) { @@ -3137,7 +3165,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) HVMTRACE_1D(TRAP_DEBUG, exit_qualification); write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE); if ( !v->domain->debugger_attached ) - hvm_inject_hw_exception(vector, HVM_DELIVER_NO_ERROR_CODE); + vmx_propagate_intr(); else domain_pause_for_debugger(); break; @@ -3206,8 +3234,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) break; case TRAP_alignment_check: HVMTRACE_1D(TRAP, vector); - __vmread(VM_EXIT_INTR_ERROR_CODE, &ecode); - hvm_inject_hw_exception(vector, ecode); + vmx_propagate_intr(); break; case TRAP_nmi: if ( MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK) != diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index 1719965..ad2018f 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -224,6 +224,18 @@ static inline void pi_clear_sn(struct pi_desc *pi_desc) #define INTR_INFO_VALID_MASK 0x80000000 /* 31 */ #define INTR_INFO_RESVD_BITS_MASK 0x7ffff000 +typedef union vmx_intr_info { + unsigned long raw; + struct { + uint8_t vector; + uint32_t type: 3, + ec_valid: 1, + nmi_unblocked: 1, + rsvd: 18, + valid: 1; + }; +} vmx_intr_info_t; + /* * Exit Qualifications for MOV for Control Register Access */