[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 7/7] x86/vmx: Fix nested VPID handling


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: chunjie.zhu@xxxxxxxxxx
  • Date: Thu, 29 Oct 2026 14:26:59 +0800
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=IZmCapoCbbC98HQoeR/WondHb4MXNQh7OP39+AjyYYE=; b=gEGAmQ9MCvGJCtlL8POtXL/J7bXw272zmKoZx4RZ/BXGp9WebYgzFP4tfhMJQE/Au5T9yI2LA2mzsrRNqqhfJLfqj7xyZo32waHTaqAI/hFWJsLGVGEz6bfCFhd2+HA5N4GBpU+DxIvs5QBSdK3kpA0sd6IhF3hSBM2AprmgvE5vfZfVhEbENPP0kuuvbidgP+fkMEd1/doBESHdAmLVc3luRs4WD6/yD7CWWF5uHjd5LnwLil1z96LmRzR/TlcU1uiYhP0aZFNDenyA4i/LOAt9D6QM9MGl6FTIO3LtSL/pWdww7dBzo+HohxrMkOvfh1F9OxBTxSioo1NG+dCtcw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=GftH9fY4Av1SSvC8NJr2nvdtWv8Y4yVwo9C+S8Eou+aR5aPDeIxQUAXQ3hXhoui8W+AbM7sg55sMr2u/UYDEI7X8VM5nqcidarD5t3IOOT/ECtiafUhqspmiB8N4MsgTCWXLvCvwgVbjkpeIW8Rh8GHAn5yXK78iJsUsvp0j7zfmJllqQDfPQmrtTgY9RY6njqM9fecOEZlVlgF14qOG4GaQd5GhR4ZNMX4WEFKUZTvDpOEociBkTp6reTXTenkby75smRJtks5aLzvL1QmbLeoEffc/dDN7IGVzSlNQuCZnsNfNnq3YfD7vHUmMd5yfUcuZMiMMx+NfHRpTRj8uAg==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-Id:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: mx.microsoft.com 1; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: andrew.cooper3@xxxxxxxxxx, anthony.perard@xxxxxxxxxx, michal.orzel@xxxxxxx, jbeulich@xxxxxxxx, julien@xxxxxxx, roger@xxxxxxxxxxxxxx, sstabellini@xxxxxxxxxx, dpsmith@xxxxxxxxxxxxxxxxxxxx, Stephen.Cheng@xxxxxxxxxx, Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
  • Delivery-date: Thu, 29 Oct 2026 06:28:53 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

From: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>

Some nested VPID problems:

* nept_get_ept_vpid_cap() ORed NVPID_CAP_BITS into the low half of
  IA32_VMX_EPT_VPID_CAP.  The VPID capability bits (INVVPID support
  and types) live in bits 32 and up, so the low-half write advertised
  unrelated EPT capabilities to L1 and never the intended INVVPID ones.
  Shift them into place.

* virtual_vmentry() only tracked the L2 VPID when L1 enabled VPID.
  When L1 does not use VPID, all of L2's linear mappings are tagged
  with VPID 0 and must be invalidated on every virtual VM entry, so
  flush the n2asid in that case as well.

* vmx_vmenter_helper() jumped over the whole ASID/EPT invalidation
  block when the CPU lacks VPID, which also skipped the EPT
  invalidation that has nothing to do with VPID.  Skip only the VPID
  part.

* Nested virt only can be enabled on any HAP-capable hardware.

Signed-off-by: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
---
 xen/arch/x86/hvm/vmx/vmx.c       |  4 ++--
 xen/arch/x86/hvm/vmx/vvmx.c      | 11 ++++++-----
 xen/arch/x86/mm/hap/nested_ept.c |  2 +-
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 3c7374a9ff42..00fe2ada4f86 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -4942,7 +4942,7 @@ bool asmlinkage vmx_vmenter_helper(const struct 
cpu_user_regs *regs)
         vmx_pi_do_resume(curr);
 
     if ( !cpu_has_vmx_vpid )
-        goto out;
+        goto skip_vpid;
     if ( nestedhvm_vcpu_in_guestmode(curr) )
         p_asid = &vcpu_nestedhvm(curr).nv_n2asid;
     else
@@ -4974,6 +4974,7 @@ bool asmlinkage vmx_vmenter_helper(const struct 
cpu_user_regs *regs)
     if ( unlikely(need_flush) )
         vpid_sync_all();
 
+ skip_vpid:
     if ( !paging_mode_shadow(curr->domain) )
     {
         struct ept_data *ept = &p2m_get_hostp2m(currd)->ept;
@@ -5016,7 +5017,6 @@ bool asmlinkage vmx_vmenter_helper(const struct 
cpu_user_regs *regs)
                      inv == 1 ? single->eptp          : 0);
     }
 
- out:
     if ( unlikely(curr->arch.hvm.vmx.lbr_flags & LBR_FIXUP_MASK) )
         lbr_fixup();
 
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index e37f59bea7ce..8b1efed8efa9 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -1264,12 +1264,14 @@ static void virtual_vmentry(struct cpu_user_regs *regs)
         __vmwrite(EPT_POINTER, get_host_eptp(v));
 
     /* nested VPID support! */
-    if ( cpu_has_vmx_vpid && nvmx_vpid_enabled(v) )
+    if ( cpu_has_vmx_vpid )
     {
         struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
-        uint32_t new_vpid = get_vvmcs(v, VIRTUAL_PROCESSOR_ID);
+        uint32_t new_vpid = nvmx_vpid_enabled(v) ?
+                            get_vvmcs(v, VIRTUAL_PROCESSOR_ID) : 0;
 
-        if ( nvmx->guest_vpid != new_vpid )
+        /* Without VPID, every virtual VM entry invalidates linear mappings. */
+        if ( !new_vpid || nvmx->guest_vpid != new_vpid )
         {
             hvm_asid_flush_vcpu_asid(&vcpu_nestedhvm(v).nv_n2asid);
             nvmx->guest_vpid = new_vpid;
@@ -2872,9 +2874,8 @@ void nvmx_set_cr_read_shadow(struct vcpu *v, unsigned int 
cr)
 
 void __init start_nested_vmx(struct hvm_function_table *hvm_function_table)
 {
-    /* TODO: Require hardware support before enabling nested virt */
     hvm_function_table->caps.nested_virt =
-        hvm_function_table->caps.hap;
+        hvm_function_table->caps.hap && cpu_has_vmx_vpid;
 }
 
 /*
diff --git a/xen/arch/x86/mm/hap/nested_ept.c b/xen/arch/x86/mm/hap/nested_ept.c
index e116d8254824..abae483713d3 100644
--- a/xen/arch/x86/mm/hap/nested_ept.c
+++ b/xen/arch/x86/mm/hap/nested_ept.c
@@ -101,7 +101,7 @@ uint64_t nept_get_ept_vpid_cap(void)
     if ( !cpu_has_vmx_ept_exec_only_supported )
         caps &= ~VMX_EPT_EXEC_ONLY_SUPPORTED;
     if ( cpu_has_vmx_vpid )
-        caps |= NVPID_CAP_BITS;
+        caps |= (uint64_t)NVPID_CAP_BITS << 32;
 
     return caps;
 }
-- 
2.34.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.