mirror of https://gitee.com/openkylin/linux.git
nds32/mm/highmem: Switch to generic kmap atomic
The mapping code is odd and looks broken. See FIXME in the comment. Also fix the harmless off by one in the FIX_KMAP_END define. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Nick Hu <nickhu@andestech.com> Cc: Greentime Hu <green.hu@gmail.com> Cc: Vincent Chen <deanbo422@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Link: https://lore.kernel.org/r/20201103095857.980576055@linutronix.de
This commit is contained in:
parent
a4c33e83bc
commit
5f037ea3b2
|
@ -157,6 +157,7 @@ config HW_SUPPORT_UNALIGNMENT_ACCESS
|
|||
config HIGHMEM
|
||||
bool "High Memory Support"
|
||||
depends on MMU && !CPU_CACHE_ALIASING
|
||||
select KMAP_LOCAL
|
||||
help
|
||||
The address space of Andes processors is only 4 Gigabytes large
|
||||
and it has to accommodate user address space, kernel address
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#include <linux/threads.h>
|
||||
#include <asm/kmap_types.h>
|
||||
#include <asm/kmap_size.h>
|
||||
#endif
|
||||
|
||||
enum fixed_addresses {
|
||||
|
@ -14,7 +14,7 @@ enum fixed_addresses {
|
|||
FIX_KMAP_RESERVED,
|
||||
FIX_KMAP_BEGIN,
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS),
|
||||
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
|
||||
#endif
|
||||
FIX_EARLYCON_MEM_BASE,
|
||||
__end_of_fixed_addresses
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#define _ASM_HIGHMEM_H
|
||||
|
||||
#include <asm/proc-fns.h>
|
||||
#include <asm/kmap_types.h>
|
||||
#include <asm/fixmap.h>
|
||||
|
||||
/*
|
||||
|
@ -45,11 +44,22 @@ extern pte_t *pkmap_page_table;
|
|||
extern void kmap_init(void);
|
||||
|
||||
/*
|
||||
* The following functions are already defined by <linux/highmem.h>
|
||||
* when CONFIG_HIGHMEM is not set.
|
||||
* FIXME: The below looks broken vs. a kmap_atomic() in task context which
|
||||
* is interupted and another kmap_atomic() happens in interrupt context.
|
||||
* But what do I know about nds32. -- tglx
|
||||
*/
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
extern void *kmap_atomic_pfn(unsigned long pfn);
|
||||
#endif
|
||||
#define arch_kmap_local_post_map(vaddr, pteval) \
|
||||
do { \
|
||||
__nds32__tlbop_inv(vaddr); \
|
||||
__nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN); \
|
||||
__nds32__tlbop_rwr(pteval); \
|
||||
__nds32__isb(); \
|
||||
} while (0)
|
||||
|
||||
#define arch_kmap_local_pre_unmap(vaddr) \
|
||||
do { \
|
||||
__nds32__tlbop_inv(vaddr); \
|
||||
__nds32__isb(); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,7 +3,6 @@ obj-y := extable.o tlb.o fault.o init.o mmap.o \
|
|||
mm-nds32.o cacheflush.o proc.o
|
||||
|
||||
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
|
||||
obj-$(CONFIG_HIGHMEM) += highmem.o
|
||||
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
CFLAGS_REMOVE_proc.o = $(CC_FLAGS_FTRACE)
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2005-2017 Andes Technology Corporation
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
void *kmap_atomic_high_prot(struct page *page, pgprot_t prot)
|
||||
{
|
||||
unsigned int idx;
|
||||
unsigned long vaddr, pte;
|
||||
int type;
|
||||
pte_t *ptep;
|
||||
|
||||
type = kmap_atomic_idx_push();
|
||||
|
||||
idx = type + KM_TYPE_NR * smp_processor_id();
|
||||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||
pte = (page_to_pfn(page) << PAGE_SHIFT) | prot;
|
||||
ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
|
||||
set_pte(ptep, pte);
|
||||
|
||||
__nds32__tlbop_inv(vaddr);
|
||||
__nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN);
|
||||
__nds32__tlbop_rwr(pte);
|
||||
__nds32__isb();
|
||||
return (void *)vaddr;
|
||||
}
|
||||
EXPORT_SYMBOL(kmap_atomic_high_prot);
|
||||
|
||||
void kunmap_atomic_high(void *kvaddr)
|
||||
{
|
||||
if (kvaddr >= (void *)FIXADDR_START) {
|
||||
unsigned long vaddr = (unsigned long)kvaddr;
|
||||
pte_t *ptep;
|
||||
kmap_atomic_idx_pop();
|
||||
__nds32__tlbop_inv(vaddr);
|
||||
__nds32__isb();
|
||||
ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
|
||||
set_pte(ptep, 0);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(kunmap_atomic_high);
|
Loading…
Reference in New Issue