mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-27 05:32:27 +00:00
xtensa: support aliasing cache in k[un]map_atomic
Map high memory pages at virtual addresses with color that match color of their physical address. Existing cache alias management mechanisms may be used with such pages. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
parent
a91902db29
commit
32544d9c10
@ -38,7 +38,8 @@ enum fixed_addresses {
|
|||||||
#ifdef CONFIG_HIGHMEM
|
#ifdef CONFIG_HIGHMEM
|
||||||
/* reserved pte's for temporary kernel mappings */
|
/* reserved pte's for temporary kernel mappings */
|
||||||
FIX_KMAP_BEGIN,
|
FIX_KMAP_BEGIN,
|
||||||
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
|
FIX_KMAP_END = FIX_KMAP_BEGIN +
|
||||||
|
(KM_TYPE_NR * NR_CPUS * DCACHE_N_COLORS) - 1,
|
||||||
#endif
|
#endif
|
||||||
__end_of_fixed_addresses
|
__end_of_fixed_addresses
|
||||||
};
|
};
|
||||||
|
@ -78,7 +78,9 @@
|
|||||||
# define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0)
|
# define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0)
|
||||||
#else
|
#else
|
||||||
# define DCACHE_ALIAS_ORDER 0
|
# define DCACHE_ALIAS_ORDER 0
|
||||||
|
# define DCACHE_ALIAS(a) ((void)(a), 0)
|
||||||
#endif
|
#endif
|
||||||
|
#define DCACHE_N_COLORS (1 << DCACHE_ALIAS_ORDER)
|
||||||
|
|
||||||
#if ICACHE_WAY_SIZE > PAGE_SIZE
|
#if ICACHE_WAY_SIZE > PAGE_SIZE
|
||||||
# define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT)
|
# define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT)
|
||||||
|
@ -14,18 +14,23 @@
|
|||||||
|
|
||||||
static pte_t *kmap_pte;
|
static pte_t *kmap_pte;
|
||||||
|
|
||||||
|
static inline enum fixed_addresses kmap_idx(int type, unsigned long color)
|
||||||
|
{
|
||||||
|
return (type + KM_TYPE_NR * smp_processor_id()) * DCACHE_N_COLORS +
|
||||||
|
color;
|
||||||
|
}
|
||||||
|
|
||||||
void *kmap_atomic(struct page *page)
|
void *kmap_atomic(struct page *page)
|
||||||
{
|
{
|
||||||
enum fixed_addresses idx;
|
enum fixed_addresses idx;
|
||||||
unsigned long vaddr;
|
unsigned long vaddr;
|
||||||
int type;
|
|
||||||
|
|
||||||
pagefault_disable();
|
pagefault_disable();
|
||||||
if (!PageHighMem(page))
|
if (!PageHighMem(page))
|
||||||
return page_address(page);
|
return page_address(page);
|
||||||
|
|
||||||
type = kmap_atomic_idx_push();
|
idx = kmap_idx(kmap_atomic_idx_push(),
|
||||||
idx = type + KM_TYPE_NR * smp_processor_id();
|
DCACHE_ALIAS(page_to_phys(page)));
|
||||||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||||
BUG_ON(!pte_none(*(kmap_pte + idx)));
|
BUG_ON(!pte_none(*(kmap_pte + idx)));
|
||||||
@ -38,12 +43,10 @@ EXPORT_SYMBOL(kmap_atomic);
|
|||||||
|
|
||||||
void __kunmap_atomic(void *kvaddr)
|
void __kunmap_atomic(void *kvaddr)
|
||||||
{
|
{
|
||||||
int idx, type;
|
|
||||||
|
|
||||||
if (kvaddr >= (void *)FIXADDR_START &&
|
if (kvaddr >= (void *)FIXADDR_START &&
|
||||||
kvaddr < (void *)FIXADDR_TOP) {
|
kvaddr < (void *)FIXADDR_TOP) {
|
||||||
type = kmap_atomic_idx();
|
int idx = kmap_idx(kmap_atomic_idx(),
|
||||||
idx = type + KM_TYPE_NR * smp_processor_id();
|
DCACHE_ALIAS((unsigned long)kvaddr));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force other mappings to Oops if they'll try to access this
|
* Force other mappings to Oops if they'll try to access this
|
||||||
|
Loading…
x
Reference in New Issue
Block a user