diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches-rt/0033-ARM-highmem-Switch-to-generic-kmap-atomic.patch | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/debian/patches-rt/0033-ARM-highmem-Switch-to-generic-kmap-atomic.patch b/debian/patches-rt/0033-ARM-highmem-Switch-to-generic-kmap-atomic.patch new file mode 100644 index 000000000..7f4d188e7 --- /dev/null +++ b/debian/patches-rt/0033-ARM-highmem-Switch-to-generic-kmap-atomic.patch @@ -0,0 +1,271 @@ +From 007968641a299ffd9fd631d7f67fc119aaf9ac5d Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner <tglx@linutronix.de> +Date: Tue, 3 Nov 2020 10:27:22 +0100 +Subject: [PATCH 033/323] ARM: highmem: Switch to generic kmap atomic +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.10/older/patches-5.10.204-rt100.tar.xz + +No reason having the same code in every architecture. + +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: Russell King <linux@armlinux.org.uk> +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: linux-arm-kernel@lists.infradead.org +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + arch/arm/Kconfig | 1 + + arch/arm/include/asm/fixmap.h | 4 +- + arch/arm/include/asm/highmem.h | 34 ++++++--- + arch/arm/include/asm/kmap_types.h | 10 --- + arch/arm/mm/Makefile | 1 - + arch/arm/mm/highmem.c | 121 ------------------------------ + 6 files changed, 27 insertions(+), 144 deletions(-) + delete mode 100644 arch/arm/include/asm/kmap_types.h + delete mode 100644 arch/arm/mm/highmem.c + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 335308aff6ce..c01251683018 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1497,6 +1497,7 @@ config HAVE_ARCH_PFN_VALID + config HIGHMEM + bool "High Memory Support" + depends on MMU ++ select KMAP_LOCAL + help + The address space of ARM processors is only 4 Gigabytes large + and it has to accommodate user address space, kernel address +diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h +index 9575b404019c..707068f852c2 100644 +--- a/arch/arm/include/asm/fixmap.h ++++ b/arch/arm/include/asm/fixmap.h +@@ -7,14 +7,14 @@ + #define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE) + + #include <linux/pgtable.h> +-#include <asm/kmap_types.h> ++#include <asm/kmap_size.h> + + enum fixed_addresses { + FIX_EARLYCON_MEM_BASE, + __end_of_permanent_fixed_addresses, + + FIX_KMAP_BEGIN = __end_of_permanent_fixed_addresses, +- FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, ++ FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1, + + /* Support writing RO kernel text via kprobes, jump labels, etc. */ + FIX_TEXT_POKE0, +diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h +index 31811be38d78..b22dffa8c7eb 100644 +--- a/arch/arm/include/asm/highmem.h ++++ b/arch/arm/include/asm/highmem.h +@@ -2,7 +2,8 @@ + #ifndef _ASM_HIGHMEM_H + #define _ASM_HIGHMEM_H + +-#include <asm/kmap_types.h> ++#include <asm/kmap_size.h> ++#include <asm/fixmap.h> + + #define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE) + #define LAST_PKMAP PTRS_PER_PTE +@@ -46,19 +47,32 @@ extern pte_t *pkmap_page_table; + + #ifdef ARCH_NEEDS_KMAP_HIGH_GET + extern void *kmap_high_get(struct page *page); +-#else ++ ++static inline void *arch_kmap_local_high_get(struct page *page) ++{ ++ if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM) && !cache_is_vivt()) ++ return NULL; ++ return kmap_high_get(page); ++} ++#define arch_kmap_local_high_get arch_kmap_local_high_get ++ ++#else /* ARCH_NEEDS_KMAP_HIGH_GET */ + static inline void *kmap_high_get(struct page *page) + { + return NULL; + } +-#endif ++#endif /* !ARCH_NEEDS_KMAP_HIGH_GET */ + +-/* +- * The following functions are already defined by <linux/highmem.h> +- * when CONFIG_HIGHMEM is not set. +- */ +-#ifdef CONFIG_HIGHMEM +-extern void *kmap_atomic_pfn(unsigned long pfn); +-#endif ++#define arch_kmap_local_post_map(vaddr, pteval) \ ++ local_flush_tlb_kernel_page(vaddr) ++ ++#define arch_kmap_local_pre_unmap(vaddr) \ ++do { \ ++ if (cache_is_vivt()) \ ++ __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); \ ++} while (0) ++ ++#define arch_kmap_local_post_unmap(vaddr) \ ++ local_flush_tlb_kernel_page(vaddr) + + #endif +diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h +deleted file mode 100644 +index 5590940ee43d..000000000000 +--- a/arch/arm/include/asm/kmap_types.h ++++ /dev/null +@@ -1,10 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-#ifndef __ARM_KMAP_TYPES_H +-#define __ARM_KMAP_TYPES_H +- +-/* +- * This is the "bare minimum". AIO seems to require this. +- */ +-#define KM_TYPE_NR 16 +- +-#endif +diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile +index 7cb1699fbfc4..c4ce477c5261 100644 +--- a/arch/arm/mm/Makefile ++++ b/arch/arm/mm/Makefile +@@ -19,7 +19,6 @@ obj-$(CONFIG_MODULES) += proc-syms.o + obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o + + obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o +-obj-$(CONFIG_HIGHMEM) += highmem.o + obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o + obj-$(CONFIG_ARM_PV_FIXUP) += pv-fixup-asm.o + +diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c +deleted file mode 100644 +index 187fab227b50..000000000000 +--- a/arch/arm/mm/highmem.c ++++ /dev/null +@@ -1,121 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* +- * arch/arm/mm/highmem.c -- ARM highmem support +- * +- * Author: Nicolas Pitre +- * Created: september 8, 2008 +- * Copyright: Marvell Semiconductors Inc. +- */ +- +-#include <linux/module.h> +-#include <linux/highmem.h> +-#include <linux/interrupt.h> +-#include <asm/fixmap.h> +-#include <asm/cacheflush.h> +-#include <asm/tlbflush.h> +-#include "mm.h" +- +-static inline void set_fixmap_pte(int idx, pte_t pte) +-{ +- unsigned long vaddr = __fix_to_virt(idx); +- pte_t *ptep = virt_to_kpte(vaddr); +- +- set_pte_ext(ptep, pte, 0); +- local_flush_tlb_kernel_page(vaddr); +-} +- +-static inline pte_t get_fixmap_pte(unsigned long vaddr) +-{ +- pte_t *ptep = virt_to_kpte(vaddr); +- +- return *ptep; +-} +- +-void *kmap_atomic_high_prot(struct page *page, pgprot_t prot) +-{ +- unsigned int idx; +- unsigned long vaddr; +- void *kmap; +- int type; +- +-#ifdef CONFIG_DEBUG_HIGHMEM +- /* +- * There is no cache coherency issue when non VIVT, so force the +- * dedicated kmap usage for better debugging purposes in that case. +- */ +- if (!cache_is_vivt()) +- kmap = NULL; +- else +-#endif +- kmap = kmap_high_get(page); +- if (kmap) +- return kmap; +- +- type = kmap_atomic_idx_push(); +- +- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id(); +- vaddr = __fix_to_virt(idx); +-#ifdef CONFIG_DEBUG_HIGHMEM +- /* +- * With debugging enabled, kunmap_atomic forces that entry to 0. +- * Make sure it was indeed properly unmapped. +- */ +- BUG_ON(!pte_none(get_fixmap_pte(vaddr))); +-#endif +- /* +- * When debugging is off, kunmap_atomic leaves the previous mapping +- * in place, so the contained TLB flush ensures the TLB is updated +- * with the new mapping. +- */ +- set_fixmap_pte(idx, mk_pte(page, prot)); +- +- return (void *)vaddr; +-} +-EXPORT_SYMBOL(kmap_atomic_high_prot); +- +-void kunmap_atomic_high(void *kvaddr) +-{ +- unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; +- int idx, type; +- +- if (kvaddr >= (void *)FIXADDR_START) { +- type = kmap_atomic_idx(); +- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id(); +- +- if (cache_is_vivt()) +- __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); +-#ifdef CONFIG_DEBUG_HIGHMEM +- BUG_ON(vaddr != __fix_to_virt(idx)); +- set_fixmap_pte(idx, __pte(0)); +-#else +- (void) idx; /* to kill a warning */ +-#endif +- kmap_atomic_idx_pop(); +- } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) { +- /* this address was obtained through kmap_high_get() */ +- kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)])); +- } +-} +-EXPORT_SYMBOL(kunmap_atomic_high); +- +-void *kmap_atomic_pfn(unsigned long pfn) +-{ +- unsigned long vaddr; +- int idx, type; +- struct page *page = pfn_to_page(pfn); +- +- preempt_disable(); +- pagefault_disable(); +- if (!PageHighMem(page)) +- return page_address(page); +- +- type = kmap_atomic_idx_push(); +- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id(); +- vaddr = __fix_to_virt(idx); +-#ifdef CONFIG_DEBUG_HIGHMEM +- BUG_ON(!pte_none(get_fixmap_pte(vaddr))); +-#endif +- set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot)); +- +- return (void *)vaddr; +-} +-- +2.43.0 + |