Skip to content

Commit

Permalink
xtensa: support aliasing cache in k[un]map_atomic
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Max Filippov committed Aug 14, 2014
1 parent a91902d commit 32544d9
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 8 deletions.
3 changes: 2 additions & 1 deletion arch/xtensa/include/asm/fixmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ 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,
FIX_KMAP_END = FIX_KMAP_BEGIN +
(KM_TYPE_NR * NR_CPUS * DCACHE_N_COLORS) - 1,
#endif
__end_of_fixed_addresses
};
Expand Down
2 changes: 2 additions & 0 deletions arch/xtensa/include/asm/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@
# define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0)
#else
# define DCACHE_ALIAS_ORDER 0
# define DCACHE_ALIAS(a) ((void)(a), 0)
#endif
#define DCACHE_N_COLORS (1 << DCACHE_ALIAS_ORDER)

#if ICACHE_WAY_SIZE > PAGE_SIZE
# define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT)
Expand Down
17 changes: 10 additions & 7 deletions arch/xtensa/mm/highmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,23 @@

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)
{
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();
idx = kmap_idx(kmap_atomic_idx_push(),
DCACHE_ALIAS(page_to_phys(page)));
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(!pte_none(*(kmap_pte + idx)));
Expand All @@ -38,12 +43,10 @@ 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();
int idx = kmap_idx(kmap_atomic_idx(),
DCACHE_ALIAS((unsigned long)kvaddr));

/*
* Force other mappings to Oops if they'll try to access this
Expand Down

0 comments on commit 32544d9

Please sign in to comment.