Commit 3293efa9 authored by Thomas Gleixner's avatar Thomas Gleixner

sparc/mm/highmem: Switch to generic kmap atomic

No reason having the same code in every architecture
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20201103095858.197568209@linutronix.de
parent 47da42b2
...@@ -139,6 +139,7 @@ config MMU ...@@ -139,6 +139,7 @@ config MMU
config HIGHMEM config HIGHMEM
bool bool
default y if SPARC32 default y if SPARC32
select KMAP_LOCAL
config ZONE_DMA config ZONE_DMA
bool bool
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/pgtable.h> #include <linux/pgtable.h>
#include <asm/vaddrs.h> #include <asm/vaddrs.h>
#include <asm/kmap_types.h>
#include <asm/pgtsrmmu.h> #include <asm/pgtsrmmu.h>
/* declarations for highmem.c */ /* declarations for highmem.c */
...@@ -33,8 +32,6 @@ extern unsigned long highstart_pfn, highend_pfn; ...@@ -33,8 +32,6 @@ extern unsigned long highstart_pfn, highend_pfn;
#define kmap_prot __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE) #define kmap_prot __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE)
extern pte_t *pkmap_page_table; extern pte_t *pkmap_page_table;
void kmap_init(void) __init;
/* /*
* Right now we initialize only a single pte table. It can be extended * Right now we initialize only a single pte table. It can be extended
* easily, subsequent pte tables have to be allocated in one physical * easily, subsequent pte tables have to be allocated in one physical
...@@ -53,6 +50,11 @@ void kmap_init(void) __init; ...@@ -53,6 +50,11 @@ void kmap_init(void) __init;
#define flush_cache_kmaps() flush_cache_all() #define flush_cache_kmaps() flush_cache_all()
/* FIXME: Use __flush_tlb_one(vaddr) instead of flush_cache_all() -- Anton */
#define arch_kmap_local_post_map(vaddr, pteval) flush_cache_all()
#define arch_kmap_local_post_unmap(vaddr) flush_cache_all()
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_HIGHMEM_H */ #endif /* _ASM_HIGHMEM_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_KMAP_TYPES_H
#define _ASM_KMAP_TYPES_H
/* Dummy header just to define km_type. None of this
* is actually used on sparc. -DaveM
*/
#include <asm-generic/kmap_types.h>
#endif
...@@ -32,13 +32,13 @@ ...@@ -32,13 +32,13 @@
#define SRMMU_NOCACHE_ALCRATIO 64 /* 256 pages per 64MB of system RAM */ #define SRMMU_NOCACHE_ALCRATIO 64 /* 256 pages per 64MB of system RAM */
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/kmap_types.h> #include <asm/kmap_size.h>
enum fixed_addresses { enum fixed_addresses {
FIX_HOLE, FIX_HOLE,
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, FIX_KMAP_BEGIN,
FIX_KMAP_END = (KM_TYPE_NR * NR_CPUS), FIX_KMAP_END = (KM_MAX_IDX * NR_CPUS),
#endif #endif
__end_of_fixed_addresses __end_of_fixed_addresses
}; };
......
...@@ -15,6 +15,3 @@ obj-$(CONFIG_SPARC32) += leon_mm.o ...@@ -15,6 +15,3 @@ obj-$(CONFIG_SPARC32) += leon_mm.o
# Only used by sparc64 # Only used by sparc64
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
# Only used by sparc32
obj-$(CONFIG_HIGHMEM) += highmem.o
// SPDX-License-Identifier: GPL-2.0
/*
* highmem.c: virtual kernel memory mappings for high memory
*
* Provides kernel-static versions of atomic kmap functions originally
* found as inlines in include/asm-sparc/highmem.h. These became
* needed as kmap_atomic() and kunmap_atomic() started getting
* called from within modules.
* -- Tomas Szepe <szepe@pinerecords.com>, September 2002
*
* But kmap_atomic() and kunmap_atomic() cannot be inlined in
* modules because they are loaded with btfixup-ped functions.
*/
/*
* The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
* gives a more generic (and caching) interface. But kmap_atomic can
* be used in IRQ contexts, so in some (very limited) cases we need it.
*
* XXX This is an old text. Actually, it's good to use atomic kmaps,
* provided you remember that they are atomic and not try to sleep
* with a kmap taken, much like a spinlock. Non-atomic kmaps are
* shared by CPUs, and so precious, and establishing them requires IPI.
* Atomic kmaps are lightweight and we may have NCPUS more of them.
*/
#include <linux/highmem.h>
#include <linux/export.h>
#include <linux/mm.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/vaddrs.h>
static pte_t *kmap_pte;
void __init kmap_init(void)
{
unsigned long address = __fix_to_virt(FIX_KMAP_BEGIN);
/* cache the first kmap pte */
kmap_pte = virt_to_kpte(address);
}
void *kmap_atomic_high_prot(struct page *page, pgprot_t prot)
{
unsigned long vaddr;
long idx, type;
type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
/* XXX Fix - Anton */
#if 0
__flush_cache_one(vaddr);
#else
flush_cache_all();
#endif
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(!pte_none(*(kmap_pte-idx)));
#endif
set_pte(kmap_pte-idx, mk_pte(page, prot));
/* XXX Fix - Anton */
#if 0
__flush_tlb_one(vaddr);
#else
flush_tlb_all();
#endif
return (void*) vaddr;
}
EXPORT_SYMBOL(kmap_atomic_high_prot);
void kunmap_atomic_high(void *kvaddr)
{
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
int type;
if (vaddr < FIXADDR_START)
return;
type = kmap_atomic_idx();
#ifdef CONFIG_DEBUG_HIGHMEM
{
unsigned long idx;
idx = type + KM_TYPE_NR * smp_processor_id();
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx));
/* XXX Fix - Anton */
#if 0
__flush_cache_one(vaddr);
#else
flush_cache_all();
#endif
/*
* force other mappings to Oops if they'll try to access
* this pte without first remap it
*/
pte_clear(&init_mm, vaddr, kmap_pte-idx);
/* XXX Fix - Anton */
#if 0
__flush_tlb_one(vaddr);
#else
flush_tlb_all();
#endif
}
#endif
kmap_atomic_idx_pop();
}
EXPORT_SYMBOL(kunmap_atomic_high);
...@@ -971,8 +971,6 @@ void __init srmmu_paging_init(void) ...@@ -971,8 +971,6 @@ void __init srmmu_paging_init(void)
sparc_context_init(num_contexts); sparc_context_init(num_contexts);
kmap_init();
{ {
unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment