Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp9581958rwb; Thu, 24 Nov 2022 15:30:11 -0800 (PST) X-Google-Smtp-Source: AA0mqf7G68e1a/VwwMUIRrfiRN+wfiQ+D3nZPu3J8tbZLtRtSfHn42Cvl+BQH56yOtICa4kSkA19 X-Received: by 2002:a05:6402:4512:b0:461:4c59:12d6 with SMTP id ez18-20020a056402451200b004614c5912d6mr32188774edb.250.1669332610929; Thu, 24 Nov 2022 15:30:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669332610; cv=none; d=google.com; s=arc-20160816; b=ebgveG1z7hp0qBg+2LjWRU6jZKVliDzK5hB2bT/U4emiPH+iSh5HKLihoBICz5jC+c gZS56HmHEIIjBCqaT15FrLlTbAn9KbNjW5anhxuyu9LQTtemK7xiaAzoY7PNFjxYL8gA vBVQGiQQ3g52YSRA/JGAKRuLs30HRTErsj9VbF5iGIazKmwR1Ocg/nIJ0Lh1xMK/cy0A cc3ffYGhFTIj6VtOPxSCFbUxp0wC7Z/DEWYNENvK9vw/nQIBxtviH4+xDUROAxZNqL9S tX60MhUUZVIAtuVaz0kYRaRUDijiGB+eTS/NAZFqD/fo6upEgDUcB29/WvDRuPMP12QT P8Fw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:date:subject:cc:to:from:dkim-signature :dkim-signature:message-id; bh=3XlTchWmSYgWxnh2ttknAUfKPOyveIAHvh7jfW9j4Pg=; b=OwQwkbfRKL7eE0lqPdhLPepEnOJDPUEJD8Z+OS24FRwij5QBtg+yG08E7ErgShanlK Dj4g5KfiT2EgKvPVWhhRHYbznCd6TuTrog/vtIQhy3dq70FxC5+SRJwm+FpPr/DqVx7K 8909Ns/G97lbZ03l/wlc5INmuNdHwiONtNLEptz62zaW04JxTH056vO6axMGmbIaS7Gd cps9ampy+K8dL7/BRRIJsiMsFf9CbVpBcvSIJ3AA+BqK6B0QnUkj68ZVspeluGKuw4zu C/uo+6d7fnxQ+RtquBRXM4pXgpgH5r1/ietLztP4ml6MeLZbzxX0HFjcSZ4dmecNUn+d 6c6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=qwGocCuz; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=ZyODNB28; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m19-20020a056402431300b004693eaeac13si1818718edc.570.2022.11.24.15.29.49; Thu, 24 Nov 2022 15:30:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=qwGocCuz; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=ZyODNB28; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229624AbiKXXYP (ORCPT + 88 others); Thu, 24 Nov 2022 18:24:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229610AbiKXXYM (ORCPT ); Thu, 24 Nov 2022 18:24:12 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A33D986A60; Thu, 24 Nov 2022 15:24:10 -0800 (PST) Message-ID: <20221124225331.464480443@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669332247; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc; bh=3XlTchWmSYgWxnh2ttknAUfKPOyveIAHvh7jfW9j4Pg=; b=qwGocCuzZIp2kiV3bXD80Ch3m8sVA3hK+bkI46Euu+ORcIXD0r36HJb/cUsNMnLDYkJahz CGqCw94Bnvpn+K18z5cNKz31Eu1Ebv9/RxIn8rgw0T/5vg2UfgnoWlFWY9VyzEy7I1ZD1m n/+w33D8zmiLSZiF8/7YmqOdPaECp24vnJ/sPAedjAQ4OerHfWlCOV6bcaAXe669f1SVVe tPgiHxeJMs0GIHjhabGQjBuePCx13eiSUvMFSnWh33ksgNFHR0Z5PeP+Hx01whMKh/mcu1 GcbDUKMp1vS2fNYi8bHPTQO4JIODATtp3AZQzGMU50P9NyyNdsGiJLSxidavTg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669332247; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc; bh=3XlTchWmSYgWxnh2ttknAUfKPOyveIAHvh7jfW9j4Pg=; b=ZyODNB28JFr+B4yU86cU4Ec/3KwX5c522Qudusr86i+XyHu2LktJ56V5F/CUcv0mft6Jzh KtFmibTMoarGw4CA== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Joerg Roedel , Will Deacon , linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Marc Zyngier , Greg Kroah-Hartman , Jason Gunthorpe , Dave Jiang , Alex Williamson , Kevin Tian , Dan Williams , Logan Gunthorpe , Ashok Raj , Jon Mason , Allen Hubbe Subject: [patch V3 00/22] genirq, PCI/MSI: Support for per device MSI and PCI/IMS - Part 2 API rework Date: Fri, 25 Nov 2022 00:24:07 +0100 (CET) X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This is V3 of the second part of the effort to provide support for per device MSI interrupt domains. Version 2 of this second part can be found here: https://lore.kernel.org/all/20221121083210.309161925@linutronix.de The first part is available here: https://lore.kernel.org/all/20221111120501.026511281@linutronix.de and has been merged into: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core This part on top of the tip irq/core branch is also available here: git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git devmsi-v3-part2 This part is the main preparation step for per device MSI domains: 1) Introduce irqdomain pointer storage space in device::msi::data and related helpers. 2) Convert interfaces to handle multiple per device MSI domains based on a domain ID 3) Provide new interfaces for allocation/free which are domain ID based and provide range allocation/free which is a prerequisite for post MSI-X enable alloc/free. 4) Switch all existing call sites of msi allocation/free interfaces over to the new interfaces 5) Remove the old interfaces Changes vs. V2: - Rework the xarray storage into per domain storage (Marc) @Kevin: I did not pick up your Reviewed-by tag due to these changes. The delta patch vs. V2 is attached below. Thanks, tglx --- diff --git a/include/linux/msi.h b/include/linux/msi.h index af9437ee4d82..43b8866c8431 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -174,24 +174,31 @@ enum msi_desc_filter { MSI_DESC_ASSOCIATED, }; + +/** + * struct msi_dev_domain - The internals of MSI domain info per device + * @store: Xarray for storing MSI descriptor pointers + * @irqdomain: Pointer to a per device interrupt domain + */ +struct msi_dev_domain { + struct xarray store; + struct irq_domain *domain; +}; + /** * msi_device_data - MSI per device data * @properties: MSI properties which are interesting to drivers * @platform_data: Platform-MSI specific data * @mutex: Mutex protecting the MSI descriptor store - * @__store: Xarray for storing MSI descriptor pointers + * @__domains: Internal data for per device MSI domains * @__iter_idx: Index to search the next entry for iterators - * @__iter_max: Index to limit the search - * @__irqdomains: Per device interrupt domains */ struct msi_device_data { unsigned long properties; struct platform_msi_priv_data *platform_data; struct mutex mutex; - struct xarray __store; + struct msi_dev_domain __domains[MSI_MAX_DEVICE_IRQDOMAINS]; unsigned long __iter_idx; - unsigned long __iter_max; - struct irq_domain *__irqdomains[MSI_MAX_DEVICE_IRQDOMAINS]; }; int msi_setup_device_data(struct device *dev); @@ -219,7 +226,8 @@ static inline struct msi_desc *msi_first_desc(struct device *dev, return msi_domain_first_desc(dev, MSI_DEFAULT_DOMAIN, filter); } -struct msi_desc *msi_next_desc(struct device *dev, enum msi_desc_filter filter); +struct msi_desc *msi_next_desc(struct device *dev, unsigned int domid, + enum msi_desc_filter filter); /** * msi_domain_for_each_desc - Iterate the MSI descriptors in a specific domain @@ -236,7 +244,7 @@ struct msi_desc *msi_next_desc(struct device *dev, enum msi_desc_filter filter); */ #define msi_domain_for_each_desc(desc, dev, domid, filter) \ for ((desc) = msi_domain_first_desc((dev), (domid), (filter)); (desc); \ - (desc) = msi_next_desc((dev), (filter))) + (desc) = msi_next_desc((dev), (domid), (filter))) /** * msi_for_each_desc - Iterate the MSI descriptors in the default irqdomain diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index c98c07ae46c9..695801b3cb68 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -34,37 +34,13 @@ struct msi_ctrl { unsigned int nirqs; }; -static void msi_domain_free_locked(struct device *dev, struct msi_ctrl *ctrl); -static inline int msi_sysfs_create_group(struct device *dev); - -/* Invalid XA index which is outside of any searchable range */ +/* Invalid Xarray index which is outside of any searchable range */ #define MSI_XA_MAX_INDEX (ULONG_MAX - 1) +/* The maximum domain size */ #define MSI_XA_DOMAIN_SIZE (MSI_MAX_INDEX + 1) -static inline void msi_setup_default_irqdomain(struct device *dev, struct msi_device_data *md) -{ - if (!dev->msi.domain) - return; - /* - * If @dev::msi::domain is a global MSI domain, copy the pointer - * into the domain array to avoid conditionals all over the place. - */ - if (!irq_domain_is_msi_parent(dev->msi.domain)) - md->__irqdomains[MSI_DEFAULT_DOMAIN] = dev->msi.domain; -} - -static int msi_get_domain_base_index(struct device *dev, unsigned int domid) -{ - lockdep_assert_held(&dev->msi.data->mutex); - - if (WARN_ON_ONCE(domid >= MSI_MAX_DEVICE_IRQDOMAINS)) - return -ENODEV; - - if (WARN_ON_ONCE(!dev->msi.data->__irqdomains[domid])) - return -ENODEV; - - return domid * MSI_XA_DOMAIN_SIZE; -} +static void msi_domain_free_locked(struct device *dev, struct msi_ctrl *ctrl); +static inline int msi_sysfs_create_group(struct device *dev); /** @@ -104,27 +80,16 @@ static void msi_free_desc(struct msi_desc *desc) kfree(desc); } -static int msi_insert_desc(struct device *dev, struct msi_desc *desc, +static int msi_insert_desc(struct msi_device_data *md, struct msi_desc *desc, unsigned int domid, unsigned int index) { - struct msi_device_data *md = dev->msi.data; - int baseidx, ret; - - baseidx = msi_get_domain_base_index(dev, domid); - if (baseidx < 0) { - ret = baseidx; - goto fail; - } + struct xarray *xa = &md->__domains[domid].store; + int ret; desc->msi_index = index; - index += baseidx; - ret = xa_insert(&md->__store, index, desc, GFP_KERNEL); + ret = xa_insert(xa, index, desc, GFP_KERNEL); if (ret) - goto fail; - return 0; - -fail: - msi_free_desc(desc); + msi_free_desc(desc); return ret; } @@ -152,7 +117,7 @@ int msi_domain_insert_msi_desc(struct device *dev, unsigned int domid, /* Copy type specific data to the new descriptor. */ desc->pci = init_desc->pci; - return msi_insert_desc(dev, desc, domid, init_desc->msi_index); + return msi_insert_desc(dev->msi.data, desc, domid, init_desc->msi_index); } static bool msi_desc_match(struct msi_desc *desc, enum msi_desc_filter filter) @@ -169,9 +134,11 @@ static bool msi_desc_match(struct msi_desc *desc, enum msi_desc_filter filter) return false; } -static bool msi_ctrl_range_valid(struct device *dev, struct msi_ctrl *ctrl) +static bool msi_ctrl_valid(struct device *dev, struct msi_ctrl *ctrl) { - if (WARN_ON_ONCE(ctrl->first > ctrl->last || + if (WARN_ON_ONCE(ctrl->domid >= MSI_MAX_DEVICE_IRQDOMAINS || + !dev->msi.data->__domains[ctrl->domid].domain || + ctrl->first > ctrl->last || ctrl->first > MSI_MAX_INDEX || ctrl->last > MSI_MAX_INDEX)) return false; @@ -180,21 +147,17 @@ static bool msi_ctrl_range_valid(struct device *dev, struct msi_ctrl *ctrl) static void msi_domain_free_descs(struct device *dev, struct msi_ctrl *ctrl) { - struct xarray *xa = &dev->msi.data->__store; struct msi_desc *desc; + struct xarray *xa; unsigned long idx; - int base; lockdep_assert_held(&dev->msi.data->mutex); - if (!msi_ctrl_range_valid(dev, ctrl)) - return; - - base = msi_get_domain_base_index(dev, ctrl->domid); - if (base < 0) + if (!msi_ctrl_valid(dev, ctrl)) return; - xa_for_each_range(xa, idx, desc, ctrl->first + base, ctrl->last + base) { + xa = &dev->msi.data->__domains[ctrl->domid].store; + xa_for_each_range(xa, idx, desc, ctrl->first, ctrl->last) { xa_erase(xa, idx); /* Leak the descriptor when it is still referenced */ @@ -234,22 +197,18 @@ static int msi_domain_add_simple_msi_descs(struct device *dev, struct msi_ctrl * { struct msi_desc *desc; unsigned int idx; - int ret, baseidx; + int ret; lockdep_assert_held(&dev->msi.data->mutex); - if (!msi_ctrl_range_valid(dev, ctrl)) + if (!msi_ctrl_valid(dev, ctrl)) return -EINVAL; - baseidx = msi_get_domain_base_index(dev, ctrl->domid); - if (baseidx < 0) - return baseidx; - for (idx = ctrl->first; idx <= ctrl->last; idx++) { desc = msi_alloc_desc(dev, 1, NULL); if (!desc) goto fail_mem; - ret = msi_insert_desc(dev, desc, ctrl->domid, idx); + ret = msi_insert_desc(dev->msi.data, desc, ctrl->domid, idx); if (ret) goto fail; } @@ -278,9 +237,12 @@ EXPORT_SYMBOL_GPL(get_cached_msi_msg); static void msi_device_data_release(struct device *dev, void *res) { struct msi_device_data *md = res; + int i; - WARN_ON_ONCE(!xa_empty(&md->__store)); - xa_destroy(&md->__store); + for (i = 0; i < MSI_MAX_DEVICE_IRQDOMAINS; i++) { + WARN_ON_ONCE(!xa_empty(&md->__domains[i].store)); + xa_destroy(&md->__domains[i].store); + } dev->msi.data = NULL; } @@ -297,7 +259,7 @@ static void msi_device_data_release(struct device *dev, void *res) int msi_setup_device_data(struct device *dev) { struct msi_device_data *md; - int ret; + int ret, i; if (dev->msi.data) return 0; @@ -312,11 +274,19 @@ int msi_setup_device_data(struct device *dev) return ret; } - msi_setup_default_irqdomain(dev, md); + for (i = 0; i < MSI_MAX_DEVICE_IRQDOMAINS; i++) + xa_init(&md->__domains[i].store); + + /* + * If @dev::msi::domain is set and is a global MSI domain, copy the + * pointer into the domain array so all code can operate on domain + * ids. The NULL pointer check is required to keep the legacy + * architecture specific PCI/MSI support working. + */ + if (dev->msi.domain && !irq_domain_is_msi_parent(dev->msi.domain)) + md->__domains[MSI_DEFAULT_DOMAIN].domain = dev->msi.domain; - xa_init(&md->__store); mutex_init(&md->mutex); - md->__iter_idx = MSI_XA_MAX_INDEX; dev->msi.data = md; devres_add(dev, md); return 0; @@ -338,17 +308,19 @@ EXPORT_SYMBOL_GPL(msi_lock_descs); */ void msi_unlock_descs(struct device *dev) { - /* Invalidate the index wich was cached by the iterator */ + /* Invalidate the index which was cached by the iterator */ dev->msi.data->__iter_idx = MSI_XA_MAX_INDEX; mutex_unlock(&dev->msi.data->mutex); } EXPORT_SYMBOL_GPL(msi_unlock_descs); -static struct msi_desc *msi_find_desc(struct msi_device_data *md, enum msi_desc_filter filter) +static struct msi_desc *msi_find_desc(struct msi_device_data *md, unsigned int domid, + enum msi_desc_filter filter) { + struct xarray *xa = &md->__domains[domid].store; struct msi_desc *desc; - xa_for_each_range(&md->__store, md->__iter_idx, desc, md->__iter_idx, md->__iter_max) { + xa_for_each_start(xa, md->__iter_idx, desc, md->__iter_idx) { if (msi_desc_match(desc, filter)) return desc; } @@ -372,26 +344,21 @@ struct msi_desc *msi_domain_first_desc(struct device *dev, unsigned int domid, enum msi_desc_filter filter) { struct msi_device_data *md = dev->msi.data; - int baseidx; - if (WARN_ON_ONCE(!md)) + if (WARN_ON_ONCE(!md || domid >= MSI_MAX_DEVICE_IRQDOMAINS)) return NULL; lockdep_assert_held(&md->mutex); - baseidx = msi_get_domain_base_index(dev, domid); - if (baseidx < 0) - return NULL; - - md->__iter_idx = baseidx; - md->__iter_max = baseidx + MSI_MAX_INDEX; - return msi_find_desc(md, filter); + md->__iter_idx = 0; + return msi_find_desc(md, domid, filter); } EXPORT_SYMBOL_GPL(msi_domain_first_desc); /** * msi_next_desc - Get the next MSI descriptor of a device * @dev: Device to operate on + * @domid: The id of the interrupt domain which should be walked. * @filter: Descriptor state filter * * The first invocation of msi_next_desc() has to be preceeded by a @@ -402,20 +369,21 @@ EXPORT_SYMBOL_GPL(msi_domain_first_desc); * Return: Pointer to the next MSI descriptor matching the search * criteria, NULL if none found. */ -struct msi_desc *msi_next_desc(struct device *dev, enum msi_desc_filter filter) +struct msi_desc *msi_next_desc(struct device *dev, unsigned int domid, + enum msi_desc_filter filter) { struct msi_device_data *md = dev->msi.data; - if (WARN_ON_ONCE(!md)) + if (WARN_ON_ONCE(!md || domid >= MSI_MAX_DEVICE_IRQDOMAINS)) return NULL; lockdep_assert_held(&md->mutex); - if (md->__iter_idx >= md->__iter_max) + if (md->__iter_idx >= (unsigned long)MSI_MAX_INDEX) return NULL; md->__iter_idx++; - return msi_find_desc(md, filter); + return msi_find_desc(md, domid, filter); } EXPORT_SYMBOL_GPL(msi_next_desc); @@ -432,12 +400,12 @@ unsigned int msi_domain_get_virq(struct device *dev, unsigned int domid, unsigne struct msi_desc *desc; unsigned int ret = 0; bool pcimsi = false; - int base; + struct xarray *xa; if (!dev->msi.data) return 0; - if (WARN_ON_ONCE(index > MSI_MAX_INDEX)) + if (WARN_ON_ONCE(index > MSI_MAX_INDEX || domid >= MSI_MAX_DEVICE_IRQDOMAINS)) return 0; /* This check is only valid for the PCI default MSI domain */ @@ -445,13 +413,8 @@ unsigned int msi_domain_get_virq(struct device *dev, unsigned int domid, unsigne pcimsi = to_pci_dev(dev)->msi_enabled; msi_lock_descs(dev); - - base = msi_get_domain_base_index(dev, domid); - if (base < 0) - goto unlock; - - base += pcimsi ? 0 : index; - desc = xa_load(&dev->msi.data->__store, base); + xa = &dev->msi.data->__domains[domid].store; + desc = xa_load(xa, pcimsi ? 0 : index); if (desc && desc->irq) { /* * PCI-MSI has only one descriptor for multiple interrupts. @@ -466,7 +429,6 @@ unsigned int msi_domain_get_virq(struct device *dev, unsigned int domid, unsigne } } -unlock: msi_unlock_descs(dev); return ret; } @@ -595,7 +557,7 @@ static struct irq_domain *msi_get_device_domain(struct device *dev, unsigned int if (WARN_ON_ONCE(domid >= MSI_MAX_DEVICE_IRQDOMAINS)) return NULL; - domain = dev->msi.data->__irqdomains[domid]; + domain = dev->msi.data->__domains[domid].domain; if (!domain) return NULL; @@ -846,9 +808,10 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, .last = virq_base + nvec - 1, }; struct msi_desc *desc; + struct xarray *xa; int ret, virq; - if (!msi_ctrl_range_valid(dev, &ctrl)) + if (!msi_ctrl_valid(dev, &ctrl)) return -EINVAL; msi_lock_descs(dev); @@ -856,8 +819,10 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, if (ret) goto unlock; + xa = &dev->msi.data->__domains[ctrl.domid].store; + for (virq = virq_base; virq < virq_base + nvec; virq++) { - desc = xa_load(&dev->msi.data->__store, virq); + desc = xa_load(xa, virq); desc->irq = virq; ops->set_desc(arg, desc); @@ -987,8 +952,8 @@ static int msi_init_virq(struct irq_domain *domain, int virq, unsigned int vflag static int __msi_domain_alloc_irqs(struct device *dev, struct irq_domain *domain, struct msi_ctrl *ctrl) { + struct xarray *xa = &dev->msi.data->__domains[ctrl->domid].store; struct msi_domain_info *info = domain->host_data; - struct xarray *xa = &dev->msi.data->__store; struct msi_domain_ops *ops = info->ops; unsigned int vflags = 0, allocated = 0; msi_alloc_info_t arg = { }; @@ -1074,7 +1039,7 @@ static int __msi_domain_alloc_locked(struct device *dev, struct msi_ctrl *ctrl) struct irq_domain *domain; int ret; - if (!msi_ctrl_range_valid(dev, ctrl)) + if (!msi_ctrl_valid(dev, ctrl)) return -EINVAL; domain = msi_get_device_domain(dev, ctrl->domid); @@ -1180,16 +1145,14 @@ int msi_domain_alloc_irqs_all_locked(struct device *dev, unsigned int domid, int static void __msi_domain_free_irqs(struct device *dev, struct irq_domain *domain, struct msi_ctrl *ctrl) { + struct xarray *xa = &dev->msi.data->__domains[ctrl->domid].store; struct msi_domain_info *info = domain->host_data; - struct xarray *xa = &dev->msi.data->__store; struct irq_data *irqd; struct msi_desc *desc; unsigned long idx; - int i, base; - - base = ctrl->domid * MSI_XA_DOMAIN_SIZE; + int i; - xa_for_each_range(xa, idx, desc, ctrl->first + base, ctrl->last + base) { + xa_for_each_range(xa, idx, desc, ctrl->first, ctrl->last) { /* Only handle MSI entries which have an interrupt associated */ if (!msi_desc_match(desc, MSI_DESC_ASSOCIATED)) continue; @@ -1214,7 +1177,7 @@ static void msi_domain_free_locked(struct device *dev, struct msi_ctrl *ctrl) struct msi_domain_ops *ops; struct irq_domain *domain; - if (!msi_ctrl_range_valid(dev, ctrl)) + if (!msi_ctrl_valid(dev, ctrl)) return; domain = msi_get_device_domain(dev, ctrl->domid);