From patchwork Mon Dec 4 02:40:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 844064 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yqq165WPjz9s7B for ; Mon, 4 Dec 2017 13:42:50 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ivOwsapY"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3yqq164KMKzDrqg for ; Mon, 4 Dec 2017 13:42:50 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ivOwsapY"; dkim-atps=neutral X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:400e:c00::243; helo=mail-pf0-x243.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ivOwsapY"; dkim-atps=neutral Received: from mail-pf0-x243.google.com (mail-pf0-x243.google.com [IPv6:2607:f8b0:400e:c00::243]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3yqpz85p56zDrZW for ; Mon, 4 Dec 2017 13:41:08 +1100 (AEDT) Received: by mail-pf0-x243.google.com with SMTP id a90so7462199pfk.1 for ; Sun, 03 Dec 2017 18:41:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=ABObf+DysQYVanu39DSE3+G1WgStYFgD/VXAlCcaEsU=; b=ivOwsapY6ain6w+OUABgz73iZuDMFKDGDK2+H4cbjw9MPgDnirTEizlWtza/IXYEOs +jWsl9L+D/C4QkI49hKwj4zteV55hZrFwYM6cLlhnkWqUifRVlUo7F7KUeWRGSkgxRiB alDUWu3v4HpKtg4iTAPNOo3p6mhJ5a6K2mVaqOPX4o9cqMWDm4ALrdkZIJpeM60ZlMD1 +d+zfIcMm4TCoQ6rj0ukaFTvT1vCSgpy6A3Fp8O8CWONGT1YvjE4oKqg2LOYc7teHl4j EQwuCpo4ah0YuTfabYX4V1dehKFoYWLObUDrKRh1/fIdgLaUVqKYyjqlX6WuhsFEekNk btsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ABObf+DysQYVanu39DSE3+G1WgStYFgD/VXAlCcaEsU=; b=oza6RHY9J4sm5kzipOomQumPiAg55VfM5jKFxg+7X+oY405zMTzqXBc8H7A/j8VlSS tb7xaB/KW5ShhCvTzx0Gg9Mzc2srHImLQFrlJOdt2oeyeFzYN1jKgmarKxqSOgOukpsy iXInXreCt5kAlbW2mYfd36jFsiEbcpVyB/KMrOWV+Crjz4rlYwxrPrZHIUanQ8WAwF+h 83iFqL6iXtLyw3C+zk3liP9dtCqbjmm/jRNOPnQ8yXBjiG3z9sxy2jEbHB3bQ7d30DgJ 450WAnQHMy0AYcBiW3u1Bj69KtFwX8FVyMfO5FrzdhfScWL5qBgLOFzikRZJgXLh/doe Bykw== X-Gm-Message-State: AJaThX7ppfW2qWm13hupMKUHx26UK6+f/XE/LNj1Hr/cMOyL5BOQfqj5 qfrk8MSmcByiHvh1ukK27Pobcg== X-Google-Smtp-Source: AGs4zMYmKJSZ8zQPwvBbZUhdyQPfzxLXGlRjHEHOySmbkoX1mc1MzCTb9atSolh0yPAtPErOmJHODQ== X-Received: by 10.84.132.34 with SMTP id 31mr12854400ple.395.1512355266147; Sun, 03 Dec 2017 18:41:06 -0800 (PST) Received: from roar.au.ibm.com (27-33-241-195.tpgi.com.au. [27.33.241.195]) by smtp.gmail.com with ESMTPSA id w24sm19657895pgm.54.2017.12.03.18.41.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:41:05 -0800 (PST) From: Nicholas Piggin To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2] powerpc/64s: ISAv3 initialize MMU registers before setting partition table Date: Mon, 4 Dec 2017 12:40:55 +1000 Message-Id: <20171204024055.11108-1-npiggin@gmail.com> X-Mailer: git-send-email 2.15.0 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michael Neuling , Nicholas Piggin , "Aneesh Kumar K . V" Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" kexec can leave MMU registers set when booting into a new kernel, PIDR in particular. The boot sequence does not zero PIDR, so it only gets set when CPUs first switch to a userspace processes (until then it's running a kernel thread with effective PID = 0). This leaves a window where a process table entry and page tables are set up due to user processes running on other CPUs, that happen to match with a stale PID. The CPU with that PID may cause speculative accesses that address quadrant 0, which will result in cached translations and PWC for that process, on a CPU which is not in the mm_cpumask and so they will not get invalidated properly. The most common result is the kernel hanging in infinite page fault loops soon after kexec (usually in schedule_tail, which is usually the first non-speculative quardant 0 access to a new PID) due to a stale PWC. However being a stale translation erorr, it could result in anything up to security and data corruption errors. Fix this by zeroing out PIDR before setting PTCR. LPIDR is also not initialized, and may cause a similar issue with speculative access to quadrant 1/2. This has not been observed, but LPIDR is cleared to prevent that possibility. Signed-off-by: Nicholas Piggin --- Since v1: - Aneesh noticed hash was not clearing LPID - Improved changelog - Improved comments Please review. Thanks, Nick arch/powerpc/mm/hash_utils_64.c | 19 +++++++++++++++++-- arch/powerpc/mm/pgtable-radix.c | 10 ++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 655a5a9a183d..d9f3a72f3981 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -1029,13 +1029,24 @@ void __init hash__early_init_mmu(void) pci_io_base = ISA_IO_BASE; #endif + /* + * kexec kernels can boot into the new kernel with PID and LPID + * registers non-zero. Zero them to prevent speculative accesses + * setting up cached translations when we turn the MMU on and + * process/partition table entries start being added. + */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) + mtspr(SPRN_PID, 0); + /* Select appropriate backend */ if (firmware_has_feature(FW_FEATURE_PS3_LV1)) ps3_early_mm_init(); else if (firmware_has_feature(FW_FEATURE_LPAR)) hpte_init_pseries(); - else if (IS_ENABLED(CONFIG_PPC_NATIVE)) + else if (IS_ENABLED(CONFIG_PPC_NATIVE)) { + mtspr(SPRN_LPID, 0); hpte_init_native(); + } if (!mmu_hash_ops.hpte_insert) panic("hash__early_init_mmu: No MMU hash ops defined!\n"); @@ -1055,11 +1066,15 @@ void __init hash__early_init_mmu(void) void hash__early_init_mmu_secondary(void) { /* Initialize hash table for that CPU */ - if (!firmware_has_feature(FW_FEATURE_LPAR)) { + if (cpu_has_feature(CPU_FTR_ARCH_300)) + mtspr(SPRN_PID, 0); + if (!firmware_has_feature(FW_FEATURE_LPAR)) { if (cpu_has_feature(CPU_FTR_POWER9_DD1)) update_hid_for_hash(); + mtspr(SPRN_LPID, 0); + if (!cpu_has_feature(CPU_FTR_ARCH_300)) mtspr(SPRN_SDR1, _SDR1); else diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c index cfbbee941a76..0c13355ddc2a 100644 --- a/arch/powerpc/mm/pgtable-radix.c +++ b/arch/powerpc/mm/pgtable-radix.c @@ -563,10 +563,18 @@ void __init radix__early_init_mmu(void) __pte_frag_nr = H_PTE_FRAG_NR; __pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT; + /* + * kexec kernels can boot into the new kernel with PID and LPID + * registers non-zero. Zero them to prevent speculative accesses + * setting up cached translations when we turn the MMU on and + * process/partition table entries start being added. + */ + mtspr(SPRN_PID, 0); if (!firmware_has_feature(FW_FEATURE_LPAR)) { radix_init_native(); if (cpu_has_feature(CPU_FTR_POWER9_DD1)) update_hid_for_radix(); + mtspr(SPRN_LPID, 0); lpcr = mfspr(SPRN_LPCR); mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR); radix_init_partition_table(); @@ -587,10 +595,12 @@ void radix__early_init_mmu_secondary(void) /* * update partition table control register and UPRT */ + mtspr(SPRN_PID, 0); if (!firmware_has_feature(FW_FEATURE_LPAR)) { if (cpu_has_feature(CPU_FTR_POWER9_DD1)) update_hid_for_radix(); + mtspr(SPRN_LPID, 0); lpcr = mfspr(SPRN_LPCR); mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);