From patchwork Mon Mar 12 06:49:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Yingliang X-Patchwork-Id: 10275537 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 124B7602C2 for ; Mon, 12 Mar 2018 06:52:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3EED28BCC for ; Mon, 12 Mar 2018 06:52:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E827228BD5; Mon, 12 Mar 2018 06:52:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5DAF228BCC for ; Mon, 12 Mar 2018 06:52:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WEEuOj1roVcEpSPm8sb4oOKvnQltOiQwLnVTby7LHW8=; b=V0708wMCLDl2ez 12C+QoXMxO49exqOVhLNk435Nvq6v3NDAjpKbHzHWEyAueFQe8MPkBmiT+ndcwLyUVzaiS4yhO4wk SujGRzyS0YZFOQZWJRyHHdN+PUXUqjtL8r0yJN9K9ILL1P6x9QsKocQMNt2cyeO/YZT5wxxS22xtm fxgznZUlhwl08W49u3LaVyVfDqQYgwalzPI8kxKFHrxCqt+p0HIxbqFgSFmUHopcR0SJSWxC2d9qd qZnzzYH+R2uDTYJqwHXdoRsobkDLKy1FoyigHj1dXP7DYyxyrs3zs93tu/Q+nS2MRmGLlR469qrr4 M7jjyyBCY4b4eKutzFog==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1evHJQ-00069d-6i; Mon, 12 Mar 2018 06:52:00 +0000 Received: from szxga05-in.huawei.com ([45.249.212.191] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1evHIA-0005Qz-5p for linux-arm-kernel@lists.infradead.org; Mon, 12 Mar 2018 06:50:46 +0000 Received: from DGGEMS402-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id C4CAE9D02C595; Mon, 12 Mar 2018 14:50:13 +0800 (CST) Received: from localhost (10.177.19.219) by DGGEMS402-HUB.china.huawei.com (10.3.19.202) with Microsoft SMTP Server id 14.3.361.1; Mon, 12 Mar 2018 14:50:05 +0800 From: Yang Yingliang To: Subject: [RFC PATCH 3/4] irqchip/gic-v3-its: change prop_page to per-cpu type to support CommonLPIAff field Date: Mon, 12 Mar 2018 14:49:54 +0800 Message-ID: <1520837395-10288-4-git-send-email-yangyingliang@huawei.com> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1520837395-10288-1-git-send-email-yangyingliang@huawei.com> References: <1520837395-10288-1-git-send-email-yangyingliang@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.19.219] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180311_235042_568426_4F3C1FB2 X-CRM114-Status: GOOD ( 13.47 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, yangyingliang@huawei.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Change prop_page to per-cpu type and add its_cpu_allocate_prop_tables() to allocate LPI property tables. This function is called by each oneline cpu and allocate tables according to the value of CommonLPIAff. The spec defines the field: CommonLPIAff, bits [25:24] The affinity level at which Redistributors share a LPI Configuration table. 00 All Redistributors must share a LPI Configuration table. 01 All Redistributors with the same Aff3 value must share an LPI Configurationt table. 10 All Redistributors with the same Aff3.Aff2 value must share an LPI Configuration table. 11 All Redistributors with the same Aff3.Aff2.Aff1 value must share an LPI Configuration table. Signed-off-by: Yang Yingliang --- drivers/irqchip/irq-gic-v3-its.c | 81 ++++++++++++++++++++++++++++---------- include/linux/irqchip/arm-gic-v3.h | 6 ++- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 4ebe131..02a5d95 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1070,7 +1070,7 @@ static void lpi_write_config(struct irq_data *d, u8 clr, u8 set) map->properties &= ~clr; map->properties |= set | LPI_PROP_GROUP1; } else { - prop_page = gic_rdists->prop_page; + prop_page = gic_data_rdist()->prop_page; hwirq = d->hwirq; } @@ -1582,24 +1582,6 @@ static void its_free_prop_table(struct page *prop_page) get_order(LPI_PROPBASE_SZ)); } -static int __init its_alloc_lpi_tables(void) -{ - phys_addr_t paddr; - - lpi_id_bits = min_t(u32, gic_rdists->id_bits, ITS_MAX_LPI_NRBITS); - gic_rdists->prop_page = its_allocate_prop_table(cpu_to_node(smp_processor_id()), - GFP_NOWAIT); - if (!gic_rdists->prop_page) { - pr_err("Failed to allocate PROPBASE\n"); - return -ENOMEM; - } - - paddr = page_to_phys(gic_rdists->prop_page); - pr_info("GIC: using LPI property table @%pa\n", &paddr); - - return its_lpi_init(lpi_id_bits); -} - static const char *its_base_type_string[] = { [GITS_BASER_TYPE_DEVICE] = "Devices", [GITS_BASER_TYPE_VCPU] = "Virtual CPUs", @@ -1935,7 +1917,7 @@ static void its_cpu_init_lpis(void) dsb(sy); /* set PROPBASE */ - val = (page_to_phys(gic_rdists->prop_page) | + val = (page_to_phys(gic_data_rdist()->prop_page) | GICR_PROPBASER_InnerShareable | GICR_PROPBASER_RaWaWb | ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK)); @@ -2037,6 +2019,59 @@ static void its_cpu_init_collection(void) spin_unlock(&its_lock); } +static int __init its_cpu_allocate_prop_tables(void) +{ + phys_addr_t paddr; + unsigned long flags; + int match_cpu; + u64 aff_mask = 0; + struct page *prop_page = NULL; + int cpu = smp_processor_id(); + + switch (gic_rdists->common_aff_lpi) { + case GICR_COMMON_ALL_SHARE: + aff_mask = 0; + break; + case GICR_COMMON_AFF3_SHARE: + aff_mask = 0xffULL << MPIDR_LEVEL_SHIFT(3); + break; + case GICR_COMMON_AFF3_AFF2_SHARE: + aff_mask = (0xffULL << MPIDR_LEVEL_SHIFT(3)) | + (0xffULL << MPIDR_LEVEL_SHIFT(2)); + break; + case GICR_COMMON_AFF3_AFF2_AFF1_SHARE: + aff_mask = (0xffULL << MPIDR_LEVEL_SHIFT(3)) | + (0xffULL << MPIDR_LEVEL_SHIFT(2)) | + (0xffULL << MPIDR_LEVEL_SHIFT(1)); + break; + default: + pr_err("Bad common_aff_lpi:%d\n", gic_rdists->common_aff_lpi); + } + + raw_spin_lock_irqsave(&gic_rdists->lock, flags); + for_each_cpu(match_cpu, cpu_possible_mask) { + struct page *match_prop_page = per_cpu_ptr(gic_rdists->rdist, match_cpu)->prop_page; + if ((cpu_logical_map(cpu) & aff_mask) == (cpu_logical_map(match_cpu) & aff_mask) && + match_prop_page) { + prop_page = match_prop_page; + break; + } + } + if (!prop_page) { + prop_page = its_allocate_prop_table(cpu_to_node(cpu), GFP_NOWAIT); + pr_err("Failed to allocate PROPBASE\n"); + raw_spin_unlock_irqrestore(&gic_rdists->lock, flags); + return -ENOMEM; + } + gic_data_rdist()->prop_page = prop_page; + raw_spin_unlock_irqrestore(&gic_rdists->lock, flags); + + paddr = page_to_phys(gic_data_rdist()->prop_page); + pr_info("CPU%d using LPI property table @%pa\n", cpu, &paddr); + + return 0; +} + static struct its_device *its_find_device(struct its_node *its, u32 dev_id) { struct its_device *its_dev = NULL, *tmp; @@ -3340,10 +3375,14 @@ static bool gic_rdists_supports_plpis(void) int its_cpu_init(void) { if (!list_empty(&its_nodes)) { + int err; if (!gic_rdists_supports_plpis()) { pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); return -ENXIO; } + err = its_cpu_allocate_prop_tables(); + if (err) + return err; its_cpu_init_lpis(); its_cpu_init_collection(); } @@ -3551,7 +3590,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, } gic_rdists = rdists; - err = its_alloc_lpi_tables(); + err = its_lpi_init(min_t(u32, gic_rdists->id_bits, ITS_MAX_LPI_NRBITS)); if (err) return err; diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 6da670a..35cafd9 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -109,6 +109,10 @@ #define GICR_TYPER_CPU_NUMBER(r) (((r) >> 8) & 0xffff) #define GICR_TYPER_COMMON_AFF_LPI(r) (((r) >> 24) & 3) +#define GICR_COMMON_ALL_SHARE 0 +#define GICR_COMMON_AFF3_SHARE 1 +#define GICR_COMMON_AFF3_AFF2_SHARE 2 +#define GICR_COMMON_AFF3_AFF2_AFF1_SHARE 3 #define GICR_WAKER_ProcessorSleep (1U << 1) #define GICR_WAKER_ChildrenAsleep (1U << 2) @@ -571,9 +575,9 @@ struct rdists { struct { void __iomem *rd_base; struct page *pend_page; + struct page *prop_page; phys_addr_t phys_base; } __percpu *rdist; - struct page *prop_page; int id_bits; u64 flags; bool has_vlpis;