From patchwork Wed Sep 9 09:59:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11765279 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 7A900746 for ; Wed, 9 Sep 2020 10:00:58 +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 4CC4121973 for ; Wed, 9 Sep 2020 10:00:58 +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="MBEJt7Ka" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4CC4121973 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass 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.92) (envelope-from ) id 1kFwtH-0008Su-0q; Wed, 09 Sep 2020 09:59:47 +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.92) (envelope-from ) id 1kFwtE-0008SC-UJ for xen-devel@lists.xenproject.org; Wed, 09 Sep 2020 09:59:44 +0000 X-Inumbo-ID: 511b9044-14ea-4679-95f9-078476ed94bd Received: from esa3.hc3370-68.iphmx.com (unknown [216.71.145.155]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 511b9044-14ea-4679-95f9-078476ed94bd; Wed, 09 Sep 2020 09:59:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1599645579; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1PbLj0WTQtCpCIy8e73E6RN9TS0bcCD9OLyImnkdXGA=; b=MBEJt7Ka2edXD0mlM5NKPzyMjuYTxbBsl7BgwcHtS7YRqL2qMC/mqZII /zRAIxUVzucoNuZEOSxxAHgVTQg5BUcj+G81A9fw3ON+wk6EETOSnmopD IbjeDyoRoVP5rLZJvaQJgnGCaSnZ7/7M9qiYvpxynIVr0XftouuXdgFzH k=; Authentication-Results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: rJfRYUrXr9To57PGQMata2dqgBUpOMRCfgQaokncr5XhphXaBatV3Kk3Ezwx7vp+dkvf8GI87w 7piYKmt/OXOrIznziCKhVbQVv3PVc+r5i089fWgzsiYzuQyUcoXlNuDDJeWj5pTpjemSlnvrPx azy6lx+S+UfTF4d0oinafiAmLgcIu3De/hGkl4+gmMXro3mImVjxrKmn6Rprf3f4tPWEvDUQqS uTOocXc5KIR+1FSYnQw47AI+ZAZQ+ICnB5wXL+9Wyp7xp6XG7l8dnAAOFG5GiMJUqeCC1B5RP+ h/k= X-SBRS: 2.7 X-MesageID: 26254229 X-Ironport-Server: esa3.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.76,409,1592884800"; d="scan'208";a="26254229" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Wei Liu , Jun Nakajima , Kevin Tian Subject: [PATCH 1/5] x86/asm: Rename FS/GS base helpers Date: Wed, 9 Sep 2020 10:59:16 +0100 Message-ID: <20200909095920.25495-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200909095920.25495-1-andrew.cooper3@citrix.com> References: <20200909095920.25495-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" They are currently named after the FSGSBASE instructions, but are not thin wrappers around said instructions, and therefore do not accurately reflect the logic they perform, especially when it comes to functioning safely in non FSGSBASE context. Rename them to {read,write}_{fs,gs}_base() to avoid confusion. No functional change. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich Reviewed-by: Kevin Tian --- CC: Jan Beulich CC: Roger Pau Monné CC: Wei Liu CC: Jun Nakajima CC: Kevin Tian --- xen/arch/x86/domain.c | 10 +++++----- xen/arch/x86/hvm/vmx/vmx.c | 8 ++++---- xen/arch/x86/pv/domain.c | 2 +- xen/arch/x86/pv/emul-priv-op.c | 14 +++++++------- xen/arch/x86/x86_64/mm.c | 8 ++++---- xen/arch/x86/x86_64/traps.c | 6 +++--- xen/include/asm-x86/msr.h | 12 ++++++------ 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index e8e91cf080..2271bee36a 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1581,9 +1581,9 @@ static void load_segments(struct vcpu *n) if ( !fs_gs_done && !compat ) { - wrfsbase(n->arch.pv.fs_base); - wrgsshadow(n->arch.pv.gs_base_kernel); - wrgsbase(n->arch.pv.gs_base_user); + write_fs_base(n->arch.pv.fs_base); + write_gs_shadow(n->arch.pv.gs_base_kernel); + write_gs_base(n->arch.pv.gs_base_user); /* If in kernel mode then switch the GS bases around. */ if ( (n->arch.flags & TF_kernel_mode) ) @@ -1710,9 +1710,9 @@ static void save_segments(struct vcpu *v) if ( !is_pv_32bit_vcpu(v) ) { - unsigned long gs_base = rdgsbase(); + unsigned long gs_base = read_gs_base(); - v->arch.pv.fs_base = rdfsbase(); + v->arch.pv.fs_base = read_fs_base(); if ( v->arch.flags & TF_kernel_mode ) v->arch.pv.gs_base_kernel = gs_base; else diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index c4b40bf3cb..d26e102970 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -512,12 +512,12 @@ static void vmx_save_guest_msrs(struct vcpu *v) * We cannot cache SHADOW_GS_BASE while the VCPU runs, as it can * be updated at any time via SWAPGS, which we cannot trap. */ - v->arch.hvm.vmx.shadow_gs = rdgsshadow(); + v->arch.hvm.vmx.shadow_gs = read_gs_shadow(); } static void vmx_restore_guest_msrs(struct vcpu *v) { - wrgsshadow(v->arch.hvm.vmx.shadow_gs); + write_gs_shadow(v->arch.hvm.vmx.shadow_gs); wrmsrl(MSR_STAR, v->arch.hvm.vmx.star); wrmsrl(MSR_LSTAR, v->arch.hvm.vmx.lstar); wrmsrl(MSR_SYSCALL_MASK, v->arch.hvm.vmx.sfmask); @@ -2958,7 +2958,7 @@ static int vmx_msr_read_intercept(unsigned int msr, uint64_t *msr_content) break; case MSR_SHADOW_GS_BASE: - *msr_content = rdgsshadow(); + *msr_content = read_gs_shadow(); break; case MSR_STAR: @@ -3190,7 +3190,7 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content) else if ( msr == MSR_GS_BASE ) __vmwrite(GUEST_GS_BASE, msr_content); else - wrgsshadow(msr_content); + write_gs_shadow(msr_content); break; diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c index 44e4ea2582..663e76c773 100644 --- a/xen/arch/x86/pv/domain.c +++ b/xen/arch/x86/pv/domain.c @@ -452,7 +452,7 @@ void toggle_guest_mode(struct vcpu *v) * Update the cached value of the GS base about to become inactive, as a * subsequent context switch won't bother re-reading it. */ - gs_base = rdgsbase(); + gs_base = read_gs_base(); if ( v->arch.flags & TF_kernel_mode ) v->arch.pv.gs_base_kernel = gs_base; else diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index a192160f84..9dd1d59423 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -511,10 +511,10 @@ static int read_segment(enum x86_segment seg, reg->base = 0; break; case x86_seg_fs: - reg->base = rdfsbase(); + reg->base = read_fs_base(); break; case x86_seg_gs: - reg->base = rdgsbase(); + reg->base = read_gs_base(); break; } @@ -871,13 +871,13 @@ static int read_msr(unsigned int reg, uint64_t *val, case MSR_FS_BASE: if ( is_pv_32bit_domain(currd) ) break; - *val = rdfsbase(); + *val = read_fs_base(); return X86EMUL_OKAY; case MSR_GS_BASE: if ( is_pv_32bit_domain(currd) ) break; - *val = rdgsbase(); + *val = read_gs_base(); return X86EMUL_OKAY; case MSR_SHADOW_GS_BASE: @@ -993,19 +993,19 @@ static int write_msr(unsigned int reg, uint64_t val, case MSR_FS_BASE: if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) ) break; - wrfsbase(val); + write_fs_base(val); return X86EMUL_OKAY; case MSR_GS_BASE: if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) ) break; - wrgsbase(val); + write_gs_base(val); return X86EMUL_OKAY; case MSR_SHADOW_GS_BASE: if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) ) break; - wrgsshadow(val); + write_gs_shadow(val); curr->arch.pv.gs_base_user = val; return X86EMUL_OKAY; diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index b69cf2dc4f..0d11a9f500 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -1030,7 +1030,7 @@ long do_set_segment_base(unsigned int which, unsigned long base) { case SEGBASE_FS: if ( is_canonical_address(base) ) - wrfsbase(base); + write_fs_base(base); else ret = -EINVAL; break; @@ -1038,7 +1038,7 @@ long do_set_segment_base(unsigned int which, unsigned long base) case SEGBASE_GS_USER: if ( is_canonical_address(base) ) { - wrgsshadow(base); + write_gs_shadow(base); v->arch.pv.gs_base_user = base; } else @@ -1047,7 +1047,7 @@ long do_set_segment_base(unsigned int which, unsigned long base) case SEGBASE_GS_KERNEL: if ( is_canonical_address(base) ) - wrgsbase(base); + write_gs_base(base); else ret = -EINVAL; break; @@ -1096,7 +1096,7 @@ long do_set_segment_base(unsigned int which, unsigned long base) : [flat] "r" (FLAT_USER_DS32) ); /* Update the cache of the inactive base, as read from the GDT/LDT. */ - v->arch.pv.gs_base_user = rdgsbase(); + v->arch.pv.gs_base_user = read_gs_base(); asm volatile ( safe_swapgs ); break; diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 93af0c5e87..4f262122b7 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -47,9 +47,9 @@ static void read_registers(struct cpu_user_regs *regs, unsigned long crs[8]) regs->es = read_sreg(es); regs->fs = read_sreg(fs); regs->gs = read_sreg(gs); - crs[5] = rdfsbase(); - crs[6] = rdgsbase(); - crs[7] = rdgsshadow(); + crs[5] = read_fs_base(); + crs[6] = read_gs_base(); + crs[7] = read_gs_shadow(); } static void _show_registers( diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h index 5c44c79600..5e141ac5a5 100644 --- a/xen/include/asm-x86/msr.h +++ b/xen/include/asm-x86/msr.h @@ -156,7 +156,7 @@ static inline unsigned long __rdgsbase(void) return base; } -static inline unsigned long rdfsbase(void) +static inline unsigned long read_fs_base(void) { unsigned long base; @@ -168,7 +168,7 @@ static inline unsigned long rdfsbase(void) return base; } -static inline unsigned long rdgsbase(void) +static inline unsigned long read_gs_base(void) { unsigned long base; @@ -180,7 +180,7 @@ static inline unsigned long rdgsbase(void) return base; } -static inline unsigned long rdgsshadow(void) +static inline unsigned long read_gs_shadow(void) { unsigned long base; @@ -196,7 +196,7 @@ static inline unsigned long rdgsshadow(void) return base; } -static inline void wrfsbase(unsigned long base) +static inline void write_fs_base(unsigned long base) { if ( read_cr4() & X86_CR4_FSGSBASE ) #ifdef HAVE_AS_FSGSBASE @@ -208,7 +208,7 @@ static inline void wrfsbase(unsigned long base) wrmsrl(MSR_FS_BASE, base); } -static inline void wrgsbase(unsigned long base) +static inline void write_gs_base(unsigned long base) { if ( read_cr4() & X86_CR4_FSGSBASE ) #ifdef HAVE_AS_FSGSBASE @@ -220,7 +220,7 @@ static inline void wrgsbase(unsigned long base) wrmsrl(MSR_GS_BASE, base); } -static inline void wrgsshadow(unsigned long base) +static inline void write_gs_shadow(unsigned long base) { if ( read_cr4() & X86_CR4_FSGSBASE ) { From patchwork Wed Sep 9 09:59:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11765281 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 08BE192C for ; Wed, 9 Sep 2020 10:01:04 +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 C6DD721973 for ; Wed, 9 Sep 2020 10:01:03 +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="OFzPl2q8" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C6DD721973 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass 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.92) (envelope-from ) id 1kFwtK-0008Ta-9Z; Wed, 09 Sep 2020 09:59:50 +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.92) (envelope-from ) id 1kFwtJ-0008SC-R2 for xen-devel@lists.xenproject.org; Wed, 09 Sep 2020 09:59:49 +0000 X-Inumbo-ID: 139cdb79-b791-44cc-b3cf-a633b1c4ad5a Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 139cdb79-b791-44cc-b3cf-a633b1c4ad5a; Wed, 09 Sep 2020 09:59:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1599645580; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yPfE7IFhRvz6YNbwtl+ttGI5B1vy4mIV43q6LhhTiko=; b=OFzPl2q8Nx5aFQYx14csQ6ZOUxvLn7lzZfONlazSbDVgdrGbwIzeM9wI sI+Iy1UNgduryWiBZQUtFjf6+zXYZGSZkcxRUTg3ptMED4lCQwYAmjMVo 5WQfINcx4XuzKRbVk5BT/VyK0KDEpAmOdqiYrMuKF8MhQA4S4yPa9SA6j U=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: goTY5gotyZpbps2UdqdYIU7CrWTkPlXDUbv50DyDhBFL1WnCvKw26rm4W9rTlGB09Hhig07Tu9 w5PI1hOm+QzsCFWk4ikb55mCbRKHlCCfrDOON8ioWZtAw8WUVSx7/sks5Fi/PXpgT5esA4B3/f ZanTu6N+eVD9lVlOhc6hEAa7jSR5EMh6Qcfomo42DsN9xObkzagdsS7WcSOOHp/bzo++V0sM3B 15DC/S+IcY7R9wePk3Ar065F0RfMTm+i3nqzVw3EFzSDAmRW9PamwXYmd4J7oWBHg3wcmwY/VT I78= X-SBRS: 2.7 X-MesageID: 26574721 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.76,409,1592884800"; d="scan'208";a="26574721" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Wei Liu Subject: [PATCH 2/5] x86/asm: Split __wr{fs, gs}base() out of write_{fs, gs}_base() Date: Wed, 9 Sep 2020 10:59:17 +0100 Message-ID: <20200909095920.25495-3-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200909095920.25495-1-andrew.cooper3@citrix.com> References: <20200909095920.25495-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" To match the read side which is already split out. A future change will want to use them. No functional change. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monné CC: Wei Liu --- xen/include/asm-x86/msr.h | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h index 5e141ac5a5..16f95e7344 100644 --- a/xen/include/asm-x86/msr.h +++ b/xen/include/asm-x86/msr.h @@ -156,6 +156,24 @@ static inline unsigned long __rdgsbase(void) return base; } +static inline void __wrfsbase(unsigned long base) +{ +#ifdef HAVE_AS_FSGSBASE + asm volatile ( "wrfsbase %0" :: "r" (base) ); +#else + asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd0" :: "a" (base) ); +#endif +} + +static inline void __wrgsbase(unsigned long base) +{ +#ifdef HAVE_AS_FSGSBASE + asm volatile ( "wrgsbase %0" :: "r" (base) ); +#else + asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd8" :: "a" (base) ); +#endif +} + static inline unsigned long read_fs_base(void) { unsigned long base; @@ -199,11 +217,7 @@ static inline unsigned long read_gs_shadow(void) static inline void write_fs_base(unsigned long base) { if ( read_cr4() & X86_CR4_FSGSBASE ) -#ifdef HAVE_AS_FSGSBASE - asm volatile ( "wrfsbase %0" :: "r" (base) ); -#else - asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd0" :: "a" (base) ); -#endif + __wrfsbase(base); else wrmsrl(MSR_FS_BASE, base); } @@ -211,11 +225,7 @@ static inline void write_fs_base(unsigned long base) static inline void write_gs_base(unsigned long base) { if ( read_cr4() & X86_CR4_FSGSBASE ) -#ifdef HAVE_AS_FSGSBASE - asm volatile ( "wrgsbase %0" :: "r" (base) ); -#else - asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd8" :: "a" (base) ); -#endif + __wrgsbase(base); else wrmsrl(MSR_GS_BASE, base); } From patchwork Wed Sep 9 09:59:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11765275 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 602E3746 for ; Wed, 9 Sep 2020 10:00:50 +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 3013D21973 for ; Wed, 9 Sep 2020 10:00:50 +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="Ks90o/Bj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3013D21973 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass 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.92) (envelope-from ) id 1kFwtP-0008V8-IG; Wed, 09 Sep 2020 09:59:55 +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.92) (envelope-from ) id 1kFwtO-0008SC-RH for xen-devel@lists.xenproject.org; Wed, 09 Sep 2020 09:59:54 +0000 X-Inumbo-ID: 5ae97973-df49-4a94-8459-a4f4a86a9017 Received: from esa3.hc3370-68.iphmx.com (unknown [216.71.145.155]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 5ae97973-df49-4a94-8459-a4f4a86a9017; Wed, 09 Sep 2020 09:59:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1599645590; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=omgwX94meR9g2tOyVCxV+2Bo3Nu0tqHjyyAWxvHuVi8=; b=Ks90o/BjeOAwW8BJ2Piub8mGKRkc+vPKMfZm3e39q0FeFJs+Pp3CsfJG JxXxb9iFBchYQYZl2jnTWnmjlQ6yszHGdXHAIUqNSpS6mnsGJvFw9cqXc qLgD8xfKbfQhHiG9s/vIko+xUZN53KRL8AunuRoj4v/8+2NHpWbiCMw5I 8=; Authentication-Results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: sEB81jO8yAmHZnB7wNrWC9viDBCDKqAgErxga3DBrc4/iJQpe79MRxz5y80jtxnEXgJkDPpCur 7RVd5nWVHmxOAqkoAyHgHvcmEZz/vCY97y7Lrglj/Wp3XQ0b7yJY+2RI0K28jh3DKdhf/mmOl/ jRJ6S0YqzX++0+ql05KefgQaL802r25lIvwq4sRMmejJ8DSwJ5Esl2kohnW9lzoW4zwS+4zs6e aoG4hEg6Gr93eJtWUuZw/dSVyVT8AHUrTXHXAzNsVfPPDCN7uVDgJWYrFIfZLKEwKguRXUWkEV m9c= X-SBRS: 2.7 X-MesageID: 26254234 X-Ironport-Server: esa3.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.76,409,1592884800"; d="scan'208";a="26254234" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Wei Liu Subject: [PATCH 3/5] x86/pv: Optimise prefetching in svm_load_segs() Date: Wed, 9 Sep 2020 10:59:18 +0100 Message-ID: <20200909095920.25495-4-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200909095920.25495-1-andrew.cooper3@citrix.com> References: <20200909095920.25495-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Split into two functions. Passing a load of zeros in results in somewhat poor register scheduling in __context_switch(). Update the prefetching comment to note that the main point is the TLB fill. Reorder the writes in svm_load_segs() to access the VMCB fields in ascending order, which gets better next-line prefetch behaviour out of hardware. Update the prefetch instruction to match. The net delta is: add/remove: 1/0 grow/shrink: 0/2 up/down: 38/-39 (-1) Function old new delta svm_load_segs_prefetch - 38 +38 __context_switch 967 951 -16 svm_load_segs 291 268 -23 Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monné CC: Wei Liu --- xen/arch/x86/domain.c | 2 +- xen/arch/x86/hvm/svm/svm.c | 43 ++++++++++++++++++++------------------- xen/include/asm-x86/hvm/svm/svm.h | 5 +++-- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 2271bee36a..0b0e3f8294 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1928,7 +1928,7 @@ static void __context_switch(void) /* Prefetch the VMCB if we expect to use it later in the context switch */ if ( cpu_has_svm && is_pv_domain(nd) && !is_pv_32bit_domain(nd) && !is_idle_domain(nd) ) - svm_load_segs(0, 0, 0, 0, 0); + svm_load_segs_prefetch(); #endif if ( need_full_gdt(nd) && !per_cpu(full_gdt_loaded, cpu) ) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 23b2a2aa17..9a2aca7770 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1520,6 +1520,19 @@ static void svm_init_erratum_383(const struct cpuinfo_x86 *c) } #ifdef CONFIG_PV +void svm_load_segs_prefetch(void) +{ + struct vmcb_struct *vmcb = this_cpu(host_vmcb_va); + + if ( vmcb ) + /* + * The main reason for this prefetch is for the TLB fill. Use the + * opporunity to fetch the lowest address used, to get the best + * behaviour out of hardwares next-line prefetcher. + */ + prefetchw(&vmcb->fs); +} + bool svm_load_segs(unsigned int ldt_ents, unsigned long ldt_base, unsigned long fs_base, unsigned long gs_base, unsigned long gs_shadow) @@ -1530,17 +1543,15 @@ bool svm_load_segs(unsigned int ldt_ents, unsigned long ldt_base, if ( unlikely(!vmcb) ) return false; - if ( !ldt_base ) - { - /* - * The actual structure field used here was arbitrarily chosen. - * Empirically it doesn't seem to matter much which element is used, - * and a clear explanation of the otherwise poor performance has not - * been found/provided so far. - */ - prefetchw(&vmcb->ldtr); - return true; - } + vmcb->fs.sel = 0; + vmcb->fs.attr = 0; + vmcb->fs.limit = 0; + vmcb->fs.base = fs_base; + + vmcb->gs.sel = 0; + vmcb->gs.attr = 0; + vmcb->gs.limit = 0; + vmcb->gs.base = gs_base; if ( likely(!ldt_ents) ) memset(&vmcb->ldtr, 0, sizeof(vmcb->ldtr)); @@ -1558,16 +1569,6 @@ bool svm_load_segs(unsigned int ldt_ents, unsigned long ldt_base, vmcb->ldtr.base = ldt_base; } - vmcb->fs.sel = 0; - vmcb->fs.attr = 0; - vmcb->fs.limit = 0; - vmcb->fs.base = fs_base; - - vmcb->gs.sel = 0; - vmcb->gs.attr = 0; - vmcb->gs.limit = 0; - vmcb->gs.base = gs_base; - vmcb->kerngsbase = gs_shadow; svm_vmload_pa(per_cpu(host_vmcb, cpu)); diff --git a/xen/include/asm-x86/hvm/svm/svm.h b/xen/include/asm-x86/hvm/svm/svm.h index 2310878e41..faeca40174 100644 --- a/xen/include/asm-x86/hvm/svm/svm.h +++ b/xen/include/asm-x86/hvm/svm/svm.h @@ -50,12 +50,13 @@ void __update_guest_eip(struct cpu_user_regs *regs, unsigned int inst_len); void svm_update_guest_cr(struct vcpu *, unsigned int cr, unsigned int flags); /* - * PV context switch helper. Calls with zero ldt_base request a prefetch of - * the VMCB area to be loaded from, instead of an actual load of state. + * PV context switch helpers. Prefetching the VMCB area itself has been shown + * to be useful for performance. * * Must only be used for NUL FS/GS, as the segment attributes/limits are not * read from the GDT/LDT. */ +void svm_load_segs_prefetch(void); bool svm_load_segs(unsigned int ldt_ents, unsigned long ldt_base, unsigned long fs_base, unsigned long gs_base, unsigned long gs_shadow); From patchwork Wed Sep 9 09:59:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11765283 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 B774F746 for ; Wed, 9 Sep 2020 10:01:31 +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 8350521973 for ; Wed, 9 Sep 2020 10:01:31 +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="GOICWHMC" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8350521973 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass 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.92) (envelope-from ) id 1kFwtU-00005E-Ro; Wed, 09 Sep 2020 10:00:00 +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.92) (envelope-from ) id 1kFwtT-0008SC-RP for xen-devel@lists.xenproject.org; Wed, 09 Sep 2020 09:59:59 +0000 X-Inumbo-ID: d67111ab-c8d0-43d3-a25c-f77c3a1c1bec Received: from esa4.hc3370-68.iphmx.com (unknown [216.71.155.144]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id d67111ab-c8d0-43d3-a25c-f77c3a1c1bec; Wed, 09 Sep 2020 09:59:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1599645591; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OwyxB5tgMIlpdQSglN/DeSMcT7TCEejwNAp6gxAeraY=; b=GOICWHMCUv4itdUtuvbkJMsaE4mN+kCxiPt7qF7oNekKq4LrA6HlrMVd WUsN/eZoJunrYelaEy/qwMxC8KkbLc6iNkUo4oF487IHbuIyBefOVPtfF LXmzXYF28PYMgnQvJDcZpF/p2x6OK6OMEOl/ENNjBNGivX+9LlDZpRT+d Y=; Authentication-Results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: Qins8ku/JDWcnxkbNzlMzFuDloJSCgl6Fw857a+WsrFgqoa38vu6EfajGklltSdgCmPGBvPmjX k7z/fkoAEslRw3i+l6icAo0+UmC4OAkbtXujNH3c43N4oSvxr4Qm/Du2dQMDdvoK1Y7IfhYSOn JF3fyQqFf7wwbcDEpW4dLzvRlaCq732xmzCepEp0AANPvYZxAZaxeH5zg9+fHakJRapFf5LYVt 21IxjK5aEH3pEhfVEW/7KYZdl97htEXRgGVpvEmU5Ql1NVSUJ7J7bOl2PR0MfgaeEw361R3qS+ ToM= X-SBRS: 2.7 X-MesageID: 27243911 X-Ironport-Server: esa4.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.76,409,1592884800"; d="scan'208";a="27243911" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Wei Liu Subject: [PATCH 4/5] x86/pv: Optimise to the segment context switching paths Date: Wed, 9 Sep 2020 10:59:19 +0100 Message-ID: <20200909095920.25495-5-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200909095920.25495-1-andrew.cooper3@citrix.com> References: <20200909095920.25495-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Save the segment selectors with explicit asm, rather than with read_sreg(). This permits the use of MOV's m16 encoding, which avoids indirecting the selector value through a register. For {save,load}_segments(), opencode the fs/gs helpers, as the optimiser is unable to rearrange the logic down to a single X86_CR4_FSGSBASE check. This removes several jumps and creates bigger basic blocks. In load_segments(), optimise GS base handling substantially. The call to svm_load_segs() already needs gsb/gss the correct way around, so hoist the logic for the later path to use it as well. Swapping the inputs in GPRs is far more efficient than using SWAPGS. Previously, there was optionally one SWAPGS from the user/kernel mode check, two SWAPGS's in write_gs_shadow() and two WRGSBASE's. Updates to GS (4 or 5 here) in quick succession stall all contemporary pipelines repeatedly. (Intel Core/Xeon pipelines have segment register renaming[1], so can continue to speculatively execute with one GS update in flight. Other pipelines cannot have two updates in flight concurrently, and must stall dispatch of the second until the first has retired.) Rewrite the logic to have exactly two WRGSBASEs and one SWAPGS, which removes two stalles all contemporary processors. Although modest, the resulting delta is: add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-106 (-106) Function old new delta paravirt_ctxt_switch_from 235 198 -37 context_switch 3582 3513 -69 in a common path. [1] https://software.intel.com/security-software-guidance/insights/deep-dive-intel-analysis-speculative-behavior-swapgs-and-segment-registers Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monné CC: Wei Liu --- xen/arch/x86/domain.c | 70 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 0b0e3f8294..ab71b9f79c 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1537,6 +1537,7 @@ arch_do_vcpu_op( static void load_segments(struct vcpu *n) { struct cpu_user_regs *uregs = &n->arch.user_regs; + unsigned long gsb = 0, gss = 0; bool compat = is_pv_32bit_vcpu(n); bool all_segs_okay = true, fs_gs_done = false; @@ -1556,18 +1557,24 @@ static void load_segments(struct vcpu *n) : [ok] "+r" (all_segs_okay) \ : [_val] "rm" (val) ) -#ifdef CONFIG_HVM - if ( cpu_has_svm && !compat && (uregs->fs | uregs->gs) <= 3 ) + if ( !compat ) { - unsigned long gsb = n->arch.flags & TF_kernel_mode - ? n->arch.pv.gs_base_kernel : n->arch.pv.gs_base_user; - unsigned long gss = n->arch.flags & TF_kernel_mode - ? n->arch.pv.gs_base_user : n->arch.pv.gs_base_kernel; + gsb = n->arch.pv.gs_base_kernel; + gss = n->arch.pv.gs_base_user; + + /* + * Figure out which way around gsb/gss want to be. gsb needs to be + * the active context, and gss needs to be the inactive context. + */ + if ( !(n->arch.flags & TF_kernel_mode) ) + SWAP(gsb, gss); - fs_gs_done = svm_load_segs(n->arch.pv.ldt_ents, LDT_VIRT_START(n), - n->arch.pv.fs_base, gsb, gss); + if ( IS_ENABLED(CONFIG_HVM) && cpu_has_svm && + (uregs->fs | uregs->gs) <= 3 ) + fs_gs_done = svm_load_segs(n->arch.pv.ldt_ents, LDT_VIRT_START(n), + n->arch.pv.fs_base, gsb, gss); } -#endif + if ( !fs_gs_done ) { load_LDT(n); @@ -1581,13 +1588,19 @@ static void load_segments(struct vcpu *n) if ( !fs_gs_done && !compat ) { - write_fs_base(n->arch.pv.fs_base); - write_gs_shadow(n->arch.pv.gs_base_kernel); - write_gs_base(n->arch.pv.gs_base_user); - - /* If in kernel mode then switch the GS bases around. */ - if ( (n->arch.flags & TF_kernel_mode) ) + if ( read_cr4() & X86_CR4_FSGSBASE ) + { + __wrgsbase(gss); + __wrfsbase(n->arch.pv.fs_base); asm volatile ( "swapgs" ); + __wrgsbase(gsb); + } + else + { + wrmsrl(MSR_FS_BASE, n->arch.pv.fs_base); + wrmsrl(MSR_GS_BASE, gsb); + wrmsrl(MSR_SHADOW_GS_BASE, gss); + } } if ( unlikely(!all_segs_okay) ) @@ -1703,16 +1716,31 @@ static void save_segments(struct vcpu *v) { struct cpu_user_regs *regs = &v->arch.user_regs; - regs->ds = read_sreg(ds); - regs->es = read_sreg(es); - regs->fs = read_sreg(fs); - regs->gs = read_sreg(gs); + asm volatile ( "mov %%ds, %[ds];\n\t" + "mov %%es, %[es];\n\t" + "mov %%fs, %[fs];\n\t" + "mov %%gs, %[gs];\n\t" + : [ds] "=m" (regs->ds), + [es] "=m" (regs->es), + [fs] "=m" (regs->fs), + [gs] "=m" (regs->gs) ); if ( !is_pv_32bit_vcpu(v) ) { - unsigned long gs_base = read_gs_base(); + unsigned long fs_base, gs_base; + + if ( read_cr4() & X86_CR4_FSGSBASE ) + { + fs_base = __rdfsbase(); + gs_base = __rdgsbase(); + } + else + { + rdmsrl(MSR_FS_BASE, fs_base); + rdmsrl(MSR_GS_BASE, gs_base); + } - v->arch.pv.fs_base = read_fs_base(); + v->arch.pv.fs_base = fs_base; if ( v->arch.flags & TF_kernel_mode ) v->arch.pv.gs_base_kernel = gs_base; else From patchwork Wed Sep 9 09:59:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11765277 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 1565292C for ; Wed, 9 Sep 2020 10:00:55 +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 D5E3121973 for ; Wed, 9 Sep 2020 10:00:54 +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="OEQTHF73" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D5E3121973 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass 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.92) (envelope-from ) id 1kFwtZ-0000dA-8m; Wed, 09 Sep 2020 10:00:05 +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.92) (envelope-from ) id 1kFwtY-0008SC-Rf for xen-devel@lists.xenproject.org; Wed, 09 Sep 2020 10:00:04 +0000 X-Inumbo-ID: 149b5651-32bd-4ba6-bbe8-03755a7a14bf Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 149b5651-32bd-4ba6-bbe8-03755a7a14bf; Wed, 09 Sep 2020 09:59:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1599645595; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lCMV0PvdXBd3HTuG95XLebEgJ53XkP2CFAQSYnTyhfA=; b=OEQTHF73pd+nx5JS+RSP4xmt9Ri4SIPXedxgR/pEYTxbwI0TDAW9LrGZ hQymwqUjzx4cU7/cbmWXNOKTb6V8o1CUGRLj2+nXCuuFyGvrSLniJqpi0 vHpQNmDuWf5AFS5m2xK3jCoWh6zxdWFvv37YjMXgNgRBd9KJFMQRmvKNe s=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: 7c1BjMqo8NZ9qb7F9SfIcsEkSSXoK1Ed+KN2abVpCNLamm/kzz8iagBzbJ4M72WnZS4EYHdyic nOQK43ZYOYmSzGxG2rWTYP/OgnMZIRmHMJhLs3W/FcjKMQYh9kBDXbyxqdR/n6cVlJBOQDqixk A/xeTrAxn6hZmaQKtxLt5Lxq36AjNEdqV7fNICPrlNNcc1to1rTFXZeKB/s42qnIB+fLexW0+3 aaVNQ1+cJVa9Av7vMs2f1oeHNbsyHkTLx5eZMFjjzvzUZBoPyh261R7eOeqgfETj4LFaAAovNt O+s= X-SBRS: 2.7 X-MesageID: 26611492 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.76,409,1592884800"; d="scan'208";a="26611492" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Wei Liu Subject: [PATCH 5/5] x86/pv: Simplify emulation for the 64bit base MSRs Date: Wed, 9 Sep 2020 10:59:20 +0100 Message-ID: <20200909095920.25495-6-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200909095920.25495-1-andrew.cooper3@citrix.com> References: <20200909095920.25495-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" is_pv_32bit_domain() is an expensive predicate, but isn't used for speculative safety in this case. Swap to checking the Long Mode bit in the CPUID policy, which is the architecturally correct behaviour. is_canonical_address() isn't a trivial predicate, but it will become more complicated when 5-level support is added. Rearrange write_msr() to collapse the common checks. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monné CC: Wei Liu For reference, the diff is: add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-152 (-152) Function old new delta read_msr 1075 1030 -45 write_msr 1537 1430 -107 but this isn't the point of the change. --- xen/arch/x86/pv/emul-priv-op.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index 9dd1d59423..0fd95fe9fa 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -848,6 +848,7 @@ static int read_msr(unsigned int reg, uint64_t *val, { struct vcpu *curr = current; const struct domain *currd = curr->domain; + const struct cpuid_policy *cp = currd->arch.cpuid; bool vpmu_msr = false; int ret; @@ -869,19 +870,19 @@ static int read_msr(unsigned int reg, uint64_t *val, return X86EMUL_OKAY; case MSR_FS_BASE: - if ( is_pv_32bit_domain(currd) ) + if ( !cp->extd.lm ) break; *val = read_fs_base(); return X86EMUL_OKAY; case MSR_GS_BASE: - if ( is_pv_32bit_domain(currd) ) + if ( !cp->extd.lm ) break; *val = read_gs_base(); return X86EMUL_OKAY; case MSR_SHADOW_GS_BASE: - if ( is_pv_32bit_domain(currd) ) + if ( !cp->extd.lm ) break; *val = curr->arch.pv.gs_base_user; return X86EMUL_OKAY; @@ -975,6 +976,7 @@ static int write_msr(unsigned int reg, uint64_t val, { struct vcpu *curr = current; const struct domain *currd = curr->domain; + const struct cpuid_policy *cp = currd->arch.cpuid; bool vpmu_msr = false; int ret; @@ -991,22 +993,22 @@ static int write_msr(unsigned int reg, uint64_t val, uint64_t temp; case MSR_FS_BASE: - if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) ) - break; - write_fs_base(val); - return X86EMUL_OKAY; - case MSR_GS_BASE: - if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) ) - break; - write_gs_base(val); - return X86EMUL_OKAY; - case MSR_SHADOW_GS_BASE: - if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) ) + if ( !cp->extd.lm || !is_canonical_address(val) ) break; - write_gs_shadow(val); - curr->arch.pv.gs_base_user = val; + + if ( reg == MSR_FS_BASE ) + write_fs_base(val); + else if ( reg == MSR_GS_BASE ) + write_gs_base(val); + else if ( reg == MSR_SHADOW_GS_BASE ) + { + write_gs_shadow(val); + curr->arch.pv.gs_base_user = val; + } + else + ASSERT_UNREACHABLE(); return X86EMUL_OKAY; case MSR_EFER: