From patchwork Tue Dec 3 17:10:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11271717 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 D6AD0921 for ; Tue, 3 Dec 2019 17:12:01 +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 A40782073B for ; Tue, 3 Dec 2019 17:12:01 +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="LZHCLhYC" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A40782073B 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 1icBh6-0005nc-1a; Tue, 03 Dec 2019 17:10:36 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1icBh5-0005nW-D2 for xen-devel@lists.xenproject.org; Tue, 03 Dec 2019 17:10:35 +0000 X-Inumbo-ID: d175aa68-15ef-11ea-83b8-bc764e2007e4 Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id d175aa68-15ef-11ea-83b8-bc764e2007e4; Tue, 03 Dec 2019 17:10:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1575393034; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=TmnJjk8TXAnHsrvKb3/LuWmnRZTU1I2EhQp5z4x3XNo=; b=LZHCLhYCm5Ba0Nk1p0I//MTXl4+4ITWy6E75UBMn8Ua0a1KAWk/9vBmX fXS82dlTiA6IUI+uThFcStPoMpAE45B8DTJ0AYeCSzegef6tWrfezbKv6 TJcdQovVf/YMNYmpctn91eeQTmLxfCzAZ2fo2bhz2KUp7fw9FCITuvvm7 k=; Authentication-Results: esa5.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 (esa5.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=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.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=esa5.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 (esa5.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=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: EeLNxnzLXLNw+BHg+r2fccFZD2vMS8c8i5yBIKoLiDVKQAzYHy6+iK5cS3yqyptE07JSIkBRIN sn18PnEUrrHfLzcKrxMdBaVM/c3R8iBq0mUo3Q+xmiqXF8feEVYFXVq0wTm+5Zxem9YfNSuuIA dcaGL/P7cFv8j4mF55GZb+naNWGqZKi+nNmBvDV6H7LxCctCmDrx989d5Icxef0zABTjvWME2b ZmQ39AHqahIPENumlE7kSoNjdcrTLJG+UpSrrAXxV59xWN0KreNjFCiC3DOZsFcZ2ikvVb7+rC RkQ= X-SBRS: 2.7 X-MesageID: 9491797 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,273,1571716800"; d="scan'208";a="9491797" From: Andrew Cooper To: Xen-devel Date: Tue, 3 Dec 2019 17:10:30 +0000 Message-ID: <20191203171030.11680-1-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 MIME-Version: 1.0 Subject: [Xen-devel] [PATCH] x86/debug: Plumb pending_dbg through the monitor and devicemodel interfaces 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: Petre Pircalabu , Tamas K Lengyel , Wei Liu , Razvan Cojocaru , Andrew Cooper , Jan Beulich , Alexandru Isaila , Ian Jackson , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Like %cr2 for pagefaults, %dr6 contains ancillary information for debug exceptions, and needs similar handling. For xendevicemodel_inject_event(), no ABI change is needed (although an API one would be ideal). Switch from 'cr2' to 'extra' in variable names which don't constitute an API change, and update the documentation to match. For the monitor interface, vm_event_debug needs extending with a pending_dbg field. Extend hvm_monitor_debug() and for now, always pass in 0 - this will be fixed eventually, when other hypervisor bugfixes are complete. While modifying hvm_monitor_debug(), take the opportunity to correct trap type and instruction length from unsigned long to unsigned int, as they are both tiny values. Finally, adjust xen-access.c to the new expectations. Introspection tools intercepting debug exceptions should mirror the new pending_dbg field into xendevicemodel_inject_event() for %dr6 to be processed correctly for the guest. Signed-off-by: Andrew Cooper Acked-by: Tamas K Lengyel Acked-by: Jan Beulich Reviewed-by: Petre Pircalabu --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné CC: Razvan Cojocaru CC: Tamas K Lengyel CC: Alexandru Isaila CC: Petre Pircalabu CC: Ian Jackson I'm expecting to commit this alongside "x86/svm: Correct vm_event API for descriptor accesses" which covers the bump of the VM_EVENT interface version. --- tools/libs/devicemodel/core.c | 4 ++-- tools/libs/devicemodel/include/xendevicemodel.h | 4 ++-- tools/tests/xen-access/xen-access.c | 7 ++++--- xen/arch/x86/hvm/monitor.c | 4 +++- xen/arch/x86/hvm/svm/svm.c | 4 ++-- xen/arch/x86/hvm/vmx/vmx.c | 6 +++--- xen/include/asm-x86/hvm/monitor.h | 3 ++- xen/include/public/hvm/dm_op.h | 2 +- xen/include/public/vm_event.h | 1 + 9 files changed, 20 insertions(+), 15 deletions(-) diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c index f76e3d305e..db501d9e80 100644 --- a/tools/libs/devicemodel/core.c +++ b/tools/libs/devicemodel/core.c @@ -536,7 +536,7 @@ int xendevicemodel_set_mem_type( int xendevicemodel_inject_event( xendevicemodel_handle *dmod, domid_t domid, int vcpu, uint8_t vector, - uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t cr2) + uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t extra) { struct xen_dm_op op; struct xen_dm_op_inject_event *data; @@ -551,7 +551,7 @@ int xendevicemodel_inject_event( data->type = type; data->error_code = error_code; data->insn_len = insn_len; - data->cr2 = cr2; + data->cr2 = extra; return xendevicemodel_op(dmod, domid, 1, &op, sizeof(op)); } diff --git a/tools/libs/devicemodel/include/xendevicemodel.h b/tools/libs/devicemodel/include/xendevicemodel.h index 08cb0d4374..e877f5c8a6 100644 --- a/tools/libs/devicemodel/include/xendevicemodel.h +++ b/tools/libs/devicemodel/include/xendevicemodel.h @@ -309,12 +309,12 @@ int xendevicemodel_set_mem_type( * @parm type the event type (see the definition of enum x86_event_type) * @parm error_code the error code or ~0 to skip * @parm insn_len the instruction length - * @parm cr2 the value of CR2 for page faults + * @parm extra type-specific extra data (%cr2 for #PF, pending_dbg for #DB) * @return 0 on success, -1 on failure. */ int xendevicemodel_inject_event( xendevicemodel_handle *dmod, domid_t domid, int vcpu, uint8_t vector, - uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t cr2); + uint8_t type, uint32_t error_code, uint8_t insn_len, uint64_t extra); /** * Shuts the domain down. diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c index 6aaee16d67..044a3a3c57 100644 --- a/tools/tests/xen-access/xen-access.c +++ b/tools/tests/xen-access/xen-access.c @@ -826,18 +826,19 @@ int main(int argc, char *argv[]) break; case VM_EVENT_REASON_DEBUG_EXCEPTION: - printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. Length: %u\n", + printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. Length: %u. Pending dbg %08"PRIx64"\n", req.data.regs.x86.rip, req.vcpu_id, req.u.debug_exception.type, - req.u.debug_exception.insn_length); + req.u.debug_exception.insn_length, + req.u.debug_exception.pending_dbg); /* Reinject */ rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id, X86_TRAP_DEBUG, req.u.debug_exception.type, -1, req.u.debug_exception.insn_length, - req.data.regs.x86.cr2); + req.u.debug_exception.pending_dbg); if (rc < 0) { ERROR("Error %d injecting breakpoint\n", rc); diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c index 7fb1e2c04e..e7fb9f4254 100644 --- a/xen/arch/x86/hvm/monitor.c +++ b/xen/arch/x86/hvm/monitor.c @@ -136,7 +136,8 @@ static inline unsigned long gfn_of_rip(unsigned long rip) } int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type, - unsigned long trap_type, unsigned long insn_length) + unsigned int trap_type, unsigned int insn_length, + unsigned int pending_dbg) { /* * rc < 0 error in monitor/vm_event, crash @@ -175,6 +176,7 @@ int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type, req.u.debug_exception.gfn = gfn_of_rip(rip); req.u.debug_exception.type = trap_type; req.u.debug_exception.insn_length = insn_length; + req.u.debug_exception.pending_dbg = pending_dbg; sync = !!ad->monitor.debug_exception_sync; break; diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 0fb1908c18..72b1dcbf54 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2649,7 +2649,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) rc = hvm_monitor_debug(regs->rip, HVM_MONITOR_DEBUG_EXCEPTION, - trap_type, inst_len); + trap_type, inst_len, 0); if ( rc < 0 ) goto unexpected_exit_type; if ( !rc ) @@ -2680,7 +2680,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) rc = hvm_monitor_debug(regs->rip, HVM_MONITOR_SOFTWARE_BREAKPOINT, X86_EVENTTYPE_SW_EXCEPTION, - inst_len); + inst_len, 0); if ( rc < 0 ) goto unexpected_exit_type; if ( !rc ) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 7450cbe40d..39efd91991 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -3834,7 +3834,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) rc = hvm_monitor_debug(regs->rip, HVM_MONITOR_DEBUG_EXCEPTION, - trap_type, insn_len); + trap_type, insn_len, 0); if ( rc < 0 ) goto exit_and_crash; @@ -3855,7 +3855,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) rc = hvm_monitor_debug(regs->rip, HVM_MONITOR_SOFTWARE_BREAKPOINT, X86_EVENTTYPE_SW_EXCEPTION, - insn_len); + insn_len, 0); if ( rc < 0 ) goto exit_and_crash; @@ -4157,7 +4157,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) { hvm_monitor_debug(regs->rip, HVM_MONITOR_SINGLESTEP_BREAKPOINT, - 0, 0); + 0, 0, 0); if ( v->domain->debugger_attached ) domain_pause_for_debugger(); diff --git a/xen/include/asm-x86/hvm/monitor.h b/xen/include/asm-x86/hvm/monitor.h index 325b44674d..66de24cb75 100644 --- a/xen/include/asm-x86/hvm/monitor.h +++ b/xen/include/asm-x86/hvm/monitor.h @@ -42,7 +42,8 @@ void hvm_monitor_descriptor_access(uint64_t exit_info, uint64_t vmx_exit_qualification, uint8_t descriptor, bool is_write); int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type, - unsigned long trap_type, unsigned long insn_length); + unsigned int trap_type, unsigned int insn_length, + unsigned int pending_dbg); int hvm_monitor_cpuid(unsigned long insn_length, unsigned int leaf, unsigned int subleaf); void hvm_monitor_interrupt(unsigned int vector, unsigned int type, diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h index d3b554d019..fd00e9d761 100644 --- a/xen/include/public/hvm/dm_op.h +++ b/xen/include/public/hvm/dm_op.h @@ -324,7 +324,7 @@ struct xen_dm_op_inject_event { /* IN - error code (or ~0 to skip) */ uint32_t error_code; uint32_t pad1; - /* IN - CR2 for page faults */ + /* IN - type-specific extra data (%cr2 for #PF, pending_dbg for #DB) */ uint64_aligned_t cr2; }; diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h index 959083d8c4..76676ff4c0 100644 --- a/xen/include/public/vm_event.h +++ b/xen/include/public/vm_event.h @@ -281,6 +281,7 @@ struct vm_event_debug { uint32_t insn_length; uint8_t type; /* HVMOP_TRAP_* */ uint8_t _pad[3]; + uint64_t pending_dbg; }; struct vm_event_mov_to_msr {