-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce fixmap area just below the vmalloc region. Use it for atomic mapping of high memory pages. High memory on cores with cache aliasing is not supported and is still to be implemented. Fail build for such configurations for now. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
- Loading branch information
Max Filippov
committed
Apr 6, 2014
1 parent
04c6b3e
commit 6555910
Showing
9 changed files
with
270 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* fixmap.h: compile-time virtual memory allocation | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
* | ||
* Copyright (C) 1998 Ingo Molnar | ||
* | ||
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 | ||
*/ | ||
|
||
#ifndef _ASM_FIXMAP_H | ||
#define _ASM_FIXMAP_H | ||
|
||
#include <asm/pgtable.h> | ||
#ifdef CONFIG_HIGHMEM | ||
#include <linux/threads.h> | ||
#include <asm/kmap_types.h> | ||
#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 end of the consistent memory region backwards. | ||
* 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. | ||
*/ | ||
enum fixed_addresses { | ||
#ifdef CONFIG_HIGHMEM | ||
/* reserved pte's for temporary kernel mappings */ | ||
FIX_KMAP_BEGIN, | ||
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, | ||
#endif | ||
__end_of_fixed_addresses | ||
}; | ||
|
||
#define FIXADDR_TOP (VMALLOC_START - PAGE_SIZE) | ||
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) | ||
#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) | ||
|
||
#include <asm-generic/fixmap.h> | ||
|
||
#define kmap_get_fixmap_pte(vaddr) \ | ||
pte_offset_kernel( \ | ||
pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), \ | ||
(vaddr) \ | ||
) | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
|
||
obj-y := init.o cache.o misc.o | ||
obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o | ||
obj-$(CONFIG_HIGHMEM) += highmem.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* High memory support for Xtensa architecture | ||
* | ||
* This file is subject to the terms and conditions of the GNU General | ||
* Public License. See the file "COPYING" in the main directory of | ||
* this archive for more details. | ||
* | ||
* Copyright (C) 2014 Cadence Design Systems Inc. | ||
*/ | ||
|
||
#include <linux/export.h> | ||
#include <linux/highmem.h> | ||
#include <asm/tlbflush.h> | ||
|
||
static pte_t *kmap_pte; | ||
|
||
void *kmap_atomic(struct page *page) | ||
{ | ||
enum fixed_addresses idx; | ||
unsigned long vaddr; | ||
int type; | ||
|
||
pagefault_disable(); | ||
if (!PageHighMem(page)) | ||
return page_address(page); | ||
|
||
type = kmap_atomic_idx_push(); | ||
idx = type + KM_TYPE_NR * smp_processor_id(); | ||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
#ifdef CONFIG_DEBUG_HIGHMEM | ||
BUG_ON(!pte_none(*(kmap_pte - idx))); | ||
#endif | ||
set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC)); | ||
|
||
return (void *)vaddr; | ||
} | ||
EXPORT_SYMBOL(kmap_atomic); | ||
|
||
void __kunmap_atomic(void *kvaddr) | ||
{ | ||
int idx, type; | ||
|
||
if (kvaddr >= (void *)FIXADDR_START && | ||
kvaddr < (void *)FIXADDR_TOP) { | ||
type = kmap_atomic_idx(); | ||
idx = type + KM_TYPE_NR * smp_processor_id(); | ||
|
||
/* | ||
* Force other mappings to Oops if they'll try to access this | ||
* pte without first remap it. Keeping stale mappings around | ||
* is a bad idea also, in case the page changes cacheability | ||
* attributes or becomes a protected page in a hypervisor. | ||
*/ | ||
pte_clear(&init_mm, kvaddr, kmap_pte - idx); | ||
local_flush_tlb_kernel_range((unsigned long)kvaddr, | ||
(unsigned long)kvaddr + PAGE_SIZE); | ||
|
||
kmap_atomic_idx_pop(); | ||
} | ||
|
||
pagefault_enable(); | ||
} | ||
EXPORT_SYMBOL(__kunmap_atomic); | ||
|
||
void __init kmap_init(void) | ||
{ | ||
unsigned long kmap_vstart; | ||
|
||
/* cache the first kmap pte */ | ||
kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); | ||
kmap_pte = kmap_get_fixmap_pte(kmap_vstart); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters