Received: by 2002:a05:6358:c692:b0:131:369:b2a3 with SMTP id fe18csp5531508rwb; Tue, 1 Aug 2023 04:18:37 -0700 (PDT) X-Google-Smtp-Source: APBJJlEp7KmYD7EDRV3qIStaRlRxWHCxo8NC27jhdGDfl5GLIH0zGNuEL86fBqb/4s5E2Cr50JG7 X-Received: by 2002:a05:6a21:4843:b0:135:4388:3978 with SMTP id au3-20020a056a21484300b0013543883978mr12231722pzc.29.1690888717639; Tue, 01 Aug 2023 04:18:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690888717; cv=none; d=google.com; s=arc-20160816; b=mp3FftY4yWIZfydxUtUjjDJgs6NSeZgr2F90bAIm//mjB9iV3LnHAzLUx48TzhxOT1 jUwbNhe8dqHva91ZkfQX1Eng5uvZlKXXBEsjOfbNpTM9syxjvTjTpKpGTCwm3hy2mgvu d+A21xfaeaFwQBL6fmMNa5qsoYuA/+Megi3InOdfTAPw2yaNrgdzBEIr2fBHoW/jHicV DN7FIRso6XJp82BN8xYQV43YpdaRYCwN62rywuEOtoawWiEkAnyMtbGIRnvmNyEuF8wt bFPMvgnbqe8C+PDuFN9rpGzl3cuRJc/NUSEgl7fghxhClCon2EFkmm5FM9uBhRonvoEx 7oSA== 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=tXQKKwpyD/5KWCvdmuzL9UCOi5F812bKdsX6A+OvjaI=; fh=mE3iieUIZLcDfOLIULj9X6/p0bMDPZGFSVRsnyRUnTc=; b=BCdgl+U0epgWQT49elpi3fByrYg2GQ/hC+stG3qQ39HcgAXEDrLouJdrkOkLA+3DRG cE4FwXF1w66H4M+YvgYI2YeMkQjhHzrAMI9wFuzspcvfuQwUbGcg8GFCWqXLMt4VyTlc KFBKyMcGMmv8k8QfYYYCWo631nR1cTSvgza234z69wNnekf57gPuljQexUL9IlF3y2G8 u8McdNqJw+6FfidDFIi4d3ly7SkbNMHNEFvrCh2nsfHJVAx+zPv2n3OJCw8CPx2TkTw5 iulGWzbmINP5TJmKJyi3mMOg0v1LOU/WxWirRLc/qiIuGtXxsecFiaJHIrP6pjYL/IkU +gJw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=Mn9w4RJy; 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 g5-20020a056a001a0500b0067af445c0f0si1823995pfv.291.2023.08.01.04.18.26; Tue, 01 Aug 2023 04:18:37 -0700 (PDT) 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=Mn9w4RJy; 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 S233926AbjHAKrb (ORCPT + 99 others); Tue, 1 Aug 2023 06:47:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233345AbjHAKrA (ORCPT ); Tue, 1 Aug 2023 06:47:00 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5126F1BF0 for ; Tue, 1 Aug 2023 03:46:55 -0700 (PDT) Message-ID: <20230801103815.707466941@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1690886813; 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=tXQKKwpyD/5KWCvdmuzL9UCOi5F812bKdsX6A+OvjaI=; b=Mn9w4RJyrHBhyieWkk9u0q52FPjCH9y2Zr91JEAbjpj1hUuZyRhsrJyOpEpF9LT+lPRXz5 gLHSeeoqpwR46IVVyuYAP6zYfrq5XMgoptLLgpZZJRr7G+88ek6RbmoRAaefP7p36MK+vm u6ymRBhNT1sd/0MI6/GN3juPfpjVBsA5KxjuAMaExahKpU7AuDdvNkzuT2yiGIcZq4C2wx RxPJVRpqPM7Pj3K+c7l0t1R866FVJlvMKcZDKJMFXXFkSqtZ/44bMdcIEkeD3oAUfCviwl Mz6t7BCnDtvHw7SszShT6qGj4CXkOVY6eMGWczlmGXh19Mjmd0icaeeUpa20IA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1690886813; 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=tXQKKwpyD/5KWCvdmuzL9UCOi5F812bKdsX6A+OvjaI=; b=KPaCfvKXD6FpJehHm2N0Z52D4OsXF745gCdHq0blGpbfmiLPN4b7Hy2P73VdxgzUTovPo4 EMMfgwpgm56I/ZCg== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Andrew Cooper , Tom Lendacky , Paolo Bonzini , Wei Liu , Arjan van de Ven , Juergen Gross , Michael Kelley , Peter Keresztes Schmidt , "Peter Zijlstra (Intel)" Subject: [patch V3 10/60] x86/apic: Register boot CPU APIC early References: <20230801103042.936020332@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Tue, 1 Aug 2023 12:46:53 +0200 (CEST) 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,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED 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 Register the boot CPU APIC right when the boot CPUs APIC is read from the hardware. No point is doing this on random places and having wild heuristics to save the boot CPU APIC ID slot and CPU number 0 reserved. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- arch/x86/kernel/apic/apic.c | 120 ++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 70 deletions(-) --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1734,6 +1734,8 @@ void apic_ap_setup(void) end_local_APIC_setup(); } +static __init void cpu_set_boot_apic(void); + static __init void apic_read_boot_cpu_id(bool x2apic) { /* @@ -1748,9 +1750,9 @@ static __init void apic_read_boot_cpu_id boot_cpu_physical_apicid = read_apic_id(); boot_cpu_apic_version = GET_APIC_VERSION(apic_read(APIC_LVR)); } + cpu_set_boot_apic(); } - #ifdef CONFIG_X86_X2APIC int x2apic_mode; EXPORT_SYMBOL_GPL(x2apic_mode); @@ -2426,76 +2428,8 @@ static int allocate_logical_cpuid(int ap return nr_logical_cpuids++; } -int generic_processor_info(int apicid, int version) +static void cpu_update_apic(int cpu, int apicid, int version) { - int cpu, max = nr_cpu_ids; - bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid, - phys_cpu_present_map); - - /* - * boot_cpu_physical_apicid is guaranteed to contain the boot CPU - * APIC ID read from the local APIC when this function is invoked. - */ - if (disabled_cpu_apicid != boot_cpu_physical_apicid && - disabled_cpu_apicid == apicid) { - int thiscpu = num_processors + disabled_cpus; - - pr_warn("APIC: Disabling requested cpu. Processor %d/0x%x ignored.\n", - thiscpu, apicid); - - disabled_cpus++; - return -ENODEV; - } - - /* - * If boot cpu has not been detected yet, then only allow upto - * nr_cpu_ids - 1 processors and keep one slot free for boot cpu - */ - if (!boot_cpu_detected && num_processors >= nr_cpu_ids - 1 && - apicid != boot_cpu_physical_apicid) { - int thiscpu = max + disabled_cpus - 1; - - pr_warn("APIC: NR_CPUS/possible_cpus limit of %i almost" - " reached. Keeping one slot for boot cpu." - " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); - - disabled_cpus++; - return -ENODEV; - } - - if (num_processors >= nr_cpu_ids) { - int thiscpu = max + disabled_cpus; - - pr_warn("APIC: NR_CPUS/possible_cpus limit of %i reached. " - "Processor %d/0x%x ignored.\n", max, thiscpu, apicid); - - disabled_cpus++; - return -EINVAL; - } - - if (apicid == boot_cpu_physical_apicid) { - /* - * x86_cpu_to_apicid is required to have processors listed - * in same order as logical cpu numbers. Hence the first - * entry is BSP, and so on. - * boot_cpu_init() already hold bit 0 in cpu_present_mask - * for BSP. - */ - cpu = 0; - - /* Logical cpuid 0 is reserved for BSP. */ - cpuid_to_apicid[0] = apicid; - } else { - cpu = allocate_logical_cpuid(apicid); - if (cpu < 0) { - disabled_cpus++; - return -EINVAL; - } - } - - /* - * Validate version - */ if (version == 0x0) { pr_warn("BIOS bug: APIC version is 0 for CPU %d/0x%x, fixing up to 0x10\n", cpu, apicid); @@ -2521,10 +2455,56 @@ int generic_processor_info(int apicid, i if (system_state != SYSTEM_BOOTING) cpu_mark_primary_thread(cpu, apicid); +} + +static __init void cpu_set_boot_apic(void) +{ + cpuid_to_apicid[0] = boot_cpu_physical_apicid; + cpu_update_apic(0, boot_cpu_physical_apicid, boot_cpu_apic_version); +} + +int generic_processor_info(int apicid, int version) +{ + int cpu, max = nr_cpu_ids; + + /* The boot CPU must be set before MADT/MPTABLE parsing happens */ + if (cpuid_to_apicid[0] == BAD_APICID) + panic("Boot CPU APIC not registered yet\n"); + + if (apicid == boot_cpu_physical_apicid) + return 0; + + if (disabled_cpu_apicid == apicid) { + int thiscpu = num_processors + disabled_cpus; + + pr_warn("APIC: Disabling requested cpu. Processor %d/0x%x ignored.\n", + thiscpu, apicid); + disabled_cpus++; + return -ENODEV; + } + + if (num_processors >= nr_cpu_ids) { + int thiscpu = max + disabled_cpus; + + pr_warn("APIC: NR_CPUS/possible_cpus limit of %i reached. " + "Processor %d/0x%x ignored.\n", max, thiscpu, apicid); + + disabled_cpus++; + return -EINVAL; + } + + cpu = allocate_logical_cpuid(apicid); + if (cpu < 0) { + disabled_cpus++; + return -EINVAL; + } + + cpu_update_apic(cpu, apicid, version); return cpu; } + void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg, bool dmar) {