From patchwork Thu Sep 17 08:46:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anshuman Khandual X-Patchwork-Id: 11782039 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8EAC96CA for ; Thu, 17 Sep 2020 08:49:21 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4071D206A1 for ; Thu, 17 Sep 2020 08:49:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="U/pU+5Cf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4071D206A1 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Owner; bh=FI/PKGcx+e/5Q/xEkba8Ix/Ws2Mj32PdcDCcGYYH/hg=; b=U/pU+5CfcO5l7AAv++1Q5weAND MVAZCFDeGsPUyOAyd2om5otELmNLHLRxNGglnubnjD7Ixv2rgrKOLFJdjKept7bpWJg4kX879HACp Q9SwdHNjj+G59ti9YaRGz4n79oEutWs0W8gu7FAxPt60KqSptxpAg6cyrl+6i/2usBl8YX5l3f0fo IcuV0QFxwLAKysybUjrzB2NJEHEgFnNywyjciEhRNkSYxp4lrxkkZfFo83S6kK0IlyT0UO6HTgh3E xDx0lGzLqSmQLQToZmZzEw8esUkOvEDuvFqop+n5NsETLHxOcotLR0bchco8oOLidgE8EphPEgaQU VsVpMBDg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kIpZv-0002nz-Dt; Thu, 17 Sep 2020 08:47:43 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kIpZs-0002mZ-AL for linux-arm-kernel@lists.infradead.org; Thu, 17 Sep 2020 08:47:41 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 034DC1FB; Thu, 17 Sep 2020 01:47:37 -0700 (PDT) Received: from p8cg001049571a15.arm.com (unknown [10.163.73.95]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 837433F718; Thu, 17 Sep 2020 01:47:33 -0700 (PDT) From: Anshuman Khandual To: linux-arm-kernel@lists.infradead.org Subject: [PATCH] arm64/mm: Validate hotplug range before creating linear mapping Date: Thu, 17 Sep 2020 14:16:42 +0530 Message-Id: <1600332402-30123-1-git-send-email-anshuman.khandual@arm.com> X-Mailer: git-send-email 2.7.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200917_044740_513693_53F3180E X-CRM114-Status: GOOD ( 17.32 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [217.140.110.172 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Anshuman Khandual , catalin.marinas@arm.com, David Hildenbrand , Robin Murphy , Steven Price , Andrew Morton , will@kernel.org, Ard Biesheuvel , linux-kernel@vger.kernel.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org During memory hotplug process, the linear mapping should not be created for a given memory range if that would fall outside the maximum allowed linear range. Else it might cause memory corruption in the kernel virtual space. Maximum linear mapping region is [PAGE_OFFSET..(PAGE_END -1)] accommodating both its ends but excluding PAGE_END. Max physical range that can be mapped inside this linear mapping range, must also be derived from its end points. When CONFIG_ARM64_VA_BITS_52 is enabled, PAGE_OFFSET is computed with the assumption of 52 bits virtual address space. However, if the CPU does not support 52 bits, then it falls back using 48 bits instead and the PAGE_END is updated to reflect this using the vabits_actual. As for PAGE_OFFSET, bits [51..48] are ignored by the MMU and remain unchanged, even though the effective start address of linear map is now slightly different. Hence, to reliably check the physical address range mapped by the linear map, the start address should be calculated using vabits_actual. This ensures that arch_add_memory() validates memory hot add range for its potential linear mapping requirement, before creating it with __create_pgd_mapping(). Cc: Catalin Marinas Cc: Will Deacon Cc: Mark Rutland Cc: Ard Biesheuvel Cc: Steven Price Cc: Robin Murphy Cc: David Hildenbrand Cc: Andrew Morton Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Fixes: 4ab215061554 ("arm64: Add memory hotplug support") Signed-off-by: Anshuman Khandual --- arch/arm64/mm/mmu.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 75df62fea1b6..d59ffabb9c84 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -1433,11 +1433,38 @@ static void __remove_pgd_mapping(pgd_t *pgdir, unsigned long start, u64 size) free_empty_tables(start, end, PAGE_OFFSET, PAGE_END); } +static bool inside_linear_region(u64 start, u64 size) +{ + /* + * Linear mapping region is the range [PAGE_OFFSET..(PAGE_END - 1)] + * accommodating both its ends but excluding PAGE_END. Max physical + * range which can be mapped inside this linear mapping range, must + * also be derived from its end points. + * + * With CONFIG_ARM64_VA_BITS_52 enabled, PAGE_OFFSET is defined with + * the assumption of 52 bits virtual address space. However, if the + * CPU does not support 52 bits, it falls back using 48 bits and the + * PAGE_END is updated to reflect this using the vabits_actual. As + * for PAGE_OFFSET, bits [51..48] are ignored by the MMU and remain + * unchanged, even though the effective start address of linear map + * is now slightly different. Hence, to reliably check the physical + * address range mapped by the linear map, the start address should + * be calculated using vabits_actual. + */ + return ((start >= __pa(_PAGE_OFFSET(vabits_actual))) + && ((start + size) <= __pa(PAGE_END - 1))); +} + int arch_add_memory(int nid, u64 start, u64 size, struct mhp_params *params) { int ret, flags = 0; + if (!inside_linear_region(start, size)) { + pr_err("[%llx %llx] is outside linear mapping region\n", start, start + size); + return -EINVAL; + } + if (rodata_full || debug_pagealloc_enabled()) flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;