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

[PATCH v4 07/12] x86/dpci: switch to use a GSI EOI callback


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • Date: Tue, 20 Apr 2021 16:07:18 +0200
  • 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=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=9LDC2BNSgnovQYjkqYHd80+wCvWWCbTTsmR77iMhVkU=; b=m3OaoOD40xsbQJsfzwIi+COsnP4PCBBlTz+vfq7Q33yd4C9DPJ882ZrCuGj72bsw1uoJv+l9QtGmq9yTC3jjAStBiYqsNpLDXXoZG3Sof2a/ulXYpK7jm0bMmQ0ytU1nDU97Kks1DZhdhYd5hAjp0SxHBojFFuN8ysuyLfgaIqbGZ/zRP42Slfjing6ZWB/8yPYrl2b9T7muZy1TWLjzzFYfgUv8ec3hEqIfR4YY/HHNKSo5TYoj0bpoOY6vR9l3biPJSarNUU5jTa+SwYUoZgm/ywxiyGWG8sLHDkZfQUumOciVWYNnYXrBMy41iMVmZVT5L8MEt4IkySfFGJB96Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bf8QqkI3NF3x9Si+1E9bN2tKcTOwYP5SrbBTvOBSAXjOGMxd6mKsd7/4+IT3OnCvf9ybF1n/19c/bs8ZV5lsg+GdTa4lSiKPwLPQXUdn3LR1DlAcokRNIm8BlpE+g5bOqkNT0oS1eRuKB9aT2aXuHpC9Tl35CEFPmuzox0O2cOpEvKfH5y5MCEvaO8lilNvnJoWKZ/rCJZx8HxPCGP6TZkYSoP3IsPjkzNFqDjSm74l+/6k0j8gn91fYrhMlF2NlNc7WehVM5W7lUZtDq1b+6ArxARI2KoCOr2EoYE2XQZ+T29QBi727smeg3744XXpstKjiIAj/4vXakq4V5iU2zA==
  • Authentication-results: esa1.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Paul Durrant <paul@xxxxxxx>
  • Delivery-date: Tue, 20 Apr 2021 14:09:38 +0000
  • Ironport-hdrordr: A9a23:6LMseKy1ofbJmcVjq4O5KrPxqe4kLtp033Aq2lEZdDV8Sebdv9 yynfgdyB//gCsQXnZlotybJKycWxrnmqJdybI6eZOvRhPvtmftFoFt6oP+3ybtcheTysd07o 0lSaR3DbTLYGRSpdrm4QW+DtYryMSG9qftvuvF03JxV2hRCp1IxS0RMHf+LmRdQg5aCZ0lUK eG7s1cqDa6PVgRZMK3Bn4KNtKz2+HjvpTgfBIAGlob+BCD5AnYlYLSPjq5+lMlUz1Jyao/6m StqWLEz4iqrv3T8G6760b99JJT8eGRqOdrJMvJscQNLyWptwDAXvUbZ5SnnBQY5N6i80wrlt 6kmWZRA+1W52nKdm+45TvBsjOQqQoG0HPpxV+GjXaLm6WQL1hbeqkx975xSRfX51Etu9txys twrhiknqFaEA/am2DF78XIPisa53acm2YokuIYkhVkIOwjQYJWxLZvmX99IdMrGSL3750fC+ 9+DM3Qz+Y+SyLlU1np+kZo29CiRXI1A1OvRVUDoNWc13xskGl+1FZw/r1Sol4wsLYGD7VU7e XNNapl0JlIU88tdKp4QMMMW9G+BGDhSQ/FWVjibmjPJeUiATbgupT36LI66KWBY5oT1qY/n5 zHTRdxqXMyU1iGM7zP4LR7tjT2BEmtVzXkzc9To7JjvKfnebbtOSqfDHgzjsqbpekFCMGzYY fzBLtmR9vYaUf+E4dA2APzH7NIL2MFbcETstEnH32UpMbmLZDrq/z7fP7fKKGFK0dnZkrPRl 84GBTjLsRJ6U6mHlXihgLKZn/rckvjubJ8eZKqutQ7+cwoDMlhowIVgVO26oWgMjtZqJE7e0 N4PffCmqO/rm+mwHbQ4wxSS15gJ3cQxI+lf2JBpAcMPU+xW60Eoc+jdWdb22bCARNjUcXMEk p6q05s8ay6a7ycrBpSRe6PAya/tT8+tXiKR5ATlumo/sH+YK41CZ4gRehWDgXEFxt8nC5ws2 ddYAo4RkvSfwmeypmNvdgxPqXyZtN8iACkLYp/snTEr3iRoskpWz8mRTK0aNWWhgwvXjJQoV V0/8Yk8f29sAfqDVF6rPUzMVVKZmjSJL5dFgyKaL9Zna3RdBhqQX2HgiGbjB8PanPnnn9i9V DJHGmxQ7XmE1BdsndX3uLR/FR4en60UmhwZnp52LcNXljuizJW66umd6Cz22yeZh8+2ekbKi jCeiZXCBhp3cqL2BmcnyuiGX0qyo41BPHUCK0uftjoqzWQAbzNsZtDM+5f/Z5jOtyrj/QCVv iHfRSJaBz/EOEk1mWu1wAYERgxjENht/zm2BfotjflmFE+BOffO1RgSfUwJcqG423tWvaP19 FYgLsOzJ+NG1S0TuTD76fdKwNnAFf0h0WdSukzs5Bava4ortJIbtHmeAqN8EsC5Qk0Kcf/qV gXT6t66o3QI4MHRb1mRwtpun4S0OmVJEQlsgbKEvYzUFEkgXjcJc6I6dPz2M0SK3zEgAPxPF WFmhcth8vtbm+m1bQADbg3LnkTQE8g6G569OfqTfybNCyaM8VC9kG9KHmzbft0T7WEA6wZql Jf78uTl+GaMwr+1wa4h0o3Hot+t0KmS9i1GgSCBKph9MG7I02Fhu+S2/GI5Q2HAAeTWgA/no 1KdUsZc8RFhH0DteQMo1ePY52yhFkknVtY6SxgjXj31OGdkT7mIX0=
  • Ironport-sdr: YcNpxn66rI5n6ipxBlSKJWsGAeHcoyOZ2njU+wNodx3vMrVqQinO/t+lAfHuZC7/GVr4JAaPgQ cNgtjEGvM/Ut8t5dtN3gndsKBGIEuy4NrOMgbr/qFus42P47UjrkBbcdGSm1depn8CkUVmI7e0 sVxShpQibMSymDA5/nVORwkjCH8j6UoPLcm8mXiIFxKadeUtQpLqKPSwd1vm7RPk1uzSUjgxmO gW2sjNvKDwuy72ZMDRj8tyxt24Gz5Cxs11vfbOHXhFWabWrOXXg6Qhd4rkhyUDBnOw0n9FA7Ft +DQ=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Switch the dpci GSI EOI callback hooks to use the newly introduced
generic callback functionality, and remove the custom dpci calls found
on the vPIC and vIO-APIC implementations.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Changes since v3:
 - Print a warning message if the EOI callback cannot be unregistered.

Changes since v2:
 - Avoid leaking the allocated callback on error paths of
   pt_irq_create_bind.

Changes since v1:
 - New in this version.
---
 xen/arch/x86/hvm/vioapic.c        |  8 -----
 xen/arch/x86/hvm/vpic.c           |  4 ---
 xen/drivers/passthrough/x86/hvm.c | 57 ++++++++++++++++++++++++++++---
 xen/include/asm-x86/hvm/io.h      |  1 -
 xen/include/asm-x86/hvm/irq.h     |  1 +
 5 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 0824ede91ab..4f844965423 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -284,7 +284,6 @@ static void vioapic_write_redirent(
              */
             ASSERT(prev_level);
             ASSERT(!top_word);
-            hvm_dpci_eoi(d, gsi);
             hvm_gsi_execute_callbacks(d, gsi);
     }
 
@@ -418,13 +417,6 @@ static void eoi_callback(struct vcpu *v, unsigned int 
vector, void *data)
 
             ent->fields.remote_irr = 0;
 
-            if ( is_iommu_enabled(d) )
-            {
-                spin_unlock(&d->arch.hvm.irq_lock);
-                hvm_dpci_eoi(d, gsi);
-                spin_lock(&d->arch.hvm.irq_lock);
-            }
-
             /*
              * Callbacks don't expect to be executed with any lock held, so
              * drop the lock that protects the vIO-APIC fields from changing.
diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c
index ef668f3668a..60d6740f69a 100644
--- a/xen/arch/x86/hvm/vpic.c
+++ b/xen/arch/x86/hvm/vpic.c
@@ -237,8 +237,6 @@ static void vpic_ioport_write(
                 ASSERT(pin < 8);
                 hvm_gsi_execute_callbacks(current->domain,
                         hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : pin));
-                hvm_dpci_eoi(current->domain,
-                             hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : 
pin));
                 __clear_bit(pin, &pending);
             }
             return;
@@ -289,8 +287,6 @@ static void vpic_ioport_write(
                 vpic_unlock(vpic);
                 hvm_gsi_execute_callbacks(current->domain,
                         hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : pin));
-                hvm_dpci_eoi(current->domain,
-                             hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : 
pin));
                 return; /* bail immediately */
             case 6: /* Set Priority                */
                 vpic->priority_add = (val + 1) & 7;
diff --git a/xen/drivers/passthrough/x86/hvm.c 
b/xen/drivers/passthrough/x86/hvm.c
index 0db26e5dbb2..02e027cff8c 100644
--- a/xen/drivers/passthrough/x86/hvm.c
+++ b/xen/drivers/passthrough/x86/hvm.c
@@ -252,7 +252,7 @@ static void hvm_gsi_eoi(struct domain *d, unsigned int gsi)
     hvm_pirq_eoi(pirq);
 }
 
-void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi)
+static void dpci_eoi(struct domain *d, unsigned int guest_gsi, void *data)
 {
     const struct hvm_irq_dpci *hvm_irq_dpci;
     const struct hvm_girq_dpci_mapping *girq;
@@ -476,6 +476,7 @@ int pt_irq_create_bind(
     {
         struct dev_intx_gsi_link *digl = NULL;
         struct hvm_girq_dpci_mapping *girq = NULL;
+        struct hvm_gsi_eoi_callback *cb = NULL;
         unsigned int guest_gsi;
 
         /*
@@ -489,7 +490,7 @@ int pt_irq_create_bind(
             unsigned int link;
 
             digl = xmalloc(struct dev_intx_gsi_link);
-            girq = xmalloc(struct hvm_girq_dpci_mapping);
+            girq = xzalloc(struct hvm_girq_dpci_mapping);
 
             if ( !digl || !girq )
             {
@@ -502,11 +503,22 @@ int pt_irq_create_bind(
             girq->bus = digl->bus = pt_irq_bind->u.pci.bus;
             girq->device = digl->device = pt_irq_bind->u.pci.device;
             girq->intx = digl->intx = pt_irq_bind->u.pci.intx;
-            list_add_tail(&digl->list, &pirq_dpci->digl_list);
+            girq->cb.callback = dpci_eoi;
 
             guest_gsi = hvm_pci_intx_gsi(digl->device, digl->intx);
             link = hvm_pci_intx_link(digl->device, digl->intx);
 
+            rc = hvm_gsi_register_callback(d, guest_gsi, &girq->cb);
+            if ( rc )
+            {
+                spin_unlock(&d->event_lock);
+                xfree(girq);
+                xfree(digl);
+                return rc;
+            }
+
+            list_add_tail(&digl->list, &pirq_dpci->digl_list);
+
             hvm_irq_dpci->link_cnt[link]++;
 
             girq->machine_gsi = pirq;
@@ -514,17 +526,43 @@ int pt_irq_create_bind(
         }
         else
         {
+            /*
+             * NB: the callback structure allocated below will never be freed
+             * once setup because it's used by the hardware domain and will
+             * never be unregistered.
+             */
+            cb = xzalloc(struct hvm_gsi_eoi_callback);
+
             ASSERT(is_hardware_domain(d));
 
+            if ( !cb )
+            {
+                spin_unlock(&d->event_lock);
+                return -ENOMEM;
+            }
+
             /* MSI_TRANSLATE is not supported for the hardware domain. */
             if ( pt_irq_bind->irq_type != PT_IRQ_TYPE_PCI ||
                  pirq >= hvm_domain_irq(d)->nr_gsis )
             {
                 spin_unlock(&d->event_lock);
-
+                xfree(cb);
                 return -EINVAL;
             }
             guest_gsi = pirq;
+
+            cb->callback = dpci_eoi;
+            /*
+             * IRQ binds created for the hardware domain are never destroyed,
+             * so it's fine to not keep a reference to cb here.
+             */
+            rc = hvm_gsi_register_callback(d, guest_gsi, cb);
+            if ( rc )
+            {
+                spin_unlock(&d->event_lock);
+                xfree(cb);
+                return rc;
+            }
         }
 
         /* Bind the same mirq once in the same domain */
@@ -596,12 +634,17 @@ int pt_irq_create_bind(
                     list_del(&digl->list);
                     link = hvm_pci_intx_link(digl->device, digl->intx);
                     hvm_irq_dpci->link_cnt[link]--;
+                    hvm_gsi_unregister_callback(d, guest_gsi, &girq->cb);
                 }
+                else
+                    hvm_gsi_unregister_callback(d, guest_gsi, cb);
+
                 pirq_dpci->flags = 0;
                 pirq_cleanup_check(info, d);
                 spin_unlock(&d->event_lock);
                 xfree(girq);
                 xfree(digl);
+                xfree(cb);
                 return rc;
             }
         }
@@ -699,6 +742,7 @@ int pt_irq_destroy_bind(
         unsigned int link = hvm_pci_intx_link(device, intx);
         struct hvm_girq_dpci_mapping *girq;
         struct dev_intx_gsi_link *digl, *tmp;
+        int rc;
 
         list_for_each_entry ( girq, &hvm_irq_dpci->girq[guest_gsi], list )
         {
@@ -708,6 +752,11 @@ int pt_irq_destroy_bind(
                  girq->machine_gsi == machine_gsi )
             {
                 list_del(&girq->list);
+                rc = hvm_gsi_unregister_callback(d, guest_gsi, &girq->cb);
+                if ( rc )
+                    printk(XENLOG_G_WARNING
+                           "%pd: unable to remove callback for GSI %u: %d\n",
+                           d, guest_gsi, rc);
                 xfree(girq);
                 girq = NULL;
                 break;
diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h
index 7f30dfa7fea..977a857f729 100644
--- a/xen/include/asm-x86/hvm/io.h
+++ b/xen/include/asm-x86/hvm/io.h
@@ -101,7 +101,6 @@ bool handle_mmio_with_translation(unsigned long gla, 
unsigned long gpfn,
                                   struct npfec);
 bool handle_pio(uint16_t port, unsigned int size, int dir);
 void hvm_interrupt_post(struct vcpu *v, int vector, int type);
-void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq);
 void msix_write_completion(struct vcpu *);
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h
index 37b8d2ba8fb..57d51c15863 100644
--- a/xen/include/asm-x86/hvm/irq.h
+++ b/xen/include/asm-x86/hvm/irq.h
@@ -156,6 +156,7 @@ struct hvm_girq_dpci_mapping {
     uint8_t device;
     uint8_t intx;
     uint8_t machine_gsi;
+    struct hvm_gsi_eoi_callback cb;
 };
 
 #define NR_ISAIRQS  16
-- 
2.30.1




 


Rackspace

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