Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp1742483ybl; Sat, 11 Jan 2020 01:54:40 -0800 (PST) X-Google-Smtp-Source: APXvYqzDz9Zsel0RtwO45QGFzVMwqFmFnNhk4X132NL81OB4CUCDbYegV3Zom1+CI9aSR94iRSbm X-Received: by 2002:a9d:7c91:: with SMTP id q17mr6459978otn.293.1578736480169; Sat, 11 Jan 2020 01:54:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578736480; cv=none; d=google.com; s=arc-20160816; b=arQjOqF5tVQAA2WiCIxXHqbKLWVueH3mwxNy00wCNpqX8C+FSk6MBZutepbQemF1Ny qMwolLhYsle12M+nsb1ZihFK3hSYgTzqW47qSblqWwDZD37eEu+e/eopBGpFvQNm0oD/ 0TUhickRqGE/cWwa1/bXvy27ZGjoeDmQh5XJAz893jtBgtQvrih065y3FaYnqH6NP0tc dhlrc/MH0qMP5cliGgr/Viq50bo74CvBBlwcYxDVamU4suoK6yvFm61kW8+K3ybnR3ll 3BYJkYCiVRIk6n9t1DmH6H4XToGNDQ4WClSxyNtrVZhq9UAbW+9luD3hVjpug9KW/8Aq e9PA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=mKgi8Vf+Nhhu1FrKXzP53KhI1FIceTnOzLjV7OIq5uU=; b=Sx7vWM9VgsRmIaRAqaPoP16ygb8kmrwAKAhLOBgpVwKd3nv1z/c773VsaMI368hzeW vJOBn99FSpz+ZMRz5vEV6BS6UU6B5ru9Bex0iPI8MAmodkoAOUTpjM73DiVRZZUZtZHY y9KdfiyjZbc27d0SOgApS2wbVrpXcIwNkpdglT9I+zIM7WT9UGgO5l6lCCWgmqup4J4F FJVAu6fNVLmeCmk4BPqeacd8XuYexqRut5a0vSeJ5Ud1Ch/GIU7tKC72rCV7v1C6l+Ql vAo+MhVlozOwqnme548n4PkncQ3xElmaqjV1BP3McvoVlH0FBpW5o0AUTxKVvVRr7En1 KBjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=gUfy4aq3; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e18si3478325oti.153.2020.01.11.01.54.29; Sat, 11 Jan 2020 01:54:40 -0800 (PST) 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; dkim=pass header.i=@kernel.org header.s=default header.b=gUfy4aq3; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728900AbgAKJxk (ORCPT + 99 others); Sat, 11 Jan 2020 04:53:40 -0500 Received: from mail.kernel.org ([198.145.29.99]:40744 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728788AbgAKJxk (ORCPT ); Sat, 11 Jan 2020 04:53:40 -0500 Received: from localhost (unknown [62.119.166.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 38EC52077C; Sat, 11 Jan 2020 09:53:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1578736419; bh=fhlcQmFWTNKfyMD+4xBpzmIXoNDEIhJpEW5MJ8XJlgA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gUfy4aq3InIGu83SWZU9GxZBT/DzHig6kikDltRF0FhKnDozYFx8SBpDr6fIZpyA3 pXcyHVh9dR59P8rEWcR/yhLDPSG66Ea1uskgDcoMBdGySnQgm3nxFZDa3Y4wMvWW1y HNGC6GK1xcw0XQV7xiAND0mwAnokXXC5d9wKVjOI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Heiko Carstens , Vasily Gorbik , Sasha Levin Subject: [PATCH 4.4 31/59] s390/smp: fix physical to logical CPU map for SMT Date: Sat, 11 Jan 2020 10:49:40 +0100 Message-Id: <20200111094844.629668515@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200111094835.417654274@linuxfoundation.org> References: <20200111094835.417654274@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Heiko Carstens [ Upstream commit 72a81ad9d6d62dcb79f7e8ad66ffd1c768b72026 ] If an SMT capable system is not IPL'ed from the first CPU the setup of the physical to logical CPU mapping is broken: the IPL core gets CPU number 0, but then the next core gets CPU number 1. Correct would be that all SMT threads of CPU 0 get the subsequent logical CPU numbers. This is important since a lot of code (like e.g. the CPU topology code) assumes that CPU maps are setup like this. If the mapping is broken the system will not IPL due to broken topology masks: [ 1.716341] BUG: arch topology broken [ 1.716342] the SMT domain not a subset of the MC domain [ 1.716343] BUG: arch topology broken [ 1.716344] the MC domain not a subset of the BOOK domain This scenario can usually not happen since LPARs are always IPL'ed from CPU 0 and also re-IPL is intiated from CPU 0. However older kernels did initiate re-IPL on an arbitrary CPU. If therefore a re-IPL from an old kernel into a new kernel is initiated this may lead to crash. Fix this by setting up the physical to logical CPU mapping correctly. Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik Signed-off-by: Sasha Levin --- arch/s390/kernel/smp.c | 80 ++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 29e5409c0d48..f113fcd781d8 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -702,39 +702,67 @@ static struct sclp_core_info *smp_get_core_info(void) static int smp_add_present_cpu(int cpu); -static int __smp_rescan_cpus(struct sclp_core_info *info, int sysfs_add) +static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail, + bool configured, bool early) { struct pcpu *pcpu; - cpumask_t avail; - int cpu, nr, i, j; + int cpu, nr, i; u16 address; nr = 0; - cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask); - cpu = cpumask_first(&avail); - for (i = 0; (i < info->combined) && (cpu < nr_cpu_ids); i++) { - if (sclp.has_core_type && info->core[i].type != boot_core_type) + if (sclp.has_core_type && core->type != boot_core_type) + return nr; + cpu = cpumask_first(avail); + address = core->core_id << smp_cpu_mt_shift; + for (i = 0; (i <= smp_cpu_mtid) && (cpu < nr_cpu_ids); i++) { + if (pcpu_find_address(cpu_present_mask, address + i)) continue; - address = info->core[i].core_id << smp_cpu_mt_shift; - for (j = 0; j <= smp_cpu_mtid; j++) { - if (pcpu_find_address(cpu_present_mask, address + j)) - continue; - pcpu = pcpu_devices + cpu; - pcpu->address = address + j; - pcpu->state = - (cpu >= info->configured*(smp_cpu_mtid + 1)) ? - CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; - smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); - set_cpu_present(cpu, true); - if (sysfs_add && smp_add_present_cpu(cpu) != 0) - set_cpu_present(cpu, false); - else - nr++; - cpu = cpumask_next(cpu, &avail); - if (cpu >= nr_cpu_ids) + pcpu = pcpu_devices + cpu; + pcpu->address = address + i; + if (configured) + pcpu->state = CPU_STATE_CONFIGURED; + else + pcpu->state = CPU_STATE_STANDBY; + smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); + set_cpu_present(cpu, true); + if (!early && smp_add_present_cpu(cpu) != 0) + set_cpu_present(cpu, false); + else + nr++; + cpumask_clear_cpu(cpu, avail); + cpu = cpumask_next(cpu, avail); + } + return nr; +} + +static int __smp_rescan_cpus(struct sclp_core_info *info, bool early) +{ + struct sclp_core_entry *core; + cpumask_t avail; + bool configured; + u16 core_id; + int nr, i; + + nr = 0; + cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask); + /* + * Add IPL core first (which got logical CPU number 0) to make sure + * that all SMT threads get subsequent logical CPU numbers. + */ + if (early) { + core_id = pcpu_devices[0].address >> smp_cpu_mt_shift; + for (i = 0; i < info->configured; i++) { + core = &info->core[i]; + if (core->core_id == core_id) { + nr += smp_add_core(core, &avail, true, early); break; + } } } + for (i = 0; i < info->combined; i++) { + configured = i < info->configured; + nr += smp_add_core(&info->core[i], &avail, configured, early); + } return nr; } @@ -782,7 +810,7 @@ static void __init smp_detect_cpus(void) /* Add CPUs present at boot */ get_online_cpus(); - __smp_rescan_cpus(info, 0); + __smp_rescan_cpus(info, true); put_online_cpus(); kfree(info); } @@ -1140,7 +1168,7 @@ int __ref smp_rescan_cpus(void) return -ENOMEM; get_online_cpus(); mutex_lock(&smp_cpu_state_mutex); - nr = __smp_rescan_cpus(info, 1); + nr = __smp_rescan_cpus(info, false); mutex_unlock(&smp_cpu_state_mutex); put_online_cpus(); kfree(info); -- 2.20.1