Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp9653452rwb; Thu, 24 Nov 2022 16:43:43 -0800 (PST) X-Google-Smtp-Source: AA0mqf4K0OJ9HDZTqrr1AZumTgnLH6UCONpja59wME86d3zNnQdE33yHCeA9NFeD9jg1chSB5bEJ X-Received: by 2002:a17:90a:a003:b0:214:1a8a:a415 with SMTP id q3-20020a17090aa00300b002141a8aa415mr37309508pjp.197.1669337023596; Thu, 24 Nov 2022 16:43:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669337023; cv=none; d=google.com; s=arc-20160816; b=RvgltipFghp8qKnAaIAI2tro3b0U0kyJPVZKracCC5j8xl5IqfhqMsSM1iis+21E74 cow3aLQVsiUX7Ah9DMX1fW1azKr25gkW2X+er0FrT6V+wNvrQryVaQwibSgJMVnm2KsH 1NXfJpBIa29iqBmimV0oNDNglT1rs5kqsiX9NacSNzVSsC5TQPCHhIccTmvqRXSeKard wueWlVYyF3slRlBdqgR8g24qA99WZrXZApCpadLz54y0cWTebQ6DBOgY8SZLR6wYEudw eBcyrgMmR2PSF83R0ds+j6scQsgHdTGwSn7sklkoyA0EBiOaThl+UMX/HEqknvnNKKyK rIVA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:date:mime-version:references:subject:cc:to:from :dkim-signature:dkim-signature:message-id; bh=O52hKM/eyXA5495ofBmhJYgeFgFMKz1bKsf4ukXppYY=; b=kPQUUaBY6mJkaffS7xE1RehK0HFNCirRrSOXEOFXsQqQQcRWmTRGRcaRoe/cmhqRaF 0AypGlgVS9PaVSw8+5stHkCAhsHzeB2XaJKPj7kYCNO0PMOKkFG/4hg011SATZ74DG1c +6CSJPwv4Sz2xJSbJ2Yg1ZwiQJWwHpy3hFx8g+HsWgo/dCa/tSgBOROyDB6IiwSNSYbE tfNBIz3kS06IvBXUmnlFIVXDDE4SA2Kus8GKEwEmTEMByFOv4PvaXW6NYHCLV4wuPb1P eJkQ7wh5IyXO8Cggs/jTQVoSdz595pNOirAE0GKS7R4kYotGP6crs1VbdfYzTHuBkczL hChQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=dopcgaOB; dkim=neutral (no key) header.i=@linutronix.de; 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 f12-20020a65400c000000b00439ae523fd2si2566103pgp.289.2022.11.24.16.43.32; Thu, 24 Nov 2022 16:43:43 -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=dopcgaOB; dkim=neutral (no key) header.i=@linutronix.de; 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 S229635AbiKXX2p (ORCPT + 87 others); Thu, 24 Nov 2022 18:28:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229966AbiKXX2a (ORCPT ); Thu, 24 Nov 2022 18:28:30 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9EE43D33BF; Thu, 24 Nov 2022 15:26:49 -0800 (PST) Message-ID: <20221124232325.798556374@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1669332359; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=O52hKM/eyXA5495ofBmhJYgeFgFMKz1bKsf4ukXppYY=; b=dopcgaOBeuvvrVBBjM0IZ0Z4kvik/8Xxm+j9VeWrZCxYVZSjAt7u7Wu3jFdqxEDwUs6Dpe ZRigkklTSw5Qbi46/l+53EZbtiawpGi1awSivW/h0qEf3eKvOkyLD+9JzcvGduXRbZsEGB xs+n1tn5OojF8ZuNu/AJLkCszv9eTIlOAJDJJ4Nn3dJCCo9O6gaS0qRvESCs5Cgfnt9YEK T5yZg75EvqwFYUGAgCoP5qqPeaZgIhea5xAsHXj5ZIWpkryKhPu39X2YnTr2E7kId+rjog RVerFXwJ+rt+WWZzl8R8LpOv8Uy2HKj//8IxlIJWp8zyBglmainSmPymXLBx3A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1669332359; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=O52hKM/eyXA5495ofBmhJYgeFgFMKz1bKsf4ukXppYY=; b=gHSz9L5yPdDRuaLfE8LQ98i2E3jVTmq3Z5/qFrAeRScCdHPL18H1Wxeq8YXUhiN2rmB9LF +zoMdTSXWUgufbDA== 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 09/33] genirq/msi: Add range checking to msi_insert_desc() References: <20221124230505.073418677@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Fri, 25 Nov 2022 00:25:59 +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 Per device domains provide the real domain size to the core code. This allows range checking on insertion of MSI descriptors and also paves the way for dynamic index allocations which are required e.g. for IMS. This avoids external mechanisms like bitmaps on the device side and just utilizes the core internal MSI descriptor storxe for it. Signed-off-by: Thomas Gleixner --- V3: Adopt to the new info->hwsize handling and to the new xarray split --- kernel/irq/msi.c | 58 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 11 deletions(-) --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -40,6 +40,7 @@ struct msi_ctrl { #define MSI_XA_DOMAIN_SIZE (MSI_MAX_INDEX + 1) static void msi_domain_free_locked(struct device *dev, struct msi_ctrl *ctrl); +static unsigned int msi_domain_get_hwsize(struct device *dev, unsigned int domid); static inline int msi_sysfs_create_group(struct device *dev); @@ -80,16 +81,28 @@ static void msi_free_desc(struct msi_des kfree(desc); } -static int msi_insert_desc(struct msi_device_data *md, struct msi_desc *desc, +static int msi_insert_desc(struct device *dev, struct msi_desc *desc, unsigned int domid, unsigned int index) { + struct msi_device_data *md = dev->msi.data; struct xarray *xa = &md->__domains[domid].store; + unsigned int hwsize; int ret; + hwsize = msi_domain_get_hwsize(dev, domid); + if (index >= hwsize) { + ret = -ERANGE; + goto fail; + } + desc->msi_index = index; ret = xa_insert(xa, index, desc, GFP_KERNEL); if (ret) - msi_free_desc(desc); + goto fail; + return 0; + +fail: + msi_free_desc(desc); return ret; } @@ -117,7 +130,7 @@ int msi_domain_insert_msi_desc(struct de /* Copy type specific data to the new descriptor. */ desc->pci = init_desc->pci; - return msi_insert_desc(dev->msi.data, desc, domid, init_desc->msi_index); + return msi_insert_desc(dev, desc, domid, init_desc->msi_index); } static bool msi_desc_match(struct msi_desc *desc, enum msi_desc_filter filter) @@ -136,11 +149,16 @@ static bool msi_desc_match(struct msi_de static bool msi_ctrl_valid(struct device *dev, struct msi_ctrl *ctrl) { + unsigned int hwsize; + 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)) + !dev->msi.data->__domains[ctrl->domid].domain)) + return false; + + hwsize = msi_domain_get_hwsize(dev, ctrl->domid); + if (WARN_ON_ONCE(ctrl->first > ctrl->last || + ctrl->first >= hwsize || + ctrl->last >= hwsize)) return false; return true; } @@ -208,7 +226,7 @@ static int msi_domain_add_simple_msi_des desc = msi_alloc_desc(dev, 1, NULL); if (!desc) goto fail_mem; - ret = msi_insert_desc(dev->msi.data, desc, ctrl->domid, idx); + ret = msi_insert_desc(dev, desc, ctrl->domid, idx); if (ret) goto fail; } @@ -407,7 +425,10 @@ unsigned int msi_domain_get_virq(struct if (!dev->msi.data) return 0; - if (WARN_ON_ONCE(index > MSI_MAX_INDEX || domid >= MSI_MAX_DEVICE_IRQDOMAINS)) + if (WARN_ON_ONCE(domid >= MSI_MAX_DEVICE_IRQDOMAINS)) + return 0; + + if (WARN_ON_ONCE(index >= msi_domain_get_hwsize(dev, domid))) return 0; /* This check is only valid for the PCI default MSI domain */ @@ -569,6 +590,20 @@ static struct irq_domain *msi_get_device return domain; } +static unsigned int msi_domain_get_hwsize(struct device *dev, unsigned int domid) +{ + struct msi_domain_info *info; + struct irq_domain *domain; + + domain = msi_get_device_domain(dev, domid); + if (domain) { + info = domain->host_data; + return info->hwsize; + } + /* No domain, no size... */ + return 0; +} + static inline void irq_chip_write_msi_msg(struct irq_data *data, struct msi_msg *msg) { @@ -1359,7 +1394,7 @@ int msi_domain_alloc_irqs_all_locked(str struct msi_ctrl ctrl = { .domid = domid, .first = 0, - .last = MSI_MAX_INDEX, + .last = msi_domain_get_hwsize(dev, domid) - 1, .nirqs = nirqs, }; @@ -1473,7 +1508,8 @@ void msi_domain_free_irqs_range(struct d */ void msi_domain_free_irqs_all_locked(struct device *dev, unsigned int domid) { - msi_domain_free_irqs_range_locked(dev, domid, 0, MSI_MAX_INDEX); + msi_domain_free_irqs_range_locked(dev, domid, 0, + msi_domain_get_hwsize(dev, domid) - 1); } /**