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

[PATCH v1 1/5] x86/nestedsvm: update vmrun without pending or deferred flag


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: chunjie.zhu@xxxxxxxxxx
  • Date: Wed, 23 Sep 2026 17:20:41 +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=NJv1vhwGLQHHcsMb5ZEwN2EqsKM7E/Z918v8aaivmyo=; b=jCo/KppaYkWkB41GNMMQwWJnNTKiwvT3MCxZY7AGTmlpMY0B7drI2qcDNtDSf1JdB8tz4xHE/Y4eRbA7ePClAzivnQT3qGfIheKi7JsW/YKvZ6xnInbj2nnhEq2wstcaynySxyk4JMcGNWMDto04xqt2idVlN63tWm8lGjZRFoMbmKquuCvthHnY0pi/zRcV1Xya1nSbKaGAmKsq9NCAzwlvYBnlB6tpanaUOOwT2gQQkk9JJ8hARPq+xk82yFUylSxAv8bO2E8lJJGj8FOX4M2RhsazaJbSrTKsfaYOePCZLIrG2lAUYjsGfjo52ukgVvmmMPhkkGjucE4M5wy/Pg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=S39SDGmxQNfwCfkqBzSUJakOgaha7dWJ+R9dFHD+aUJmI0HrMoKtVWs+yYUugIeCPrlZSJBtmIRfttVEhpOl3sFJLkNHBjohuAl3M25kJKhQU128Y08am4BDWcIofHU4XN3vOn96aqDs6QL43iS3PKLprUBs6bDdJ1R0VKbx+j7xd0FTSBq/oJ75zuesLlxWOIvBHDdWUqRXnQ+xt9ynq5ebGWD6J5uqnuxOB79N5uZn71gv3EfpNZZFzpxMXbRnV399YPWty0SA6gqmQKVQAjzy6BivLTbtJk2/vuJ2iOQaierA59W1Duve/SrPaaVeqE730JOj7XTL9gNy6Wn1cw==
  • 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: 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: Wed, 23 Sep 2026 09:21:16 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

From: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>

Signed-off-by: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
---
 xen/arch/x86/hvm/svm/entry.S      | 48 +++++++++++++++++++++++--------
 xen/arch/x86/hvm/svm/nestedhvm.h  |  1 +
 xen/arch/x86/hvm/svm/nestedsvm.c  | 31 +++++++++++++++++++-
 xen/arch/x86/hvm/svm/svm.c        | 11 +++++--
 xen/arch/x86/x86_64/asm-offsets.c |  1 +
 5 files changed, 77 insertions(+), 15 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/entry.S b/xen/arch/x86/hvm/svm/entry.S
index d9613a2a8fed..59d865635fd5 100644
--- a/xen/arch/x86/hvm/svm/entry.S
+++ b/xen/arch/x86/hvm/svm/entry.S
@@ -28,31 +28,51 @@ FUNC(svm_asm_do_resume)
         GET_CURRENT(bx)
 .Lsvm_do_resume:
         call svm_intr_assist
-        call nsvm_vcpu_switch
-        ASSERT_NOT_IN_ATOMIC
 
-        mov  VCPU_processor(%rbx),%eax
-        lea  irq_stat+IRQSTAT_softirq_pending(%rip),%rdx
+        /*
+         * The nested p2m repair below may need to take nestedp2m_lock and
+         * issue synchronous cross-CPU TLB flush IPIs, doing this with
+         * interrupts disabled can deadlock.
+         */
         xor  %ecx,%ecx
-        shl  $IRQSTAT_shift,%eax
-        cli
-        cmp  %ecx,(%rdx,%rax,1)
-        jne  .Lsvm_process_softirqs
-
         cmp  %cl,VCPU_nsvm_hap_enabled(%rbx)
 UNLIKELY_START(ne, nsvm_hap)
+        cmpb $0,VCPU_nhvm_guestmode(%rbx)
+        UNLIKELY_DONE(z, nsvm_hap)
+        cmpb $0,VCPU_nhvm_stale_np2m(%rbx)
+        jne  .Lsvm_update_nestedp2m
         cmp  %rcx,VCPU_nhvm_p2m(%rbx)
         sete %al
         test VCPU_nhvm_guestmode(%rbx),%al
         UNLIKELY_DONE(z, nsvm_hap)
+.Lsvm_update_nestedp2m:
         /*
-         * Someone shot down our nested p2m table; go round again
-         * and nsvm_vcpu_switch() will fix it for us.
+         * The nested p2m table is stale, fix it here.
          */
-        sti
+        mov  %rbx,%rdi
+        call nsvm_vcpu_update_nestedp2m
         jmp  .Lsvm_do_resume
 __UNLIKELY_END(nsvm_hap)
 
+        ASSERT_NOT_IN_ATOMIC
+
+        mov  VCPU_processor(%rbx),%eax
+        lea  irq_stat+IRQSTAT_softirq_pending(%rip),%rdx
+        xor  %ecx,%ecx
+        shl  $IRQSTAT_shift,%eax
+        cli
+        cmp  %ecx,(%rdx,%rax,1)
+        jne  .Lsvm_process_softirqs
+
+        cmp  %cl,VCPU_nsvm_hap_enabled(%rbx)
+        je   .Lsvm_vmenter
+        cmpb $0,VCPU_nhvm_guestmode(%rbx)
+        je   .Lsvm_vmenter
+        cmpb $0,VCPU_nhvm_stale_np2m(%rbx)
+        jne  .Lsvm_retry_nestedp2m
+
+.Lsvm_vmenter:
+
         call svm_vmenter_helper
 
         clgi
@@ -148,4 +168,8 @@ __UNLIKELY_END(nsvm_hap)
         sti
         call do_softirq
         jmp  .Lsvm_do_resume
+
+.Lsvm_retry_nestedp2m:
+        sti
+        jmp  .Lsvm_do_resume
 END(svm_asm_do_resume)
diff --git a/xen/arch/x86/hvm/svm/nestedhvm.h b/xen/arch/x86/hvm/svm/nestedhvm.h
index 9bb04a043430..e22ef259c171 100644
--- a/xen/arch/x86/hvm/svm/nestedhvm.h
+++ b/xen/arch/x86/hvm/svm/nestedhvm.h
@@ -41,6 +41,7 @@ void cf_check nsvm_vcpu_destroy(struct vcpu *v);
 int cf_check nsvm_vcpu_initialise(struct vcpu *v);
 int cf_check nsvm_vcpu_reset(struct vcpu *v);
 int nsvm_vcpu_vmrun(struct vcpu *v, struct cpu_user_regs *regs);
+void nsvm_vcpu_update_nestedp2m(struct vcpu *v);
 int cf_check nsvm_vcpu_vmexit_event(struct vcpu *v,
                                     const struct x86_event *event);
 uint64_t cf_check nsvm_vcpu_hostcr3(struct vcpu *v);
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index a8b15d6eae05..171b32be2416 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -361,6 +361,35 @@ static void nestedsvm_vmcb_set_nestedp2m(struct vcpu *v,
     n2vmcb->_h_cr3 = pagetable_get_paddr(p2m_get_pagetable(p2m));
 }
 
+void nsvm_vcpu_update_nestedp2m(struct vcpu *v)
+{
+    struct nestedvcpu *nv;
+    struct nestedsvm *svm;
+    struct p2m_domain *p2m;
+
+    ASSERT(v != NULL);
+
+    nv = &vcpu_nestedhvm(v);
+    svm = &vcpu_nestedsvm(v);
+
+    if ( !nestedhvm_paging_mode_hap(v) )
+        return;
+
+    p2m = p2m_get_nestedp2m(v);
+
+    /*
+     * This may happen if we've handled VMEXIT_NPF at the same time as a
+     * nested flush IPI from another CPU.  We've got a different P2M so the
+     * host CR3 needs updating.
+     */
+    if ( svm->ns_vmcb_hostcr3 != vmcb_get_h_cr3(nv->nv_vvmcx) ||
+         vmcb_get_h_cr3(nv->nv_n2vmcx) !=
+         pagetable_get_paddr(p2m_get_pagetable(p2m)) )
+        nestedsvm_vmcb_set_nestedp2m(v, nv->nv_vvmcx, nv->nv_n2vmcx);
+
+    nv->stale_np2m = false;
+}
+
 static int nsvm_vmcb_prepare4vmrun(struct vcpu *v, struct cpu_user_regs *regs)
 {
     struct nestedvcpu *nv = &vcpu_nestedhvm(v);
@@ -516,7 +545,7 @@ static int nsvm_vmcb_prepare4vmrun(struct vcpu *v, struct 
cpu_user_regs *regs)
         /* host nested paging + guest nested paging. */
         vmcb_set_np(n2vmcb, true);
 
-        nestedsvm_vmcb_set_nestedp2m(v, ns_vmcb, n2vmcb);
+        nsvm_vcpu_update_nestedp2m(v);
 
         /* hvm_set_cr3() below sets v->arch.hvm.guest_cr[3] for us. */
         rc = hvm_set_cr3(ns_vmcb->_cr3, false, true);
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index e6a0edcf71ab..fc447d24d67e 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -2118,6 +2118,8 @@ static void
 svm_vmexit_do_vmrun(struct cpu_user_regs *regs,
                     struct vcpu *v, uint64_t vmcbaddr)
 {
+    int rc;
+
     if ( !nsvm_efer_svm_enabled(v) )
     {
         hvm_inject_hw_exception(X86_EXC_UD, X86_EVENT_NO_EC);
@@ -2131,8 +2133,13 @@ svm_vmexit_do_vmrun(struct cpu_user_regs *regs,
         return;
     }
 
-    vcpu_nestedhvm(v).nv_vmentry_pending = 1;
-    return;
+    rc = nsvm_vcpu_vmrun(v, regs);
+    if ( rc )
+    {
+        if ( nestedsvm_vcpu_vmexit(v, regs, VMEXIT_INVALID, 0, 0) ==
+             NESTEDHVM_VMEXIT_FATALERROR )
+            domain_crash(v->domain);
+    }
 }
 
 static struct page_info *
diff --git a/xen/arch/x86/x86_64/asm-offsets.c 
b/xen/arch/x86/x86_64/asm-offsets.c
index baf266ab8013..772d1959e5a5 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -129,6 +129,7 @@ void __dummy__(void)
 
     OFFSET(VCPU_nhvm_guestmode, struct vcpu, arch.hvm.nvcpu.nv_guestmode);
     OFFSET(VCPU_nhvm_p2m, struct vcpu, arch.hvm.nvcpu.nv_p2m);
+    OFFSET(VCPU_nhvm_stale_np2m, struct vcpu, arch.hvm.nvcpu.stale_np2m);
     OFFSET(VCPU_nsvm_hap_enabled, struct vcpu, 
arch.hvm.nvcpu.u.nsvm.ns_hap_enabled);
     BLANK();
 #endif
-- 
2.34.1




 


Rackspace

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