From patchwork Tue Nov 17 09:40:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shannon Zhao X-Patchwork-Id: 7634821 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 87A6BBF90C for ; Tue, 17 Nov 2015 09:57:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 70CE620489 for ; Tue, 17 Nov 2015 09:57:44 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 71E9120483 for ; Tue, 17 Nov 2015 09:57:43 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zycyu-0002xB-SO; Tue, 17 Nov 2015 09:55:20 +0000 Received: from mail-wm0-x234.google.com ([2a00:1450:400c:c09::234]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zyco3-0006Wf-4K for linux-arm-kernel@lists.infradead.org; Tue, 17 Nov 2015 09:44:14 +0000 Received: by wmww144 with SMTP id w144so145581379wmw.1 for ; Tue, 17 Nov 2015 01:43:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Mn6HgGlqIXPJq+7NcKEXMAMwL4OJioaJqXxcxteAK1E=; b=zBb1s5Hk9NgHlFAA25gq8dy5OPpqKTkATvWoy8yDy2HrdhC61Wl6ajmFvOXklUeSNP KLudYZNBlS4j6uG6Zoff9X/8ie5MiJykxT8jompp5O0r/J8xL2smW/oHAIXsLBUd63Bo 7NV991EHrW1mS/Ovu2JXLBjISMWSgP7CMcscDEGG/rZ3kCGn3lztCRu2dW8CSU8ru4e6 EhVoxPo12tyi8cCoDL4wYFP3KrhCaoU0tOl9sPpNo/oUrfuDzBlui7JtfV3ehgPu5+TI Kdm38U2I5U0WKS+eh0sUdIaDRkAkhb7APLzBCSafGp0Jnluo5uN+Idwj2j6fKuCzXYHl W0aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Mn6HgGlqIXPJq+7NcKEXMAMwL4OJioaJqXxcxteAK1E=; b=F5/od861e5cb5oExLjeMJbGFcwwNy/8UvEKpLKQvM8tdvhg3TgEmA0v9roNZ54nsfV CykO2RvGlqZMWLKwc2Qu9VUCTne/S8njxFCtEPEeLo2qoHzGHXly8yQXCduGK2Gfqe0f KW5gWRDZiTmbydDlua8PGoru+F/ne7WFe22r8ArbY85MMz3i0JUF47GYioTn+xpuSBB8 EVGKMayw1zkpvkkct9g7ksVAryDEGCpS/j6DDS3ZrGX9n4AF+d5n6iaT/DP8QdjMnOzH xyEf2lK6rhqZPkku9XRHm4GkFwAcwHGM8xv+BeyL91CHuBH+a0qXK6r1Y4ejSPRqr2yD nZtw== X-Gm-Message-State: ALoCoQloz8BItcb1zKCvsBnTI8j5P6Ng3rfOfPzX9ecTEy/Pcky5/7hufYho1BxEr0m5QmM1znH4 X-Received: by 10.28.107.26 with SMTP id g26mr1541863wmc.34.1447753425660; Tue, 17 Nov 2015 01:43:45 -0800 (PST) Received: from localhost ([78.129.251.54]) by smtp.gmail.com with ESMTPSA id z1sm7157046wje.35.2015.11.17.01.43.42 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 17 Nov 2015 01:43:44 -0800 (PST) From: shannon.zhao@linaro.org To: ian.campbell@citrix.com, stefano.stabellini@citrix.com, keir@xen.org, jbeulich@suse.com, andrew.cooper3@citrix.com, julien.grall@citrix.com, xen-devel@lists.xen.org Subject: [PATCH v3 18/62] arm/acpi: Parse MADT to map logical cpu to MPIDR and get cpu_possible_map Date: Tue, 17 Nov 2015 17:40:17 +0800 Message-Id: <1447753261-7552-19-git-send-email-shannon.zhao@linaro.org> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1447753261-7552-1-git-send-email-shannon.zhao@linaro.org> References: <1447753261-7552-1-git-send-email-shannon.zhao@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151117_014408_126181_85F05BE9 X-CRM114-Status: GOOD ( 19.14 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, hangaohuai@huawei.com, ard.biesheuvel@linaro.org, shannon.zhao@linaro.org, christoffer.dall@linaro.org, peter.huangpeng@huawei.com, david.vrabel@citrix.com, zhaoshenglong@huawei.com, linux-arm-kernel@lists.infradead.org, roger.pau@citrix.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Parth Dixit MADT contains the information for MPIDR which is essential for SMP initialization, parse the GIC cpu interface structures to get the MPIDR value and map it to cpu_logical_map(), and add enabled cpu with valid MPIDR into cpu_possible_map. Signed-off-by: Hanjun Guo Signed-off-by: Tomasz Nowicki Signed-off-by: Naresh Bhat Signed-off-by: Parth Dixit Signed-off-by: Shannon Zhao --- xen/arch/arm/acpi/boot.c | 121 +++++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/acpi.h | 2 + xen/include/xen/acpi.h | 4 ++ 3 files changed, 127 insertions(+) diff --git a/xen/arch/arm/acpi/boot.c b/xen/arch/arm/acpi/boot.c index 0fabe7d..913d2a5 100644 --- a/xen/arch/arm/acpi/boot.c +++ b/xen/arch/arm/acpi/boot.c @@ -32,6 +32,127 @@ #include #include +#include + +/* Processors with enabled flag and sane MPIDR */ +static int enabled_cpus; + +/* Boot CPU is valid or not in MADT */ +static bool_t __initdata bootcpu_valid; + +/* total number of cpus in this system */ +static unsigned int __initdata total_cpus = 0; + +/* + * acpi_map_gic_cpu_interface - generates a logical cpu number + * and map to MPIDR represented by GICC structure + */ +static void __init +acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor) +{ + int i; + u64 mpidr = processor->arm_mpidr & MPIDR_HWID_MASK; + bool enabled = !!(processor->flags & ACPI_MADT_ENABLED); + + if (mpidr == MPIDR_INVALID) { + printk("Skip MADT cpu entry with invalid MPIDR\n"); + return; + } + + total_cpus++; + if (!enabled) + return; + + if (enabled_cpus >= NR_CPUS) { + printk("NR_CPUS limit of %d reached, Processor %d/0x%"PRIx64" ignored.\n", + NR_CPUS, total_cpus, mpidr); + return; + } + + /* Check if GICC structure of boot CPU is available in the MADT */ + if (cpu_logical_map(0) == mpidr) { + if (bootcpu_valid) { + printk("Firmware bug, duplicate CPU MPIDR: 0x%"PRIx64" in MADT\n", + mpidr); + return; + } + + bootcpu_valid = true; + } + + /* + * Duplicate MPIDRs are a recipe for disaster. Scan + * all initialized entries and check for + * duplicates. If any is found just ignore the CPU. + */ + for (i = 1; i < enabled_cpus; i++) { + if (cpu_logical_map(i) == mpidr) { + printk("Firmware bug, duplicate CPU MPIDR: 0x%"PRIx64" in MADT\n", + mpidr); + return; + } + } + + if (!acpi_psci_present()) + return; + + /* CPU 0 was already initialized */ + if (enabled_cpus) { + if (arch_cpu_init(enabled_cpus, NULL) < 0) + return; + + /* map the logical cpu id to cpu MPIDR */ + cpu_logical_map(enabled_cpus) = mpidr; + } + + enabled_cpus++; +} + +static int __init +acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_madt_generic_interrupt *processor; + + processor = (struct acpi_madt_generic_interrupt *)header; + + if (BAD_MADT_ENTRY(processor, end)) + return -EINVAL; + + acpi_table_print_madt_entry(header); + acpi_map_gic_cpu_interface(processor); + return 0; +} + +/* Parse GIC cpu interface entries in MADT for SMP init */ +void __init acpi_smp_init_cpus(void) +{ + int count, i; + + /* + * do a partial walk of MADT to determine how many CPUs + * we have including disabled CPUs, and get information + * we need for SMP init + */ + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, + acpi_parse_gic_cpu_interface, 0); + + if (count <= 0) { + printk("Error parsing GIC CPU interface entry\n"); + return; + } + + if (!bootcpu_valid) { + printk("MADT missing boot CPU MPIDR, not enabling secondaries\n"); + return; + } + + for (i = 0; i < enabled_cpus; i++) + cpumask_set_cpu(i, &cpu_possible_map); + + /* Make boot-up look pretty */ + printk("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus); +} static int __init acpi_parse_fadt(struct acpi_table_header *table) { diff --git a/xen/include/asm-arm/acpi.h b/xen/include/asm-arm/acpi.h index 65f80b1..1efa29d 100644 --- a/xen/include/asm-arm/acpi.h +++ b/xen/include/asm-arm/acpi.h @@ -33,9 +33,11 @@ extern bool_t acpi_disabled; #ifdef CONFIG_ACPI bool_t __init acpi_psci_present(void); bool_t __init acpi_psci_hvc_present(void); +void __init acpi_smp_init_cpus(void); #else static inline bool_t acpi_psci_present(void) { return false; } static inline bool_t acpi_psci_hvc_present(void) {return false; } +static inline void acpi_smp_init_cpus(void) { } #endif /* CONFIG_ACPI */ /* Basic configuration for ACPI */ diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h index 48d7810..723ece8 100644 --- a/xen/include/xen/acpi.h +++ b/xen/include/xen/acpi.h @@ -39,6 +39,10 @@ #define ACPI_MADT_GET_POLARITY(inti) ACPI_MADT_GET_(POLARITY, inti) #define ACPI_MADT_GET_TRIGGER(inti) ACPI_MADT_GET_(TRIGGER, inti) +#define BAD_MADT_ENTRY(entry, end) ( \ + (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ + ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) + #ifdef CONFIG_ACPI_BOOT enum acpi_interrupt_id {