From patchwork Thu Jan 2 08:45:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924338 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 142C8E77198 for ; Thu, 2 Jan 2025 08:46:11 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863729.1275089 (Exim 4.92) (envelope-from ) id 1tTGpu-0004rf-1C; Thu, 02 Jan 2025 08:45:46 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863729.1275089; Thu, 02 Jan 2025 08:45:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGpt-0004rY-TG; Thu, 02 Jan 2025 08:45:45 +0000 Received: by outflank-mailman (input) for mailman id 863729; Thu, 02 Jan 2025 08:45:44 +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 1tTGps-0004rF-0c for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:44 +0000 Received: from mail180-50.suw31.mandrillapp.com (mail180-50.suw31.mandrillapp.com [198.2.180.50]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f1f4674c-c8e5-11ef-a0db-8be0dac302b0; Thu, 02 Jan 2025 09:45:41 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-50.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fC5pWxzCf9LdN for ; Thu, 2 Jan 2025 08:45:39 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id df1be6e558d14edfa793741efcf07dff; Thu, 02 Jan 2025 08:45:39 +0000 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: f1f4674c-c8e5-11ef-a0db-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807539; x=1736068039; bh=BJl20UXfBA4BW0v81Q6NN4eicGukuW4vkuA5YVw5iK4=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=R2HyN6daFUx7f/DGci4uyqP1DGfmGBFXYvMbr7UXaGvdwtiwsTbHFHiZsr0+GOXuF A3D6aWyivUX/ukCkeRQ0FDzYPC4dgm7HP7TDgC3BLj0U1RU6tSMnItZV0xaOmrZu/Z YWcYyW8EGIDmVz3kbo7y8YsEzvDH+kZzUmT8azr+mtYNcLOLSLbO/9lZ9ELTmiXNtn tg5q8HyAr9KvN3rApou2nfV9Ao0jijvI27vuqqX0wv9MS6bAItYjpnBvPyLzZTEP4M BSXHZq5VDWkkO3dinfIfbMwjqeFvGcwKJ5q6u2r+/pZ2PjfgPB903j5GRCzh06iUQF kWIlfcmPg7IcQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807539; x=1736068039; i=ngoc-tu.dinh@vates.tech; bh=BJl20UXfBA4BW0v81Q6NN4eicGukuW4vkuA5YVw5iK4=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=hEV/1FEFqKFnyK7Vu6MLCMxGqVFzDgIr9pq9Urh6J5V1TmqGYD5eipLawoj0SOstN zMso3m0sQ6O+yWz697lo+CiTrHrXGmUxXGdkrvop3jB/2BIgwrXEvjSl+DqOVBbYHI k7uWaUDxb9J1WZpn1s38hL0TsYwIYONUBW21dhfIE+cu+Z/4oD3IelqwCgbz23JMkw US36Xt4nip40aaUwDtp4VTmHVkPRbcpuxVAbYR4iUyukz1SbERhDqJQ0qqy+SMyjf8 xQsQYvnQ2x72D3Pim1X+EzwWIFX2n0MkPLEhH1LcK2ABFuMeTKBJJuCkuaW7MjF3Q5 zu5h9TexRgPYA== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_01/10=5D_x86=3A_Add_architectural_LBR_def?= =?utf-8?q?initions?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807538677 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-2-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2Edf1be6e558d14edfa793741efcf07dff?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:39 +0000 MIME-Version: 1.0 Signed-off-by: Tu Dinh --- xen/arch/x86/include/asm/msr-index.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/xen/arch/x86/include/asm/msr-index.h b/xen/arch/x86/include/asm/msr-index.h index 9cdb5b2625..97df740b04 100644 --- a/xen/arch/x86/include/asm/msr-index.h +++ b/xen/arch/x86/include/asm/msr-index.h @@ -112,6 +112,8 @@ #define MCU_OPT_CTRL_GDS_MIT_DIS (_AC(1, ULL) << 4) #define MCU_OPT_CTRL_GDS_MIT_LOCK (_AC(1, ULL) << 5) +#define MSR_LER_INFO 0x000001e0 + #define MSR_RTIT_OUTPUT_BASE 0x00000560 #define MSR_RTIT_OUTPUT_MASK 0x00000561 #define MSR_RTIT_CTL 0x00000570 @@ -193,6 +195,16 @@ #define MSR_UARCH_MISC_CTRL 0x00001b01 #define UARCH_CTRL_DOITM (_AC(1, ULL) << 0) +/* Architectural LBR state MSRs */ +#define MSR_LBR_INFO(n) (0x00001200 + (n)) +#define MSR_LBR_CTL 0x000014ce +#define LBR_CTL_VALID _AC(0x7f000f, ULL) +#define MSR_LBR_DEPTH 0x000014cf +#define MSR_LBR_FROM_IP(n) (0x00001500 + (n)) +#define MSR_LBR_TO_IP(n) (0x00001600 + (n)) +/* Must be updated along with XSTATE LBR state size */ +#define NUM_MSR_ARCH_LBR_FROM_TO 32 + #define MSR_EFER _AC(0xc0000080, U) /* Extended Feature Enable Register */ #define EFER_SCE (_AC(1, ULL) << 0) /* SYSCALL Enable */ #define EFER_LME (_AC(1, ULL) << 8) /* Long Mode Enable */ From patchwork Thu Jan 2 08:45:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924346 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 BD332E77198 for ; Thu, 2 Jan 2025 08:46:16 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863734.1275130 (Exim 4.92) (envelope-from ) id 1tTGpw-0005eB-Nb; Thu, 02 Jan 2025 08:45:48 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863734.1275130; Thu, 02 Jan 2025 08:45:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGpw-0005c9-Fr; Thu, 02 Jan 2025 08:45:48 +0000 Received: by outflank-mailman (input) for mailman id 863734; Thu, 02 Jan 2025 08:45:47 +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 1tTGpu-0004rS-TN for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:46 +0000 Received: from mail180-50.suw31.mandrillapp.com (mail180-50.suw31.mandrillapp.com [198.2.180.50]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f31ee457-c8e5-11ef-99a4-01e77a169b0f; Thu, 02 Jan 2025 09:45:43 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-50.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fD0pbvzCf9NcD for ; Thu, 2 Jan 2025 08:45:40 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id 943f3a70b64046b588551a553066481c; Thu, 02 Jan 2025 08:45:40 +0000 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: f31ee457-c8e5-11ef-99a4-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807540; x=1736068040; bh=dELO6CDglzR9hmFa5QjoLHtaiu13YDfJwfi0OKMMoQA=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=oEwTlY8uDgrvRWkS0Z9vdf4fv80hy5wYUCl1bQAtxZCXy+a1QHf/+Vw7ewex8sn5K eUK4EyMLCAQH1cjCUXtH0wJGSGshlpGLnLY57S9VlGn6b981Hvj+1ygavAvbAs8tKm TZgAXisAojhQk4K12Lnumis/aZ1DVZTnfa/5ZH7H7VfqLD+hTQMZI6dFIVDAnQwgwv eQ9CokXO2brU/+Z9Nf5T6X/SBqElPw+EyFw7MAlCbiOeiI5+u67nlQU2lxXg5GD+/u yiI0k2qrpnu44FvhZUsmGJNv/6T/sNQRWSBJ8J6oNrliD6oqnrhFzxtHhzan62Ilys zmaABvDOSWDVw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807540; x=1736068040; i=ngoc-tu.dinh@vates.tech; bh=dELO6CDglzR9hmFa5QjoLHtaiu13YDfJwfi0OKMMoQA=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=iGqymsuQXVhCzxCuEXFwK58EpGs985GZ3J9HGbTPgDBnKcVcrAO8BnTT+G50b4VpG sBlw1IVDxfuwXMLzfVGCyMPFqvBl5osJzNzX+cA0nS6xt4e2Q2lrJ6vT/GwQyhIyHC 62Iax0x43PeL/aG8sCh5EsSV2ygK5lCPMQx3N5j5wn+0qQu0xp6oPgnCtjiIFNitDV z3YQEsZQl0jKlLJdrL2AlvNwCOtk5RtQIixkoF828XmGwi1BCmAtNjPmzfvFs91CND vW3e1HKYEEHaJYvdGIH+XRXIeDCjnQTVtQLJAgzXjgaXqBXgDEccYclf9mSeqD8iHG kHJfqoEnTTFbw== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_02/10=5D_x86=3A_Define_arch_LBR_feature_b?= =?utf-8?q?its?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807539234 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-3-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2E943f3a70b64046b588551a553066481c?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:40 +0000 MIME-Version: 1.0 Add three featureset words corresponding to the 3 CPUID words in leaf 0x1c. Intel SDM states that CPUID may indicate a LBR depth of up to 64. However, since XSAVE LBR state only goes up to 32 LBRs, don't expose the other CPUID depth bits for now. Signed-off-by: Tu Dinh --- xen/arch/x86/include/asm/cpufeature.h | 5 ++ xen/include/public/arch-x86/cpufeatureset.h | 28 ++++++++++- xen/include/xen/lib/x86/cpu-policy.h | 51 ++++++++++++++++++++- xen/lib/x86/cpuid.c | 6 +++ 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/include/asm/cpufeature.h b/xen/arch/x86/include/asm/cpufeature.h index 3a06b6f297..4323ffb8cb 100644 --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -219,6 +219,11 @@ static inline bool boot_cpu_has(unsigned int feat) #define cpu_has_rfds_no boot_cpu_has(X86_FEATURE_RFDS_NO) #define cpu_has_rfds_clear boot_cpu_has(X86_FEATURE_RFDS_CLEAR) +/* CPUID level 0x0000001c.eax */ + +#define current_cpu_has_lbr_lip cpu_has(¤t_cpu_data, \ + X86_FEATURE_LBR_LIP); + /* Synthesized. */ #define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON) #define cpu_has_cpuid_faulting boot_cpu_has(X86_FEATURE_CPUID_FAULTING) diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h index 8fa3fb711a..86d3e61438 100644 --- a/xen/include/public/arch-x86/cpufeatureset.h +++ b/xen/include/public/arch-x86/cpufeatureset.h @@ -284,7 +284,7 @@ XEN_CPUFEATURE(SERIALIZE, 9*32+14) /*A SERIALIZE insn */ XEN_CPUFEATURE(HYBRID, 9*32+15) /* Heterogeneous platform */ XEN_CPUFEATURE(TSXLDTRK, 9*32+16) /*a TSX load tracking suspend/resume insns */ XEN_CPUFEATURE(PCONFIG, 9*32+18) /* PCONFIG instruction */ -XEN_CPUFEATURE(ARCH_LBR, 9*32+19) /* Architectural Last Branch Record */ +XEN_CPUFEATURE(ARCH_LBR, 9*32+19) /*s Architectural Last Branch Record */ XEN_CPUFEATURE(CET_IBT, 9*32+20) /* CET - Indirect Branch Tracking */ XEN_CPUFEATURE(AMX_BF16, 9*32+22) /* AMX BFloat16 instruction */ XEN_CPUFEATURE(AVX512_FP16, 9*32+23) /*A AVX512 FP16 instructions */ @@ -379,6 +379,32 @@ XEN_CPUFEATURE(RFDS_CLEAR, 16*32+28) /*!A| Register File(s) cleared by V /* Intel-defined CPU features, MSR_ARCH_CAPS 0x10a.edx, word 17 */ +/* Intel-defined CPU features, CPUID level 0x0000001c.eax, word 18 */ +XEN_CPUFEATURE(LBR_DEPTH_8, 18*32+ 0) /*s Depth 8 */ +XEN_CPUFEATURE(LBR_DEPTH_16, 18*32+ 1) /*s Depth 16 */ +XEN_CPUFEATURE(LBR_DEPTH_24, 18*32+ 2) /*s Depth 24 */ +XEN_CPUFEATURE(LBR_DEPTH_32, 18*32+ 3) /*s Depth 32 */ +XEN_CPUFEATURE(LBR_DEPTH_40, 18*32+ 4) /* Depth 40 */ +XEN_CPUFEATURE(LBR_DEPTH_48, 18*32+ 5) /* Depth 48 */ +XEN_CPUFEATURE(LBR_DEPTH_56, 18*32+ 6) /* Depth 56 */ +XEN_CPUFEATURE(LBR_DEPTH_64, 18*32+ 7) /* Depth 64 */ +XEN_CPUFEATURE(LBR_DCST_RST, 18*32+30) /*s Deep C-state reset */ +XEN_CPUFEATURE(LBR_LIP, 18*32+31) /*! IP is linear IP */ + +/* Intel-defined CPU features, CPUID level 0x0000001c.ebx, word 19 */ +XEN_CPUFEATURE(LBR_CPL_FILTER, 19*32+ 0) /*s CPL filtering */ +XEN_CPUFEATURE(LBR_BR_FILTER, 19*32+ 1) /*s Branch filtering */ +XEN_CPUFEATURE(LBR_CALL_STACK, 19*32+ 2) /*s Call stack mode */ + +/* Intel-defined CPU features, CPUID level 0x0000001c.ecx, word 20 */ +XEN_CPUFEATURE(LBR_MISPRED, 20*32+ 0) /*s Mispredict mode */ +XEN_CPUFEATURE(LBR_TIMED, 20*32+ 1) /*s Timed mode */ +XEN_CPUFEATURE(LBR_BR_TYPE, 20*32+ 2) /*s Branch type */ +XEN_CPUFEATURE(LBR_EVENT_LOG_0, 20*32+16) /*s Event logging for counter 0 */ +XEN_CPUFEATURE(LBR_EVENT_LOG_1, 20*32+17) /*s Event logging for counter 1 */ +XEN_CPUFEATURE(LBR_EVENT_LOG_2, 20*32+18) /*s Event logging for counter 2 */ +XEN_CPUFEATURE(LBR_EVENT_LOG_3, 20*32+19) /*s Event logging for counter 3 */ + #endif /* XEN_CPUFEATURE */ /* Clean up from a default include. Close the enum (for C). */ diff --git a/xen/include/xen/lib/x86/cpu-policy.h b/xen/include/xen/lib/x86/cpu-policy.h index f43e1a3b21..f3b331f36c 100644 --- a/xen/include/xen/lib/x86/cpu-policy.h +++ b/xen/include/xen/lib/x86/cpu-policy.h @@ -22,6 +22,9 @@ #define FEATURESET_7d1 15 /* 0x00000007:1.edx */ #define FEATURESET_m10Al 16 /* 0x0000010a.eax */ #define FEATURESET_m10Ah 17 /* 0x0000010a.edx */ +#define FEATURESET_1Ca 18 /* 0x0000001c.eax */ +#define FEATURESET_1Cb 19 /* 0x0000001c.ebx */ +#define FEATURESET_1Cc 20 /* 0x0000001c.ecx */ struct cpuid_leaf { @@ -85,7 +88,7 @@ unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx); */ const char *x86_cpuid_vendor_to_str(unsigned int vendor); -#define CPUID_GUEST_NR_BASIC (0xdu + 1) +#define CPUID_GUEST_NR_BASIC (0x1cu + 1) #define CPUID_GUEST_NR_CACHE (5u + 1) #define CPUID_GUEST_NR_FEAT (2u + 1) #define CPUID_GUEST_NR_TOPO (1u + 1) @@ -158,6 +161,52 @@ struct cpu_policy uint64_t :64, :64; /* Leaf 0xb - Topology. */ uint64_t :64, :64; /* Leaf 0xc - rsvd */ uint64_t :64, :64; /* Leaf 0xd - XSTATE. */ + + uint64_t :64, :64; /* Leaf 0xe - rsvd */ + uint64_t :64, :64; /* Leaf 0xf - rsvd */ + uint64_t :64, :64; /* Leaf 0x10 - rsvd */ + uint64_t :64, :64; /* Leaf 0x11 - rsvd */ + uint64_t :64, :64; /* Leaf 0x12 - rsvd */ + uint64_t :64, :64; /* Leaf 0x13 - rsvd */ + uint64_t :64, :64; /* Leaf 0x14 - rsvd */ + uint64_t :64, :64; /* Leaf 0x15 - rsvd */ + uint64_t :64, :64; /* Leaf 0x16 - rsvd */ + uint64_t :64, :64; /* Leaf 0x17 - rsvd */ + uint64_t :64, :64; /* Leaf 0x18 - rsvd */ + uint64_t :64, :64; /* Leaf 0x19 - rsvd */ + uint64_t :64, :64; /* Leaf 0x1a - rsvd */ + uint64_t :64, :64; /* Leaf 0x1b - rsvd */ + + union { + uint32_t _1Ca; + struct { + uint32_t supported_depths:8; + uint32_t :22; + uint32_t deep_cstate_reset:1; + uint32_t ip_contains_lip:1; + } lbr_1Ca; + }; + union { + uint32_t _1Cb; + struct { + uint32_t cpl_filter:1; + uint32_t br_filter:1; + uint32_t call_stack:1; + } lbr_1Cb; + }; + union { + uint32_t _1Cc; + struct { + uint32_t mispred:1; + uint32_t timed:1; + uint32_t br_type:1; + uint32_t :13; + uint32_t event_log_0:1; + uint32_t event_log_1:1; + uint32_t event_log_2:1; + uint32_t event_log_3:1; + } lbr_1Cc; + }; }; } basic; diff --git a/xen/lib/x86/cpuid.c b/xen/lib/x86/cpuid.c index eb7698dc73..4d19349b17 100644 --- a/xen/lib/x86/cpuid.c +++ b/xen/lib/x86/cpuid.c @@ -81,6 +81,9 @@ void x86_cpu_policy_to_featureset( fs[FEATURESET_7d1] = p->feat._7d1; fs[FEATURESET_m10Al] = p->arch_caps.lo; fs[FEATURESET_m10Ah] = p->arch_caps.hi; + fs[FEATURESET_1Ca] = p->basic._1Ca; + fs[FEATURESET_1Cb] = p->basic._1Cb; + fs[FEATURESET_1Cc] = p->basic._1Cc; } void x86_cpu_featureset_to_policy( @@ -104,6 +107,9 @@ void x86_cpu_featureset_to_policy( p->feat._7d1 = fs[FEATURESET_7d1]; p->arch_caps.lo = fs[FEATURESET_m10Al]; p->arch_caps.hi = fs[FEATURESET_m10Ah]; + p->basic._1Ca = fs[FEATURESET_1Ca]; + p->basic._1Cb = fs[FEATURESET_1Cb]; + p->basic._1Cc = fs[FEATURESET_1Cc]; } void x86_cpu_policy_recalc_synth(struct cpu_policy *p) From patchwork Thu Jan 2 08:45:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924337 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 619F0E77188 for ; Thu, 2 Jan 2025 08:46:10 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863732.1275120 (Exim 4.92) (envelope-from ) id 1tTGpw-0005XR-3R; Thu, 02 Jan 2025 08:45:48 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863732.1275120; Thu, 02 Jan 2025 08:45:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGpv-0005WT-Sr; Thu, 02 Jan 2025 08:45:47 +0000 Received: by outflank-mailman (input) for mailman id 863732; Thu, 02 Jan 2025 08:45:46 +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 1tTGpu-0004rS-39 for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:46 +0000 Received: from mail180-50.suw31.mandrillapp.com (mail180-50.suw31.mandrillapp.com [198.2.180.50]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f31ba6ce-c8e5-11ef-99a4-01e77a169b0f; Thu, 02 Jan 2025 09:45:43 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-50.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fD21KZzCfD7Mc for ; Thu, 2 Jan 2025 08:45:40 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id 8f8814d4b30a41adb33ecc6a9e833b61; Thu, 02 Jan 2025 08:45:40 +0000 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: f31ba6ce-c8e5-11ef-99a4-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807540; x=1736068040; bh=pAHxWdtF5F+VmVe6AG5QRFQ7htoBqzkaXnBayvRsH38=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=sCGaJGcFBppRgs03cEtlCOCLOHlzZKqwDj4/K/CHee3G4z7HS3zIxXzCNS6U4wvmL fH2QJw5ie5V0aiFoRNWQ0NgWWg/CqYT/kdcoKtM24AUHkXR/hSq6AHTXBDBMLD6P23 FdTgDZQce6mZybN3ZUWUqlgLxjiOMkyAtTi6D+YU8pXo/F3AxLUBbXBPnVRdCEBfDK 5QQJJqHLCYUz1FRrqnEOgKEts5s/n94/cBn42guFOJ8Us6kRTiGiyLTUBO0udj2+AK pIhcMq3GeqyLKuFdD7cAmtBO/YeCx94iMO0wRekz4Qb1/4/oINWOieNoUfdhyU0bs5 e5ind8mh0o73g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807540; x=1736068040; i=ngoc-tu.dinh@vates.tech; bh=pAHxWdtF5F+VmVe6AG5QRFQ7htoBqzkaXnBayvRsH38=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=wKVy2yAvNOjQbLmYOqN5D9dTy5JW3Hcmw4706h6l5wzpo78PK4184mbr2qyVcNWr0 0DahWdqVMf+l8fHJtJ/+a8chQgLF+DksU0fbZBvMYnbobPd/flZMa6vS1dyLbXf8rU i68vgWz10wVPucpBPDbimnP68jzdimdurL8oeU7OmalPubBI7sviN2VIySQZZ6uZz1 ebU0Cci3u5Qp8p2hHs7Wy5eHBJZbkIJ60pUE5KuE7IdI3nEMYDzw9xWZKqwysNhlfC y72QZBp1h7qhFYxZX6nS5EuIfQl8Yc9RsziZRgRHbnYESgbB5ye58zARaQMA8ik2vY xvZuaZOpQPByg== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_03/10=5D_tools=3A_Add_arch_LBR_feature_bi?= =?utf-8?q?ts?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807539448 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-4-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2E8f8814d4b30a41adb33ecc6a9e833b61?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:40 +0000 MIME-Version: 1.0 Signed-off-by: Tu Dinh --- tools/libs/light/libxl_cpuid.c | 3 +++ tools/misc/xen-cpuid.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tools/libs/light/libxl_cpuid.c b/tools/libs/light/libxl_cpuid.c index 063fe86eb7..05be36f258 100644 --- a/tools/libs/light/libxl_cpuid.c +++ b/tools/libs/light/libxl_cpuid.c @@ -342,6 +342,9 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list *policy, const char* str) CPUID_ENTRY(0x00000007, 1, CPUID_REG_EDX), MSR_ENTRY(0x10a, CPUID_REG_EAX), MSR_ENTRY(0x10a, CPUID_REG_EDX), + CPUID_ENTRY(0x0000001C, NA, CPUID_REG_EAX), + CPUID_ENTRY(0x0000001C, NA, CPUID_REG_EBX), + CPUID_ENTRY(0x0000001C, NA, CPUID_REG_ECX), #undef MSR_ENTRY #undef CPUID_ENTRY }; diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c index 4c4593528d..4f0fb0a6ea 100644 --- a/tools/misc/xen-cpuid.c +++ b/tools/misc/xen-cpuid.c @@ -37,6 +37,9 @@ static const struct { { "CPUID 0x00000007:1.edx", "7d1" }, { "MSR_ARCH_CAPS.lo", "m10Al" }, { "MSR_ARCH_CAPS.hi", "m10Ah" }, + { "CPUID 0x0000001c.eax", "1Ca" }, + { "CPUID 0x0000001c.ebx", "1Cb" }, + { "CPUID 0x0000001c.ecx", "1Cc" }, }; #define COL_ALIGN "24" From patchwork Thu Jan 2 08:45:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924341 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 253C4E77199 for ; Thu, 2 Jan 2025 08:46:11 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863735.1275139 (Exim 4.92) (envelope-from ) id 1tTGpx-0005tN-DZ; Thu, 02 Jan 2025 08:45:49 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863735.1275139; Thu, 02 Jan 2025 08:45:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGpx-0005pv-5B; Thu, 02 Jan 2025 08:45:49 +0000 Received: by outflank-mailman (input) for mailman id 863735; Thu, 02 Jan 2025 08:45:48 +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 1tTGpv-0004rS-Th for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:47 +0000 Received: from mail180-50.suw31.mandrillapp.com (mail180-50.suw31.mandrillapp.com [198.2.180.50]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f48e5d1a-c8e5-11ef-99a4-01e77a169b0f; Thu, 02 Jan 2025 09:45:44 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-50.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fD3qg1zCfD7NJ for ; Thu, 2 Jan 2025 08:45:40 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id 82f3a02c5edd4500b772e324054fe213; Thu, 02 Jan 2025 08:45:40 +0000 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: f48e5d1a-c8e5-11ef-99a4-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807540; x=1736068040; bh=lteVOQO/826dQJiMQ3UsqhNPnk1VKMnXNeukA1WaOSo=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=A6bso6XOHwrewVbQ+GskSObYNPGIX1Z4vhv/ffgdUazMyxQSZsEEaPk0tuSGHrq/F KYgQCzfwX0m5g/4AVJehlT1kJzGpXcUgETl0kHVv8aK1NpKDtShWDszEtWijRe+zhV cxKDotiNCCNYhL3hCpGErxUnTkGhBQs05o0SmRlNIQpHr2AsrjP984+UZyIJoGBUpH OMlT1szBwBRh4qM/VTzbHtG0B/ZEMCNUHKfo5dwdDFMSrxvtDDlQKIE/JNI386Y/E1 KJj/SXclW1/ha0rF9iIiQ+2V4tHqTxkU2c2XAoFEVl+/bucBAnFeacesc+Bai+6asa W8WNAuglkrvOQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807540; x=1736068040; i=ngoc-tu.dinh@vates.tech; bh=lteVOQO/826dQJiMQ3UsqhNPnk1VKMnXNeukA1WaOSo=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=UfzJS6fJ8E+WavFGOSGkBzZTURV4Gl+aOiYx+VuffqxzhyZWj3xr5tQAgiogajDYK LuY4Us1eph/9dB0X8QxdP7KYNI+SqK5sXjzGPsH2XGjnN5j7cPb+fKjdFZhd9n0C8f ZW0MyY0IP82iB+Z6lgdGg5J73x1Q5+SYD0PhNpnFBNeR4nj0KI089j6o8nSidVLkqN WBJ+gyyL6n8i+mBxN1CRErFBE0wkFa/cpshmwfcEH7m8Ee0H/rFbKBeHcm8VrGk+WV 4TIzgUQcVJIEZiPNa6p19D9v2hNmiC4KzrFPa0xNfp+BCTO65QjEITQbBXmYsK4+JJ onHUjurDqe5Kw== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_04/10=5D_x86=3A_Calculate_arch_LBR_CPUID_?= =?utf-8?q?policies?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807539667 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-5-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2E82f3a02c5edd4500b772e324054fe213?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:40 +0000 MIME-Version: 1.0 Ensure that the arch LBR feature and its dependents are disabled if any prerequisites are not available. Signed-off-by: Tu Dinh --- xen/arch/x86/cpu-policy.c | 28 ++++++++++++++++++++++++++++ xen/arch/x86/cpu/common.c | 7 +++++++ 2 files changed, 35 insertions(+) diff --git a/xen/arch/x86/cpu-policy.c b/xen/arch/x86/cpu-policy.c index 78bc9872b0..b1398b2e3c 100644 --- a/xen/arch/x86/cpu-policy.c +++ b/xen/arch/x86/cpu-policy.c @@ -190,6 +190,16 @@ static void sanitise_featureset(uint32_t *fs) } } +static void recalculate_arch_lbr(struct cpu_policy *p) +{ + if ( p->basic.max_leaf < 0x1c || + !(cpu_policy_xstates(&host_cpu_policy) & X86_XSS_LBR) || + p->basic.lbr_1Ca.supported_depths == 0) + p->feat.arch_lbr = 0; + if ( !p->feat.arch_lbr ) + p->basic.raw[0x1c] = EMPTY_LEAF; +} + static void recalculate_xstate(struct cpu_policy *p) { uint64_t xstates = XSTATE_FP_SSE; @@ -219,6 +229,9 @@ static void recalculate_xstate(struct cpu_policy *p) if ( p->feat.amx_tile ) xstates |= X86_XCR0_TILE_CFG | X86_XCR0_TILE_DATA; + if ( p->feat.arch_lbr ) + xstates |= X86_XSS_LBR; + /* Subleaf 0 */ p->xstate.max_size = xstate_uncompressed_size(xstates & ~XSTATE_XSAVES_ONLY); @@ -271,6 +284,8 @@ static void recalculate_misc(struct cpu_policy *p) p->basic.raw[0xc] = EMPTY_LEAF; + zero_leaves(p->basic.raw, 0xe, 0x1b); + p->extd.e1d &= ~CPUID_COMMON_1D_FEATURES; /* Most of Power/RAS hidden from guests. */ @@ -630,6 +645,7 @@ static void __init calculate_pv_max_policy(void) sanitise_featureset(fs); x86_cpu_featureset_to_policy(fs, p); + recalculate_arch_lbr(p); recalculate_xstate(p); p->extd.raw[0xa] = EMPTY_LEAF; /* No SVM for PV guests. */ @@ -670,6 +686,7 @@ static void __init calculate_pv_def_policy(void) } x86_cpu_featureset_to_policy(fs, p); + recalculate_arch_lbr(p); recalculate_xstate(p); } @@ -755,6 +772,14 @@ static void __init calculate_hvm_max_policy(void) if ( !cpu_has_vmx_xsaves ) __clear_bit(X86_FEATURE_XSAVES, fs); + + /* + * VMX bitmap is needed for passing through LBR info MSRs. + * Require it for virtual arch LBR. + */ + if ( !cpu_has_vmx_guest_lbr_ctl || !cpu_has_vmx_msr_bitmap || + !cpu_has_vmx_xsaves ) + __clear_bit(X86_FEATURE_ARCH_LBR, fs); } /* @@ -787,6 +812,7 @@ static void __init calculate_hvm_max_policy(void) sanitise_featureset(fs); x86_cpu_featureset_to_policy(fs, p); + recalculate_arch_lbr(p); recalculate_xstate(p); /* It's always possible to emulate CPUID faulting for HVM guests */ @@ -839,6 +865,7 @@ static void __init calculate_hvm_def_policy(void) } x86_cpu_featureset_to_policy(fs, p); + recalculate_arch_lbr(p); recalculate_xstate(p); } @@ -971,6 +998,7 @@ void recalculate_cpuid_policy(struct domain *d) p->extd.maxlinaddr = p->extd.lm ? 48 : 32; + recalculate_arch_lbr(p); recalculate_xstate(p); recalculate_misc(p); diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 067d855bad..0056b55457 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -505,6 +505,13 @@ static void generic_identify(struct cpuinfo_x86 *c) &c->x86_capability[FEATURESET_Da1], &tmp, &tmp, &tmp); + if (c->cpuid_level >= 0x1c) + cpuid(0x1c, + &c->x86_capability[FEATURESET_1Ca], + &c->x86_capability[FEATURESET_1Cb], + &c->x86_capability[FEATURESET_1Cc], + &tmp); + if (test_bit(X86_FEATURE_ARCH_CAPS, c->x86_capability)) rdmsr(MSR_ARCH_CAPABILITIES, c->x86_capability[FEATURESET_m10Al], From patchwork Thu Jan 2 08:45:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924336 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 6FAFEE77194 for ; Thu, 2 Jan 2025 08:46:10 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863737.1275165 (Exim 4.92) (envelope-from ) id 1tTGpz-0006X4-5D; Thu, 02 Jan 2025 08:45:51 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863737.1275165; Thu, 02 Jan 2025 08:45:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGpy-0006W9-Sk; Thu, 02 Jan 2025 08:45:50 +0000 Received: by outflank-mailman (input) for mailman id 863737; Thu, 02 Jan 2025 08:45:50 +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 1tTGpx-0004rS-UK for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:49 +0000 Received: from mail180-50.suw31.mandrillapp.com (mail180-50.suw31.mandrillapp.com [198.2.180.50]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f5908fed-c8e5-11ef-99a4-01e77a169b0f; Thu, 02 Jan 2025 09:45:46 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-50.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fD5n5HzCf9M37 for ; Thu, 2 Jan 2025 08:45:40 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id 18bc4adf6c0c4943a835c5bc80ce84cb; Thu, 02 Jan 2025 08:45:40 +0000 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: f5908fed-c8e5-11ef-99a4-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807540; x=1736068040; bh=mzhXuh0ndyjVjpzrrKA3CLzzrom7CZG1ilSX478/eBg=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=oDCE65nLyW+4kZGft2uh059FpwIwEueCaNkKPOqR4qKgZ9asIUVyLSu9WliVX/lFt HjW7vUdQvjKPQ+Z5vsIT+NDkW3B5f4NuFGyaZn7ebPHat+5nJY9k3j4OcCDBeT8Hf5 SuzhFE6e0ZBcTcjCt6nvUoSIRhlKXHU/gBLgd69GiYaQTg7DdMk0rjrtn9mhNww5J/ i8T6DkNcuzuie6/zz8hj0LRvcf+SurMdLTj7slyVyXsZeGFyRJnYDJi4Svu0qy8ekQ HCztn4N6idpPsqlKxpb34fOVZAZN9aWPKRf1nbBNNt4IPi8joto40BELFQ3eNQjxw+ HrWVGMELfkFzQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807540; x=1736068040; i=ngoc-tu.dinh@vates.tech; bh=mzhXuh0ndyjVjpzrrKA3CLzzrom7CZG1ilSX478/eBg=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=O+r6NcYohpfHx1h+H0YjkdzcWSY9atwvPggh+iuatsHlmcnivPBokfNhI88D02J7C avhzxVYyQM7mFbxrG1Tax4w2HEdM63sEWtui4MOwGev9O2POXZFC0gzfG1vevkNgI4 D5odIRyCKRLqNb8ZHiCkzr6UFykXnhdo7mlog4CJgBXGBB1GbaCWuHCGEGw/Z9FlwC o8+gAo9DIHkq1QDWKRwJH1tbkKTwRY9Ef0IRs8fbg8RPuA78jTIRH83e6dlm9W4Sz4 ZVgScCgL+8YNyam/yi7Bslp9G4jjgjym9OWSpUWh/8Cdr0pq9Wsf+hgnMzt5Jcr947 91P/BmnQ1CICA== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_05/10=5D_x86=3A_Keep_a_copy_of_XSAVE_area?= =?utf-8?q?_size?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807539875 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-6-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2E18bc4adf6c0c4943a835c5bc80ce84cb?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:40 +0000 MIME-Version: 1.0 Signed-off-by: Tu Dinh --- xen/arch/x86/include/asm/domain.h | 1 + xen/arch/x86/xstate.c | 1 + 2 files changed, 2 insertions(+) diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h index b79d6badd7..d3f2695c20 100644 --- a/xen/arch/x86/include/asm/domain.h +++ b/xen/arch/x86/include/asm/domain.h @@ -638,6 +638,7 @@ struct arch_vcpu * #NM handler, we XRSTOR the states we XSAVE-ed; */ struct xsave_struct *xsave_area; + unsigned int xsave_area_size; uint64_t xcr0; /* Accumulated eXtended features mask for using XSAVE/XRESTORE by Xen * itself, as we can never know whether guest OS depends on content diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index af9e345a7a..baae8e1a13 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -550,6 +550,7 @@ int xstate_alloc_save_area(struct vcpu *v) save_area->fpu_sse.mxcsr = MXCSR_DEFAULT; v->arch.xsave_area = save_area; + v->arch.xsave_area_size = size; v->arch.xcr0 = 0; v->arch.xcr0_accum = 0; From patchwork Thu Jan 2 08:45:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924340 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 7CAC9C3DA4A for ; Thu, 2 Jan 2025 08:46:10 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863738.1275178 (Exim 4.92) (envelope-from ) id 1tTGq0-0006yX-J9; Thu, 02 Jan 2025 08:45:52 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863738.1275178; Thu, 02 Jan 2025 08:45:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGq0-0006yI-Dq; Thu, 02 Jan 2025 08:45:52 +0000 Received: by outflank-mailman (input) for mailman id 863738; Thu, 02 Jan 2025 08:45:51 +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 1tTGpy-0004rS-Uf for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:50 +0000 Received: from mail180-50.suw31.mandrillapp.com (mail180-50.suw31.mandrillapp.com [198.2.180.50]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f6180e64-c8e5-11ef-99a4-01e77a169b0f; Thu, 02 Jan 2025 09:45:47 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-50.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fF0HDGzCf9PP7 for ; Thu, 2 Jan 2025 08:45:41 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id 90040212465a4a738ee55cacd36524b5; Thu, 02 Jan 2025 08:45:41 +0000 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: f6180e64-c8e5-11ef-99a4-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807541; x=1736068041; bh=TpWqF+7FFQ/hg2SGplPXaNKTXRGvQnA48A/EDvktoFg=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=wZggbVYg/0D2l7QYN02MOgR+27vLGOqgHk9ISz2Iroxf9JE31GrQS6PkvY8ZsFMNB xicMvz7ofdHZR/srTQRrHMmMp4xgEJOpLbyuNlHCoT3tHBDNDaIFeei6IzcOLjaQJ2 hjq08RoeD0Rl1D/p3XyLhXeVXch6pquZD7nqDAhUPEpJf37fvPDlQcigSffPqAFIDV GymYotau6IfIdlh2W3xg6RAF4Mc1pIDkf1FVtWmsU1acoMQQd8pAcjOs3dCLwwYbi9 dR2ef/aAbMt3UOstha+F5ezga3Dr+/GDNExeQeUwX8NiSi1isGwRLwSCsMkTVgj+Y5 EIopVjjhQsidw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807541; x=1736068041; i=ngoc-tu.dinh@vates.tech; bh=TpWqF+7FFQ/hg2SGplPXaNKTXRGvQnA48A/EDvktoFg=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=Hn3NVoe1PhkrToobEUFCMSDliQow30HntEDnILD8wUomW/r1LuP7eFIHor5R/Tqok 8pzaAqs/uICRumoYKyo7dutEciIN/RkC1xPPjhPppKiDcsDZGkHOAoYTeCPwIzuxHU 5BF1KDf35bywQWK7oQY4t9lFuoZOSF0tM4L8k45HIHq7MfNrmUmf+eWSCONPXi11YL DRq8NXmjpcs3wpDLCX+oKuZS68XF3SzGASf6gT4eOde52Ai1CVZRv3dVsOAfmxV4UC TFgUpq+w5eRn1o60yXZYZtpuvyAtqBCJtS40nl11CylMTubfDoBv/22Tihr+5oha3f oc3pi+tABpkLQ== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_06/10=5D_x86=3A_Enable_XSTATE_save/restor?= =?utf-8?q?e_for_arch_LBR?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807540083 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-7-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2E90040212465a4a738ee55cacd36524b5?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:41 +0000 MIME-Version: 1.0 Add a function get_xstate_component_comp() to allow fetching a specific XSTATE component from a compressed image. Also add LBR state declarations in xstate.h. Signed-off-by: Tu Dinh --- xen/arch/x86/include/asm/xstate.h | 22 ++++++++- xen/arch/x86/msr.c | 3 +- xen/arch/x86/xstate.c | 79 +++++++++++++++++++++++-------- 3 files changed, 79 insertions(+), 25 deletions(-) diff --git a/xen/arch/x86/include/asm/xstate.h b/xen/arch/x86/include/asm/xstate.h index 07017cc4ed..cc77f599d7 100644 --- a/xen/arch/x86/include/asm/xstate.h +++ b/xen/arch/x86/include/asm/xstate.h @@ -33,13 +33,13 @@ extern uint32_t mxcsr_mask; #define XSTATE_FP_SSE (X86_XCR0_X87 | X86_XCR0_SSE) #define XCNTXT_MASK (X86_XCR0_X87 | X86_XCR0_SSE | X86_XCR0_YMM | \ X86_XCR0_OPMASK | X86_XCR0_ZMM | X86_XCR0_HI_ZMM | \ - XSTATE_NONLAZY) + XSTATE_NONLAZY | XSTATE_XSAVES_ONLY) #define XSTATE_ALL (~(1ULL << 63)) #define XSTATE_NONLAZY (X86_XCR0_BNDREGS | X86_XCR0_BNDCSR | X86_XCR0_PKRU | \ X86_XCR0_TILE_CFG | X86_XCR0_TILE_DATA) #define XSTATE_LAZY (XSTATE_ALL & ~XSTATE_NONLAZY) -#define XSTATE_XSAVES_ONLY 0 +#define XSTATE_XSAVES_ONLY (X86_XSS_LBR) #define XSTATE_COMPACTION_ENABLED (1ULL << 63) #define XSTATE_XSS (1U << 0) @@ -91,6 +91,21 @@ struct xstate_bndcsr { uint64_t bndstatus; }; +struct xstate_lbr_entry { + uint64_t lbr_from_ip; + uint64_t lbr_to_ip; + uint64_t lbr_info; +}; + +struct xstate_lbr { + uint64_t lbr_ctl; + uint64_t lbr_depth; + uint64_t ler_from_ip; + uint64_t ler_to_ip; + uint64_t ler_info; + struct xstate_lbr_entry entries[32]; +}; + /* extended state operations */ bool __must_check set_xcr0(u64 xfeatures); uint64_t get_xcr0(void); @@ -114,6 +129,9 @@ int xstate_alloc_save_area(struct vcpu *v); void xstate_init(struct cpuinfo_x86 *c); unsigned int xstate_uncompressed_size(uint64_t xcr0); unsigned int xstate_compressed_size(uint64_t xstates); +void *get_xstate_component_comp(struct xsave_struct *xstate, + unsigned int size, + uint64_t component); static inline uint64_t xgetbv(unsigned int index) { diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c index 289cf10b78..68a419ac8e 100644 --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -522,8 +522,7 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) if ( !cp->xstate.xsaves ) goto gp_fault; - /* No XSS features currently supported for guests */ - if ( val != 0 ) + if ( val & ~(uint64_t)XSTATE_XSAVES_ONLY ) goto gp_fault; msrs->xss.raw = val; diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index baae8e1a13..607bf9c8a5 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -18,13 +18,16 @@ #include /* - * Maximum size (in byte) of the XSAVE/XRSTOR save area required by all + * Maximum size (in byte) of the XSAVE(S)/XRSTOR(S) save area required by all * the supported and enabled features on the processor, including the * XSAVE.HEADER. We only enable XCNTXT_MASK that we have known. */ static u32 __read_mostly xsave_cntxt_size; -/* A 64-bit bitmask of the XSAVE/XRSTOR features supported by processor. */ +/* + * A 64-bit bitmask of the XSAVE(S)/XRSTOR(S) features supported by + * processor. + */ u64 __read_mostly xfeature_mask; unsigned int *__read_mostly xstate_offsets; @@ -126,7 +129,8 @@ static int setup_xstate_features(bool bsp) cpuid_count(XSTATE_CPUID, leaf, &eax, &ebx, &ecx, &edx); BUG_ON(eax != xstate_sizes[leaf]); - BUG_ON(ebx != xstate_offsets[leaf]); + if ( (1ul << leaf) & X86_XCR0_STATES ) + BUG_ON(ebx != xstate_offsets[leaf]); BUG_ON(!(ecx & XSTATE_ALIGN64) != !test_bit(leaf, &xstate_align)); } } @@ -210,7 +214,7 @@ void expand_xsave_states(const struct vcpu *v, void *dest, unsigned int size) * non-compacted offset. */ src = xstate; - valid = xstate_bv & ~XSTATE_FP_SSE; + valid = xstate_bv & ~XSTATE_FP_SSE & ~X86_XSS_STATES; while ( valid ) { u64 feature = valid & -valid; @@ -276,7 +280,7 @@ void compress_xsave_states(struct vcpu *v, const void *src, unsigned int size) * possibly compacted offset. */ dest = xstate; - valid = xstate_bv & ~XSTATE_FP_SSE; + valid = xstate_bv & ~XSTATE_FP_SSE & ~X86_XSS_STATES; while ( valid ) { u64 feature = valid & -valid; @@ -516,7 +520,7 @@ int xstate_alloc_save_area(struct vcpu *v) */ size = XSTATE_AREA_MIN_SIZE; } - else if ( !is_idle_vcpu(v) || !cpu_has_xsavec ) + else if ( !is_idle_vcpu(v) || (!cpu_has_xsavec && !cpu_has_xsaves) ) { size = xsave_cntxt_size; BUG_ON(size < XSTATE_AREA_MIN_SIZE); @@ -678,12 +682,9 @@ static void __init check_new_xstate(struct xcheck_state *s, uint64_t new) (new & X86_XSS_STATES)); /* User or supervisor, not both. */ s->states |= new; - if ( new & X86_XCR0_STATES ) - { - if ( !set_xcr0(s->states & X86_XCR0_STATES) ) - BUG(); - } - else + if ( !set_xcr0(s->states & X86_XCR0_STATES) ) + BUG(); + if ( cpu_has_xsaves ) set_msr_xss(s->states & X86_XSS_STATES); /* @@ -850,8 +851,8 @@ void xstate_init(struct cpuinfo_x86 *c) boolean_param("xsave", use_xsave); bool bsp = c == &boot_cpu_data; - u32 eax, ebx, ecx, edx; - u64 feature_mask; + uint32_t eax, ebx, ecx, edx; + uint64_t feature_mask, supervisor_feature_mask = 0; if ( bsp ) { @@ -874,7 +875,8 @@ void xstate_init(struct cpuinfo_x86 *c) } cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx); - feature_mask = (((u64)edx << 32) | eax) & XCNTXT_MASK; + feature_mask = (((u64)edx << 32) | eax) & + (XCNTXT_MASK & ~X86_XSS_STATES); BUG_ON(!valid_xcr0(feature_mask)); BUG_ON(!(feature_mask & X86_XCR0_SSE)); @@ -892,25 +894,36 @@ void xstate_init(struct cpuinfo_x86 *c) BUG(); if ( cpu_has_xsaves ) { + cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx); + supervisor_feature_mask = (((uint64_t)edx << 32) | ecx) & XCNTXT_MASK; + this_cpu(xss) = ~0; - set_msr_xss(0); + set_msr_xss(supervisor_feature_mask); } if ( bsp ) { - xfeature_mask = feature_mask; + xfeature_mask = feature_mask | supervisor_feature_mask; /* * xsave_cntxt_size is the max size required by enabled features. * We know FP/SSE and YMM about eax, and nothing about edx at present. */ xsave_cntxt_size = cpuid_count_ebx(0xd, 0); - printk("xstate: size: %#x and states: %#"PRIx64"\n", - xsave_cntxt_size, xfeature_mask); + if ( cpu_has_xsaves ) + xsave_cntxt_size = max(xsave_cntxt_size, cpuid_count_ebx(0xd, 1)); + printk("xstate: size: %#x, states: %#"PRIx64 + ", supervisor states: %#"PRIx64"\n", + xsave_cntxt_size, feature_mask, supervisor_feature_mask); } else { - BUG_ON(xfeature_mask != feature_mask); - BUG_ON(xsave_cntxt_size != cpuid_count_ebx(0xd, 0)); + uint32_t ap_xsave_cntxt_size; + + BUG_ON(xfeature_mask != (feature_mask | supervisor_feature_mask)); + ap_xsave_cntxt_size = cpuid_count_ebx(0xd, 0); + if ( cpu_has(¤t_cpu_data, X86_FEATURE_XSAVES) ) + ap_xsave_cntxt_size = max(ap_xsave_cntxt_size, cpuid_count_ebx(0xd, 1)); + BUG_ON(xsave_cntxt_size != ap_xsave_cntxt_size); } if ( setup_xstate_features(bsp) && bsp ) @@ -1072,6 +1085,30 @@ void xstate_set_init(uint64_t mask) BUG(); } +void *get_xstate_component_comp(struct xsave_struct *xstate, + unsigned int size, + uint64_t component) +{ + uint16_t comp_offsets[sizeof(xfeature_mask) * 8]; + uint16_t offset; + unsigned int i = ilog2(component); + + ASSERT(generic_hweightl(component) == 1); + + if ( !(xstate->xsave_hdr.xcomp_bv & XSTATE_COMPACTION_ENABLED) || + i >= xstate_features || + xstate_sizes[i] == 0 || + !(xstate->xsave_hdr.xcomp_bv & component) ) + return NULL; + + setup_xstate_comp(comp_offsets, xstate->xsave_hdr.xcomp_bv); + offset = comp_offsets[i]; + if ( xstate_sizes[i] + offset > size ) + return NULL; + + return (void *)xstate + offset; +} + /* * Local variables: * mode: C From patchwork Thu Jan 2 08:45:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924343 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 A7DD7E77188 for ; Thu, 2 Jan 2025 08:46:14 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863739.1275188 (Exim 4.92) (envelope-from ) id 1tTGq1-0007HM-Sy; Thu, 02 Jan 2025 08:45:53 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863739.1275188; Thu, 02 Jan 2025 08:45:53 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGq1-0007GF-OA; Thu, 02 Jan 2025 08:45:53 +0000 Received: by outflank-mailman (input) for mailman id 863739; Thu, 02 Jan 2025 08:45:52 +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 1tTGpz-0004rS-V4 for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:51 +0000 Received: from mail180-50.suw31.mandrillapp.com (mail180-50.suw31.mandrillapp.com [198.2.180.50]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f692b2ef-c8e5-11ef-99a4-01e77a169b0f; Thu, 02 Jan 2025 09:45:48 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-50.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fF1C1JzCfD7NC for ; Thu, 2 Jan 2025 08:45:41 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id b133c83311a14cd3872070929731beea; Thu, 02 Jan 2025 08:45:41 +0000 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: f692b2ef-c8e5-11ef-99a4-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807541; x=1736068041; bh=QFIxqPt7/jeUPPpwBYw+2ueBPIx3z09csJHPFtv383Y=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=0RUiMycPuccrGYEQh6/0epojJrlT9+8TcXJXNq0kLcAZXp+/4ZXOnYdFppzmha5ju Gf6/c5/OJugVYnrxJQQfGiqUmZ/V7m4lVMdQzR4+3GmWLyR3qto6TH9Wcv1FXPNnP/ cob4hZrFNiLHKfF5F7N/hlI3bsoC5tjPRu0DKjMtX91XaXigUXNRkyIZtNbGwZonx+ phD6Ay1TMRnfjgQaKrizq3rkNMiqD3j1Y4fUWEDl8KVj9ZSa+TRWZJ1gXoOJ1d5/Cp Y2IipbICa0c2IfWL/2bSgUSUtRdElI0LL2ba2mVgb0pdF6nWT1HEja6H6XTsnDOUc0 WbKyAF07GMwMg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807541; x=1736068041; i=ngoc-tu.dinh@vates.tech; bh=QFIxqPt7/jeUPPpwBYw+2ueBPIx3z09csJHPFtv383Y=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=UQewD+KVlhDdl1+IdAMse4OdZYUZ5geILHQ/MlXHjP83PXH8QiqU+XvdCQdxxRB6k iBf6RSVtEwnaW8xDO+8ZtgAfd6zhlOvQ20ZmVu4zeTd0GxDUcDyWk5kJ0u+qDplSoo 1w/nW76hofiNowGgrDilqv9p1gWx1HC+4K1m3odOPiZFJPP/+e2mn0jsq2LV3OMBeK Vn484RFCoD4XkMFlPv8MViv5uMvJc3E16qSDU/qUhA3xpwvGlUISCB8701r1VywA+L ahCy/rnA8oHkjRzpeGY4kDyrnPcSCf6s59Xz0rv0hiGl7AZUmtneIHYBS5s0lQPH5f c5qvNS8CXlL/A== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_07/10=5D_x86/hvm=3A_Don=27t_count_XSS_bit?= =?utf-8?q?s_in_XSAVE_size?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807540297 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-8-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2Eb133c83311a14cd3872070929731beea?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:41 +0000 MIME-Version: 1.0 HVM vCPU state images are uncompressed and therefore can't contain XSS states. Signed-off-by: Tu Dinh --- xen/arch/x86/hvm/hvm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 922c9b3af6..c7b93c7d91 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -1208,7 +1208,8 @@ HVM_REGISTER_SAVE_RESTORE(CPU, hvm_save_cpu_ctxt, NULL, hvm_load_cpu_ctxt, 1, #define HVM_CPU_XSAVE_SIZE(xcr0) (offsetof(struct hvm_hw_cpu_xsave, \ save_area) + \ - xstate_uncompressed_size(xcr0)) + xstate_uncompressed_size(xcr0 & \ + ~X86_XSS_STATES)) static int cf_check hvm_save_cpu_xsave_states( struct vcpu *v, hvm_domain_context_t *h) From patchwork Thu Jan 2 08:45:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924345 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 D7C19E77197 for ; Thu, 2 Jan 2025 08:46:15 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863730.1275094 (Exim 4.92) (envelope-from ) id 1tTGpu-0004tg-9Y; Thu, 02 Jan 2025 08:45:46 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863730.1275094; Thu, 02 Jan 2025 08:45:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGpu-0004se-3f; Thu, 02 Jan 2025 08:45:46 +0000 Received: by outflank-mailman (input) for mailman id 863730; Thu, 02 Jan 2025 08:45:44 +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 1tTGps-0004rF-EC for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:44 +0000 Received: from mail180-43.suw31.mandrillapp.com (mail180-43.suw31.mandrillapp.com [198.2.180.43]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f2e07578-c8e5-11ef-a0db-8be0dac302b0; Thu, 02 Jan 2025 09:45:42 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-43.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fF5Mh3zLfHBGS for ; Thu, 2 Jan 2025 08:45:41 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id d628a30899f042d695a6c136380c8c92; Thu, 02 Jan 2025 08:45:41 +0000 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: f2e07578-c8e5-11ef-a0db-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807541; x=1736068041; bh=R32ivPZ8JUTitnv8cnvvzU3Su0yCpWPGxSwsBLOjoMQ=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=FOZPufxURTOJy7jIkSOWuXuzFjoTT6HtVVRLQZXjWLU2rGd4rxAKTsQK1RH1aKLBP OCZQVmacuF27CIiKezl1StZeWVwSBHy6Y2AFrO5rs2HVWEk4azJg3gxxNZBwdnga9c XQssrH2yJxpiYUaVlpWJfMSB8Pi6ng7oTU3DnJ0zcnNTMAJurlfS+6cf2yyu0dmDp4 ks/BJUcjyqrZoslDwUKUeYlbdWcf3N5gzCiVjqoHtNqZm6+6azL8tHKK8mkoydWw2o h5clkv9woQ/CPdcyRJ1TR/JQqehG+NPbXictUbGLw3TLbCemVp/vnjLZt81Vof35fm wS/xMw1b6vcig== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807541; x=1736068041; i=ngoc-tu.dinh@vates.tech; bh=R32ivPZ8JUTitnv8cnvvzU3Su0yCpWPGxSwsBLOjoMQ=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=TeEufgR2NQZPge6us8mIOYWSDG5iDl4P3Bz+153exU8Ee8nbhAfzDljnr6veMuVCM A3xg/8RWs34txfq9KsxIiPhC2//5iF6xizgYg9AKWxdiuzdyt4GkmBfWWQpFdDYgq5 Q3PAkqeQQOX6DqvRkjlsp8CqHhannave30oTYkBUu2osvm5hhPWR0PBV83fWanyKt9 Mhehk3xJIQo8hXbaWTOpX9PzSdPGbldVdhgzhjVt9FJzECNnM1IvLAO1b8KlfQe/r4 JyKZSk0oZ4keEGrj/i6/d6LkCZR/79U8jTSdf8CyL7EW6z1fTFNygLxtxe8fCQd5af v9m8S5NFaBs3g== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_08/10=5D_x86/emulate=3A_Implement_XSAVES/?= =?utf-8?q?XRSTORS_for_arch_LBR?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807540507 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-9-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2Ed628a30899f042d695a6c136380c8c92?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:41 +0000 MIME-Version: 1.0 Add new set_lbr_depth HVM function and emulate ops to support LBR XSAVES/XRSTORS emulation. Add the appropriate instruction hooks to 0fc7.c. Translate LBR registers using cs.base within a large block emulator operation. Signed-off-by: Tu Dinh --- tools/tests/x86_emulator/x86-emulate.h | 2 + xen/arch/x86/hvm/emulate.c | 11 ++ xen/arch/x86/include/asm/hvm/hvm.h | 3 + xen/arch/x86/x86_emulate/0fc7.c | 260 ++++++++++++++++++------- xen/arch/x86/x86_emulate/blk.c | 142 ++++++++++++++ xen/arch/x86/x86_emulate/private.h | 8 + xen/arch/x86/x86_emulate/util-xen.c | 14 ++ xen/arch/x86/x86_emulate/x86_emulate.c | 19 ++ xen/arch/x86/x86_emulate/x86_emulate.h | 33 ++++ 9 files changed, 422 insertions(+), 70 deletions(-) diff --git a/tools/tests/x86_emulator/x86-emulate.h b/tools/tests/x86_emulator/x86-emulate.h index 929c1a72ae..75a9a65ae7 100644 --- a/tools/tests/x86_emulator/x86-emulate.h +++ b/tools/tests/x86_emulator/x86-emulate.h @@ -218,6 +218,8 @@ void wrpkru(unsigned int val); #define cpu_has_fma4 (cpu_policy.extd.fma4 && xcr0_mask(6)) #define cpu_has_tbm cpu_policy.extd.tbm +#define current_cpu_has_lbr_lip cpu_policy.basic.lbr_1Ca.ip_contains_lip + int emul_test_cpuid( uint32_t leaf, uint32_t subleaf, diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index a1935a1748..c3b0bd4cbe 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -2562,6 +2562,16 @@ static int cf_check hvmemul_vmfunc( return rc; } +static int cf_check hvmemul_set_lbr_depth( + uint32_t depth, + struct x86_emulate_ctxt *ctxt) +{ + if ( !hvm_funcs.set_lbr_depth ) + return X86EMUL_UNHANDLEABLE; + alternative_vcall(hvm_funcs.set_lbr_depth, current, depth); + return X86EMUL_OKAY; +} + static const struct x86_emulate_ops hvm_emulate_ops = { .read = hvmemul_read, .insn_fetch = hvmemul_insn_fetch, @@ -2590,6 +2600,7 @@ static const struct x86_emulate_ops hvm_emulate_ops = { .get_fpu = hvmemul_get_fpu, .put_fpu = hvmemul_put_fpu, .vmfunc = hvmemul_vmfunc, + .set_lbr_depth = hvmemul_set_lbr_depth, }; static const struct x86_emulate_ops hvm_emulate_ops_no_write = { diff --git a/xen/arch/x86/include/asm/hvm/hvm.h b/xen/arch/x86/include/asm/hvm/hvm.h index cad3a94278..bfce78952f 100644 --- a/xen/arch/x86/include/asm/hvm/hvm.h +++ b/xen/arch/x86/include/asm/hvm/hvm.h @@ -238,6 +238,9 @@ struct hvm_function_table { int (*vmtrace_get_option)(struct vcpu *v, uint64_t key, uint64_t *value); int (*vmtrace_reset)(struct vcpu *v); + /* Arch LBR */ + void (*set_lbr_depth)(struct vcpu *v, uint32_t depth); + uint64_t (*get_reg)(struct vcpu *v, unsigned int reg); void (*set_reg)(struct vcpu *v, unsigned int reg, uint64_t val); diff --git a/xen/arch/x86/x86_emulate/0fc7.c b/xen/arch/x86/x86_emulate/0fc7.c index 5268d5cafd..bb2b308afe 100644 --- a/xen/arch/x86/x86_emulate/0fc7.c +++ b/xen/arch/x86/x86_emulate/0fc7.c @@ -10,6 +10,10 @@ #include "private.h" +#if defined(__XEN__) && !defined(X86EMUL_NO_FPU) +# include +#endif + /* Avoid namespace pollution. */ #undef cmpxchg @@ -107,87 +111,203 @@ int x86emul_0fc7(struct x86_emulate_state *s, } else { - union { - uint32_t u32[2]; - uint64_t u64[2]; - } *old, *aux; - - /* cmpxchg8b/cmpxchg16b */ - generate_exception_if((s->modrm_reg & 7) != 1, X86_EXC_UD); - fail_if(!ops->cmpxchg); - if ( s->rex_prefix & REX_W ) - { - host_and_vcpu_must_have(cx16); - generate_exception_if(!is_aligned(s->ea.mem.seg, s->ea.mem.off, 16, - ctxt, ops), - X86_EXC_GP, 0); - s->op_bytes = 16; - } - else + switch ( s->modrm_reg & 7 ) { - vcpu_must_have(cx8); - s->op_bytes = 8; - } + default: + return X86EMUL_UNRECOGNIZED; - old = container_of(&mmvalp->ymm[0], typeof(*old), u64[0]); - aux = container_of(&mmvalp->ymm[2], typeof(*aux), u64[0]); + case 1: /* cmpxchg8b/cmpxchg16b */ + { + union { + uint32_t u32[2]; + uint64_t u64[2]; + } *old, *aux; - /* Get actual old value. */ - if ( (rc = ops->read(s->ea.mem.seg, s->ea.mem.off, old, s->op_bytes, - ctxt)) != X86EMUL_OKAY ) - goto done; + fail_if(!ops->cmpxchg); + if ( s->rex_prefix & REX_W ) + { + host_and_vcpu_must_have(cx16); + generate_exception_if(!is_aligned(s->ea.mem.seg, s->ea.mem.off, 16, + ctxt, ops), + X86_EXC_GP, 0); + s->op_bytes = 16; + } + else + { + vcpu_must_have(cx8); + s->op_bytes = 8; + } - /* Get expected value. */ - if ( s->op_bytes == 8 ) - { - aux->u32[0] = regs->eax; - aux->u32[1] = regs->edx; - } - else - { - aux->u64[0] = regs->r(ax); - aux->u64[1] = regs->r(dx); - } + old = container_of(&mmvalp->ymm[0], typeof(*old), u64[0]); + aux = container_of(&mmvalp->ymm[2], typeof(*aux), u64[0]); - if ( memcmp(old, aux, s->op_bytes) ) - { - cmpxchgNb_failed: - /* Expected != actual: store actual to rDX:rAX and clear ZF. */ - regs->r(ax) = s->op_bytes == 8 ? old->u32[0] : old->u64[0]; - regs->r(dx) = s->op_bytes == 8 ? old->u32[1] : old->u64[1]; - regs->eflags &= ~X86_EFLAGS_ZF; - } - else - { - /* - * Expected == actual: Get proposed value, attempt atomic cmpxchg - * and set ZF if successful. - */ - if ( s->op_bytes == 8 ) - { - aux->u32[0] = regs->ebx; - aux->u32[1] = regs->ecx; - } - else - { - aux->u64[0] = regs->r(bx); - aux->u64[1] = regs->r(cx); + /* Get actual old value. */ + if ( (rc = ops->read(s->ea.mem.seg, s->ea.mem.off, old, s->op_bytes, + ctxt)) != X86EMUL_OKAY ) + goto done; + + /* Get expected value. */ + if ( s->op_bytes == 8 ) + { + aux->u32[0] = regs->eax; + aux->u32[1] = regs->edx; + } + else + { + aux->u64[0] = regs->r(ax); + aux->u64[1] = regs->r(dx); + } + + if ( memcmp(old, aux, s->op_bytes) ) + { + cmpxchgNb_failed: + /* Expected != actual: store actual to rDX:rAX and clear ZF. */ + regs->r(ax) = s->op_bytes == 8 ? old->u32[0] : old->u64[0]; + regs->r(dx) = s->op_bytes == 8 ? old->u32[1] : old->u64[1]; + regs->eflags &= ~X86_EFLAGS_ZF; + } + else + { + /* + * Expected == actual: Get proposed value, attempt atomic cmpxchg + * and set ZF if successful. + */ + if ( s->op_bytes == 8 ) + { + aux->u32[0] = regs->ebx; + aux->u32[1] = regs->ecx; + } + else + { + aux->u64[0] = regs->r(bx); + aux->u64[1] = regs->r(cx); + } + + switch ( rc = ops->cmpxchg(s->ea.mem.seg, s->ea.mem.off, old, aux, + s->op_bytes, s->lock_prefix, ctxt) ) + { + case X86EMUL_OKAY: + regs->eflags |= X86_EFLAGS_ZF; + break; + + case X86EMUL_CMPXCHG_FAILED: + rc = X86EMUL_OKAY; + goto cmpxchgNb_failed; + + default: + goto done; + } + } + break; } - switch ( rc = ops->cmpxchg(s->ea.mem.seg, s->ea.mem.off, old, aux, - s->op_bytes, s->lock_prefix, ctxt) ) +#if defined(__XEN__) && !defined(X86EMUL_NO_FPU) + case 3: /* xrstors */ + case 5: /* xsaves */ { - case X86EMUL_OKAY: - regs->eflags |= X86_EFLAGS_ZF; - break; + unsigned long cr0, cr4; + unsigned long xcr0, xss; + struct segment_register cs; - case X86EMUL_CMPXCHG_FAILED: - rc = X86EMUL_OKAY; - goto cmpxchgNb_failed; + generate_exception_if(s->vex.pfx, X86_EXC_UD); + host_and_vcpu_must_have(xsaves); + generate_exception_if(s->ea.type != OP_MEM, X86_EXC_UD); + generate_exception_if(!is_aligned(s->ea.mem.seg, s->ea.mem.off, + 64, ctxt, ops), + X86_EXC_GP, 0); + fail_if(!ops->blk || !ops->read_cr || !ops->read_xcr || + !ops->read_msr || !ops->write_msr || + !ops->read_segment); + fail_if(vcpu_has_arch_lbr() && !ops->set_lbr_depth); - default: - goto done; + if ( ops->read_cr(4, &cr4, ctxt) != X86EMUL_OKAY || + ops->read_cr(0, &cr0, ctxt) != X86EMUL_OKAY ) + cr0 = cr4 = 0; + generate_exception_if(!(cr4 & X86_CR4_OSXSAVE), X86_EXC_UD); + generate_exception_if(cr0 & X86_CR0_TS, X86_EXC_NM); + generate_exception_if(!mode_ring0(), X86_EXC_GP, 0); + + if ( (rc = ops->read_segment(x86_seg_cs, + &cs, ctxt)) != X86EMUL_OKAY || + (rc = ops->read_xcr(0, &xcr0, ctxt)) != X86EMUL_OKAY || + (rc = ops->read_msr(MSR_IA32_XSS, + &xss, ctxt)) != X86EMUL_OKAY ) + goto done; + + if ( vcpu_has_arch_lbr() && + ((rc = ops->read_msr(MSR_LBR_CTL, &ctxt->xsaves.lbr_ctl, + ctxt)) != X86EMUL_OKAY || + (rc = ops->read_msr(MSR_LBR_DEPTH, &ctxt->xsaves.lbr_depth, + ctxt)) != X86EMUL_OKAY) ) + goto done; + + s->blk = (s->modrm_reg & 7) == 3 ? blk_xrstors : blk_xsaves; + ctxt->xsaves.rfbm = ((uint64_t)regs->edx << 32) | regs->eax; + ctxt->xsaves.rfbm &= xcr0 | xss; + + if ( s->blk == blk_xrstors ) + { + struct xsave_struct hdr; + int i; + + if ( (rc = ops->read(s->ea.mem.seg, s->ea.mem.off, &hdr, + sizeof(hdr), ctxt)) != X86EMUL_OKAY ) + goto done; + /* + * We must validate xcomp_bv at this stage to get a + * stable XSAVE area size. + */ + generate_exception_if(!xsave_area_compressed(&hdr), + X86_EXC_GP, 0); + generate_exception_if(hdr.xsave_hdr.xcomp_bv & + ~XSTATE_COMPACTION_ENABLED & + ~(xcr0 | xss), + X86_EXC_GP, 0); + generate_exception_if(hdr.xsave_hdr.xstate_bv & + ~hdr.xsave_hdr.xcomp_bv, + X86_EXC_GP, 0); + for ( i = 0; i < ARRAY_SIZE(hdr.xsave_hdr.reserved); i++ ) + generate_exception_if(hdr.xsave_hdr.reserved[i], + X86_EXC_GP, 0); + ctxt->xsaves.size = xstate_compressed_size( + hdr.xsave_hdr.xcomp_bv & + ~XSTATE_COMPACTION_ENABLED); + } + else + { + ctxt->xsaves.size = + xstate_compressed_size(ctxt->xsaves.rfbm); + } + + if ( (rc = ops->blk(s->ea.mem.seg, s->ea.mem.off, NULL, + ctxt->xsaves.size, ®s->eflags, + s, ctxt)) != X86EMUL_OKAY ) + goto done; + + if ( s->blk == blk_xrstors && vcpu_has_arch_lbr() ) + { + if ( (rc = ops->write_msr(MSR_LBR_CTL, + ctxt->xsaves.lbr_ctl, + ctxt)) != X86EMUL_OKAY || + (rc = ops->set_lbr_depth(ctxt->xsaves.lbr_depth, + ctxt)) != X86EMUL_OKAY ) + goto done; + /* + * Even if xstate_bv[LBR]=0, XRSTORS will still clear + * LBR/LER MSRs. + */ + if ( !(ctxt->xsaves.xstate_bv & X86_XSS_LBR) && + ((rc = ops->write_msr(MSR_IA32_LASTINTFROMIP, 0, + ctxt)) != X86EMUL_OKAY || + (rc = ops->write_msr(MSR_IA32_LASTINTTOIP, 0, + ctxt)) != X86EMUL_OKAY || + (rc = ops->write_msr(MSR_LER_INFO, 0, + ctxt)) != X86EMUL_OKAY) ) + goto done; + } + break; } +#endif /* __XEN__ && X86EMUL_NO_FPU */ } } diff --git a/xen/arch/x86/x86_emulate/blk.c b/xen/arch/x86/x86_emulate/blk.c index 08a05f8453..ed85a58f30 100644 --- a/xen/arch/x86/x86_emulate/blk.c +++ b/xen/arch/x86/x86_emulate/blk.c @@ -17,6 +17,29 @@ # endif #endif +#if defined(__XEN__) && !defined(X86EMUL_NO_FPU) +static struct xstate_lbr * +x86_translate_lbr(struct x86_emulate_state *s, + struct x86_emulate_ctxt *ctxt, + const struct segment_register *cs, + bool saving, + struct xstate_lbr *lbr) +{ + uint64_t cs_offset; + uint32_t i; + + cs_offset = x86_get_lbr_cs_offset(ctxt->cpuid, mode_64bit(), cs, saving); + lbr->ler_from_ip += cs_offset; + lbr->ler_to_ip += cs_offset; + for ( i = 0; i < ctxt->xsaves.lbr_depth; i++ ) + { + lbr->entries[i].lbr_from_ip += cs_offset; + lbr->entries[i].lbr_to_ip += cs_offset; + } + return lbr; +} +#endif + int x86_emul_blk( void *ptr, void *data, @@ -373,6 +396,125 @@ int x86_emul_blk( } break; +/* + * XSAVES/XRSTORS emulation uses the host's XSS instructions and therefore + * can't be used in an usermode emulator. + */ +#if defined(__XEN__) && !defined(X86EMUL_NO_FPU) + +#define _xrstors(pfx, mem, eax, edx, faulted) \ + asm volatile ( "1: .byte " pfx "0x0f,0xc7,0x1f\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + "2: incl %[faulted]\n" \ + " jmp 3b\n" \ + " .previous\n" \ + _ASM_EXTABLE(1b, 2b) \ + : "+m" (*mem), [faulted] "+g" (faulted) \ + : "a" (eax), "d" (edx), "D" (mem) ) +#define _xsaves(pfx, mem, eax, edx, faulted) \ + asm volatile ( "1: .byte " pfx "0x0f,0xc7,0x2f\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + "2: incl %[faulted]\n" \ + " jmp 3b\n" \ + " .previous\n" \ + _ASM_EXTABLE(1b, 2b) \ + : "+m" (*mem), [faulted] "+g" (faulted) \ + : "a" (eax), "d" (edx), "D" (mem) ) + + case blk_xrstors: + { + struct xsave_struct *xstate = ptr; + unsigned int faulted; + + ASSERT(!data); + + if ( ctxt->xsaves.rfbm & xstate->xsave_hdr.xcomp_bv & X86_XSS_LBR ) + { + struct xstate_lbr *lbr; + + lbr = get_xstate_component_comp(xstate, bytes, X86_XSS_LBR); + generate_exception_if(!lbr, X86_EXC_GP, 0); + if ( xstate->xsave_hdr.xstate_bv & X86_XSS_LBR ) + { + generate_exception_if(lbr->lbr_ctl & ~LBR_CTL_VALID, + X86_EXC_GP, 0); + generate_exception_if(lbr->lbr_depth == 0 || + lbr->lbr_depth > + NUM_MSR_ARCH_LBR_FROM_TO || + lbr->lbr_depth % 8 != 0, + X86_EXC_GP, 0); + + if ( !mode_64bit() ) + x86_translate_lbr(s, ctxt, data, false, lbr); + ctxt->xsaves.lbr_ctl = lbr->lbr_ctl; + ctxt->xsaves.lbr_depth = lbr->lbr_depth; + lbr->lbr_ctl = 0; + } + else + { + ctxt->xsaves.lbr_ctl = 0; + /* Don't touch the previous LBR depth */ + } + } + + faulted = 0; + if ( s->rex_prefix & REX_W ) + _xrstors("0x48,", xstate, ctxt->xsaves.rfbm & UINT32_MAX, + ctxt->xsaves.rfbm >> 32, faulted); + else + _xrstors("", xstate, ctxt->xsaves.rfbm & UINT32_MAX, + ctxt->xsaves.rfbm >> 32, faulted); + generate_exception_if(faulted, X86_EXC_GP, 0); + + ctxt->xsaves.xstate_bv = xstate->xsave_hdr.xstate_bv; + + break; + } + + case blk_xsaves: + { + struct xsave_struct *xstate = ptr; + unsigned int faulted; + + ASSERT(!data); + + /* Defeat XSAVES modified optimization using XRSTORS with EDX=EAX=0 */ + memset(xstate, 0, sizeof(*xstate)); + xstate->xsave_hdr.xcomp_bv = XSTATE_COMPACTION_ENABLED; + faulted = 0; + _xrstors("", xstate, 0, 0, faulted); + generate_exception_if(faulted, X86_EXC_GP, 0); + + faulted = 0; + if ( s->rex_prefix & REX_W ) + _xsaves("0x48,", xstate, ctxt->xsaves.rfbm & UINT32_MAX, + ctxt->xsaves.rfbm >> 32, faulted); + else + _xsaves("", xstate, ctxt->xsaves.rfbm & UINT32_MAX, + ctxt->xsaves.rfbm >> 32, faulted); + generate_exception_if(faulted, X86_EXC_GP, 0); + + if ( ctxt->xsaves.rfbm & xstate->xsave_hdr.xcomp_bv & X86_XSS_LBR ) + { + struct xstate_lbr *lbr; + + lbr = get_xstate_component_comp(xstate, bytes, X86_XSS_LBR); + generate_exception_if(!lbr, X86_EXC_GP, 0); + if ( !mode_64bit() && (xstate->xsave_hdr.xstate_bv & X86_XSS_LBR) ) + x86_translate_lbr(s, ctxt, data, true, lbr); + lbr->lbr_ctl = ctxt->xsaves.lbr_ctl; + lbr->lbr_depth = ctxt->xsaves.lbr_depth; + } + + break; + } +#undef _xsaves +#undef _xrstors + +#endif /* __XEN__ && X86EMUL_NO_FPU */ + default: ASSERT_UNREACHABLE(); return X86EMUL_UNHANDLEABLE; diff --git a/xen/arch/x86/x86_emulate/private.h b/xen/arch/x86/x86_emulate/private.h index ef4745f56e..a48d647df7 100644 --- a/xen/arch/x86/x86_emulate/private.h +++ b/xen/arch/x86/x86_emulate/private.h @@ -295,6 +295,10 @@ struct x86_emulate_state { blk_fxsave, #endif blk_movdir, +#ifndef X86EMUL_NO_FPU + blk_xrstors, + blk_xsaves, +#endif } blk; uint8_t modrm, modrm_mod, modrm_reg, modrm_rm; uint8_t sib_index, sib_scale; @@ -537,6 +541,7 @@ amd_like(const struct x86_emulate_ctxt *ctxt) #define vcpu_has_avx() (ctxt->cpuid->basic.avx) #define vcpu_has_f16c() (ctxt->cpuid->basic.f16c) #define vcpu_has_rdrand() (ctxt->cpuid->basic.rdrand) +#define vcpu_has_lbr_lip() (ctxt->cpuid->basic.lbr_1Ca.ip_contains_lip) #define vcpu_has_mmxext() (ctxt->cpuid->extd.mmxext || vcpu_has_sse()) #define vcpu_has_3dnow_ext() (ctxt->cpuid->extd._3dnowext) @@ -587,6 +592,7 @@ amd_like(const struct x86_emulate_ctxt *ctxt) #define vcpu_has_avx512_vp2intersect() (ctxt->cpuid->feat.avx512_vp2intersect) #define vcpu_has_serialize() (ctxt->cpuid->feat.serialize) #define vcpu_has_tsxldtrk() (ctxt->cpuid->feat.tsxldtrk) +#define vcpu_has_arch_lbr() (ctxt->cpuid->feat.arch_lbr) #define vcpu_has_avx512_fp16() (ctxt->cpuid->feat.avx512_fp16) #define vcpu_has_sha512() (ctxt->cpuid->feat.sha512) #define vcpu_has_sm3() (ctxt->cpuid->feat.sm3) @@ -600,6 +606,8 @@ amd_like(const struct x86_emulate_ctxt *ctxt) #define vcpu_has_avx_ne_convert() (ctxt->cpuid->feat.avx_ne_convert) #define vcpu_has_avx_vnni_int16() (ctxt->cpuid->feat.avx_vnni_int16) +#define vcpu_has_xsaves() (ctxt->cpuid->xstate.xsaves) + #define vcpu_must_have(feat) \ generate_exception_if(!vcpu_has_##feat(), X86_EXC_UD) diff --git a/xen/arch/x86/x86_emulate/util-xen.c b/xen/arch/x86/x86_emulate/util-xen.c index 5e90818010..e5c34b5b42 100644 --- a/xen/arch/x86/x86_emulate/util-xen.c +++ b/xen/arch/x86/x86_emulate/util-xen.c @@ -96,6 +96,20 @@ bool cf_check x86_insn_is_cr_access(const struct x86_emulate_state *s, return false; } +bool cf_check x86_insn_is_xsaves(const struct x86_emulate_state *s, + const struct x86_emulate_ctxt *ctxt) +{ + return ctxt->opcode == X86EMUL_OPC(0x0f, 0xc7) && s->ea.type == OP_MEM && + (s->modrm_reg & 7) == 5; +} + +bool cf_check x86_insn_is_xrstors(const struct x86_emulate_state *s, + const struct x86_emulate_ctxt *ctxt) +{ + return ctxt->opcode == X86EMUL_OPC(0x0f, 0xc7) && s->ea.type == OP_MEM && + (s->modrm_reg & 7) == 3; +} + unsigned long x86_insn_immediate(const struct x86_emulate_state *s, unsigned int nr) { diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index b89d440133..92c23006e5 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -8592,6 +8592,25 @@ int x86_emul_rmw( } #undef stub_exn +uint64_t x86_get_lbr_cs_offset(const struct cpu_policy *cp, + bool is_long_mode, + const struct segment_register *cs, + bool saving) +{ + bool host_lip, guest_lip; + + host_lip = current_cpu_has_lbr_lip; + guest_lip = !!cp->basic.lbr_1Ca.ip_contains_lip; + + if ( host_lip == guest_lip || is_long_mode ) + return 0; + else if ( (host_lip && !guest_lip && saving) || + (!host_lip && guest_lip && !saving) ) + return -cs->base; + else + return cs->base; +} + static void __init __maybe_unused build_assertions(void) { /* Check the values against SReg3 encoding in opcode/ModRM bytes. */ diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h index d75658eba0..cc86ec3cee 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.h +++ b/xen/arch/x86/x86_emulate/x86_emulate.h @@ -534,6 +534,10 @@ struct x86_emulate_ops /* vmfunc: Emulate VMFUNC via given set of EAX ECX inputs */ int (*vmfunc)( struct x86_emulate_ctxt *ctxt); + + int (*set_lbr_depth)( + uint32_t depth, + struct x86_emulate_ctxt *ctxt); }; struct cpu_user_regs; @@ -572,6 +576,22 @@ struct x86_emulate_ctxt /* Long mode active? */ bool lma; + struct { + /* In */ + uint64_t rfbm; + unsigned int size; + /* Inout */ + /* + * MSR_LBR_{CTL,DEPTH} don't match guest state, so we need to pass + * them to the emulator. + */ + uint64_t lbr_ctl; + uint64_t lbr_depth; + /* Out */ + /* XRSTORS */ + uint64_t xstate_bv; + } xsaves; + /* * Output-only state: */ @@ -763,6 +783,14 @@ bool cf_check x86_insn_is_cr_access(const struct x86_emulate_state *s, const struct x86_emulate_ctxt *ctxt); +bool cf_check +x86_insn_is_xsaves(const struct x86_emulate_state *s, + const struct x86_emulate_ctxt *ctxt); + +bool cf_check +x86_insn_is_xrstors(const struct x86_emulate_state *s, + const struct x86_emulate_ctxt *ctxt); + #if !defined(__XEN__) || defined(NDEBUG) static inline void x86_emulate_free_state(struct x86_emulate_state *s) {} #else @@ -802,6 +830,11 @@ x86_emul_blk( struct x86_emulate_state *s, struct x86_emulate_ctxt *ctxt); +uint64_t x86_get_lbr_cs_offset(const struct cpu_policy *cp, + bool is_long_mode, + const struct segment_register *cs, + bool reading); + static inline void x86_emul_hw_exception( unsigned int vector, int error_code, struct x86_emulate_ctxt *ctxt) { From patchwork Thu Jan 2 08:45:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924342 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 9D3E6E7719A for ; Thu, 2 Jan 2025 08:46:12 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863733.1275124 (Exim 4.92) (envelope-from ) id 1tTGpw-0005aD-Bs; Thu, 02 Jan 2025 08:45:48 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863733.1275124; Thu, 02 Jan 2025 08:45:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGpw-0005ZF-4k; Thu, 02 Jan 2025 08:45:48 +0000 Received: by outflank-mailman (input) for mailman id 863733; Thu, 02 Jan 2025 08:45:46 +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 1tTGpu-0004rS-A6 for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:46 +0000 Received: from mail180-43.suw31.mandrillapp.com (mail180-43.suw31.mandrillapp.com [198.2.180.43]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f2f0b31b-c8e5-11ef-99a4-01e77a169b0f; Thu, 02 Jan 2025 09:45:42 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-43.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fF660tzLfHCqL for ; Thu, 2 Jan 2025 08:45:41 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id 68aac7873e55466da24a0637d6e85abf; Thu, 02 Jan 2025 08:45:41 +0000 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: f2f0b31b-c8e5-11ef-99a4-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807541; x=1736068041; bh=bzh0Fm9xRWi5sdSCui/eX3MkuuuaQvZQ4zYj+fK0gX8=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=uMkU/I3HMgS2qZGZSO21pzx6J2vDfpojCPFRvo48ZMp+qtHL366nMvfZiUiodET6M 219uHx3eq4dNDpR0/Xxe51wM9AJwPlbCIq6CpRFeyh4tS+Y4Xw4i91N9viKENyD2Fx TRKHg4wtmFTv3Hybe5/l+1opTsgP4onGoAsm4TLjXymY8QuAEDr3Fn7K2bNRoLxT/u skA4Ai2EpdZlizGVZsxAnGWK2ftbrQPxBQ49QVvDt/GE+0h+vc36Jyq5OixO+rUhJ5 BHyxyLUyQ8xwAL5HOFTidAdp+Dmpv89nyKVh6xEe8stYGbz1yF1Dp0p8xKEr4nfwQr aJkiQvFK+PS8w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807541; x=1736068041; i=ngoc-tu.dinh@vates.tech; bh=bzh0Fm9xRWi5sdSCui/eX3MkuuuaQvZQ4zYj+fK0gX8=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=soK6Agw0aE8t92BfDTToFSRLwzXj7Bg2MKx/bNYyVtyUu8eODd49fpS9RqBYvbeaZ 8IOuZemgOsEXgYlI9P2oms/DzRhoMqU07bSK3Lxub4R4qk0DRplHCiS3lf1bA12738 6FyQGbvdOyXi3bDF/zSi+zQlm3mNZiEfxnaUzKeYeFXH30uvJjbK3flXIC1liS7cKX zKIF1D6dtU90dK+KCxzy19BjYhv+1fiSPtUVtYAj2krjfo4DHLRzU7OTUuJCmXeDLv ATOCqgetCGEMyWmw3Wyxk5PGI6AjP+JVk5xun0+CIdqormyoRzIq6SEl9YlPgz55BF bj8b9S6flXZyQ== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_09/10=5D_x86/vmx=3A_Implement_arch_LBR?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807540946 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-10-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2E68aac7873e55466da24a0637d6e85abf?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:41 +0000 MIME-Version: 1.0 Use guest LBR_CTL in VMCS to limit LBR operation per guest. Use MSR bitmap to disable interception of arch LBR MSRs. Reconfigure bitmap on each valid LBR depth write. Signed-off-by: Tu Dinh --- xen/arch/x86/domain.c | 7 + xen/arch/x86/hvm/vmx/vmcs.c | 11 +- xen/arch/x86/hvm/vmx/vmx.c | 203 ++++++++++++++++++++++-- xen/arch/x86/include/asm/hvm/vmx/vmcs.h | 11 ++ xen/arch/x86/include/asm/msr.h | 5 + xen/arch/x86/msr.c | 86 ++++++++++ 6 files changed, 307 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 78a13e6812..8ed35cbbc8 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -2021,6 +2021,13 @@ static void __context_switch(void) if ( cpu_has_xsaves && is_hvm_vcpu(n) ) set_msr_xss(n->arch.msrs->xss.raw); } +#ifdef CONFIG_HVM + /* XRSTORS LBR state behavior depends on MSR_LBR_DEPTH */ + if ( using_vmx() && + is_hvm_vcpu(n) && + n->domain->arch.cpu_policy->feat.arch_lbr ) + wrmsrl(MSR_LBR_DEPTH, n->arch.msrs->lbr_depth.raw); +#endif vcpu_restore_fpu_nonlazy(n, false); nd->arch.ctxt_switch->to(n); } diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 147e998371..a16daad78a 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -203,6 +203,7 @@ static void __init vmx_display_features(void) P(cpu_has_vmx_bus_lock_detection, "Bus Lock Detection"); P(cpu_has_vmx_notify_vm_exiting, "Notify VM Exit"); P(cpu_has_vmx_virt_spec_ctrl, "Virtualize SPEC_CTRL"); + P(cpu_has_vmx_guest_lbr_ctl, "Architectural LBR virtualization"); #undef P if ( !printed ) @@ -448,7 +449,8 @@ static int vmx_init_vmcs_config(bool bsp) min = VM_EXIT_ACK_INTR_ON_EXIT; opt = (VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_LOAD_HOST_PAT | - VM_EXIT_LOAD_HOST_EFER | VM_EXIT_CLEAR_BNDCFGS); + VM_EXIT_LOAD_HOST_EFER | VM_EXIT_CLEAR_BNDCFGS | + VM_EXIT_CLEAR_GUEST_LBR_CTL); min |= VM_EXIT_IA32E_MODE; _vmx_vmexit_control = adjust_vmx_controls( "VMExit Control", min, opt, MSR_IA32_VMX_EXIT_CTLS, &mismatch); @@ -489,7 +491,7 @@ static int vmx_init_vmcs_config(bool bsp) min = 0; opt = (VM_ENTRY_LOAD_GUEST_PAT | VM_ENTRY_LOAD_GUEST_EFER | - VM_ENTRY_LOAD_BNDCFGS); + VM_ENTRY_LOAD_BNDCFGS | VM_ENTRY_LOAD_GUEST_LBR_CTL); _vmx_vmentry_control = adjust_vmx_controls( "VMEntry Control", min, opt, MSR_IA32_VMX_ENTRY_CTLS, &mismatch); @@ -1329,6 +1331,9 @@ static int construct_vmcs(struct vcpu *v) | (paging_mode_hap(d) ? 0 : (1U << X86_EXC_PF)) | (v->arch.fully_eager_fpu ? 0 : (1U << X86_EXC_NM)); + if ( cpu_has_vmx_guest_lbr_ctl ) + __vmwrite(GUEST_LBR_CTL, 0); + if ( cpu_has_vmx_notify_vm_exiting ) __vmwrite(NOTIFY_WINDOW, vm_notify_window); @@ -2087,6 +2092,8 @@ void vmcs_dump_vcpu(struct vcpu *v) vmr32(GUEST_PREEMPTION_TIMER), vmr32(GUEST_SMBASE)); printk("DebugCtl = 0x%016lx DebugExceptions = 0x%016lx\n", vmr(GUEST_IA32_DEBUGCTL), vmr(GUEST_PENDING_DBG_EXCEPTIONS)); + if ( vmentry_ctl & VM_ENTRY_LOAD_GUEST_LBR_CTL ) + printk("LbrCtl = 0x%016lx\n", vmr(GUEST_LBR_CTL)); if ( vmentry_ctl & (VM_ENTRY_LOAD_PERF_GLOBAL_CTRL | VM_ENTRY_LOAD_BNDCFGS) ) printk("PerfGlobCtl = 0x%016lx BndCfgS = 0x%016lx\n", vmr(GUEST_PERF_GLOBAL_CTRL), vmr(GUEST_BNDCFGS)); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 9f1e9d515f..c706f01d79 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -48,6 +48,7 @@ #include #include #include +#include #include static bool __initdata opt_force_ept; @@ -773,6 +774,67 @@ void vmx_update_exception_bitmap(struct vcpu *v) __vmwrite(EXCEPTION_BITMAP, bitmap); } +static void cf_check vmx_set_lbr_depth(struct vcpu *v, + uint32_t depth) +{ + struct cpu_policy *cp = v->domain->arch.cpu_policy; + bool host_lip, guest_lip; + uint32_t i; + + if ( !cp->feat.arch_lbr ) + return; + + ASSERT(depth != 0 && + depth <= NUM_MSR_ARCH_LBR_FROM_TO && + depth % 8 == 0); + ASSERT(cp->basic.lbr_1Ca.supported_depths & ((1u << (depth / 8)) - 1)); + + host_lip = current_cpu_has_lbr_lip; + guest_lip = !!cp->basic.lbr_1Ca.ip_contains_lip; + + if ( v->arch.msrs->lbr_depth.raw == depth && + v->arch.hvm.vmx.last_host_lip == host_lip ) + return; + + if ( host_lip != guest_lip ) + { + for ( i = 0; i < depth; i++ ) + { + vmx_set_msr_intercept(v, MSR_LBR_FROM_IP(i), VMX_MSR_RW); + vmx_set_msr_intercept(v, MSR_LBR_TO_IP(i), VMX_MSR_RW); + } + vmx_set_msr_intercept(v, MSR_IA32_LASTINTFROMIP, VMX_MSR_RW); + vmx_set_msr_intercept(v, MSR_IA32_LASTINTTOIP, VMX_MSR_RW); + } + else + { + for ( i = 0; i < depth; i++ ) + { + vmx_clear_msr_intercept(v, MSR_LBR_FROM_IP(i), VMX_MSR_RW); + vmx_clear_msr_intercept(v, MSR_LBR_TO_IP(i), VMX_MSR_RW); + } + vmx_clear_msr_intercept(v, MSR_IA32_LASTINTFROMIP, VMX_MSR_RW); + vmx_clear_msr_intercept(v, MSR_IA32_LASTINTTOIP, VMX_MSR_RW); + } + + /* MSR_{LBR,LER}_INFO don't need translating */ + for ( i = 0; i < depth; i++ ) + vmx_clear_msr_intercept(v, MSR_LBR_INFO(i), VMX_MSR_RW); + vmx_clear_msr_intercept(v, MSR_LER_INFO, VMX_MSR_RW); + /* MSRs beyond LBR_DEPTH always need #GP */ + for ( i = depth; i < NUM_MSR_ARCH_LBR_FROM_TO; i++ ) + { + vmx_set_msr_intercept(v, MSR_LBR_INFO(i), VMX_MSR_RW); + vmx_set_msr_intercept(v, MSR_LBR_FROM_IP(i), VMX_MSR_RW); + vmx_set_msr_intercept(v, MSR_LBR_TO_IP(i), VMX_MSR_RW); + } + + __vmwrite(XSS_EXIT_BITMAP, host_lip == guest_lip ? 0 : X86_XSS_LBR); + + v->arch.msrs->lbr_depth.raw = depth; + v->arch.hvm.vmx.last_host_lip = host_lip; +} + static void cf_check vmx_cpuid_policy_changed(struct vcpu *v) { const struct cpu_policy *cp = v->domain->arch.cpu_policy; @@ -871,6 +933,16 @@ static void cf_check vmx_cpuid_policy_changed(struct vcpu *v) else vmx_set_msr_intercept(v, MSR_PKRS, VMX_MSR_RW); + if ( cp->feat.arch_lbr && v->arch.msrs->lbr_depth.raw == 0 ) + { + uint32_t max_depth; + + ASSERT(cp->basic.lbr_1Ca.supported_depths > 0); + max_depth = fls(cp->basic.lbr_1Ca.supported_depths) * 8; + + vmx_set_lbr_depth(v, max_depth); + } + out: vmx_vmcs_exit(v); @@ -2635,6 +2707,7 @@ static uint64_t cf_check vmx_get_reg(struct vcpu *v, unsigned int reg) { const struct vcpu *curr = current; struct domain *d = v->domain; + const struct cpu_policy *cp = d->arch.cpu_policy; const struct vcpu_msrs *msrs = v->arch.msrs; uint64_t val = 0; int rc; @@ -2679,6 +2752,48 @@ static uint64_t cf_check vmx_get_reg(struct vcpu *v, unsigned int reg) __vmread(GUEST_BNDCFGS, &val); break; + case MSR_LBR_CTL: + __vmread(GUEST_LBR_CTL, &val); + break; + + case MSR_LBR_DEPTH: + val = v->arch.msrs->lbr_depth.raw; + break; + + case MSR_LER_INFO: + case MSR_LBR_INFO(0)...MSR_LBR_INFO(NUM_MSR_ARCH_LBR_FROM_TO - 1): + if ( v != curr ) + { + val = 0; + break; + } + rdmsrl(reg, val); + break; + + case MSR_IA32_LASTINTFROMIP: + case MSR_IA32_LASTINTTOIP: + case MSR_LBR_FROM_IP(0)...MSR_LBR_FROM_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1): + case MSR_LBR_TO_IP(0)...MSR_LBR_TO_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1): + { + struct segment_register cs; + int mode_64bit; + uint64_t offset; + + if ( v != curr ) + { + val = 0; + break; + } + + mode_64bit = vmx_guest_x86_mode(v) == X86_MODE_64BIT; + hvm_get_segment_register(v, x86_seg_cs, &cs); + offset = x86_get_lbr_cs_offset(cp, mode_64bit, &cs, true); + + rdmsrl(reg, val); + val += offset; + break; + } + default: printk(XENLOG_G_ERR "%s(%pv, 0x%08x) Bad register\n", __func__, v, reg); @@ -2695,6 +2810,7 @@ static void cf_check vmx_set_reg(struct vcpu *v, unsigned int reg, uint64_t val) const struct vcpu *curr = current; struct vcpu_msrs *msrs = v->arch.msrs; struct domain *d = v->domain; + const struct cpu_policy *cp = d->arch.cpu_policy; int rc; /* Logic which doesn't require remote VMCS acquisition. */ @@ -2734,6 +2850,43 @@ static void cf_check vmx_set_reg(struct vcpu *v, unsigned int reg, uint64_t val) __vmwrite(GUEST_BNDCFGS, val); break; + case MSR_LBR_CTL: + __vmwrite(GUEST_LBR_CTL, val); + break; + + case MSR_LBR_DEPTH: + if ( v == curr ) + wrmsrl(MSR_LBR_DEPTH, val); + vmx_set_lbr_depth(v, val); + break; + + case MSR_LER_INFO: + case MSR_LBR_INFO(0)...MSR_LBR_INFO(NUM_MSR_ARCH_LBR_FROM_TO - 1): + if ( v == curr ) + wrmsrl(reg, val); + break; + + case MSR_IA32_LASTINTFROMIP: + case MSR_IA32_LASTINTTOIP: + case MSR_LBR_FROM_IP(0)...MSR_LBR_FROM_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1): + case MSR_LBR_TO_IP(0)...MSR_LBR_TO_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1): + { + struct segment_register cs; + bool mode_64bit; + uint64_t offset; + + if ( v != curr ) + break; + + mode_64bit = vmx_guest_x86_mode(v) == X86_MODE_64BIT; + hvm_get_segment_register(v, x86_seg_cs, &cs); + offset = x86_get_lbr_cs_offset(cp, mode_64bit, &cs, false); + + val += offset; + wrmsrl(reg, val); + break; + } + default: printk(XENLOG_G_ERR "%s(%pv, 0x%08x, 0x%016"PRIx64") Bad register\n", __func__, v, reg, val); @@ -2805,6 +2958,7 @@ static struct hvm_function_table __initdata_cf_clobber vmx_function_table = { .vmtrace_set_option = vmtrace_set_option, .vmtrace_get_option = vmtrace_get_option, .vmtrace_reset = vmtrace_reset, + .set_lbr_depth = vmx_set_lbr_depth, .get_reg = vmx_get_reg, .set_reg = vmx_set_reg, @@ -3997,18 +4151,6 @@ static void vmx_idtv_reinject(unsigned long idtv_info) } } -static void vmx_handle_xsaves(void) -{ - gdprintk(XENLOG_ERR, "xsaves should not cause vmexit\n"); - domain_crash(current->domain); -} - -static void vmx_handle_xrstors(void) -{ - gdprintk(XENLOG_ERR, "xrstors should not cause vmexit\n"); - domain_crash(current->domain); -} - static void vmx_handle_descriptor_access(uint32_t exit_reason) { uint64_t instr_info; @@ -4055,6 +4197,36 @@ static void undo_nmis_unblocked_by_iret(void) guest_info | VMX_INTR_SHADOW_NMI); } +static void vmx_handle_xsaves_xrstors(bool saving) +{ + struct hvm_emulate_ctxt ctxt; + int rc; + + if ( saving ) + hvm_emulate_init_once(&ctxt, x86_insn_is_xsaves, guest_cpu_user_regs()); + else + hvm_emulate_init_once(&ctxt, x86_insn_is_xrstors, guest_cpu_user_regs()); + + switch ( rc = hvm_emulate_one(&ctxt, VIO_no_completion) ) + { + case X86EMUL_UNHANDLEABLE: + hvm_dump_emulation_state(XENLOG_G_WARNING, "XSAVES/XRSTORS", &ctxt, rc); + hvm_inject_hw_exception(X86_EXC_UD, 0); + return; + + case X86EMUL_UNRECOGNIZED: + hvm_dump_emulation_state(XENLOG_G_WARNING, "XSAVES/XRSTORS", &ctxt, rc); + hvm_inject_hw_exception(X86_EXC_UD, X86_EVENT_NO_EC); + break; + + case X86EMUL_EXCEPTION: + hvm_inject_event(&ctxt.ctxt.event); + break; + } + + hvm_emulate_writeback(&ctxt); +} + void asmlinkage vmx_vmexit_handler(struct cpu_user_regs *regs) { unsigned long exit_qualification, exit_reason, idtv_info, intr_info = 0; @@ -4695,11 +4867,11 @@ void asmlinkage vmx_vmexit_handler(struct cpu_user_regs *regs) break; case EXIT_REASON_XSAVES: - vmx_handle_xsaves(); + vmx_handle_xsaves_xrstors(true); break; case EXIT_REASON_XRSTORS: - vmx_handle_xrstors(); + vmx_handle_xsaves_xrstors(false); break; case EXIT_REASON_ACCESS_GDTR_OR_IDTR: @@ -4818,6 +4990,9 @@ bool asmlinkage vmx_vmenter_helper(const struct cpu_user_regs *regs) if ( curr->domain->arch.hvm.pi_ops.vcpu_block ) vmx_pi_do_resume(curr); + /* Update the XSS exiting bitmap in case of vCPU migration. */ + vmx_set_lbr_depth(curr, curr->arch.msrs->lbr_depth.raw); + if ( !cpu_has_vmx_vpid ) goto out; if ( nestedhvm_vcpu_in_guestmode(curr) ) diff --git a/xen/arch/x86/include/asm/hvm/vmx/vmcs.h b/xen/arch/x86/include/asm/hvm/vmx/vmcs.h index 939b87eb50..da7e0b4103 100644 --- a/xen/arch/x86/include/asm/hvm/vmx/vmcs.h +++ b/xen/arch/x86/include/asm/hvm/vmx/vmcs.h @@ -154,6 +154,9 @@ struct vmx_vcpu { /* Are we emulating rather than VMENTERing? */ uint8_t vmx_emulate; + /* If the vCPU last ran on a host CPU with XEN_X86_FEATURE_LBR_LIP */ + bool last_host_lip; + /* For legacy LBR only */ uint8_t lbr_flags; /* Bitmask of segments that we can't safely use in virtual 8086 mode */ @@ -229,6 +232,7 @@ extern u32 vmx_pin_based_exec_control; #define VM_EXIT_LOAD_HOST_EFER 0x00200000 #define VM_EXIT_SAVE_PREEMPT_TIMER 0x00400000 #define VM_EXIT_CLEAR_BNDCFGS 0x00800000 +#define VM_EXIT_CLEAR_GUEST_LBR_CTL 0x04000000 extern u32 vmx_vmexit_control; #define VM_ENTRY_IA32E_MODE 0x00000200 @@ -238,6 +242,7 @@ extern u32 vmx_vmexit_control; #define VM_ENTRY_LOAD_GUEST_PAT 0x00004000 #define VM_ENTRY_LOAD_GUEST_EFER 0x00008000 #define VM_ENTRY_LOAD_BNDCFGS 0x00010000 +#define VM_ENTRY_LOAD_GUEST_LBR_CTL 0x00200000 extern u32 vmx_vmentry_control; #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001U @@ -391,6 +396,10 @@ extern u64 vmx_ept_vpid_cap; #define cpu_has_vmx_notify_vm_exiting \ (IS_ENABLED(CONFIG_INTEL_VMX) && \ vmx_secondary_exec_control & SECONDARY_EXEC_NOTIFY_VM_EXITING) +#define cpu_has_vmx_guest_lbr_ctl \ + (IS_ENABLED(CONFIG_INTEL_VMX) && \ + (vmx_vmexit_control & VM_EXIT_CLEAR_GUEST_LBR_CTL) && \ + (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_LBR_CTL)) #define VMCS_RID_TYPE_MASK 0x80000000U @@ -480,6 +489,8 @@ enum vmcs_field { GUEST_PDPTE0 = 0x0000280a, #define GUEST_PDPTE(n) (GUEST_PDPTE0 + (n) * 2) /* n = 0...3 */ GUEST_BNDCFGS = 0x00002812, + GUEST_RTIT_CTL = 0x00002814, + GUEST_LBR_CTL = 0x00002816, HOST_PAT = 0x00002c00, HOST_EFER = 0x00002c02, HOST_PERF_GLOBAL_CTRL = 0x00002c04, diff --git a/xen/arch/x86/include/asm/msr.h b/xen/arch/x86/include/asm/msr.h index 7b00a4db5d..d7578d8cab 100644 --- a/xen/arch/x86/include/asm/msr.h +++ b/xen/arch/x86/include/asm/msr.h @@ -389,6 +389,11 @@ struct vcpu_msrs uint64_t raw; } xss; + /* 0x000014cf - MSR_LBR_DEPTH */ + struct { + uint64_t raw; + } lbr_depth; + /* * 0xc0000103 - MSR_TSC_AUX * diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c index 68a419ac8e..6c72728f81 100644 --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -193,6 +193,38 @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val) goto gp_fault; goto get_reg; + case MSR_LBR_CTL: + case MSR_LBR_DEPTH: + case MSR_LER_INFO: + if ( !cp->feat.arch_lbr ) + goto gp_fault; + + goto get_reg; + + case MSR_LBR_INFO(0)...MSR_LBR_INFO(NUM_MSR_ARCH_LBR_FROM_TO - 1): + if ( !cp->feat.arch_lbr ) + goto gp_fault; + + if ( msr - MSR_LBR_INFO(0) >= msrs->lbr_depth.raw ) + goto gp_fault; + + goto get_reg; + + case MSR_IA32_LASTINTFROMIP: + case MSR_IA32_LASTINTTOIP: + case MSR_LBR_FROM_IP(0)...MSR_LBR_FROM_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1): + case MSR_LBR_TO_IP(0)...MSR_LBR_TO_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1): + if ( !cp->feat.arch_lbr ) + goto gp_fault; + + if ( (msr >= MSR_LBR_FROM_IP(msrs->lbr_depth.raw) && + msr <= MSR_LBR_FROM_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1)) || + (msr >= MSR_LBR_TO_IP(msrs->lbr_depth.raw) && + msr <= MSR_LBR_TO_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1)) ) + goto gp_fault; + + goto get_reg; + case MSR_IA32_XSS: if ( !cp->xstate.xsaves ) goto gp_fault; @@ -516,6 +548,60 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) } goto set_reg; + + case MSR_LBR_CTL: + if ( !cp->feat.arch_lbr ) + goto gp_fault; + + if ( val & ~LBR_CTL_VALID ) + goto gp_fault; + + goto set_reg; + + case MSR_LBR_DEPTH: + if ( !cp->feat.arch_lbr ) + goto gp_fault; + + if ( val == 0 || + val > NUM_MSR_ARCH_LBR_FROM_TO || + val % 8 != 0 ) + goto gp_fault; + + if ( !(cp->basic.lbr_1Ca.supported_depths & + ((1u << (val / 8)) - 1)) ) + goto gp_fault; + + goto set_reg; + + case MSR_LER_INFO: + if ( !cp->feat.arch_lbr ) + goto gp_fault; + + goto set_reg; + + case MSR_LBR_INFO(0)...MSR_LBR_INFO(NUM_MSR_ARCH_LBR_FROM_TO - 1): + if ( !cp->feat.arch_lbr ) + goto gp_fault; + + if ( msr - MSR_LBR_INFO(0) >= v->arch.msrs->lbr_depth.raw ) + goto gp_fault; + + goto set_reg; + + case MSR_IA32_LASTINTFROMIP: + case MSR_IA32_LASTINTTOIP: + case MSR_LBR_FROM_IP(0)...MSR_LBR_FROM_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1): + case MSR_LBR_TO_IP(0)...MSR_LBR_TO_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1): + if ( !cp->feat.arch_lbr ) + goto gp_fault; + + if ( (msr >= MSR_LBR_FROM_IP(v->arch.msrs->lbr_depth.raw) && + msr <= MSR_LBR_FROM_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1)) || + (msr >= MSR_LBR_TO_IP(v->arch.msrs->lbr_depth.raw) && + msr <= MSR_LBR_TO_IP(NUM_MSR_ARCH_LBR_FROM_TO - 1)) ) + goto gp_fault; + + goto set_reg; #endif /* CONFIG_HVM */ case MSR_IA32_XSS: From patchwork Thu Jan 2 08:45:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tu Dinh X-Patchwork-Id: 13924344 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 D3EF6E7718B for ; Thu, 2 Jan 2025 08:46:14 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.863731.1275102 (Exim 4.92) (envelope-from ) id 1tTGpu-000548-NI; Thu, 02 Jan 2025 08:45:46 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 863731.1275102; Thu, 02 Jan 2025 08:45:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tTGpu-00051D-IA; Thu, 02 Jan 2025 08:45:46 +0000 Received: by outflank-mailman (input) for mailman id 863731; Thu, 02 Jan 2025 08:45:45 +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 1tTGpt-0004rF-LT for xen-devel@lists.xenproject.org; Thu, 02 Jan 2025 08:45:45 +0000 Received: from mail180-43.suw31.mandrillapp.com (mail180-43.suw31.mandrillapp.com [198.2.180.43]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f428e5d7-c8e5-11ef-a0db-8be0dac302b0; Thu, 02 Jan 2025 09:45:44 +0100 (CET) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-43.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4YP0fG01BLzLfHFtk for ; Thu, 2 Jan 2025 08:45:42 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id b25bb21507ab41e49a5a6432f490ffb0; Thu, 02 Jan 2025 08:45:41 +0000 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: f428e5d7-c8e5-11ef-a0db-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1735807542; x=1736068042; bh=hkByZLzlrTXwHXqACXZ3W4ofBw/54TO6ZVkDh0SDWck=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=qRjX6uuvQTFN+E3Sz5ngLDXYHs9Z28eGHZ8DJ70l8b/Qt8hpcemSQzFlptMBR9fR0 OOdXrAD2TEMxMBo4gRjFfs+ZKVVu7Wx6zOjBYE2vNrsvaCug7kirYYyIiJxGOSZVHG kRtgv9YWNVxs2k4CTsZVX/BBgLQw2ph4kk0W0qhqaNtRUs2yOrzQQGHsZt+0y3lwJs ySLAoGn3Yupc20xqxruRxifHCNEPrR2OVu32yYbonSiVYrsQRHydXykHzbb+KNdycg U9wOg6X9T1d4FIDNPUmXV7cF5DVCivj5ZnshQ6Xhm86jPvOjCkfAWM+XUHroF8KH4k CosZhzl/WsRxg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1735807542; x=1736068042; i=ngoc-tu.dinh@vates.tech; bh=hkByZLzlrTXwHXqACXZ3W4ofBw/54TO6ZVkDh0SDWck=; h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID: Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date: Subject:From; b=mNtI0Y832PLwvUSKMU4hCF3CVP7UH5Q/mOWj1qd4RyIGz+HstL1n501TS2eP3hDJK meQau9ifxLlKgfYBYvCSutQNpWetuvvPbi+Mc2ZPWPfudylxlKuq8+iiRTu5Oja0Ln oFYQJVfJ78UhE5WGTfts2scVqA2oh19jEexrfLIjdBBlWx0EjSY/bgMbhBcplp03y1 rD7WachW9uaCtQwuFkTexe4xfF0f48EEcfYH5yCe6i5V/wM3zdmx59EO4CwXxrtQgF TqS7D0/NuE4yis+/0rmcVPdLS2ASWgDgglpxaZTxJ0Wj0Qp+qkNg6HnHCEoiNyggza ACoMbO8oYybmg== From: "Tu Dinh" Subject: =?utf-8?q?=5BRFC_PATCH_v2_10/10=5D_x86/hvm=3A_Enable_XSAVES_LBR_sav?= =?utf-8?q?e/restore?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1735807541149 To: xen-devel@lists.xenproject.org Cc: "Tu Dinh" , "Anthony PERARD" , "Juergen Gross" , "Jan Beulich" , "Andrew Cooper" , " =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= " Message-Id: <20250102084413.102-11-ngoc-tu.dinh@vates.tech> In-Reply-To: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> References: <20250102084413.102-1-ngoc-tu.dinh@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?utf-8?q?Please_forward_a_copy_of_this_message=2C_including?= =?utf-8?q?_all_headers=2C_to_abuse=40mandrill=2Ecom=2E_You_can_also_report_?= =?utf-8?q?abuse_here=3A_https=3A//mandrillapp=2Ecom/contact/abuse=3Fid=3D30?= =?utf-8?q?504962=2Eb25bb21507ab41e49a5a6432f490ffb0?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250102:md Date: Thu, 02 Jan 2025 08:45:41 +0000 MIME-Version: 1.0 Add a new save code type CPU_XSAVES_CODE containing a compressed XSAVES image. Signed-off-by: Tu Dinh --- xen/arch/x86/hvm/hvm.c | 67 +++++++++++++++++++++----- xen/arch/x86/xstate.c | 3 +- xen/include/public/arch-x86/hvm/save.h | 4 +- 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index c7b93c7d91..e5a50d9fca 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -1238,6 +1238,36 @@ static int cf_check hvm_save_cpu_xsave_states( return 0; } +#define HVM_CPU_XSAVES_SIZE(xcr0) (offsetof(struct hvm_hw_cpu_xsave, \ + save_area) + \ + xstate_compressed_size(xcr0)) + +static int cf_check hvm_save_cpu_xsaves_states( + struct vcpu *v, hvm_domain_context_t *h) +{ + struct hvm_hw_cpu_xsave *ctxt; + unsigned int size; + int err; + + if ( !xsave_enabled(v) ) + return 0; /* do nothing */ + + size = HVM_CPU_XSAVES_SIZE(v->arch.xcr0_accum); + err = _hvm_init_entry(h, CPU_XSAVES_CODE, v->vcpu_id, size); + if ( err ) + return err; + + ctxt = (struct hvm_hw_cpu_xsave *)&h->data[h->cur]; + h->cur += size; + ctxt->xfeature_mask = xfeature_mask; + ctxt->xcr0 = v->arch.xcr0; + ctxt->xcr0_accum = v->arch.xcr0_accum; + + memcpy(&ctxt->save_area, v->arch.xsave_area, size); + + return 0; +} + /* * Structure layout conformity checks, documenting correctness of the cast in * the invocation of validate_xstate() below. @@ -1311,6 +1341,10 @@ static int cf_check hvm_load_cpu_xsave_states( ctxt = (struct hvm_hw_cpu_xsave *)&h->data[h->cur]; h->cur += desc->length; + if ( !cpu_has_xsaves && + xsave_area_compressed((const void *)&ctxt->save_area) ) + return -EOPNOTSUPP; + err = validate_xstate(d, ctxt->xcr0, ctxt->xcr0_accum, (const void *)&ctxt->save_area.xsave_hdr); if ( err ) @@ -1322,7 +1356,10 @@ static int cf_check hvm_load_cpu_xsave_states( ctxt->xcr0, ctxt->save_area.xsave_hdr.xstate_bv, err); return err; } - size = HVM_CPU_XSAVE_SIZE(ctxt->xcr0_accum); + if ( xsave_area_compressed((const void *)&ctxt->save_area) ) + size = HVM_CPU_XSAVES_SIZE(ctxt->xcr0_accum); + else + size = HVM_CPU_XSAVE_SIZE(ctxt->xcr0_accum); desc_length = desc->length; if ( desc_length > size ) { @@ -1348,14 +1385,7 @@ static int cf_check hvm_load_cpu_xsave_states( desc_length = size; } - if ( xsave_area_compressed((const void *)&ctxt->save_area) ) - { - printk(XENLOG_G_WARNING - "HVM%d.%u restore: compressed xsave state not supported\n", - d->domain_id, vcpuid); - return -EOPNOTSUPP; - } - else if ( desc_length != size ) + if ( desc_length != size ) { printk(XENLOG_G_WARNING "HVM%d.%u restore mismatch: xsave length %#x != %#x\n", @@ -1367,8 +1397,13 @@ static int cf_check hvm_load_cpu_xsave_states( v->arch.xcr0 = ctxt->xcr0; v->arch.xcr0_accum = ctxt->xcr0_accum; v->arch.nonlazy_xstate_used = ctxt->xcr0_accum & XSTATE_NONLAZY; - compress_xsave_states(v, &ctxt->save_area, - size - offsetof(struct hvm_hw_cpu_xsave, save_area)); + if ( xsave_area_compressed((const void *)&ctxt->save_area) ) + memcpy(v->arch.xsave_area, &ctxt->save_area, + size - offsetof(struct hvm_hw_cpu_xsave, save_area)); + else + compress_xsave_states(v, &ctxt->save_area, + size - offsetof(struct hvm_hw_cpu_xsave, + save_area)); return 0; } @@ -1385,6 +1420,7 @@ static const uint32_t msrs_to_send[] = { MSR_AMD64_DR1_ADDRESS_MASK, MSR_AMD64_DR2_ADDRESS_MASK, MSR_AMD64_DR3_ADDRESS_MASK, + MSR_LBR_DEPTH, }; static int cf_check hvm_save_cpu_msrs(struct vcpu *v, hvm_domain_context_t *h) @@ -1572,6 +1608,15 @@ static int __init cf_check hvm_register_CPU_save_and_restore(void) sizeof(struct hvm_save_descriptor), HVMSR_PER_VCPU); + hvm_register_savevm(CPU_XSAVES_CODE, + "CPU_XSAVES", + hvm_save_cpu_xsaves_states, + NULL, + hvm_load_cpu_xsave_states, + HVM_CPU_XSAVES_SIZE(xfeature_mask) + + sizeof(struct hvm_save_descriptor), + HVMSR_PER_VCPU); + hvm_register_savevm(CPU_MSR_CODE, "CPU_MSR", hvm_save_cpu_msrs, diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index 607bf9c8a5..1c7a39e778 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -946,8 +946,7 @@ int validate_xstate(const struct domain *d, uint64_t xcr0, uint64_t xcr0_accum, !valid_xcr0(xcr0_accum) ) return -EINVAL; - if ( (xcr0_accum & ~xfeature_mask) || - hdr->xcomp_bv ) + if ( xcr0_accum & ~xfeature_mask ) return -EOPNOTSUPP; for ( i = 0; i < ARRAY_SIZE(hdr->reserved); ++i ) diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/arch-x86/hvm/save.h index 7ecacadde1..89651f3dd3 100644 --- a/xen/include/public/arch-x86/hvm/save.h +++ b/xen/include/public/arch-x86/hvm/save.h @@ -624,12 +624,14 @@ struct hvm_msr { #define CPU_MSR_CODE 20 +#define CPU_XSAVES_CODE 21 + /* Range 22 - 34 (inclusive) reserved for Amazon */ /* * Largest type-code in use */ -#define HVM_SAVE_CODE_MAX 20 +#define HVM_SAVE_CODE_MAX 21 #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */