From nobody Fri May 17 08:39:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1708015692; cv=none; d=zohomail.com; s=zohoarc; b=CLdLu2mflbM9X+ECKeiYHp249o/edzH8uLYpOYzIZpgvT5H/z3ijX1CJqFkOvYKXBJzZyft1OIBFEEl5vMpvFgmzIFIHfKzt5iamNtGqpnesWbAdSILajerLq8j1z77a/LHShSg05c0hyqx7a75Aac7Owt2GtRvFhaHGeJnd97I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1708015692; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=xSzGKUbvTBsdZuAtSzwneLv26whzlKaeewJgB2jp/94=; b=WYQory1fmgh89hKVmh7Sf2JkNCEhsDLDT+7Nwz6rqaeqBqhm20XwtyHtvYZwUQ6wdM6aIgv5nxTIbdOy+SkfOpPp/1H29xoCWWbllp+GttetdU5N48DlsAQHWHtjK3D11h36vaJP4lTqoi+Nu2krZkni4i9w+uua8zRN7ejVdRg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1708015692366514.6338168804547; Thu, 15 Feb 2024 08:48:12 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.681949.1060956 (Exim 4.92) (envelope-from ) id 1raetu-0004SF-RY; Thu, 15 Feb 2024 16:47:54 +0000 Received: by outflank-mailman (output) from mailman id 681949.1060956; Thu, 15 Feb 2024 16:47:54 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1raetu-0004S8-OW; Thu, 15 Feb 2024 16:47:54 +0000 Received: by outflank-mailman (input) for mailman id 681949; Thu, 15 Feb 2024 16:47:53 +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 1raett-0004Rj-3z for xen-devel@lists.xenproject.org; Thu, 15 Feb 2024 16:47:53 +0000 Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [2a00:1450:4864:20::233]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f49632b7-cc21-11ee-98f5-efadbce2ee36; Thu, 15 Feb 2024 17:47:50 +0100 (CET) Received: by mail-lj1-x233.google.com with SMTP id 38308e7fff4ca-2d180d6bd32so14188001fa.1 for ; Thu, 15 Feb 2024 08:47:51 -0800 (PST) Received: from localhost ([213.195.118.74]) by smtp.gmail.com with ESMTPSA id bg38-20020a05600c3ca600b0040f0219c371sm2638382wmb.19.2024.02.15.08.47.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Feb 2024 08:47:49 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version 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: f49632b7-cc21-11ee-98f5-efadbce2ee36 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1708015670; x=1708620470; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=xSzGKUbvTBsdZuAtSzwneLv26whzlKaeewJgB2jp/94=; b=hrHcT5XPoMvA3u5OKPUn4l3w3JbwCgr63zEDWE8Uw5l3kFvNkoNX+oDxefefWN7Q/c hZ/4L7wzhiAWmRo94DYaZ12mRqWuWU7nu7WasyPXVccyhTtv81oZdXrATKBJ4LHtC4ak 7qMVIX7SSrUw1PwWMYM/yDJe/OZ6Qrk31L0ro= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708015670; x=1708620470; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=xSzGKUbvTBsdZuAtSzwneLv26whzlKaeewJgB2jp/94=; b=WRl70vYutmck7Y0mJIxB4iPTqa2sRGdwvx4N8P1fIv5+IsmnVTMDZBYpnPwcsBdBGw 2H5YIq0qVLhg+GB+NxVEOcg2nCwugJZfliWbNdGmCT7v6edkukNMgpQOpm/CupiKPuEh m4n80NkJdKlTrSUP0DxwS2GxzlOnkWLShEEcKsuHxUFeDhgI4smUpFsf4AZr2pd4Nwgk fVyLgMfDndjgXV5CswVALFcTk6IwCZl5EQHXREWOZ9B/ZsP8+JMzwotZeD7zDOC9Czoh ZIhL1VKsWYtsgYQ+9G63IMPHkhSJpaQZAeQovUOFf400QD5tXdVhQOG1l0ZyCDp12OWI Jvqg== X-Gm-Message-State: AOJu0Yy2nY1wwfKiUrVVGWdf/UY+J21awnEyZnhxiOL9kBGXaGkBosNK M1D4VIgmv6lgoxVnnvLpbX17tffrSHI0yLrVLDEQnP9Bn5xONU+xTjby0ugixpvxR3DwnXLF9ti Z X-Google-Smtp-Source: AGHT+IE3hBMqk8WEqty7E9FUs9rDel5zITU7RK4j3j9/wvow2YcUTc4U6xj9B59iHnWJuA31EWt+Pw== X-Received: by 2002:a05:651c:1a0c:b0:2d2:a9d:e315 with SMTP id by12-20020a05651c1a0c00b002d20a9de315mr1760900ljb.52.1708015669770; Thu, 15 Feb 2024 08:47:49 -0800 (PST) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Jun Nakajima , Kevin Tian , Jan Beulich , Andrew Cooper , Wei Liu Subject: [PATCH v3] x86/vmx: add support for virtualize SPEC_CTRL Date: Thu, 15 Feb 2024 17:46:53 +0100 Message-ID: <20240215164653.27210-1-roger.pau@citrix.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1708015694824100001 The feature is defined in the tertiary exec control, and is available start= ing from Sapphire Rapids and Alder Lake CPUs. When enabled, two extra VMCS fields are used: SPEC_CTRL mask and shadow. B= its set in mask are not allowed to be toggled by the guest (either set or clear) and the value in the shadow field is the value the guest expects to be in t= he SPEC_CTRL register. By using it the hypervisor can force the value of SPEC_CTRL bits behind the guest back without having to trap all accesses to SPEC_CTRL, note that no b= its are forced into the guest as part of this patch. It also allows getting ri= d of SPEC_CTRL in the guest MSR load list, since the value in the shadow field w= ill be loaded by the hardware on vmentry. Signed-off-by: Roger Pau Monn=C3=A9 Reviewed-by: Jan Beulich --- Changes since v2: - Adjust comments. - Unconditionally set SPEC_CTRL_MASK in the VMCS if present. Changes since v1: - Expand commit message and code comments. - Prefix the output of the VMCS dump with '0x'. --- xen/arch/x86/hvm/vmx/vmcs.c | 10 +++++- xen/arch/x86/hvm/vmx/vmx.c | 41 ++++++++++++++++++++----- xen/arch/x86/include/asm/hvm/vmx/vmcs.h | 5 +++ xen/arch/x86/include/asm/msr.h | 9 ++++-- 4 files changed, 55 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 9e016634ab5c..1d1e4a8fdd03 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -202,6 +202,7 @@ static void __init vmx_display_features(void) P(cpu_has_vmx_tsc_scaling, "TSC Scaling"); 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"); #undef P =20 if ( !printed ) @@ -365,7 +366,7 @@ static int vmx_init_vmcs_config(bool bsp) =20 if ( _vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_TERTIARY_CONTROL= S ) { - uint64_t opt =3D 0; + uint64_t opt =3D TERTIARY_EXEC_VIRT_SPEC_CTRL; =20 _vmx_tertiary_exec_control =3D adjust_vmx_controls2( "Tertiary Exec Control", 0, opt, @@ -1378,6 +1379,10 @@ static int construct_vmcs(struct vcpu *v) rc =3D vmx_add_msr(v, MSR_PRED_CMD, PRED_CMD_IBPB, VMX_MSR_HOST); =20 + /* Set any bits we don't allow toggling in the mask field. */ + if ( cpu_has_vmx_virt_spec_ctrl ) + __vmwrite(SPEC_CTRL_MASK, v->arch.msrs->spec_ctrl.raw); + out: vmx_vmcs_exit(v); =20 @@ -2086,6 +2091,9 @@ void vmcs_dump_vcpu(struct vcpu *v) if ( v->arch.hvm.vmx.secondary_exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY ) printk("InterruptStatus =3D %04x\n", vmr16(GUEST_INTR_STATUS)); + if ( cpu_has_vmx_virt_spec_ctrl ) + printk("SPEC_CTRL mask =3D 0x%016lx shadow =3D 0x%016lx\n", + vmr(SPEC_CTRL_MASK), vmr(SPEC_CTRL_SHADOW)); =20 printk("*** Host State ***\n"); printk("RIP =3D 0x%016lx (%ps) RSP =3D 0x%016lx\n", diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 48376cc32751..4ce248fe1276 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -823,18 +823,29 @@ static void cf_check vmx_cpuid_policy_changed(struct = vcpu *v) { vmx_clear_msr_intercept(v, MSR_SPEC_CTRL, VMX_MSR_RW); =20 - rc =3D vmx_add_guest_msr(v, MSR_SPEC_CTRL, 0); - if ( rc ) - goto out; + if ( !cpu_has_vmx_virt_spec_ctrl ) + { + rc =3D vmx_add_guest_msr(v, MSR_SPEC_CTRL, 0); + if ( rc ) + goto out; + } } else { vmx_set_msr_intercept(v, MSR_SPEC_CTRL, VMX_MSR_RW); =20 - rc =3D vmx_del_msr(v, MSR_SPEC_CTRL, VMX_MSR_GUEST); - if ( rc && rc !=3D -ESRCH ) - goto out; - rc =3D 0; /* Tolerate -ESRCH */ + /* + * NB: there's no need to clear the virtualize SPEC_CTRL control, = as + * the MSR intercept takes precedence. The SPEC_CTRL shadow and m= ask + * VMCS fields don't take effect if the intercept is set. + */ + if ( !cpu_has_vmx_virt_spec_ctrl ) + { + rc =3D vmx_del_msr(v, MSR_SPEC_CTRL, VMX_MSR_GUEST); + if ( rc && rc !=3D -ESRCH ) + goto out; + rc =3D 0; /* Tolerate -ESRCH */ + } } =20 /* MSR_PRED_CMD is safe to pass through if the guest knows about it. */ @@ -2629,6 +2640,9 @@ static uint64_t cf_check vmx_get_reg(struct vcpu *v, = unsigned int reg) switch ( reg ) { case MSR_SPEC_CTRL: + if ( cpu_has_vmx_virt_spec_ctrl ) + /* Requires remote VMCS loaded - fetched below. */ + break; rc =3D vmx_read_guest_msr(v, reg, &val); if ( rc ) { @@ -2652,6 +2666,11 @@ static uint64_t cf_check vmx_get_reg(struct vcpu *v,= unsigned int reg) vmx_vmcs_enter(v); switch ( reg ) { + case MSR_SPEC_CTRL: + ASSERT(cpu_has_vmx_virt_spec_ctrl); + __vmread(SPEC_CTRL_SHADOW, &val); + break; + case MSR_IA32_BNDCFGS: __vmread(GUEST_BNDCFGS, &val); break; @@ -2678,6 +2697,9 @@ static void cf_check vmx_set_reg(struct vcpu *v, unsi= gned int reg, uint64_t val) switch ( reg ) { case MSR_SPEC_CTRL: + if ( cpu_has_vmx_virt_spec_ctrl ) + /* Requires remote VMCS loaded - set below. */ + break; rc =3D vmx_write_guest_msr(v, reg, val); if ( rc ) { @@ -2698,6 +2720,11 @@ static void cf_check vmx_set_reg(struct vcpu *v, uns= igned int reg, uint64_t val) vmx_vmcs_enter(v); switch ( reg ) { + case MSR_SPEC_CTRL: + ASSERT(cpu_has_vmx_virt_spec_ctrl); + __vmwrite(SPEC_CTRL_SHADOW, val); + break; + case MSR_IA32_BNDCFGS: __vmwrite(GUEST_BNDCFGS, val); break; diff --git a/xen/arch/x86/include/asm/hvm/vmx/vmcs.h b/xen/arch/x86/include= /asm/hvm/vmx/vmcs.h index a7dd2eeffcad..58140af69153 100644 --- a/xen/arch/x86/include/asm/hvm/vmx/vmcs.h +++ b/xen/arch/x86/include/asm/hvm/vmx/vmcs.h @@ -270,6 +270,9 @@ extern u32 vmx_secondary_exec_control; #define TERTIARY_EXEC_VIRT_SPEC_CTRL BIT(7, UL) extern uint64_t vmx_tertiary_exec_control; =20 +#define cpu_has_vmx_virt_spec_ctrl \ + (vmx_tertiary_exec_control & TERTIARY_EXEC_VIRT_SPEC_CTRL) + #define VMX_EPT_EXEC_ONLY_SUPPORTED 0x00000001 #define VMX_EPT_WALK_LENGTH_4_SUPPORTED 0x00000040 #define VMX_EPT_MEMORY_TYPE_UC 0x00000100 @@ -436,6 +439,8 @@ enum vmcs_field { XSS_EXIT_BITMAP =3D 0x0000202c, TSC_MULTIPLIER =3D 0x00002032, TERTIARY_VM_EXEC_CONTROL =3D 0x00002034, + SPEC_CTRL_MASK =3D 0x0000204a, + SPEC_CTRL_SHADOW =3D 0x0000204c, GUEST_PHYSICAL_ADDRESS =3D 0x00002400, VMCS_LINK_POINTER =3D 0x00002800, GUEST_IA32_DEBUGCTL =3D 0x00002802, diff --git a/xen/arch/x86/include/asm/msr.h b/xen/arch/x86/include/asm/msr.h index 1d8ea9f26faa..eed7b36cd992 100644 --- a/xen/arch/x86/include/asm/msr.h +++ b/xen/arch/x86/include/asm/msr.h @@ -302,8 +302,13 @@ struct vcpu_msrs * For PV guests, this holds the guest kernel value. It is accessed on * every entry/exit path. * - * For VT-x guests, the guest value is held in the MSR guest load/save - * list. + * For VT-x guests, the guest value is held in the MSR guest load/save= list + * if there's no support for virtualized SPEC_CTRL. If virtualized + * SPEC_CTRL is enabled the value here signals which bits in SPEC_CTRL= the + * guest is not able to modify. Note that the value for those bits us= ed in + * Xen context is also used in the guest context. Setting a bit here + * doesn't force such bit to set in the guest context unless also set = in + * Xen selection of SPEC_CTRL. * * For SVM, the guest value lives in the VMCB, and hardware saves/rest= ores * the host value automatically. However, guests run with the OR of t= he --=20 2.43.0