Received: by 10.223.185.116 with SMTP id b49csp717941wrg; Wed, 21 Feb 2018 05:54:46 -0800 (PST) X-Google-Smtp-Source: AH8x226Mnrcg4xNKEZQehp6/Ts/wCbcrsk9Vu3gu3PZrKqkDmfDYXZQiv6wAu1dcmAOKx8woX5yL X-Received: by 2002:a17:902:22f:: with SMTP id 44-v6mr3211500plc.418.1519221286678; Wed, 21 Feb 2018 05:54:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519221286; cv=none; d=google.com; s=arc-20160816; b=jjcKpgxDkUPhff8nfCFCV/0XoV0tTnCKpEwurawqEh1j+TMms04JxrWo9EYDexwCOs gN8Y3kqPejuHfw/l9zI1dmgabemnB8X71xJcYA7gzKeXvDzgoq81ch1Q6KwSISZh8B1N kbPLqstALSyFNjDtjWNb51S4COAO27QkvIOCBNB/x9Zr3dFniwKBqFAOw93zQpJHQWLE uoDQ6ksBNm0Mov3cMGvZ9F/DT3rYL/px+3k+MqpXk842XUUdmNOeqgMWCTS9EBD9VfRq lEa1sTiz8lCHjF/Kp4lwrEHZZQRaIA6dc1NDwhh1jiHjukYujM8zjSQxE7gp3FDrKhBM p+rQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=IAGLG0aDXSp1tJ434D2e9ZwN9b3bdhqQxw0kPjBkhX0=; b=DAmwP/Kggh1WILnTQKaczFR+cNAuflAnGdz/eaCtC4g7XrkhD4HAdMOFBl+HOo8x6G wioEsVc4PQx8bx0ikuXFkZoItg64sp+LuiYW4V1azzqxzLSWjZSvL6EeIA+6Z+f6GwNO LHyvFa7f+uZEoW33z9vQDguYUsmcCxbx6gir9HmDK5OTQ68VRQN6YiCVrskurtMrXzAW Jao9EXL1Lm7CpmQfZhnrZSBCIKyeQn/bXlBJflwRhMLLneO2pLt3r3tx/dicBKoTHkTl Ln4zOtGSMReh4lz/h9k/76N2vf0BOXS1lZwuPTX4RAc9ut7efbwTvykyTa9WXefBKL+L YBPQ== ARC-Authentication-Results: i=1; mx.google.com; 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 t18si1193595pfg.246.2018.02.21.05.54.32; Wed, 21 Feb 2018 05:54:46 -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; 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 S965189AbeBUNHj (ORCPT + 99 others); Wed, 21 Feb 2018 08:07:39 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:41698 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965160AbeBUNHh (ORCPT ); Wed, 21 Feb 2018 08:07:37 -0500 Received: from localhost (LFbn-1-12258-90.w90-92.abo.wanadoo.fr [90.92.71.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id D85CAFE3; Wed, 21 Feb 2018 13:07:36 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Balbir Singh , Michael Ellerman Subject: [PATCH 4.15 046/163] powerpc/mm/radix: Split linear mapping on hot-unplug Date: Wed, 21 Feb 2018 13:47:55 +0100 Message-Id: <20180221124532.939396545@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180221124529.931834518@linuxfoundation.org> References: <20180221124529.931834518@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Balbir Singh commit 4dd5f8a99e791a8c6500e3592f3ce81ae7edcde1 upstream. This patch splits the linear mapping if the hot-unplug range is smaller than the mapping size. The code detects if the mapping needs to be split into a smaller size and if so, uses the stop machine infrastructure to clear the existing mapping and then remap the remaining range using a smaller page size. The code will skip any region of the mapping that overlaps with kernel text and warn about it once. We don't want to remove a mapping where the kernel text and the LMB we intend to remove overlap in the same TLB mapping as it may affect the currently executing code. I've tested these changes under a kvm guest with 2 vcpus, from a split mapping point of view, some of the caveats mentioned above applied to the testing I did. Fixes: 4b5d62ca17a1 ("powerpc/mm: add radix__remove_section_mapping()") Signed-off-by: Balbir Singh [mpe: Tweak change log to match updated behaviour] Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/mm/pgtable-radix.c | 95 +++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 21 deletions(-) --- a/arch/powerpc/mm/pgtable-radix.c +++ b/arch/powerpc/mm/pgtable-radix.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -671,6 +672,30 @@ static void free_pmd_table(pmd_t *pmd_st pud_clear(pud); } +struct change_mapping_params { + pte_t *pte; + unsigned long start; + unsigned long end; + unsigned long aligned_start; + unsigned long aligned_end; +}; + +static int stop_machine_change_mapping(void *data) +{ + struct change_mapping_params *params = + (struct change_mapping_params *)data; + + if (!data) + return -1; + + spin_unlock(&init_mm.page_table_lock); + pte_clear(&init_mm, params->aligned_start, params->pte); + create_physical_mapping(params->aligned_start, params->start); + create_physical_mapping(params->end, params->aligned_end); + spin_lock(&init_mm.page_table_lock); + return 0; +} + static void remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end) { @@ -699,6 +724,52 @@ static void remove_pte_table(pte_t *pte_ } } +/* + * clear the pte and potentially split the mapping helper + */ +static void split_kernel_mapping(unsigned long addr, unsigned long end, + unsigned long size, pte_t *pte) +{ + unsigned long mask = ~(size - 1); + unsigned long aligned_start = addr & mask; + unsigned long aligned_end = addr + size; + struct change_mapping_params params; + bool split_region = false; + + if ((end - addr) < size) { + /* + * We're going to clear the PTE, but not flushed + * the mapping, time to remap and flush. The + * effects if visible outside the processor or + * if we are running in code close to the + * mapping we cleared, we are in trouble. + */ + if (overlaps_kernel_text(aligned_start, addr) || + overlaps_kernel_text(end, aligned_end)) { + /* + * Hack, just return, don't pte_clear + */ + WARN_ONCE(1, "Linear mapping %lx->%lx overlaps kernel " + "text, not splitting\n", addr, end); + return; + } + split_region = true; + } + + if (split_region) { + params.pte = pte; + params.start = addr; + params.end = end; + params.aligned_start = addr & ~(size - 1); + params.aligned_end = min_t(unsigned long, aligned_end, + (unsigned long)__va(memblock_end_of_DRAM())); + stop_machine(stop_machine_change_mapping, ¶ms, NULL); + return; + } + + pte_clear(&init_mm, addr, pte); +} + static void remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end) { @@ -714,13 +785,7 @@ static void remove_pmd_table(pmd_t *pmd_ continue; if (pmd_huge(*pmd)) { - if (!IS_ALIGNED(addr, PMD_SIZE) || - !IS_ALIGNED(next, PMD_SIZE)) { - WARN_ONCE(1, "%s: unaligned range\n", __func__); - continue; - } - - pte_clear(&init_mm, addr, (pte_t *)pmd); + split_kernel_mapping(addr, end, PMD_SIZE, (pte_t *)pmd); continue; } @@ -745,13 +810,7 @@ static void remove_pud_table(pud_t *pud_ continue; if (pud_huge(*pud)) { - if (!IS_ALIGNED(addr, PUD_SIZE) || - !IS_ALIGNED(next, PUD_SIZE)) { - WARN_ONCE(1, "%s: unaligned range\n", __func__); - continue; - } - - pte_clear(&init_mm, addr, (pte_t *)pud); + split_kernel_mapping(addr, end, PUD_SIZE, (pte_t *)pud); continue; } @@ -777,13 +836,7 @@ static void remove_pagetable(unsigned lo continue; if (pgd_huge(*pgd)) { - if (!IS_ALIGNED(addr, PGDIR_SIZE) || - !IS_ALIGNED(next, PGDIR_SIZE)) { - WARN_ONCE(1, "%s: unaligned range\n", __func__); - continue; - } - - pte_clear(&init_mm, addr, (pte_t *)pgd); + split_kernel_mapping(addr, end, PGDIR_SIZE, (pte_t *)pgd); continue; }