Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp208284ybe; Thu, 12 Sep 2019 18:30:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqwyS71Eu3JumjLyBz6eL0aEcndvu+dABlfSb8g236mPU5pdF1Jd737jifWC0fo+cAzpx/7k X-Received: by 2002:a17:906:7ac6:: with SMTP id k6mr32633672ejo.243.1568338199947; Thu, 12 Sep 2019 18:29:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568338199; cv=none; d=google.com; s=arc-20160816; b=0WYK1woPtIKEq2beKiliUZh6Esa0YVsUA2fJFC3j0XlGoACmbUWtshQRUDbj2b8Qmy bpp7pX5LD/uGuSIeoTsL62bqZO62Qrf1LnC9y+a0t+d8Tf+0dpUhp/+85sUvFjmKmOKn zu57cICtMabr15bMBEGmmlXFToJqIqS/Mf79KQnB6yhRsrDPIeKNTE5xUQX7Z0ZWlbBC 40GKeNdo/Hz58LO184wTJQVXbIorUQdUnfQIi2iyL3I1eLvoj3JDxsjOiACi4V23LBnO 4b5k6PjirmvDDzDXFVdw3s9E6njaejF4bj6f0tqJRP3CSC4NIrJvE6qWXcUwduxPP0b8 ucqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=HpaTk0fc8ksKkUFz9rnov8IyCsR2sJH6mC9/Kx/Q/DA=; b=tiO6uRk9JtYsdRDQynwWl/Yp4+tfuN2BZohxyc4+gFfkYOi/Z7cck7IJtL2PluNe0G 7xU/IzXJf/pCX391DByfzuWMQjpvIAhr0C6dBQE1M7tUhnYO5qVl2OKyNFvLgx6JOirc ERKQNOY4QQvb7Cdgq22sGUc1ZxSQCH7RT9Cio0Dixe7BzVOO0HwALJYcPPB2bYzNetf+ A74u4D8UfDNMuSQqB+yL1NFvr+XOsM5ePPWvhqig22zybu/v3Ok8IN1529Utgjk0E4lK lWp4cNtw6GMFn7bhsIbfOMcye+z+KD+hVNxENKchOBmn0bEzUDHWW1zfuGGKLH0iNSwv JQlw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m10si412541ejc.337.2019.09.12.18.29.36; Thu, 12 Sep 2019 18:29:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728781AbfIMBO6 (ORCPT + 99 others); Thu, 12 Sep 2019 21:14:58 -0400 Received: from mga12.intel.com ([192.55.52.136]:29376 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727518AbfIMBOr (ORCPT ); Thu, 12 Sep 2019 21:14:47 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Sep 2019 18:14:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="197403712" Received: from megha-z97x-ud7-th.sc.intel.com ([143.183.85.162]) by orsmga002.jf.intel.com with ESMTP; 12 Sep 2019 18:14:46 -0700 From: Megha Dey To: linux-kernel@vger.kernel.org, x86@kernel.org, linux-pci@vger.kernel.org, maz@kernel.org, bhelgaas@google.com, rafael@kernel.org, gregkh@linuxfoundation.org, tglx@linutronix.de, hpa@zytor.com, alex.williamson@redhat.com, jgg@mellanox.com Cc: ashok.raj@intel.com, megha.dey@intel.com, jacob.jun.pan@intel.com, Megha Dey , Jacob Pan , Sanjay Kumar Subject: [RFC V1 5/7] x86/ims: Introduce x86_ims_ops Date: Thu, 12 Sep 2019 18:32:06 -0700 Message-Id: <1568338328-22458-6-git-send-email-megha.dey@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1568338328-22458-1-git-send-email-megha.dey@linux.intel.com> References: <1568338328-22458-1-git-send-email-megha.dey@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch introduces an x86 specific indirect mechanism to setup the interrupt message storage. The IMS specific functions (setup, teardown, restore) become function pointers in an x86_ims_ops struct, that defaults to their implementations in ims.c and ims-msi.c. Cc: Jacob Pan Signed-off-by: Sanjay Kumar Signed-off-by: Megha Dey --- arch/x86/include/asm/pci.h | 4 ++++ arch/x86/include/asm/x86_init.h | 10 ++++++++++ arch/x86/kernel/apic/ims.c | 18 ++++++++++++++++++ arch/x86/kernel/x86_init.c | 23 +++++++++++++++++++++++ drivers/base/ims-msi.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/msi.h | 6 ++++++ 6 files changed, 95 insertions(+) diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index e662f98..2ef513f 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -114,6 +114,10 @@ struct msi_desc; int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); void native_teardown_msi_irq(unsigned int irq); void native_restore_msi_irqs(struct pci_dev *dev); +#ifdef CONFIG_MSI_IMS +int native_setup_ims_irqs(struct device *dev, int nvec); +#endif + #else #define native_setup_msi_irqs NULL #define native_teardown_msi_irq NULL diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index ac09341..9c2cbbb 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -287,6 +287,15 @@ struct x86_msi_ops { void (*restore_msi_irqs)(struct pci_dev *dev); }; +struct device; + +struct x86_ims_ops { + int (*setup_ims_irqs)(struct device *dev, int nvec); + void (*teardown_ims_irq)(unsigned int irq); + void (*teardown_ims_irqs)(struct device *dev); + void (*restore_ims_irqs)(struct device *dev); +}; + struct x86_apic_ops { unsigned int (*io_apic_read) (unsigned int apic, unsigned int reg); void (*restore)(void); @@ -297,6 +306,7 @@ extern struct x86_cpuinit_ops x86_cpuinit; extern struct x86_platform_ops x86_platform; extern struct x86_msi_ops x86_msi; extern struct x86_apic_ops x86_apic_ops; +extern struct x86_ims_ops x86_ims; extern void x86_early_init_platform_quirks(void); extern void x86_init_noop(void); diff --git a/arch/x86/kernel/apic/ims.c b/arch/x86/kernel/apic/ims.c index d9808a5..a539666 100644 --- a/arch/x86/kernel/apic/ims.c +++ b/arch/x86/kernel/apic/ims.c @@ -9,6 +9,7 @@ #include #include #include +#include /* * Determine if a dev is mdev or not. Return NULL if not mdev device. @@ -45,6 +46,23 @@ static struct pci_dev *ims_get_pci_dev(struct device *dev) return pdev; } +int native_setup_ims_irqs(struct device *dev, int nvec) +{ + struct irq_domain *domain; + struct irq_alloc_info info; + struct pci_dev *pdev = ims_get_pci_dev(dev); + + init_irq_alloc_info(&info, NULL); + info.type = X86_IRQ_ALLOC_TYPE_MSIX; + info.msi_dev = pdev; + + domain = irq_remapping_get_ims_irq_domain(&info); + if (!domain) + return -ENOSYS; + + return msi_domain_alloc_irqs(domain, dev, nvec); +} + int dev_ims_prepare(struct irq_domain *domain, struct device *dev, int nvec, msi_alloc_info_t *arg) { diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 1bef687..3ce42d4 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -153,6 +153,29 @@ void arch_restore_msi_irqs(struct pci_dev *dev) } #endif +#if defined(CONFIG_MSI_IMS) +struct x86_ims_ops x86_ims __ro_after_init = { + .setup_ims_irqs = native_setup_ims_irqs, + .teardown_ims_irqs = dev_ims_teardown_irqs, + .restore_ims_irqs = dev_ims_restore_irqs, +}; + +int arch_setup_ims_irqs(struct device *dev, int nvec) +{ + return x86_ims.setup_ims_irqs(dev, nvec); +} + +void arch_teardown_ims_irqs(struct device *dev) +{ + x86_ims.teardown_ims_irqs(dev); +} + +void arch_restore_ims_irqs(struct device *dev) +{ + x86_ims.restore_ims_irqs(dev); +} +#endif + struct x86_apic_ops x86_apic_ops __ro_after_init = { .io_apic_read = native_io_apic_read, .restore = native_restore_boot_irq_mode, diff --git a/drivers/base/ims-msi.c b/drivers/base/ims-msi.c index 68dc10f..df28ee2 100644 --- a/drivers/base/ims-msi.c +++ b/drivers/base/ims-msi.c @@ -92,3 +92,37 @@ void dev_ims_write_msg(struct irq_data *data, struct msi_msg *msg) __dev_write_ims_msg(desc, msg); } EXPORT_SYMBOL_GPL(dev_ims_write_msg); + +void dev_ims_teardown_irqs(struct device *dev) +{ + struct msi_desc *entry; + + for_each_msi_entry(entry, dev) + if (entry->irq && entry->tag == IRQ_MSI_TAG_IMS) + arch_teardown_msi_irq(entry->irq); +} + +static void dev_ims_restore_irq(struct device *dev, int irq) +{ + struct msi_desc *entry = NULL; + struct dev_ims_ops *ops; + + for_each_msi_entry(entry, dev) + if (irq == entry->irq && entry->tag == IRQ_MSI_TAG_IMS) + break; + + if (entry) { + ops = entry->dev_ims.priv->ims_ops; + if (ops && ops->irq_write_msi_msg) + ops->irq_write_msi_msg(entry, &entry->msg); + } +} + +void dev_ims_restore_irqs(struct device *dev) +{ + struct msi_desc *entry; + + for_each_msi_entry(entry, dev) + if (entry->tag == IRQ_MSI_TAG_IMS) + dev_ims_restore_irq(dev, entry->irq); +} diff --git a/include/linux/msi.h b/include/linux/msi.h index 246285a..37070bf 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -233,6 +233,8 @@ void pci_msi_unmask_irq(struct irq_data *data); void dev_ims_unmask_irq(struct irq_data *data); void dev_ims_mask_irq(struct irq_data *data); void dev_ims_write_msg(struct irq_data *data, struct msi_msg *msg); +void dev_ims_teardown_irqs(struct device *dev); +void dev_ims_restore_irqs(struct device *dev); /* * The arch hooks to setup up msi irqs. Those functions are @@ -245,6 +247,10 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); void arch_teardown_msi_irqs(struct pci_dev *dev); void arch_restore_msi_irqs(struct pci_dev *dev); +int arch_setup_ims_irqs(struct device *dev, int nvec); +void arch_teardown_ims_irqs(struct device *dev); +void arch_restore_ims_irqs(struct device *dev); + void default_teardown_msi_irqs(struct pci_dev *dev); void default_restore_msi_irqs(struct pci_dev *dev); -- 2.7.4