From patchwork Mon Aug 21 15:56:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jinoh Kang X-Patchwork-Id: 13359600 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id C0C00EE49A6 for ; Mon, 21 Aug 2023 15:57:16 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.587665.919020 (Exim 4.92) (envelope-from ) id 1qY7H6-0007VL-PX; Mon, 21 Aug 2023 15:57:04 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 587665.919020; Mon, 21 Aug 2023 15:57:04 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7H6-0007VE-Md; Mon, 21 Aug 2023 15:57:04 +0000 Received: by outflank-mailman (input) for mailman id 587665; Mon, 21 Aug 2023 15:57:02 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7H4-0007V2-M2 for xen-devel@lists.xenproject.org; Mon, 21 Aug 2023 15:57:02 +0000 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [2607:f8b0:4864:20::102c]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 5c90cd57-403b-11ee-9b0c-b553b5be7939; Mon, 21 Aug 2023 17:57:00 +0200 (CEST) Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-26f7f71b9a7so308867a91.0 for ; Mon, 21 Aug 2023 08:57:00 -0700 (PDT) Received: from [10.137.0.57] ([14.33.99.107]) by smtp.gmail.com with ESMTPSA id f22-20020a17090ac29600b00263f41a655esm6289831pjt.43.2023.08.21.08.56.56 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 21 Aug 2023 08:56:58 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 5c90cd57-403b-11ee-9b0c-b553b5be7939 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692633419; x=1693238219; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id:from:to :cc:subject:date:message-id:reply-to; bh=/2S0z9KCvAaRErAryR0gpUbfAsu6gl92wga3E9uUth4=; b=Mconjy7Yf+r6vIKYmFbGdiTN6T/DewIdZjYxdi97et9rDNokWyE6VZUBfmUzZy4ut7 imLiDtywDEK1ZUEkLWsJ61VfccZiaQg+5HofI+IglssYSvK21N6k4lH6ZAXXdmLryN9i K08U+NydR8oww2UXZIN3GNDEPoql/SJVEMkA6CHpZLkfgZo8kGqF3uAPeSuyu41ONgy9 78UeB8MnBdNsENP5aBigo5+OFQk3a3lLHJz1fnPq4FaQdVJwLlqXAHuoCEBcXO/7ce4T caOKHOTTLXfpesww9E0SvgnRn7bab3iLcwTKjPesy0/wgYfSCb8X9uS+8bwIWOObGPPX KEJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692633419; x=1693238219; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=/2S0z9KCvAaRErAryR0gpUbfAsu6gl92wga3E9uUth4=; b=HpqerTCVX9M7VOfzUaJbvI9uS8YLqf/5HH5FfIstLWoPm84e//6CEvMJ1F2/mg5/BT wB+lmJWjWPzQzbH7f2KRbKyRid9imZxiaJI0LLRFIYm1aQ61KZNFjs8xEC6bgJ2/TSmo NP2GmeJs1dDrhFv26hZ+6fPJlSaouYW9irUWNwyExyk8oos8xn8C3KcO3gbcWb13RsEM mAoJ6IYOCnju0+x2uoGdjwvUwEDSYoO9kNsK8uQmQp9B4B9XWNJS5f9VvTVkZ9Kx9LNf 8JOyCo5zAVwZYYzvidSS5J5OvGtB5kKZKAPTrolLjOWzM1dLmCWxjxPheFZNNGvYwp7g b7Zw== X-Gm-Message-State: AOJu0YyAc9HzLlsKZZLODVh9LZMQaT20r5mq2bxBNF0+7zmAt2mX40RA e0Ux0qKc/xbg7lYwTGXiTE7tNP+alL+WXA== X-Google-Smtp-Source: AGHT+IGcH8j7FW4s549lSLTCMkNwyP2n1sZ3ocgNK1HHJTek8E51XVy8+DH2mzTgO5wUO5bISqDcBQ== X-Received: by 2002:a17:90b:a03:b0:267:f1d0:ca70 with SMTP id gg3-20020a17090b0a0300b00267f1d0ca70mr6265049pjb.47.1692633418866; Mon, 21 Aug 2023 08:56:58 -0700 (PDT) Message-ID: Date: Tue, 22 Aug 2023 00:56:54 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 From: Jinoh Kang Subject: [PATCH 1/5] x86: Fix calculation of %dr6/7 reserved bits To: xen-devel@lists.xenproject.org, Andrew Cooper Cc: Jan Beulich , Wei Liu , =?utf-8?q?Roger_P?= =?utf-8?q?au_Monn=C3=A9?= References: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> Content-Language: en-US In-Reply-To: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> From: Andrew Cooper The reserved bit calculations for %dr6 and %dr7 depend on whether the VM has the Restricted Transnational Memory feature available. Introduce adjust_dr{6,7}_rsvd() and replace the opencoded logic and constants (except for DR_STATUS_RESERVED_ONE which is (mis)used elsewhere and will be removed after future bugfixes). The use of these helpers in set_debugreg() covers toolstack values for PV guests, but HVM guests need similar treatment. The use of the guests cpuid policy is less than optimal in the create/restore paths. However in such cases, the policy will be the guest maximum policy, which will be more permissive with respect to the RTM feature. Signed-off-by: Jinoh Kang --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/domain.c | 7 +++-- xen/arch/x86/hvm/hvm.c | 6 ++-- xen/arch/x86/include/asm/debugreg.h | 44 +++++++++++++++++++++++++---- xen/arch/x86/pv/misc-hypercalls.c | 16 +++-------- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index fe86a7f853..a39710b5af 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1053,6 +1053,7 @@ int arch_set_info_guest( struct vcpu *v, vcpu_guest_context_u c) { struct domain *d = v->domain; + const struct cpu_policy *cp = d->arch.cpuid; unsigned int i; unsigned long flags; bool compat; @@ -1165,10 +1166,10 @@ int arch_set_info_guest( if ( is_hvm_domain(d) ) { - for ( i = 0; i < ARRAY_SIZE(v->arch.dr); ++i ) + for ( i = 0; i < ARRAY_SIZE(v->arch.dr) - 2; ++i ) v->arch.dr[i] = c(debugreg[i]); - v->arch.dr6 = c(debugreg[6]); - v->arch.dr7 = c(debugreg[7]); + v->arch.dr6 = adjust_dr6_rsvd(c(debugreg[6]), cp->feat.rtm); + v->arch.dr7 = adjust_dr7_rsvd(c(debugreg[7]), cp->feat.rtm); if ( v->vcpu_id == 0 ) d->vm_assist = c.nat->vm_assist; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 3a99c0ff20..66ead0b878 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -985,6 +986,7 @@ unsigned long hvm_cr4_guest_valid_bits(const struct domain *d) static int cf_check hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) { + const struct cpu_policy *cp = d->arch.cpuid; unsigned int vcpuid = hvm_load_instance(h); struct vcpu *v; struct hvm_hw_cpu ctxt; @@ -1166,8 +1168,8 @@ static int cf_check hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h) v->arch.dr[1] = ctxt.dr1; v->arch.dr[2] = ctxt.dr2; v->arch.dr[3] = ctxt.dr3; - v->arch.dr6 = ctxt.dr6; - v->arch.dr7 = ctxt.dr7; + v->arch.dr6 = adjust_dr6_rsvd(ctxt.dr6, cp->feat.rtm); + v->arch.dr7 = adjust_dr7_rsvd(ctxt.dr7, cp->feat.rtm); hvmemul_cancel(v); diff --git a/xen/arch/x86/include/asm/debugreg.h b/xen/arch/x86/include/asm/debugreg.h index 86aa6d7143..8be60910b4 100644 --- a/xen/arch/x86/include/asm/debugreg.h +++ b/xen/arch/x86/include/asm/debugreg.h @@ -10,9 +10,18 @@ #define DR_STATUS 6 #define DR_CONTROL 7 -/* Define a few things for the status register. We can use this to determine - which debugging register was responsible for the trap. The other bits - are either reserved or not of interest to us. */ +/* + * DR6 status bits. + * N.B. For backwards compatibility, X86_DR6_RTM has inverted polarity. + */ +#define X86_DR6_B0 (1u << 0) /* Breakpoint 0 triggered */ +#define X86_DR6_B1 (1u << 1) /* Breakpoint 1 triggered */ +#define X86_DR6_B2 (1u << 2) /* Breakpoint 2 triggered */ +#define X86_DR6_B3 (1u << 3) /* Breakpoint 3 triggered */ +#define X86_DR6_BD (1u << 13) /* Debug register accessed */ +#define X86_DR6_BS (1u << 14) /* Single step */ +#define X86_DR6_BT (1u << 15) /* Task switch */ +#define X86_DR6_RTM (1u << 16) /* #DB/#BP in RTM region */ #define DR_TRAP0 (0x1) /* db0 */ #define DR_TRAP1 (0x2) /* db1 */ @@ -21,7 +30,6 @@ #define DR_STEP (0x4000) /* single-step */ #define DR_SWITCH (0x8000) /* task switch */ #define DR_NOT_RTM (0x10000) /* clear: #BP inside RTM region */ -#define DR_STATUS_RESERVED_ZERO (~0xffffefffUL) /* Reserved, read as zero */ #define DR_STATUS_RESERVED_ONE 0xffff0ff0UL /* Reserved, read as one */ /* Now define a bunch of things for manipulating the control register. @@ -61,8 +69,6 @@ We can slow the instruction pipeline for instructions coming via the gdt or the ldt if we want to. I am not sure why this is an advantage */ -#define DR_CONTROL_RESERVED_ZERO (~0xffff27ffUL) /* Reserved, read as zero */ -#define DR_CONTROL_RESERVED_ONE (0x00000400UL) /* Reserved, read as one */ #define DR_LOCAL_EXACT_ENABLE (0x00000100UL) /* Local exact enable */ #define DR_GLOBAL_EXACT_ENABLE (0x00000200UL) /* Global exact enable */ #define DR_RTM_ENABLE (0x00000800UL) /* RTM debugging enable */ @@ -80,4 +86,30 @@ long set_debugreg(struct vcpu *, unsigned int reg, unsigned long value); void activate_debugregs(const struct vcpu *); +static inline unsigned long adjust_dr6_rsvd(unsigned long dr6, bool rtm) +{ + /* + * DR6: Bits 4-11,17-31 reserved (set to 1). + * Bit 16 reserved (set to 1) if RTM unavailable. + * Bit 12 reserved (set to 0). + */ + dr6 |= 0xfffe0ff0 | (rtm ? 0 : X86_DR6_RTM); + dr6 &= 0xffffefff; + + return dr6; +} + +static inline unsigned long adjust_dr7_rsvd(unsigned long dr7, bool rtm) +{ + /* + * DR7: Bit 10 reserved (set to 1). + * Bit 11 reserved (set to 0) if RTM unavailable. + * Bits 12,14-15 reserved (set to 0). + */ + dr7 |= 0x00000400; + dr7 &= 0xffff23ff & (rtm ? 0 : ~DR_RTM_ENABLE); + + return dr7; +} + #endif /* _X86_DEBUGREG_H */ diff --git a/xen/arch/x86/pv/misc-hypercalls.c b/xen/arch/x86/pv/misc-hypercalls.c index b11bd718b7..e44f2556c8 100644 --- a/xen/arch/x86/pv/misc-hypercalls.c +++ b/xen/arch/x86/pv/misc-hypercalls.c @@ -56,6 +56,7 @@ long do_fpu_taskswitch(int set) long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value) { struct vcpu *curr = current; + const struct cpu_policy *cp = curr->domain->arch.cpuid; switch ( reg ) { @@ -86,12 +87,7 @@ long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value) if ( value != (uint32_t)value ) return -EINVAL; - /* - * DR6: Bits 4-11,16-31 reserved (set to 1). - * Bit 12 reserved (set to 0). - */ - value &= ~DR_STATUS_RESERVED_ZERO; /* reserved bits => 0 */ - value |= DR_STATUS_RESERVED_ONE; /* reserved bits => 1 */ + value = adjust_dr6_rsvd(value, cp->feat.rtm); v->arch.dr6 = value; if ( v == curr ) @@ -108,12 +104,8 @@ long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value) if ( value != (uint32_t)value ) return -EINVAL; - /* - * DR7: Bit 10 reserved (set to 1). - * Bits 11-12,14-15 reserved (set to 0). - */ - value &= ~DR_CONTROL_RESERVED_ZERO; /* reserved bits => 0 */ - value |= DR_CONTROL_RESERVED_ONE; /* reserved bits => 1 */ + value = adjust_dr7_rsvd(value, cp->feat.rtm); + /* * Privileged bits: * GD (bit 13): must be 0. From patchwork Mon Aug 21 15:57:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jinoh Kang X-Patchwork-Id: 13359610 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 2FEB2EE49A6 for ; Mon, 21 Aug 2023 16:02:45 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.587695.919061 (Exim 4.92) (envelope-from ) id 1qY7MC-00037f-6p; Mon, 21 Aug 2023 16:02:20 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 587695.919061; Mon, 21 Aug 2023 16:02:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7MC-00037Y-45; Mon, 21 Aug 2023 16:02:20 +0000 Received: by outflank-mailman (input) for mailman id 587695; Mon, 21 Aug 2023 16:02:18 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7MA-00037S-Mc for xen-devel@lists.xenproject.org; Mon, 21 Aug 2023 16:02:18 +0000 Received: from mail-qv1-xf30.google.com (mail-qv1-xf30.google.com [2607:f8b0:4864:20::f30]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 191a2662-403c-11ee-8782-cb3800f73035; Mon, 21 Aug 2023 18:02:16 +0200 (CEST) Received: by mail-qv1-xf30.google.com with SMTP id 6a1803df08f44-64f383be0d4so11292386d6.3 for ; Mon, 21 Aug 2023 09:02:16 -0700 (PDT) Received: from [10.137.0.57] ([14.33.99.107]) by smtp.gmail.com with ESMTPSA id w24-20020aa78598000000b0068892a66b5csm6326109pfn.77.2023.08.21.08.57.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 21 Aug 2023 08:57:04 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 191a2662-403c-11ee-8782-cb3800f73035 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692633735; x=1693238535; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id:from:to :cc:subject:date:message-id:reply-to; bh=rcvI6BZjybNsQpnXFA/kOhrlUplNszr0VzIfXd6lzuc=; b=o0AEj9FV+uPHAhr5gDF077SdH56OuNRVmYupSAxDBzuFAMrSv7QmEDSgbdavflm1Po 1RZXL00JNYwdUsmPudsPhG09nqrfZ1ipfaSL8gKztUPa6SiBkIHHVOSh67C1qAnE8Rnj aunrj4pb1EQiNfdJHWv5I818JFS0gFYi8E0G/51tWaYKrecjZGsGupK2OiN/Zgto4ToQ LINvd0KwyOFmpUQceQhoWpseFe1R35sgdt0DGd4AILC2cZ8EaMoo4oGqXwJC7BpobiX2 VpXken/E6+41S0Sn6JzO/IuUFQYdRXT+C/k9WI+tc+YtvNiZTyxFA5FBZgoRVOER3aLs 1eDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692633735; x=1693238535; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rcvI6BZjybNsQpnXFA/kOhrlUplNszr0VzIfXd6lzuc=; b=RHdbw0a2hI94xhTiG5qoH8x2ShlXaKZkViu+EyXWiBNcd18+uFAhoLefZfJ5pgj94N iXgfZfHNHFYG1zLNoQ9UljrCNQEPAfEfNeQuVzr6oqnhvzi4CvV2CAPdep85fQmiIioz 5cow7LXDgnZLfn2SjlF9UC3aVa7hIlpqR9hE/4xxwRy/RvLveKt2rmyKaKO2e08orht+ TBNve4B2ok4lZ8yA+Ogh6AIropV/MP1C0W47evmNPs4O1+xj7cnJR+zA2X/S3czW34IM F+MsMyqp29pAbf8v7wutXEkgHCsAqr4PTeCqTvboJWbcoPLpkVst7m0upPoosP0QdWGD SN6w== X-Gm-Message-State: AOJu0YxRT2nakYuGF3A1jrPoiOhP79d2oboLf5yW7fV0c7NAY2k8+rlH phUZt713FqWk+Tb7zA7hZYx0/DeQs64Ghw== X-Google-Smtp-Source: AGHT+IG9nzyYO7XWBCTfZ/MQCvZngajnf3c6sN3apWr2WuD5z1MrMNP2t6ssgvevRZYfN+Lfykthmw== X-Received: by 2002:a05:6870:470e:b0:1c0:1caf:3324 with SMTP id b14-20020a056870470e00b001c01caf3324mr9797661oaq.44.1692633425056; Mon, 21 Aug 2023 08:57:05 -0700 (PDT) Message-ID: <49f8d2f3-c468-774c-11d1-04a08169620d@gmail.com> Date: Tue, 22 Aug 2023 00:57:00 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 From: Jinoh Kang Subject: [PATCH 2/5] x86/emul: Add pending_dbg field to x86_event To: xen-devel@lists.xenproject.org, Andrew Cooper Cc: Jan Beulich , Wei Liu , =?utf-8?q?Roger_P?= =?utf-8?q?au_Monn=C3=A9?= , Jun Nakajima , Kevin Tian , Tim Deegan References: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> Content-Language: en-US In-Reply-To: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> From: Andrew Cooper All #DB exceptions result in an update of %dr6, but this isn't captured in Xen's handling. PV guests generally work by modifying %dr6 before raising #DB, whereas HVM guests do nothing and have a single-step special case in the lowest levels of {vmx,svm}_inject_event(). All of this is buggy, but in particular, task switches with the trace flag never end up signalling BT in %dr6. To begin resolving this issue, add a new pending_dbg field to x86_event (unioned with cr2 to avoid taking any extra space), and introduce {pv,hvm}_inject_debug_exn() helpers to replace the current callers using {pv,hvm}_inject_hw_exception(). A key property is that pending_dbg is taken with positive polarity to deal with RTM sensibly. Most callers pass in a constant, but callers passing in a hardware %dr6 value need to xor the value with X86_DR6_DEFAULT to flip the polarity of RTM and reserved fields. For PV guests, move the ad-hoc updating of %dr6 into pv_inject_event(). This in principle breaks the handing of RTM in do_debug(), but PV guests can't actually enable MSR_DEBUGCTL.RTM yet, so this doesn't matter in practice. Signed-off-by: Jinoh Kang --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné CC: Jun Nakajima CC: Kevin Tian CC: Tim Deegan --- xen/arch/x86/hvm/emulate.c | 3 ++- xen/arch/x86/hvm/hvm.c | 2 +- xen/arch/x86/hvm/svm/svm.c | 9 ++++++--- xen/arch/x86/hvm/vmx/vmx.c | 13 ++++++++----- xen/arch/x86/include/asm/debugreg.h | 3 +++ xen/arch/x86/include/asm/domain.h | 12 ++++++++++++ xen/arch/x86/include/asm/hvm/hvm.h | 15 ++++++++++++++- xen/arch/x86/mm/shadow/multi.c | 5 +++-- xen/arch/x86/pv/emul-priv-op.c | 11 +++++------ xen/arch/x86/pv/emulate.c | 6 ++---- xen/arch/x86/pv/ro-page-fault.c | 3 ++- xen/arch/x86/pv/traps.c | 16 ++++++++++++---- xen/arch/x86/traps.c | 6 +----- xen/arch/x86/x86_emulate/x86_emulate.h | 5 ++++- 14 files changed, 75 insertions(+), 34 deletions(-) diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index 9b6e4c8bc6..129403ad90 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -2673,7 +2674,7 @@ static int _hvm_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt, } if ( hvmemul_ctxt->ctxt.retire.singlestep ) - hvm_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); + hvm_inject_debug_exn(X86_DR6_BS); new_intr_shadow = hvmemul_ctxt->intr_shadow; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 66ead0b878..c3d46841c2 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3229,7 +3229,7 @@ void hvm_task_switch( } if ( (tss.trace & 1) && !exn_raised ) - hvm_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); + hvm_inject_debug_exn(X86_DR6_BT); out: hvm_unmap_entry(optss_desc); diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 01dd592d9b..ac3123c56f 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -96,7 +96,7 @@ void __update_guest_eip(struct cpu_user_regs *regs, unsigned int inst_len) curr->arch.hvm.svm.vmcb->int_stat.intr_shadow = 0; if ( regs->eflags & X86_EFLAGS_TF ) - hvm_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); + hvm_inject_debug_exn(X86_DR6_BS); } static void cf_check svm_cpu_down(void) @@ -2755,7 +2755,10 @@ void svm_vmexit_handler(void) goto unexpected_exit_type; if ( !rc ) hvm_inject_exception(X86_EXC_DB, - trap_type, insn_len, X86_EVENT_NO_EC); + trap_type, insn_len, X86_EVENT_NO_EC, + exit_reason == VMEXIT_ICEBP ? 0 : + /* #DB - Hardware already updated dr6. */ + vmcb_get_dr6(vmcb) ^ X86_DR6_DEFAULT); } else domain_pause_for_debugger(); @@ -2785,7 +2788,7 @@ void svm_vmexit_handler(void) if ( !rc ) hvm_inject_exception(X86_EXC_BP, X86_EVENTTYPE_SW_EXCEPTION, - insn_len, X86_EVENT_NO_EC); + insn_len, X86_EVENT_NO_EC, 0 /* N/A */); } break; diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 7ec44018d4..716115332b 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -3068,7 +3068,7 @@ void update_guest_eip(void) } if ( regs->eflags & X86_EFLAGS_TF ) - hvm_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); + hvm_inject_debug_exn(X86_DR6_BS); } static void cf_check vmx_fpu_dirty_intercept(void) @@ -3911,7 +3911,7 @@ static int vmx_handle_eoi_write(void) * 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(unsigned long intr) +static void vmx_propagate_intr(unsigned long intr, unsigned long pending_dbg) { struct x86_event event = { .vector = MASK_EXTR(intr, INTR_INFO_VECTOR_MASK), @@ -3935,6 +3935,9 @@ static void vmx_propagate_intr(unsigned long intr) else event.insn_len = 0; + if ( event.vector == X86_EXC_DB ) + event.pending_dbg = pending_dbg; + hvm_inject_event(&event); } @@ -4300,7 +4303,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) if ( rc < 0 ) goto exit_and_crash; if ( !rc ) - vmx_propagate_intr(intr_info); + vmx_propagate_intr(intr_info, exit_qualification); } else domain_pause_for_debugger(); @@ -4321,7 +4324,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) if ( rc < 0 ) goto exit_and_crash; if ( !rc ) - vmx_propagate_intr(intr_info); + vmx_propagate_intr(intr_info, 0 /* N/A */); } else { @@ -4361,7 +4364,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) break; case X86_EXC_AC: HVMTRACE_1D(TRAP, vector); - vmx_propagate_intr(intr_info); + vmx_propagate_intr(intr_info, 0 /* N/A */); break; case X86_EXC_NMI: if ( MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK) != diff --git a/xen/arch/x86/include/asm/debugreg.h b/xen/arch/x86/include/asm/debugreg.h index 8be60910b4..a1df74c02e 100644 --- a/xen/arch/x86/include/asm/debugreg.h +++ b/xen/arch/x86/include/asm/debugreg.h @@ -83,6 +83,9 @@ asm volatile ( "mov %%db" #reg ",%0" : "=r" (__val) ); \ __val; \ }) + +struct vcpu; + long set_debugreg(struct vcpu *, unsigned int reg, unsigned long value); void activate_debugregs(const struct vcpu *); diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h index c2d9fc333b..eba11adf33 100644 --- a/xen/arch/x86/include/asm/domain.h +++ b/xen/arch/x86/include/asm/domain.h @@ -729,6 +729,18 @@ static inline void pv_inject_hw_exception(unsigned int vector, int errcode) pv_inject_event(&event); } +static inline void pv_inject_debug_exn(unsigned long pending_dbg) +{ + struct x86_event event = { + .vector = X86_EXC_DB, + .type = X86_EVENTTYPE_HW_EXCEPTION, + .error_code = X86_EVENT_NO_EC, + .pending_dbg = pending_dbg, + }; + + pv_inject_event(&event); +} + static inline void pv_inject_page_fault(int errcode, unsigned long cr2) { const struct x86_event event = { diff --git a/xen/arch/x86/include/asm/hvm/hvm.h b/xen/arch/x86/include/asm/hvm/hvm.h index 6d53713fc3..43989f1681 100644 --- a/xen/arch/x86/include/asm/hvm/hvm.h +++ b/xen/arch/x86/include/asm/hvm/hvm.h @@ -503,13 +503,14 @@ hvm_get_cpl(struct vcpu *v) static inline void hvm_inject_exception( unsigned int vector, unsigned int type, - unsigned int insn_len, int error_code) + unsigned int insn_len, int error_code, unsigned long extra) { struct x86_event event = { .vector = vector, .type = type, .insn_len = insn_len, .error_code = error_code, + .cr2 = extra, /* Any union field will do. */ }; hvm_inject_event(&event); @@ -526,6 +527,18 @@ static inline void hvm_inject_hw_exception(unsigned int vector, int errcode) hvm_inject_event(&event); } +static inline void hvm_inject_debug_exn(unsigned long pending_dbg) +{ + struct x86_event event = { + .vector = X86_EXC_DB, + .type = X86_EVENTTYPE_HW_EXCEPTION, + .error_code = X86_EVENT_NO_EC, + .pending_dbg = pending_dbg, + }; + + hvm_inject_event(&event); +} + static inline void hvm_inject_page_fault(int errcode, unsigned long cr2) { struct x86_event event = { diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index cf74fdf5dd..6056626912 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -2788,7 +2789,7 @@ static int cf_check sh_page_fault( #endif if ( emul_ctxt.ctxt.retire.singlestep ) - hvm_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); + hvm_inject_debug_exn(X86_DR6_BS); #if GUEST_PAGING_LEVELS == 3 /* PAE guest */ /* @@ -2829,7 +2830,7 @@ static int cf_check sh_page_fault( TRACE_SHADOW_PATH_FLAG(TRCE_SFLAG_EMULATION_LAST_FAILED); if ( emul_ctxt.ctxt.retire.singlestep ) - hvm_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); + hvm_inject_debug_exn(X86_DR6_BS); break; /* Don't emulate again if we failed! */ } diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index 142bc4818c..72d0514e74 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -1360,12 +1360,11 @@ int pv_emulate_privileged_op(struct cpu_user_regs *regs) case X86EMUL_OKAY: if ( ctxt.ctxt.retire.singlestep ) ctxt.bpmatch |= DR_STEP; - if ( ctxt.bpmatch ) - { - curr->arch.dr6 |= ctxt.bpmatch | DR_STATUS_RESERVED_ONE; - if ( !(curr->arch.pv.trap_bounce.flags & TBF_EXCEPTION) ) - pv_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); - } + + if ( ctxt.bpmatch && + !(curr->arch.pv.trap_bounce.flags & TBF_EXCEPTION) ) + pv_inject_debug_exn(ctxt.bpmatch); + /* fall through */ case X86EMUL_RETRY: return EXCRET_fault_fixed; diff --git a/xen/arch/x86/pv/emulate.c b/xen/arch/x86/pv/emulate.c index e7a1c0a2cc..aa8af96c30 100644 --- a/xen/arch/x86/pv/emulate.c +++ b/xen/arch/x86/pv/emulate.c @@ -71,11 +71,9 @@ void pv_emul_instruction_done(struct cpu_user_regs *regs, unsigned long rip) { regs->rip = rip; regs->eflags &= ~X86_EFLAGS_RF; + if ( regs->eflags & X86_EFLAGS_TF ) - { - current->arch.dr6 |= DR_STEP | DR_STATUS_RESERVED_ONE; - pv_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); - } + pv_inject_debug_exn(X86_DR6_BS); } uint64_t pv_get_reg(struct vcpu *v, unsigned int reg) diff --git a/xen/arch/x86/pv/ro-page-fault.c b/xen/arch/x86/pv/ro-page-fault.c index cad28ef928..50c37fbd25 100644 --- a/xen/arch/x86/pv/ro-page-fault.c +++ b/xen/arch/x86/pv/ro-page-fault.c @@ -9,6 +9,7 @@ */ #include +#include #include #include "emulate.h" @@ -390,7 +391,7 @@ int pv_ro_page_fault(unsigned long addr, struct cpu_user_regs *regs) /* Fallthrough */ case X86EMUL_OKAY: if ( ctxt.retire.singlestep ) - pv_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); + pv_inject_debug_exn(X86_DR6_BS); /* Fallthrough */ case X86EMUL_RETRY: diff --git a/xen/arch/x86/pv/traps.c b/xen/arch/x86/pv/traps.c index 74f333da7e..4f5641a47c 100644 --- a/xen/arch/x86/pv/traps.c +++ b/xen/arch/x86/pv/traps.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -50,9 +51,9 @@ void pv_inject_event(const struct x86_event *event) tb->cs = ti->cs; tb->eip = ti->address; - if ( event->type == X86_EVENTTYPE_HW_EXCEPTION && - vector == X86_EXC_PF ) + switch ( vector | -(event->type == X86_EVENTTYPE_SW_INTERRUPT) ) { + case X86_EXC_PF: curr->arch.pv.ctrlreg[2] = event->cr2; arch_set_cr2(curr, event->cr2); @@ -62,9 +63,16 @@ void pv_inject_event(const struct x86_event *event) error_code |= PFEC_user_mode; trace_pv_page_fault(event->cr2, error_code); - } - else + break; + + case X86_EXC_DB: + curr->arch.dr6 |= event->pending_dbg; + /* Fallthrough */ + + default: trace_pv_trap(vector, regs->rip, use_error_code, error_code); + break; + } if ( use_error_code ) { diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index a898e1f2d7..640b60e0e5 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1989,17 +1989,13 @@ void do_debug(struct cpu_user_regs *regs) return; } - /* Save debug status register where guest OS can peek at it */ - v->arch.dr6 |= (dr6 & ~X86_DR6_DEFAULT); - v->arch.dr6 &= (dr6 | ~X86_DR6_DEFAULT); - if ( guest_kernel_mode(v, regs) && v->domain->debugger_attached ) { domain_pause_for_debugger(); return; } - pv_inject_hw_exception(X86_EXC_DB, X86_EVENT_NO_EC); + pv_inject_debug_exn(dr6 ^ X86_DR6_DEFAULT); } void do_entry_CP(struct cpu_user_regs *regs) diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h index 698750267a..e348e3c1d3 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.h +++ b/xen/arch/x86/x86_emulate/x86_emulate.h @@ -78,7 +78,10 @@ struct x86_event { uint8_t type; /* X86_EVENTTYPE_* */ uint8_t insn_len; /* Instruction length */ int32_t error_code; /* X86_EVENT_NO_EC if n/a */ - unsigned long cr2; /* Only for X86_EXC_PF h/w exception */ + union { + unsigned long cr2; /* #PF */ + unsigned long pending_dbg; /* #DB (new DR6 bits, positive polarity) */ + }; }; /* From patchwork Mon Aug 21 15:57:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jinoh Kang X-Patchwork-Id: 13359601 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 6E945EE4993 for ; Mon, 21 Aug 2023 15:57:31 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.587666.919030 (Exim 4.92) (envelope-from ) id 1qY7HI-0007oZ-1R; Mon, 21 Aug 2023 15:57:16 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 587666.919030; Mon, 21 Aug 2023 15:57:16 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7HH-0007oS-V5; Mon, 21 Aug 2023 15:57:15 +0000 Received: by outflank-mailman (input) for mailman id 587666; Mon, 21 Aug 2023 15:57:15 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7HH-0007T4-Dh for xen-devel@lists.xenproject.org; Mon, 21 Aug 2023 15:57:15 +0000 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [2607:f8b0:4864:20::62e]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 64b76b61-403b-11ee-8782-cb3800f73035; Mon, 21 Aug 2023 17:57:14 +0200 (CEST) Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1bf0b24d925so20967405ad.3 for ; Mon, 21 Aug 2023 08:57:14 -0700 (PDT) Received: from [10.137.0.57] ([14.33.99.107]) by smtp.gmail.com with ESMTPSA id f9-20020a170902ce8900b001ae0a4b1d3fsm7191686plg.153.2023.08.21.08.57.08 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 21 Aug 2023 08:57:11 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 64b76b61-403b-11ee-8782-cb3800f73035 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692633432; x=1693238232; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id:from:to :cc:subject:date:message-id:reply-to; bh=hSh7CjYmh4pzgCRYpqWLhaZZ/JE6zO58mEjCpiQd2qI=; b=f76C1e8xFy+qyoOxihP2DN4q0r9qi06GSdUr8g9MSCelkUNXFBjGQ6tIMjsy5uh+rZ zGJjr1vxNSO1fXU3CNqmO+rIUkphjLiSra6DbmiPHfrDnecvnPJqmCGbVnEcdOl6MEDP xExA6UKPcrkr+wf0j5vGKSyvccA9K9Z+cQjmi8oo3wgGMUIgZybVii7ttSui7ig4HVER JB2UFK2KReg3YmdHyOag1zoEf9gjYHGbYiUQ0jU0jxKRbUQxmjisy8nQBJSnAU29VapZ klCzlI4tWqsx8CrGYmj+4CSyfXxn64vHGWkUsKFH2ZpCHDKVEo8t3QIrKQ/BrMX8XqE2 hJQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692633432; x=1693238232; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=hSh7CjYmh4pzgCRYpqWLhaZZ/JE6zO58mEjCpiQd2qI=; b=LY/XLpq92NFEsJCv9+W8BODtdfdgWtE3/wp2wyYXNibBWkVs7asH0NzLOBdk2xDW5S K+Qtnpp81p82SGbwdE9NOTqxmIViOjKi8xmdMhVFuvxjzFzc13yfLXiRdfBVWDl2mcJQ Va6yuKDSjccdvzOP1sO90d+X6vNFT5ZYaMUjdcCwC9bf8QIpornJKBxUPVuQ5XY7H/MY gdZ8h1fWusQORGKHYw9RBBFBt/yteLu+HfsOLEYI2AGc5SqkmHyqsZH0fC7Y76HDHBho eYY/thSz4irbq+XEyJaNgPhjGHYLKoVz7kidd3W074p6GYuhBpVKWci+VpMRKMg1kCe6 F90A== X-Gm-Message-State: AOJu0YwB82J7AKz3lM+4NL7JqD0Wk/WI8mMkpdSa4Br4MwC6NE6Am1RT kMZdVcRP0mgSIC4PYO68/NdwZC0kHBAmSA== X-Google-Smtp-Source: AGHT+IGRQ+QsQ9szgfNdvXXaxuwNTqett1/4eESHiEzQvtoF2kdaWBk+HuAZFyNgb48bAI7hq0cqlQ== X-Received: by 2002:a17:902:dac2:b0:1bb:99d3:6a53 with SMTP id q2-20020a170902dac200b001bb99d36a53mr5646803plx.20.1692633432525; Mon, 21 Aug 2023 08:57:12 -0700 (PDT) Message-ID: Date: Tue, 22 Aug 2023 00:57:07 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 From: Jinoh Kang Subject: [PATCH 3/5] x86/hvm: RFC - PROBABLY BROKEN - Defer all debugging/monitor actions to {svm,vmx}_inject_event() To: xen-devel@lists.xenproject.org, Andrew Cooper Cc: Jan Beulich , Wei Liu , =?utf-8?q?Roger_P?= =?utf-8?q?au_Monn=C3=A9?= , Jun Nakajima , Kevin Tian , Razvan Cojocaru , Tamas K Lengyel References: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> Content-Language: en-US In-Reply-To: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> From: Andrew Cooper Currently, there is a lot of functionality in the #DB intercepts, and some repeated functionality in the *_inject_event() logic. The gdbsx code is implemented at both levels (albeit differently for #BP, which is presumably due to the fact that the old emulator behaviour used to be to move %rip forwards for traps), while the monitor behaviour only exists at the intercept level. Updating of %dr6 is implemented (buggily) at both levels, but having it at both levels is problematic to implement correctly. Rearrange the logic to have nothing interesting at the intercept level, and everything implemented at the injection level. Amongst other things, this means that the monitor subsystem will pick up debug actions from emulated events. Signed-off-by: Jinoh Kang --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné CC: Jun Nakajima CC: Kevin Tian CC: Razvan Cojocaru CC: Tamas K Lengyel This is RFC because it probably breaks introspection, as injection replies from the introspection engine will (probably, but I haven't confirmed) trigger new monitor events. First of all, monitoring emulated debug events is a change in behaviour, although IMO it is more of a bugfix than a new feature. Also, similar changes will happen to other monitored events as we try to unify the intercept/emulation paths. As for the recursive triggering of monitor events, I was considering extending the monitor infrastructure to have a "in monitor reply" boolean which causes hvm_monitor_debug() to ignore the recursive request. Does this plan sound ok, or have I missed something more subtle with monitor handling? --- xen/arch/x86/hvm/svm/svm.c | 126 ++++++++++++++++++++----------------- xen/arch/x86/hvm/vmx/vmx.c | 102 +++++++++++++----------------- 2 files changed, 110 insertions(+), 118 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index ac3123c56f..bd3adde0ec 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1328,19 +1328,50 @@ static void cf_check svm_inject_event(const struct x86_event *event) switch ( _event.vector | -(_event.type == X86_EVENTTYPE_SW_INTERRUPT) ) { case X86_EXC_DB: - if ( regs->eflags & X86_EFLAGS_TF ) - { - __restore_debug_registers(vmcb, curr); - vmcb_set_dr6(vmcb, vmcb_get_dr6(vmcb) | DR_STEP); - } + /* + * On AMD hardware, a #DB exception: + * 1) Merges new status bits into %dr6 + * 2) Clears %dr7.gd and MSR_DEBUGCTL.{LBR,BTF} + * + * Item 1 is done by hardware before a #DB intercepted vmexit, but we + * may end up here from emulation so have to repeat it ourselves. + * Item 2 is done by hardware when injecting a #DB exception. + */ + __restore_debug_registers(vmcb, curr); + vmcb_set_dr6(vmcb, vmcb_get_dr6(vmcb) | _event.pending_dbg); + /* fall through */ case X86_EXC_BP: if ( curr->domain->debugger_attached ) { /* Debug/Int3: Trap to debugger. */ + if ( _event.vector == X86_EXC_BP ) + { + /* N.B. Can't use __update_guest_eip() for risk of recusion. */ + regs->rip += _event.insn_len; + regs->eflags &= ~X86_EFLAGS_RF; + curr->arch.gdbsx_vcpu_event = X86_EXC_BP; + } + domain_pause_for_debugger(); return; } + else + { + int rc = hvm_monitor_debug(regs->rip, + _event.vector == X86_EXC_DB + ? HVM_MONITOR_DEBUG_EXCEPTION + : HVM_MONITOR_SOFTWARE_BREAKPOINT, + _event.type, _event.insn_len, + _event.pending_dbg); + if ( rc < 0 ) + { + gprintk(XENLOG_ERR, "Monitor debug error %d\n", rc); + return svm_crash_or_fault(curr); + } + if ( rc ) + return; /* VCPU paused. Wait for monitor. */ + } break; case X86_EXC_PF: @@ -2730,67 +2761,46 @@ void svm_vmexit_handler(void) case VMEXIT_ICEBP: case VMEXIT_EXCEPTION_DB: - if ( !v->domain->debugger_attached ) + case VMEXIT_EXCEPTION_BP: + { + unsigned int vec, type, len, extra; + + switch ( exit_reason ) { - unsigned int trap_type; + case VMEXIT_ICEBP: + vec = X86_EXC_DB; + type = X86_EVENTTYPE_PRI_SW_EXCEPTION; + len = svm_get_insn_len(v, INSTR_ICEBP); + extra = 0; + break; - if ( likely(exit_reason != VMEXIT_ICEBP) ) - { - trap_type = X86_EVENTTYPE_HW_EXCEPTION; - insn_len = 0; - } - else - { - trap_type = X86_EVENTTYPE_PRI_SW_EXCEPTION; - insn_len = svm_get_insn_len(v, INSTR_ICEBP); + case VMEXIT_EXCEPTION_DB: + vec = X86_EXC_DB; + type = X86_EVENTTYPE_HW_EXCEPTION; + len = 0; + /* #DB - Hardware has already updated %dr6 for us. */ + extra = vmcb_get_dr6(vmcb) ^ X86_DR6_DEFAULT; + break; - if ( !insn_len ) - break; - } + case VMEXIT_EXCEPTION_BP: + vec = X86_EXC_BP; + type = X86_EVENTTYPE_SW_EXCEPTION; + len = svm_get_insn_len(v, INSTR_INT3); + extra = 0; /* N/A */ + break; - rc = hvm_monitor_debug(regs->rip, - HVM_MONITOR_DEBUG_EXCEPTION, - trap_type, insn_len, 0); - if ( rc < 0 ) - goto unexpected_exit_type; - if ( !rc ) - hvm_inject_exception(X86_EXC_DB, - trap_type, insn_len, X86_EVENT_NO_EC, - exit_reason == VMEXIT_ICEBP ? 0 : - /* #DB - Hardware already updated dr6. */ - vmcb_get_dr6(vmcb) ^ X86_DR6_DEFAULT); + default: + ASSERT_UNREACHABLE(); + goto unexpected_exit_type; } - else - domain_pause_for_debugger(); - break; - case VMEXIT_EXCEPTION_BP: - insn_len = svm_get_insn_len(v, INSTR_INT3); - - if ( insn_len == 0 ) - break; + /* svm_get_insn_len() failure. #GP queued up. */ + if ( type >= X86_EVENTTYPE_SW_INTERRUPT && !len ) + break; - if ( v->domain->debugger_attached ) - { - /* AMD Vol2, 15.11: INT3, INTO, BOUND intercepts do not update RIP. */ - __update_guest_eip(regs, insn_len); - current->arch.gdbsx_vcpu_event = X86_EXC_BP; - domain_pause_for_debugger(); - } - else - { - rc = hvm_monitor_debug(regs->rip, - HVM_MONITOR_SOFTWARE_BREAKPOINT, - X86_EVENTTYPE_SW_EXCEPTION, - insn_len, 0); - if ( rc < 0 ) - goto unexpected_exit_type; - if ( !rc ) - hvm_inject_exception(X86_EXC_BP, - X86_EVENTTYPE_SW_EXCEPTION, - insn_len, X86_EVENT_NO_EC, 0 /* N/A */); - } + hvm_inject_exception(vec, type, len, X86_EVENT_NO_EC, extra); break; + } case VMEXIT_EXCEPTION_NM: svm_fpu_dirty_intercept(); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 716115332b..65166348f1 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2018,15 +2018,21 @@ static void cf_check vmx_inject_event(const struct x86_event *event) unsigned long intr_info; struct vcpu *curr = current; struct x86_event _event = *event; + struct cpu_user_regs *regs = guest_cpu_user_regs(); switch ( _event.vector | -(_event.type == X86_EVENTTYPE_SW_INTERRUPT) ) { case X86_EXC_DB: - if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF ) - { - __restore_debug_registers(curr); - write_debugreg(6, read_debugreg(6) | DR_STEP); - } + /* + * On Intel hardware, a #DB exception: + * 1) Merges new status bits into %dr6 + * 2) Clears %dr7.gd and MSR_DEBUGCTL.LBR + * + * All actions are left up to the hypervisor to perform. + */ + __restore_debug_registers(curr); + write_debugreg(6, read_debugreg(6) | event->pending_dbg); + if ( !nestedhvm_vcpu_in_guestmode(curr) || !nvmx_intercepts_exception(curr, X86_EXC_DB, _event.error_code) ) { @@ -2037,16 +2043,39 @@ static void cf_check vmx_inject_event(const struct x86_event *event) __vmread(GUEST_IA32_DEBUGCTL, &val); __vmwrite(GUEST_IA32_DEBUGCTL, val & ~IA32_DEBUGCTLMSR_LBR); } - if ( cpu_has_monitor_trap_flag ) - break; + /* fall through */ case X86_EXC_BP: if ( curr->domain->debugger_attached ) { /* Debug/Int3: Trap to debugger. */ + if ( _event.vector == X86_EXC_BP ) + { + /* N.B. Can't use __update_guest_eip() for risk of recusion. */ + regs->rip += _event.insn_len; + regs->eflags &= ~X86_EFLAGS_RF; + curr->arch.gdbsx_vcpu_event = X86_EXC_BP; + } + domain_pause_for_debugger(); return; } + else + { + int rc = hvm_monitor_debug(regs->rip, + _event.vector == X86_EXC_DB + ? HVM_MONITOR_DEBUG_EXCEPTION + : HVM_MONITOR_SOFTWARE_BREAKPOINT, + _event.type, _event.insn_len, 0); + if ( rc < 0 ) + { + gprintk(XENLOG_ERR, "Monitor debug error %d\n", rc); + domain_crash(curr->domain); + return; + } + if ( rc ) + return; /* VCPU paused. Wait for monitor. */ + } break; case X86_EXC_PF: @@ -4242,14 +4271,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) switch ( vector ) { case X86_EXC_DB: - /* - * Updates DR6 where debugger can peek (See 3B 23.2.1, - * Table 23-1, "Exit Qualification for Debug Exceptions"). - */ __vmread(EXIT_QUALIFICATION, &exit_qualification); HVMTRACE_1D(TRAP_DEBUG, exit_qualification); - __restore_debug_registers(v); - write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE); /* * Work around SingleStep + STI/MovSS VMEntry failures. @@ -4286,53 +4309,15 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) } } - if ( !v->domain->debugger_attached ) - { - unsigned long insn_len = 0; - int rc; - unsigned long trap_type = MASK_EXTR(intr_info, - INTR_INFO_INTR_TYPE_MASK); - - if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT ) - __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len); - - rc = hvm_monitor_debug(regs->rip, - HVM_MONITOR_DEBUG_EXCEPTION, - trap_type, insn_len, 0); - - if ( rc < 0 ) - goto exit_and_crash; - if ( !rc ) - vmx_propagate_intr(intr_info, exit_qualification); - } - else - domain_pause_for_debugger(); + vmx_propagate_intr(intr_info, exit_qualification); break; + case X86_EXC_BP: + case X86_EXC_AC: HVMTRACE_1D(TRAP, vector); - if ( !v->domain->debugger_attached ) - { - unsigned long insn_len; - int rc; - - __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len); - rc = hvm_monitor_debug(regs->rip, - HVM_MONITOR_SOFTWARE_BREAKPOINT, - X86_EVENTTYPE_SW_EXCEPTION, - insn_len, 0); - - if ( rc < 0 ) - goto exit_and_crash; - if ( !rc ) - vmx_propagate_intr(intr_info, 0 /* N/A */); - } - else - { - update_guest_eip(); /* Safe: INT3 */ - v->arch.gdbsx_vcpu_event = X86_EXC_BP; - domain_pause_for_debugger(); - } + vmx_propagate_intr(intr_info, 0 /* N/A */); break; + case X86_EXC_NM: HVMTRACE_1D(TRAP, vector); vmx_fpu_dirty_intercept(); @@ -4362,10 +4347,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) hvm_inject_page_fault(regs->error_code, exit_qualification); break; - case X86_EXC_AC: - HVMTRACE_1D(TRAP, vector); - vmx_propagate_intr(intr_info, 0 /* N/A */); - break; + case X86_EXC_NMI: if ( MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK) != X86_EVENTTYPE_NMI ) From patchwork Mon Aug 21 15:57:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jinoh Kang X-Patchwork-Id: 13359602 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id E8D4FEE49AA for ; Mon, 21 Aug 2023 15:57:31 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.587667.919041 (Exim 4.92) (envelope-from ) id 1qY7HL-00086w-Ew; Mon, 21 Aug 2023 15:57:19 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 587667.919041; Mon, 21 Aug 2023 15:57:19 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7HL-00086p-A2; Mon, 21 Aug 2023 15:57:19 +0000 Received: by outflank-mailman (input) for mailman id 587667; Mon, 21 Aug 2023 15:57:18 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7HK-0007V2-O6 for xen-devel@lists.xenproject.org; Mon, 21 Aug 2023 15:57:18 +0000 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [2607:f8b0:4864:20::62b]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 665de17f-403b-11ee-9b0c-b553b5be7939; Mon, 21 Aug 2023 17:57:16 +0200 (CEST) Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-1bf3a2f44ffso24607645ad.1 for ; Mon, 21 Aug 2023 08:57:16 -0700 (PDT) Received: from [10.137.0.57] ([14.33.99.107]) by smtp.gmail.com with ESMTPSA id j10-20020a170902da8a00b001a5fccab02dsm7208314plx.177.2023.08.21.08.57.13 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 21 Aug 2023 08:57:15 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 665de17f-403b-11ee-9b0c-b553b5be7939 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692633435; x=1693238235; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id:from:to :cc:subject:date:message-id:reply-to; bh=koUXgNo33NkQg7mV/s+CjTkEjQnqF6941wnkN2hmX0k=; b=IYVEF72TlmOtSXZ8/QHVjcuwh+UuhF8PLcwOopLQlmKmuqDsTnNUidItKCWBYYyqX8 tIxOyYivlstDVUe1reaaWAJ059BQeT+dVWVgf70sZhwYbpCuVhvEmvwsjDLZrsXV+wcf i55eQ8d4a2osp85mwZsw7V+Gaap/1jcr0xlHYiTjKaMBSdG2kP4hcZNZkmfVlBRIBL46 g9rNYgBGrhsg5b4h1gRI5n2a72tSxCQulU2fAXFDFo72RzV0jDW2pujX4l0JRHiqTh/H 979sKKdKVN+J96Nk+ExZMueRM3P/9garyxjrjreTLUgvwqNfVdwj6eolNRvqgb2iOCcc Pkbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692633435; x=1693238235; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=koUXgNo33NkQg7mV/s+CjTkEjQnqF6941wnkN2hmX0k=; b=fa0zSnyOkxf4P8wsv56stPH/Jy2ty8kj/YkjLiIA/IczSGRFh6YDm0QF/UacIo0KKm eW2Yqyl9Y3LTRKZpDrd7Ncx7YZIzM2XE9AbvOrf6FMXdDbPDXZeVDcnZ1lZNTxQskO/u aUaAQfNdgWfGpW3PNVSJU6PMlpfmsFm51w3w4bjDbbS3fSRTeqOzkOl4JK1SgUP2ibII T2xpdcOOFaW/4WsCUPqHkNjom8kWztRrdimn/bYR97wuQwHMnVKbevatBEkRjuSUIhjQ Pu7CGIjXJnsdBkvx3w1HL171GDl8NZfD+zPxmrwm8AlfX+2FRr8qFwKp1qyX28UL3vLr cy4A== X-Gm-Message-State: AOJu0YzKvAEyQKUiXIAAIw9Slo23DPWDUZmgiUEOj2XTHS7425/lLYOV 1WbGSgcrishSv92f49nXFFlwcP58KrDQJQ== X-Google-Smtp-Source: AGHT+IEAQP3ubFa0rv1Xj61latk7fdjmjugV/wzlkma7nTyCWeQFbKZrYjbeVHqauzgXtCdwLVubHA== X-Received: by 2002:a17:903:1111:b0:1b9:de75:d5bb with SMTP id n17-20020a170903111100b001b9de75d5bbmr10714294plh.7.1692633435482; Mon, 21 Aug 2023 08:57:15 -0700 (PDT) Message-ID: <2ba03e50-421c-9163-355c-d7c612f2f711@gmail.com> Date: Tue, 22 Aug 2023 00:57:11 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 From: Jinoh Kang Subject: [PATCH 4/5] x86: Fix merging of new status bits into %dr6 To: xen-devel@lists.xenproject.org, Andrew Cooper Cc: Jan Beulich , Wei Liu , =?utf-8?q?Roger_P?= =?utf-8?q?au_Monn=C3=A9?= , Jun Nakajima , Kevin Tian References: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> Content-Language: en-US In-Reply-To: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> From: Andrew Cooper The current logic used to update %dr6 when injecting #DB is buggy. The architectural behaviour is to overwrite B{0..3} (rather than accumulate) and accumulate all other bits. Introduce a new merge_dr6() helper, which also takes care of handing RTM correctly. Signed-off-by: Jinoh Kang --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné CC: Jun Nakajima CC: Kevin Tian --- xen/arch/x86/hvm/svm/svm.c | 3 ++- xen/arch/x86/hvm/vmx/vmx.c | 3 ++- xen/arch/x86/include/asm/debugreg.h | 30 +++++++++++++++++++++++++++- xen/arch/x86/include/asm/x86-defns.h | 10 ---------- xen/arch/x86/pv/traps.c | 3 ++- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index bd3adde0ec..7a5652f3df 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1338,7 +1338,8 @@ static void cf_check svm_inject_event(const struct x86_event *event) * Item 2 is done by hardware when injecting a #DB exception. */ __restore_debug_registers(vmcb, curr); - vmcb_set_dr6(vmcb, vmcb_get_dr6(vmcb) | _event.pending_dbg); + vmcb_set_dr6(vmcb, merge_dr6(vmcb_get_dr6(vmcb), _event.pending_dbg, + curr->domain->arch.cpuid->feat.rtm)); /* fall through */ case X86_EXC_BP: diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 65166348f1..1fd902ed74 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2031,7 +2031,8 @@ static void cf_check vmx_inject_event(const struct x86_event *event) * All actions are left up to the hypervisor to perform. */ __restore_debug_registers(curr); - write_debugreg(6, read_debugreg(6) | event->pending_dbg); + write_debugreg(6, merge_dr6(read_debugreg(6), event->pending_dbg, + curr->domain->arch.cpuid->feat.rtm)); if ( !nestedhvm_vcpu_in_guestmode(curr) || !nvmx_intercepts_exception(curr, X86_EXC_DB, _event.error_code) ) diff --git a/xen/arch/x86/include/asm/debugreg.h b/xen/arch/x86/include/asm/debugreg.h index a1df74c02e..fd32846397 100644 --- a/xen/arch/x86/include/asm/debugreg.h +++ b/xen/arch/x86/include/asm/debugreg.h @@ -23,6 +23,14 @@ #define X86_DR6_BT (1u << 15) /* Task switch */ #define X86_DR6_RTM (1u << 16) /* #DB/#BP in RTM region */ +#define X86_DR6_BP_MASK \ + (X86_DR6_B0 | X86_DR6_B1 | X86_DR6_B2 | X86_DR6_B3) + +#define X86_DR6_KNOWN_MASK \ + (X86_DR6_BP_MASK | X86_DR6_BD | X86_DR6_BS | X86_DR6_BT | X86_DR6_RTM) + +#define X86_DR6_DEFAULT 0xffff0ff0 /* Default %dr6 value. */ + #define DR_TRAP0 (0x1) /* db0 */ #define DR_TRAP1 (0x2) /* db1 */ #define DR_TRAP2 (0x4) /* db2 */ @@ -30,7 +38,6 @@ #define DR_STEP (0x4000) /* single-step */ #define DR_SWITCH (0x8000) /* task switch */ #define DR_NOT_RTM (0x10000) /* clear: #BP inside RTM region */ -#define DR_STATUS_RESERVED_ONE 0xffff0ff0UL /* Reserved, read as one */ /* Now define a bunch of things for manipulating the control register. The top two bytes of the control register consist of 4 fields of 4 @@ -74,6 +81,8 @@ #define DR_RTM_ENABLE (0x00000800UL) /* RTM debugging enable */ #define DR_GENERAL_DETECT (0x00002000UL) /* General detect enable */ +#define X86_DR7_DEFAULT 0x00000400 /* Default %dr7 value. */ + #define write_debugreg(reg, val) do { \ unsigned long __val = val; \ asm volatile ( "mov %0,%%db" #reg : : "r" (__val) ); \ @@ -102,6 +111,25 @@ static inline unsigned long adjust_dr6_rsvd(unsigned long dr6, bool rtm) return dr6; } +static inline unsigned long merge_dr6(unsigned long dr6, unsigned long new, + bool rtm) +{ + /* Flip dr6 to have positive polarity. */ + dr6 ^= X86_DR6_DEFAULT; + + /* Sanity check that only known values are passed in. */ + ASSERT(!(dr6 & ~X86_DR6_KNOWN_MASK)); + ASSERT(!(new & ~X86_DR6_KNOWN_MASK)); + + /* Breakpoints 0-3 overridden. BD, BS, BT and RTM accumulate. */ + dr6 = (dr6 & ~X86_DR6_BP_MASK) | new; + + /* Flip dr6 back to having default polarity. */ + dr6 ^= X86_DR6_DEFAULT; + + return adjust_dr6_rsvd(dr6, rtm); +} + static inline unsigned long adjust_dr7_rsvd(unsigned long dr7, bool rtm) { /* diff --git a/xen/arch/x86/include/asm/x86-defns.h b/xen/arch/x86/include/asm/x86-defns.h index e350227e57..7fbc74850a 100644 --- a/xen/arch/x86/include/asm/x86-defns.h +++ b/xen/arch/x86/include/asm/x86-defns.h @@ -100,16 +100,6 @@ #define X86_XCR0_LWP_POS 62 #define X86_XCR0_LWP (1ULL << X86_XCR0_LWP_POS) -/* - * Debug status flags in DR6. - */ -#define X86_DR6_DEFAULT 0xffff0ff0 /* Default %dr6 value. */ - -/* - * Debug control flags in DR7. - */ -#define X86_DR7_DEFAULT 0x00000400 /* Default %dr7 value. */ - /* * Invalidation types for the INVPCID instruction. */ diff --git a/xen/arch/x86/pv/traps.c b/xen/arch/x86/pv/traps.c index 4f5641a47c..65b41e6115 100644 --- a/xen/arch/x86/pv/traps.c +++ b/xen/arch/x86/pv/traps.c @@ -66,7 +66,8 @@ void pv_inject_event(const struct x86_event *event) break; case X86_EXC_DB: - curr->arch.dr6 |= event->pending_dbg; + curr->arch.dr6 = merge_dr6(curr->arch.dr6, event->pending_dbg, + curr->domain->arch.cpuid->feat.rtm); /* Fallthrough */ default: From patchwork Mon Aug 21 15:57:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jinoh Kang X-Patchwork-Id: 13359603 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 00E1CEE4993 for ; Mon, 21 Aug 2023 15:57:38 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.587669.919051 (Exim 4.92) (envelope-from ) id 1qY7HP-0008T1-LB; Mon, 21 Aug 2023 15:57:23 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 587669.919051; Mon, 21 Aug 2023 15:57:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7HP-0008Sn-Hh; Mon, 21 Aug 2023 15:57:23 +0000 Received: by outflank-mailman (input) for mailman id 587669; Mon, 21 Aug 2023 15:57:21 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qY7HN-0007T4-Tu for xen-devel@lists.xenproject.org; Mon, 21 Aug 2023 15:57:21 +0000 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [2607:f8b0:4864:20::1035]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 69179f1c-403b-11ee-8782-cb3800f73035; Mon, 21 Aug 2023 17:57:21 +0200 (CEST) Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-26b1adbd655so1683174a91.1 for ; Mon, 21 Aug 2023 08:57:21 -0700 (PDT) Received: from [10.137.0.57] ([14.33.99.107]) by smtp.gmail.com with ESMTPSA id gk10-20020a17090b118a00b00263f5ac814esm8006442pjb.38.2023.08.21.08.57.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 21 Aug 2023 08:57:19 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 69179f1c-403b-11ee-8782-cb3800f73035 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692633440; x=1693238240; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id:from:to :cc:subject:date:message-id:reply-to; bh=3h0/4vMhdc6NEPPkooWDGkHtRbVMqlbYe751/Lp+iP4=; b=mWSIgkZCck934AGqU7WG5KHhLW1pQeWfoIFz9a8LxWINvtYpDgE5Q8y2TeurJRSTPY raCgRIOVqQwYPS233mfh3hKSeUfKsb8aIZ+3bUA8ih1/kr/Q3Oz9JMh9duY6XGdQmLGM NztUs7Z9AnrPMslcb8ZlW2YSYQ+z6na9/jT1k0dmYDjV0zO/oNxrp5y23PjSgBAko2h+ Zh8xVhnSwfmcuDd1sQ1EA2a87/qfKrrKtBCLosBfVMnHzHlHcipUAQzE304HdX+NoyqI mvtRcj2NiAAv+nELIuSAFokQF7y8Bm3BbyuC9edejyKfp15f+sJRcNJZYX2hw2FW0KNq nEsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692633440; x=1693238240; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3h0/4vMhdc6NEPPkooWDGkHtRbVMqlbYe751/Lp+iP4=; b=A8makKs7xIKEzecC2850zwNJ3cpCZO+5+jhebGxa45/3tguk/ItMMz57kVWIxdeq3v 1Z5r9W/9MLnVdeofjIK9yuLXnUyZhWEDpnhGcXDH0uH56frS28LREs8Rd4kbwd0Av8UP iaOeh5JTgW37A7U2yJLYaIyxKwfcLk+zDbjEKgiFvkZ1KwEd5bi/f8hhh9pYDHeK2yD2 HqcVc1oZJwU80bOK8mDop40mDkF2XH43TKdx5THk7pktKSPC4GXfzSaH4fUj1eS4U/Fe gVm2EnRahcnOXwxGLhtWhWTWoUkFwa9m8RDZGZNXBrPb9t4zcW8F8QBFSsq8RtqEOs7g A+1g== X-Gm-Message-State: AOJu0YwSYwHQCZe9MmGB59QrJzLqBZjDNH/sOgDMU7f2O2Ua75nI81wg xMj+xuyFelUmyxSAAc8J2YRnhsP/e3QdWg== X-Google-Smtp-Source: AGHT+IFAEAp8qN0zy425H2mzixp+DP/gF9uDNT86EnfWADBY6jmQA7seN41nIAGrKeijPlLJrWveTw== X-Received: by 2002:a17:90a:c691:b0:262:ecd9:ed09 with SMTP id n17-20020a17090ac69100b00262ecd9ed09mr4460482pjt.33.1692633440024; Mon, 21 Aug 2023 08:57:20 -0700 (PDT) Message-ID: Date: Tue, 22 Aug 2023 00:57:16 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 From: Jinoh Kang Subject: [PATCH 5/5] x86/dbg: Cleanup of legacy dr6 constants To: xen-devel@lists.xenproject.org, Andrew Cooper Cc: Jan Beulich , Wei Liu , =?utf-8?q?Roger_P?= =?utf-8?q?au_Monn=C3=A9?= References: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> Content-Language: en-US In-Reply-To: <5fa229fc-9514-abc6-5e72-2447a2c637d0@gmail.com> From: Andrew Cooper Replace the few remaining uses with X86_DR6_* constants. Signed-off-by: Jinoh Kang --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/hvm/vmx/vmx.c | 2 +- xen/arch/x86/include/asm/debugreg.h | 17 ----------------- xen/arch/x86/pv/emul-priv-op.c | 2 +- xen/arch/x86/traps.c | 2 +- 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 1fd902ed74..43b57a444e 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -4306,7 +4306,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) __vmread(GUEST_PENDING_DBG_EXCEPTIONS, &pending_dbg); __vmwrite(GUEST_PENDING_DBG_EXCEPTIONS, - pending_dbg | DR_STEP); + pending_dbg | X86_DR6_BS); } } diff --git a/xen/arch/x86/include/asm/debugreg.h b/xen/arch/x86/include/asm/debugreg.h index fd32846397..1061fdaaae 100644 --- a/xen/arch/x86/include/asm/debugreg.h +++ b/xen/arch/x86/include/asm/debugreg.h @@ -1,15 +1,6 @@ #ifndef _X86_DEBUGREG_H #define _X86_DEBUGREG_H - -/* Indicate the register numbers for a number of the specific - debug registers. Registers 0-3 contain the addresses we wish to trap on */ - -#define DR_FIRSTADDR 0 -#define DR_LASTADDR 3 -#define DR_STATUS 6 -#define DR_CONTROL 7 - /* * DR6 status bits. * N.B. For backwards compatibility, X86_DR6_RTM has inverted polarity. @@ -31,14 +22,6 @@ #define X86_DR6_DEFAULT 0xffff0ff0 /* Default %dr6 value. */ -#define DR_TRAP0 (0x1) /* db0 */ -#define DR_TRAP1 (0x2) /* db1 */ -#define DR_TRAP2 (0x4) /* db2 */ -#define DR_TRAP3 (0x8) /* db3 */ -#define DR_STEP (0x4000) /* single-step */ -#define DR_SWITCH (0x8000) /* task switch */ -#define DR_NOT_RTM (0x10000) /* clear: #BP inside RTM region */ - /* Now define a bunch of things for manipulating the control register. The top two bytes of the control register consist of 4 fields of 4 bits - each field corresponds to one of the four debug registers, diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index 72d0514e74..78a1f4aff7 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -1359,7 +1359,7 @@ int pv_emulate_privileged_op(struct cpu_user_regs *regs) { case X86EMUL_OKAY: if ( ctxt.ctxt.retire.singlestep ) - ctxt.bpmatch |= DR_STEP; + ctxt.bpmatch |= X86_DR6_BS; if ( ctxt.bpmatch && !(curr->arch.pv.trap_bounce.flags & TBF_EXCEPTION) ) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 640b60e0e5..829741ff78 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1955,7 +1955,7 @@ void do_debug(struct cpu_user_regs *regs) * If however we do, safety measures need to be enacted. Use a big * hammer and clear all debug settings. */ - if ( dr6 & (DR_TRAP3 | DR_TRAP2 | DR_TRAP1 | DR_TRAP0) ) + if ( dr6 & X86_DR6_BP_MASK ) { unsigned int bp, dr7 = read_debugreg(7);