Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32544d9c authored by Max Filippov's avatar Max Filippov
Browse files

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: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent a91902db
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
};
+2 −0
Original line number Diff line number Diff line
@@ -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)
+10 −7
Original line number Diff line number Diff line
@@ -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)));
@@ -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