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

[PATCH v1] x86/nestedsvm: remove dead code for shadow-paging L1 hosts


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: chunjie.zhu@xxxxxxxxxx
  • Date: Tue, 20 Oct 2026 11:05:09 +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=Whm9uRPOF4Hbvb1JS/w5hT4zxkjRsYJdS4cbIT+zFDU=; b=F4CItEqE6zx0EXmHn4/y62x/bhPguVO5UEYBYbqfnlotCLA9mk8yPk/ox5qOZBPNVl8R2kDILzIqImLqjtUMGzuCQc663ET5xj4HHONDGzgY3c/EjS5tkITkXf/qcUvsVe02tLVcgm7hhssV2288de6Si6cMlMjm44ZKP/0MinHggbiyRacGfAs69Q5FmKuCUXwDagwALukbqahv6aR+MJXGWR6g8fS8ohejG9odUGLDMpxg8n1lT0XgvQiZ2eC9Bm6TVTOvhlmCbg6XzuKjlhfwxBNWOxlbt1in4pB503k95zjE7HA5GiPXoj3S0HXLgd7OveoPRIBFvzkX8wM9XQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FErW5QHXosfYnH1RgkUSTQ8yOJHFvCMqPjtG6UZiyB3RFXw6LOW9V9q7++JfVMVIoopwHiSN8Z6iunFA2U400u9VjtMbdEEignvEML/q1vWnS9sgui7m5lJIfgg9il4vlI/PSssLs4h98YVLX3gC8fYX52V1iB5KNmbFqvIuPCoWiUPvz2ZXa3dHoxrFtM9H7tvKuvwoLBAZyd9cdO3L9C+64ulrXtqMWBWTn/AUJK5L+3hxl04/IJ9fnhIrR/8luTJ1jWI9zKMRJQXR4O7lqXCQCAPtN1i85okVVP1jbGL/mFR7W8brf7cQ/4nC4/MxEVGKr38Pt9iP/dbQYgESXA==
  • 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: jbeulich@xxxxxxxx, andrew.cooper3@xxxxxxxxxx, roger@xxxxxxxxxxxxxx, jason.andryuk@xxxxxxx, teddy.astie@xxxxxxxxxx, Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
  • Delivery-date: Tue, 20 Oct 2026 03:05:33 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

From: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>

Nested virtualization is only permitted together with HAP:
sanitise_domain_config() rejects XEN_DOMCTL_CDF_nested_virt without
XEN_DOMCTL_CDF_hap.  The L1 domain therefore cannot be in shadow paging
mode while nested virt is enabled, and paging_mode_shadow(v->domain) is
always false in the nested SVM code.

nsvm_vcpu_hostrestore(), nsvm_vmcb_prepare4vmrun(),
nsvm_vmcb_prepare4vmexit() and nestedsvm_check_intercepts() still carry
incomplete, never-executed handling for the "host shadow paging + guest
shadow paging" case.  Drop it, and guard the remaining branch with
BUG_ON(paging_mode_shadow(v->domain)) to document the invariant.

In nestedsvm_check_intercepts()'s #PF handling, test
nestedhvm_paging_mode_hap() first, so the reachable "host nested paging +
guest shadow paging" case returns NESTEDHVM_VMEXIT_INJECT directly.

Also drop the now always-true paging_mode_hap() check from
svm_nested_features_on_efer_update(), and the stale "shadow-on-shadow"
TODO in paging_update_nestedmode().

No functional change.

Signed-off-by: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
---
 xen/arch/x86/hvm/svm/nestedsvm.c | 65 +++++++++++---------------------
 xen/arch/x86/mm/paging.c         |  1 -
 2 files changed, 22 insertions(+), 44 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index dc2b6a42534a..748c821d40f8 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -304,21 +304,12 @@ static int nsvm_vcpu_hostrestore(struct vcpu *v, struct 
cpu_user_regs *regs)
         /* host nested paging + guest nested paging. */
         /* hvm_set_cr3() below sets v->arch.hvm.guest_cr[3] for us. */
     }
-    else if ( paging_mode_hap(v->domain) )
-    {
-        /* host nested paging + guest shadow paging. */
-        /* hvm_set_cr3() below sets v->arch.hvm.guest_cr[3] for us. */
-    }
     else
     {
-        /* host shadow paging + guest shadow paging. */
-
-        /* Reset MMU context  -- XXX (hostrestore) not yet working*/
-        if ( !pagetable_is_null(v->arch.guest_table) )
-            put_page(pagetable_get_page(v->arch.guest_table));
-        v->arch.guest_table = pagetable_null();
-        /* hvm_set_cr3() below sets v->arch.hvm.guest_cr[3] for us. */
+        /* host shadow paging + guest shadow paging cannot happen */
+        BUG_ON(paging_mode_shadow(v->domain));
     }
+
     rc = hvm_set_cr3(n1vmcb->_cr3, false, true);
     if ( rc == X86EMUL_EXCEPTION )
         hvm_inject_hw_exception(X86_EXC_GP, 0);
@@ -580,8 +571,11 @@ static int nsvm_vmcb_prepare4vmrun(struct vcpu *v, struct 
cpu_user_regs *regs)
         if ( rc != X86EMUL_OKAY )
             gdprintk(XENLOG_ERR, "hvm_set_cr3 failed, rc: %u\n", rc);
     }
-    else if ( paging_mode_hap(v->domain) )
+    else
     {
+        /* host shadow paging + guest shadow paging cannot happen */
+        BUG_ON(paging_mode_shadow(v->domain));
+
         /* host nested paging + guest shadow paging. */
         vmcb_set_np(n2vmcb, true);
         /* Keep h_cr3 as it is. */
@@ -596,16 +590,6 @@ static int nsvm_vmcb_prepare4vmrun(struct vcpu *v, struct 
cpu_user_regs *regs)
         if ( rc != X86EMUL_OKAY )
             gdprintk(XENLOG_ERR, "hvm_set_cr3 failed, rc: %u\n", rc);
     }
-    else
-    {
-        /* host shadow paging + guest shadow paging. */
-        vmcb_set_np(n2vmcb, false);
-        n2vmcb->_h_cr3 = 0x0;
-
-        /* TODO: Once shadow-shadow paging is in place come back to here
-         * and set host_vmcb->_cr3 to the shadowed shadow table.
-         */
-    }
 
     /* DRn */
     if ( !clean.dr )
@@ -1088,8 +1072,11 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct 
cpu_user_regs *regs)
          * unshadowed guest h_cr3 is kept in ns_vmcb->h_cr3,
          * hence we keep the ns_vmcb->h_cr3 value. */
     }
-    else if ( paging_mode_hap(v->domain) )
+    else
     {
+        /* host shadow paging + guest shadow paging cannot happen */
+        BUG_ON(paging_mode_shadow(v->domain));
+
         /* host nested paging + guest shadow paging. */
         vmcb_set_np(ns_vmcb, false);
         /* Throw h_cr3 away. Guest is not allowed to set it or
@@ -1099,15 +1086,6 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct 
cpu_user_regs *regs)
          * by restoring cached intercepts). */
         ns_vmcb->_cr3 = n2vmcb->_cr3;
     }
-    else
-    {
-        /* host shadow paging + guest shadow paging. */
-        vmcb_set_np(ns_vmcb, false);
-        ns_vmcb->_h_cr3 = 0x0;
-        /* The vmcb->_cr3 is the shadowed cr3. The original
-         * unshadowed guest cr3 is kept in ns_vmcb->_cr3,
-         * hence we keep the ns_vmcb->_cr3 value. */
-    }
 
     /* LBR virtualization - keep lbr control as is */
 
@@ -1320,16 +1298,16 @@ nestedsvm_check_intercepts(struct vcpu *v, struct 
cpu_user_regs *regs,
             /* host nested paging + guest nested paging */
             return NESTEDHVM_VMEXIT_HOST;
         }
-        if ( paging_mode_hap(v->domain) )
+        else
         {
+            /* host shadow paging + guest shadow paging cannot happen */
+            BUG_ON(paging_mode_shadow(v->domain));
+
             if ( is_intercepted )
                 return NESTEDHVM_VMEXIT_FATALERROR;
             /* host nested paging + guest shadow paging */
             return NESTEDHVM_VMEXIT_HOST;
         }
-        /* host shadow paging + guest shadow paging */
-        /* Can this happen? */
-        BUG();
 
     case VMEXIT_EXCEPTION_PF:
         if ( nestedhvm_paging_mode_hap(v) )
@@ -1341,12 +1319,14 @@ nestedsvm_check_intercepts(struct vcpu *v, struct 
cpu_user_regs *regs,
             /* l2 guest intercepts #PF unnecessarily */
             return NESTEDHVM_VMEXIT_INJECT;
         }
-        if ( !paging_mode_hap(v->domain) )
-            /* host shadow paging + guest shadow paging */
-            return NESTEDHVM_VMEXIT_HOST;
+        else
+        {
+            /* host shadow paging + guest shadow paging cannot happen */
+            BUG_ON(!paging_mode_hap(v->domain));
 
-        /* host nested paging + guest shadow paging */
-        return NESTEDHVM_VMEXIT_INJECT;
+            /* host nested paging + guest shadow paging */
+            return NESTEDHVM_VMEXIT_INJECT;
+        }
     case VMEXIT_VMMCALL:
         /* Always let the guest handle VMMCALL/VMCALL */
         return NESTEDHVM_VMEXIT_INJECT;
@@ -1619,7 +1599,6 @@ void svm_nested_features_on_efer_update(struct vcpu *v)
     if ( nsvm_efer_svm_enabled(v) )
     {
         if ( !vmcb->virt_ext.fields.vloadsave_enable &&
-             paging_mode_hap(v->domain) &&
              cpu_has_svm_vloadsave )
         {
             vmcb->virt_ext.fields.vloadsave_enable = 1;
diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c
index 65455a686787..277d84fb4cb8 100644
--- a/xen/arch/x86/mm/paging.c
+++ b/xen/arch/x86/mm/paging.c
@@ -924,7 +924,6 @@ void paging_update_nestedmode(struct vcpu *v)
         /* nested-on-nested */
         v->arch.paging.nestedmode = hap_paging_get_mode(v);
     else
-        /* TODO: shadow-on-shadow */
         v->arch.paging.nestedmode = NULL;
     hvm_asid_flush_vcpu(v);
 }
-- 
2.34.1




 


Rackspace

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