Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp3414794pxb; Mon, 16 Nov 2020 14:09:31 -0800 (PST) X-Google-Smtp-Source: ABdhPJyn23knTP6+8Amjp8uTEITYBJgGdFqINaVVu/BOkmASx3ERl0gM/uy8QzcLImguTsnEQP/J X-Received: by 2002:a17:906:f296:: with SMTP id gu22mr16700565ejb.475.1605564570807; Mon, 16 Nov 2020 14:09:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605564570; cv=none; d=google.com; s=arc-20160816; b=BW6bXFR8delG9AbVfM8gkPnqbi2fsZeboNyrw6YWii8iBdTKJ2vL0PBoo2aSVIKowS 03FMGhhJFI/eOyBZIAOexUyrjWpxw/kWnm/zyqV6RweCTMT8dQaEejNslm9KYVn12G2S uihP0n2dXxRnlUwdn7EHV+RH3KjEwww5R7pBOnafqAmroR2W81KnAomJo/DA2VET/zFh VZwV9glkd3vz10OSAM0NyyrizxH4d/O/VPmKNR5OFQHV2BK8vN7XG/bfMaA/bkJO3oZB xhaJhO+VtYNpzL+1NihxSHYQBXWEQE5qYE7lv5vpsBl5w1oOrvlhJpsaw8W7u53cBikR pv7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=26EBQuDLqRfJIob62SZ1w327byH5+z8iA8+RsCArhFc=; b=nuGgjufoi0nbqIV+SF9frhWUQ2/zYLNGJ3xV25r+QirtRXkQYx1zPb0iEI62o7CstA NGVnCw8lTeexGLvSKeHo6aeaTJfoZa5uaJFGdUCbDSMrm5/gyvwxWjI6ZVkiOsRqjUq6 FLsdcFWOTNcebyiJDurVDzhIPw7TKP/TpK8BwZFhad74dI+B9w5MEnt3GWrJvnYTznhe v7cLkdZD59x4VMWMAx71uXnbqMZJe30r+7QfwQmtIE63/TK9moRV57ww/n8M8TD0S1t8 Ptw6Gbk1DWW4RXJXcHs18kVPAITUu9sD6WwMRLlsqI9Hp0oQy8ovcf7NqMPICLrZCnvh 0A0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="quK/hU5E"; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=PAmYrdu8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h2si12299188ejd.547.2020.11.16.14.09.06; Mon, 16 Nov 2020 14:09:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="quK/hU5E"; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=PAmYrdu8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S1732381AbgKPUYX (ORCPT + 99 others); Mon, 16 Nov 2020 15:24:23 -0500 Received: from Galois.linutronix.de ([193.142.43.55]:43464 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726657AbgKPUYW (ORCPT ); Mon, 16 Nov 2020 15:24:22 -0500 Date: Mon, 16 Nov 2020 20:24:18 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1605558259; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=26EBQuDLqRfJIob62SZ1w327byH5+z8iA8+RsCArhFc=; b=quK/hU5EWlIbLZzck0ReJs47B52II3g4eMXncbaKCqH106rDTe5CcU4XHJwb4BdnvqJm37 VsVr0EWOb00RXHEf8zFvTLooNi0ojgNkhzZbIQ7bbCQQLFqc1c7ZP/a36BGxQZUG1+noJR 5u2bKlTFha+ASy8Ahsox4V8vchvaj9LLBtXL9kFj5ZeOWBOQt93qxrfdZaZX7fbXQy4oq5 5VCRf2t8LA7et/Bl+4HXX24zf+A5K6vDbhGbGdA7ABcBv3DnFmwTS7zg9YTfarftoqek95 mxUKbg66JP5ukm8w3KxCR+RQPLUVsK5pAJGlgBWeU1UqNOJud/5/EPZf35Bd0w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1605558259; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=26EBQuDLqRfJIob62SZ1w327byH5+z8iA8+RsCArhFc=; b=PAmYrdu8IJT4WCBYuAKTVHo8B8VF4Zo40Bi12m4Xd4Cennumn/oaRovR2z/2LLpvy8h7Qa QM0QvAdrSWbu3WBQ== From: "tip-bot2 for Thomas Gleixner" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: core/mm] xtensa/mm/highmem: Make generic kmap_atomic() work correctly Cc: Max Filippov , Thomas Gleixner , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20201116193253.23875-1-jcmvbkbc@gmail.com> References: <20201116193253.23875-1-jcmvbkbc@gmail.com> MIME-Version: 1.0 Message-ID: <160555825838.11244.4652932210210243090.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the core/mm branch of tip: Commit-ID: 1eb0616c2df5b78c301eaa7bd2ee859f43915001 Gitweb: https://git.kernel.org/tip/1eb0616c2df5b78c301eaa7bd2ee859f43915001 Author: Thomas Gleixner AuthorDate: Mon, 16 Nov 2020 11:32:53 -08:00 Committer: Thomas Gleixner CommitterDate: Mon, 16 Nov 2020 21:19:24 +01:00 xtensa/mm/highmem: Make generic kmap_atomic() work correctly The conversion to the generic kmap_atomic() implementation missed the fact that xtensa's fixmap works bottom up while all other implementations work top down. There is no real reason why xtensa needs to work that way. Cure it by: - Using the generic fix_to_virt()/virt_to_fix() functions which work top down - Adjusting the mapping defines - Using the generic index calculation for the non cache aliasing case - Making the cache colour offset reverse so the effective index is correct While at it, remove the outdated and misleading comment above the fixmap enum which originates from the initial copy&pasta of this code from i386. [ Max: Fixed the off by one in the index calculation ] Fixes: 629ed3f7dad2 ("xtensa/mm/highmem: Switch to generic kmap atomic") Reported-by: Max Filippov Signed-off-by: Thomas Gleixner Signed-off-by: Max Filippov Signed-off-by: Thomas Gleixner Tested-by: Max Filippov Link: https://lore.kernel.org/r/20201116193253.23875-1-jcmvbkbc@gmail.com --- arch/xtensa/include/asm/fixmap.h | 55 +++--------------------------- arch/xtensa/include/asm/highmem.h | 15 ++++---- arch/xtensa/mm/highmem.c | 18 ++++++---- arch/xtensa/mm/init.c | 4 +- arch/xtensa/mm/mmu.c | 3 +- 5 files changed, 31 insertions(+), 64 deletions(-) diff --git a/arch/xtensa/include/asm/fixmap.h b/arch/xtensa/include/asm/fixmap.h index 92049b6..1c65dc1 100644 --- a/arch/xtensa/include/asm/fixmap.h +++ b/arch/xtensa/include/asm/fixmap.h @@ -17,63 +17,22 @@ #include #include #include -#endif -/* - * Here we define all the compile-time 'special' virtual - * addresses. The point is to have a constant address at - * compile time, but to set the physical address only - * in the boot process. We allocate these special addresses - * from the start of the consistent memory region upwards. - * Also this lets us do fail-safe vmalloc(), we - * can guarantee that these special addresses and - * vmalloc()-ed addresses never overlap. - * - * these 'compile-time allocated' memory buffers are - * fixed-size 4k pages. (or larger if used with an increment - * higher than 1) use fixmap_set(idx,phys) to associate - * physical memory with fixmap indices. - */ +/* The map slots for temporary mappings via kmap_atomic/local(). */ enum fixed_addresses { -#ifdef CONFIG_HIGHMEM - /* reserved pte's for temporary kernel mappings */ FIX_KMAP_BEGIN, FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS * DCACHE_N_COLORS) - 1, -#endif __end_of_fixed_addresses }; -#define FIXADDR_TOP (XCHAL_KSEG_CACHED_VADDR - PAGE_SIZE) +#define FIXADDR_END (XCHAL_KSEG_CACHED_VADDR - PAGE_SIZE) #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) -#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) +/* Enforce that FIXADDR_START is PMD aligned to handle cache aliasing */ +#define FIXADDR_START ((FIXADDR_END - FIXADDR_SIZE) & PMD_MASK) +#define FIXADDR_TOP (FIXADDR_START + FIXADDR_SIZE - PAGE_SIZE) -#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT)) -#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT) - -#ifndef __ASSEMBLY__ -/* - * 'index to address' translation. If anyone tries to use the idx - * directly without translation, we catch the bug with a NULL-deference - * kernel oops. Illegal ranges of incoming indices are caught too. - */ -static __always_inline unsigned long fix_to_virt(const unsigned int idx) -{ - /* Check if this memory layout is broken because fixmap overlaps page - * table. - */ - BUILD_BUG_ON(FIXADDR_START < - TLBTEMP_BASE_1 + TLBTEMP_SIZE); - BUILD_BUG_ON(idx >= __end_of_fixed_addresses); - return __fix_to_virt(idx); -} - -static inline unsigned long virt_to_fix(const unsigned long vaddr) -{ - BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); - return __virt_to_fix(vaddr); -} - -#endif +#include +#endif /* CONFIG_HIGHMEM */ #endif diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 0fc3b1c..34b8b62 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h @@ -12,6 +12,7 @@ #ifndef _XTENSA_HIGHMEM_H #define _XTENSA_HIGHMEM_H +#ifdef CONFIG_HIGHMEM #include #include #include @@ -58,6 +59,13 @@ static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color) { return pkmap_map_wait_arr + color; } + +enum fixed_addresses kmap_local_map_idx(int type, unsigned long pfn); +#define arch_kmap_local_map_idx kmap_local_map_idx + +enum fixed_addresses kmap_local_unmap_idx(int type, unsigned long addr); +#define arch_kmap_local_unmap_idx kmap_local_unmap_idx + #endif extern pte_t *pkmap_page_table; @@ -67,15 +75,10 @@ static inline void flush_cache_kmaps(void) flush_cache_all(); } -enum fixed_addresses kmap_local_map_idx(int type, unsigned long pfn); -#define arch_kmap_local_map_idx kmap_local_map_idx - -enum fixed_addresses kmap_local_unmap_idx(int type, unsigned long addr); -#define arch_kmap_local_unmap_idx kmap_local_unmap_idx - #define arch_kmap_local_post_unmap(vaddr) \ local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE) void kmap_init(void); +#endif /* CONFIG_HIGHMEM */ #endif diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c index 0735ca5..35c4f7d 100644 --- a/arch/xtensa/mm/highmem.c +++ b/arch/xtensa/mm/highmem.c @@ -23,16 +23,16 @@ static void __init kmap_waitqueues_init(void) for (i = 0; i < ARRAY_SIZE(pkmap_map_wait_arr); ++i) init_waitqueue_head(pkmap_map_wait_arr + i); } -#else -static inline void kmap_waitqueues_init(void) -{ -} -#endif static inline enum fixed_addresses kmap_idx(int type, unsigned long color) { - return (type + KM_MAX_IDX * smp_processor_id()) * DCACHE_N_COLORS + - color; + int idx = (type + KM_MAX_IDX * smp_processor_id()) * DCACHE_N_COLORS; + + /* + * The fixmap operates top down, so the color offset needs to be + * reverse as well. + */ + return idx + DCACHE_N_COLORS - 1 - color; } enum fixed_addresses kmap_local_map_idx(int type, unsigned long pfn) @@ -45,6 +45,10 @@ enum fixed_addresses kmap_local_unmap_idx(int type, unsigned long addr) return kmap_idx(type, DCACHE_ALIAS(addr)); } +#else +static inline void kmap_waitqueues_init(void) { } +#endif + void __init kmap_init(void) { /* Check if this memory layout is broken because PKMAP overlaps diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index c6fc83e..0f85666 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -147,8 +147,8 @@ void __init mem_init(void) #ifdef CONFIG_HIGHMEM PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE, (LAST_PKMAP*PAGE_SIZE) >> 10, - FIXADDR_START, FIXADDR_TOP, - (FIXADDR_TOP - FIXADDR_START) >> 10, + FIXADDR_START, FIXADDR_END, + (FIXADDR_END - FIXADDR_START) >> 10, #endif PAGE_OFFSET, PAGE_OFFSET + (max_low_pfn - min_low_pfn) * PAGE_SIZE, diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index fd2193d..7e4d97d 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c @@ -52,7 +52,8 @@ static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages) static void __init fixedrange_init(void) { - init_pmd(__fix_to_virt(0), __end_of_fixed_addresses); + BUILD_BUG_ON(FIXADDR_START < TLBTEMP_BASE_1 + TLBTEMP_SIZE); + init_pmd(FIXADDR_START, __end_of_fixed_addresses); } #endif