18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * High memory handling common code and variables.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de
68c2ecf20Sopenharmony_ci *          Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Redesigned the x86 32-bit VM architecture to deal with
108c2ecf20Sopenharmony_ci * 64-bit physical space. With current x86 CPUs this
118c2ecf20Sopenharmony_ci * means up to 64 Gigabytes physical RAM.
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * Rewrote high memory support to move the page cache into
148c2ecf20Sopenharmony_ci * high memory. Implemented permanent (schedulable) kmaps
158c2ecf20Sopenharmony_ci * based on Linus' idea.
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <linux/mm.h>
218c2ecf20Sopenharmony_ci#include <linux/export.h>
228c2ecf20Sopenharmony_ci#include <linux/swap.h>
238c2ecf20Sopenharmony_ci#include <linux/bio.h>
248c2ecf20Sopenharmony_ci#include <linux/pagemap.h>
258c2ecf20Sopenharmony_ci#include <linux/mempool.h>
268c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
278c2ecf20Sopenharmony_ci#include <linux/init.h>
288c2ecf20Sopenharmony_ci#include <linux/hash.h>
298c2ecf20Sopenharmony_ci#include <linux/highmem.h>
308c2ecf20Sopenharmony_ci#include <linux/kgdb.h>
318c2ecf20Sopenharmony_ci#include <asm/tlbflush.h>
328c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32)
358c2ecf20Sopenharmony_ciDEFINE_PER_CPU(int, __kmap_atomic_idx);
368c2ecf20Sopenharmony_ci#endif
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci/*
398c2ecf20Sopenharmony_ci * Virtual_count is not a pure "count".
408c2ecf20Sopenharmony_ci *  0 means that it is not mapped, and has not been mapped
418c2ecf20Sopenharmony_ci *    since a TLB flush - it is usable.
428c2ecf20Sopenharmony_ci *  1 means that there are no users, but it has been mapped
438c2ecf20Sopenharmony_ci *    since the last TLB flush - so we can't use it.
448c2ecf20Sopenharmony_ci *  n means that there are (n-1) current users of it.
458c2ecf20Sopenharmony_ci */
468c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/*
498c2ecf20Sopenharmony_ci * Architecture with aliasing data cache may define the following family of
508c2ecf20Sopenharmony_ci * helper functions in its asm/highmem.h to control cache color of virtual
518c2ecf20Sopenharmony_ci * addresses where physical memory pages are mapped by kmap.
528c2ecf20Sopenharmony_ci */
538c2ecf20Sopenharmony_ci#ifndef get_pkmap_color
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/*
568c2ecf20Sopenharmony_ci * Determine color of virtual address where the page should be mapped.
578c2ecf20Sopenharmony_ci */
588c2ecf20Sopenharmony_cistatic inline unsigned int get_pkmap_color(struct page *page)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	return 0;
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci#define get_pkmap_color get_pkmap_color
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/*
658c2ecf20Sopenharmony_ci * Get next index for mapping inside PKMAP region for page with given color.
668c2ecf20Sopenharmony_ci */
678c2ecf20Sopenharmony_cistatic inline unsigned int get_next_pkmap_nr(unsigned int color)
688c2ecf20Sopenharmony_ci{
698c2ecf20Sopenharmony_ci	static unsigned int last_pkmap_nr;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	last_pkmap_nr = (last_pkmap_nr + 1) & LAST_PKMAP_MASK;
728c2ecf20Sopenharmony_ci	return last_pkmap_nr;
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/*
768c2ecf20Sopenharmony_ci * Determine if page index inside PKMAP region (pkmap_nr) of given color
778c2ecf20Sopenharmony_ci * has wrapped around PKMAP region end. When this happens an attempt to
788c2ecf20Sopenharmony_ci * flush all unused PKMAP slots is made.
798c2ecf20Sopenharmony_ci */
808c2ecf20Sopenharmony_cistatic inline int no_more_pkmaps(unsigned int pkmap_nr, unsigned int color)
818c2ecf20Sopenharmony_ci{
828c2ecf20Sopenharmony_ci	return pkmap_nr == 0;
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci/*
868c2ecf20Sopenharmony_ci * Get the number of PKMAP entries of the given color. If no free slot is
878c2ecf20Sopenharmony_ci * found after checking that many entries, kmap will sleep waiting for
888c2ecf20Sopenharmony_ci * someone to call kunmap and free PKMAP slot.
898c2ecf20Sopenharmony_ci */
908c2ecf20Sopenharmony_cistatic inline int get_pkmap_entries_count(unsigned int color)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	return LAST_PKMAP;
938c2ecf20Sopenharmony_ci}
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci/*
968c2ecf20Sopenharmony_ci * Get head of a wait queue for PKMAP entries of the given color.
978c2ecf20Sopenharmony_ci * Wait queues for different mapping colors should be independent to avoid
988c2ecf20Sopenharmony_ci * unnecessary wakeups caused by freeing of slots of other colors.
998c2ecf20Sopenharmony_ci */
1008c2ecf20Sopenharmony_cistatic inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait);
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	return &pkmap_map_wait;
1058c2ecf20Sopenharmony_ci}
1068c2ecf20Sopenharmony_ci#endif
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ciatomic_long_t _totalhigh_pages __read_mostly;
1098c2ecf20Sopenharmony_ciEXPORT_SYMBOL(_totalhigh_pages);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ciEXPORT_PER_CPU_SYMBOL(__kmap_atomic_idx);
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ciunsigned int nr_free_highpages (void)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	struct zone *zone;
1168c2ecf20Sopenharmony_ci	unsigned int pages = 0;
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	for_each_populated_zone(zone) {
1198c2ecf20Sopenharmony_ci		if (is_highmem(zone))
1208c2ecf20Sopenharmony_ci			pages += zone_page_state(zone, NR_FREE_PAGES);
1218c2ecf20Sopenharmony_ci	}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	return pages;
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistatic int pkmap_count[LAST_PKMAP];
1278c2ecf20Sopenharmony_cistatic  __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock);
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_cipte_t * pkmap_page_table;
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci/*
1328c2ecf20Sopenharmony_ci * Most architectures have no use for kmap_high_get(), so let's abstract
1338c2ecf20Sopenharmony_ci * the disabling of IRQ out of the locking in that case to save on a
1348c2ecf20Sopenharmony_ci * potential useless overhead.
1358c2ecf20Sopenharmony_ci */
1368c2ecf20Sopenharmony_ci#ifdef ARCH_NEEDS_KMAP_HIGH_GET
1378c2ecf20Sopenharmony_ci#define lock_kmap()             spin_lock_irq(&kmap_lock)
1388c2ecf20Sopenharmony_ci#define unlock_kmap()           spin_unlock_irq(&kmap_lock)
1398c2ecf20Sopenharmony_ci#define lock_kmap_any(flags)    spin_lock_irqsave(&kmap_lock, flags)
1408c2ecf20Sopenharmony_ci#define unlock_kmap_any(flags)  spin_unlock_irqrestore(&kmap_lock, flags)
1418c2ecf20Sopenharmony_ci#else
1428c2ecf20Sopenharmony_ci#define lock_kmap()             spin_lock(&kmap_lock)
1438c2ecf20Sopenharmony_ci#define unlock_kmap()           spin_unlock(&kmap_lock)
1448c2ecf20Sopenharmony_ci#define lock_kmap_any(flags)    \
1458c2ecf20Sopenharmony_ci		do { spin_lock(&kmap_lock); (void)(flags); } while (0)
1468c2ecf20Sopenharmony_ci#define unlock_kmap_any(flags)  \
1478c2ecf20Sopenharmony_ci		do { spin_unlock(&kmap_lock); (void)(flags); } while (0)
1488c2ecf20Sopenharmony_ci#endif
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistruct page *kmap_to_page(void *vaddr)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	unsigned long addr = (unsigned long)vaddr;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) {
1558c2ecf20Sopenharmony_ci		int i = PKMAP_NR(addr);
1568c2ecf20Sopenharmony_ci		return pte_page(pkmap_page_table[i]);
1578c2ecf20Sopenharmony_ci	}
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	return virt_to_page(addr);
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmap_to_page);
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic void flush_all_zero_pkmaps(void)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	int i;
1668c2ecf20Sopenharmony_ci	int need_flush = 0;
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	flush_cache_kmaps();
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	for (i = 0; i < LAST_PKMAP; i++) {
1718c2ecf20Sopenharmony_ci		struct page *page;
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci		/*
1748c2ecf20Sopenharmony_ci		 * zero means we don't have anything to do,
1758c2ecf20Sopenharmony_ci		 * >1 means that it is still in use. Only
1768c2ecf20Sopenharmony_ci		 * a count of 1 means that it is free but
1778c2ecf20Sopenharmony_ci		 * needs to be unmapped
1788c2ecf20Sopenharmony_ci		 */
1798c2ecf20Sopenharmony_ci		if (pkmap_count[i] != 1)
1808c2ecf20Sopenharmony_ci			continue;
1818c2ecf20Sopenharmony_ci		pkmap_count[i] = 0;
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci		/* sanity check */
1848c2ecf20Sopenharmony_ci		BUG_ON(pte_none(pkmap_page_table[i]));
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci		/*
1878c2ecf20Sopenharmony_ci		 * Don't need an atomic fetch-and-clear op here;
1888c2ecf20Sopenharmony_ci		 * no-one has the page mapped, and cannot get at
1898c2ecf20Sopenharmony_ci		 * its virtual address (and hence PTE) without first
1908c2ecf20Sopenharmony_ci		 * getting the kmap_lock (which is held here).
1918c2ecf20Sopenharmony_ci		 * So no dangers, even with speculative execution.
1928c2ecf20Sopenharmony_ci		 */
1938c2ecf20Sopenharmony_ci		page = pte_page(pkmap_page_table[i]);
1948c2ecf20Sopenharmony_ci		pte_clear(&init_mm, PKMAP_ADDR(i), &pkmap_page_table[i]);
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci		set_page_address(page, NULL);
1978c2ecf20Sopenharmony_ci		need_flush = 1;
1988c2ecf20Sopenharmony_ci	}
1998c2ecf20Sopenharmony_ci	if (need_flush)
2008c2ecf20Sopenharmony_ci		flush_tlb_kernel_range(PKMAP_ADDR(0), PKMAP_ADDR(LAST_PKMAP));
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci/**
2048c2ecf20Sopenharmony_ci * kmap_flush_unused - flush all unused kmap mappings in order to remove stray mappings
2058c2ecf20Sopenharmony_ci */
2068c2ecf20Sopenharmony_civoid kmap_flush_unused(void)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	lock_kmap();
2098c2ecf20Sopenharmony_ci	flush_all_zero_pkmaps();
2108c2ecf20Sopenharmony_ci	unlock_kmap();
2118c2ecf20Sopenharmony_ci}
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_cistatic inline unsigned long map_new_virtual(struct page *page)
2148c2ecf20Sopenharmony_ci{
2158c2ecf20Sopenharmony_ci	unsigned long vaddr;
2168c2ecf20Sopenharmony_ci	int count;
2178c2ecf20Sopenharmony_ci	unsigned int last_pkmap_nr;
2188c2ecf20Sopenharmony_ci	unsigned int color = get_pkmap_color(page);
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_cistart:
2218c2ecf20Sopenharmony_ci	count = get_pkmap_entries_count(color);
2228c2ecf20Sopenharmony_ci	/* Find an empty entry */
2238c2ecf20Sopenharmony_ci	for (;;) {
2248c2ecf20Sopenharmony_ci		last_pkmap_nr = get_next_pkmap_nr(color);
2258c2ecf20Sopenharmony_ci		if (no_more_pkmaps(last_pkmap_nr, color)) {
2268c2ecf20Sopenharmony_ci			flush_all_zero_pkmaps();
2278c2ecf20Sopenharmony_ci			count = get_pkmap_entries_count(color);
2288c2ecf20Sopenharmony_ci		}
2298c2ecf20Sopenharmony_ci		if (!pkmap_count[last_pkmap_nr])
2308c2ecf20Sopenharmony_ci			break;	/* Found a usable entry */
2318c2ecf20Sopenharmony_ci		if (--count)
2328c2ecf20Sopenharmony_ci			continue;
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci		/*
2358c2ecf20Sopenharmony_ci		 * Sleep for somebody else to unmap their entries
2368c2ecf20Sopenharmony_ci		 */
2378c2ecf20Sopenharmony_ci		{
2388c2ecf20Sopenharmony_ci			DECLARE_WAITQUEUE(wait, current);
2398c2ecf20Sopenharmony_ci			wait_queue_head_t *pkmap_map_wait =
2408c2ecf20Sopenharmony_ci				get_pkmap_wait_queue_head(color);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci			__set_current_state(TASK_UNINTERRUPTIBLE);
2438c2ecf20Sopenharmony_ci			add_wait_queue(pkmap_map_wait, &wait);
2448c2ecf20Sopenharmony_ci			unlock_kmap();
2458c2ecf20Sopenharmony_ci			schedule();
2468c2ecf20Sopenharmony_ci			remove_wait_queue(pkmap_map_wait, &wait);
2478c2ecf20Sopenharmony_ci			lock_kmap();
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci			/* Somebody else might have mapped it while we slept */
2508c2ecf20Sopenharmony_ci			if (page_address(page))
2518c2ecf20Sopenharmony_ci				return (unsigned long)page_address(page);
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci			/* Re-start */
2548c2ecf20Sopenharmony_ci			goto start;
2558c2ecf20Sopenharmony_ci		}
2568c2ecf20Sopenharmony_ci	}
2578c2ecf20Sopenharmony_ci	vaddr = PKMAP_ADDR(last_pkmap_nr);
2588c2ecf20Sopenharmony_ci	set_pte_at(&init_mm, vaddr,
2598c2ecf20Sopenharmony_ci		   &(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot));
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	pkmap_count[last_pkmap_nr] = 1;
2628c2ecf20Sopenharmony_ci	set_page_address(page, (void *)vaddr);
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	return vaddr;
2658c2ecf20Sopenharmony_ci}
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci/**
2688c2ecf20Sopenharmony_ci * kmap_high - map a highmem page into memory
2698c2ecf20Sopenharmony_ci * @page: &struct page to map
2708c2ecf20Sopenharmony_ci *
2718c2ecf20Sopenharmony_ci * Returns the page's virtual memory address.
2728c2ecf20Sopenharmony_ci *
2738c2ecf20Sopenharmony_ci * We cannot call this from interrupts, as it may block.
2748c2ecf20Sopenharmony_ci */
2758c2ecf20Sopenharmony_civoid *kmap_high(struct page *page)
2768c2ecf20Sopenharmony_ci{
2778c2ecf20Sopenharmony_ci	unsigned long vaddr;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	/*
2808c2ecf20Sopenharmony_ci	 * For highmem pages, we can't trust "virtual" until
2818c2ecf20Sopenharmony_ci	 * after we have the lock.
2828c2ecf20Sopenharmony_ci	 */
2838c2ecf20Sopenharmony_ci	lock_kmap();
2848c2ecf20Sopenharmony_ci	vaddr = (unsigned long)page_address(page);
2858c2ecf20Sopenharmony_ci	if (!vaddr)
2868c2ecf20Sopenharmony_ci		vaddr = map_new_virtual(page);
2878c2ecf20Sopenharmony_ci	pkmap_count[PKMAP_NR(vaddr)]++;
2888c2ecf20Sopenharmony_ci	BUG_ON(pkmap_count[PKMAP_NR(vaddr)] < 2);
2898c2ecf20Sopenharmony_ci	unlock_kmap();
2908c2ecf20Sopenharmony_ci	return (void*) vaddr;
2918c2ecf20Sopenharmony_ci}
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmap_high);
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci#ifdef ARCH_NEEDS_KMAP_HIGH_GET
2968c2ecf20Sopenharmony_ci/**
2978c2ecf20Sopenharmony_ci * kmap_high_get - pin a highmem page into memory
2988c2ecf20Sopenharmony_ci * @page: &struct page to pin
2998c2ecf20Sopenharmony_ci *
3008c2ecf20Sopenharmony_ci * Returns the page's current virtual memory address, or NULL if no mapping
3018c2ecf20Sopenharmony_ci * exists.  If and only if a non null address is returned then a
3028c2ecf20Sopenharmony_ci * matching call to kunmap_high() is necessary.
3038c2ecf20Sopenharmony_ci *
3048c2ecf20Sopenharmony_ci * This can be called from any context.
3058c2ecf20Sopenharmony_ci */
3068c2ecf20Sopenharmony_civoid *kmap_high_get(struct page *page)
3078c2ecf20Sopenharmony_ci{
3088c2ecf20Sopenharmony_ci	unsigned long vaddr, flags;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	lock_kmap_any(flags);
3118c2ecf20Sopenharmony_ci	vaddr = (unsigned long)page_address(page);
3128c2ecf20Sopenharmony_ci	if (vaddr) {
3138c2ecf20Sopenharmony_ci		BUG_ON(pkmap_count[PKMAP_NR(vaddr)] < 1);
3148c2ecf20Sopenharmony_ci		pkmap_count[PKMAP_NR(vaddr)]++;
3158c2ecf20Sopenharmony_ci	}
3168c2ecf20Sopenharmony_ci	unlock_kmap_any(flags);
3178c2ecf20Sopenharmony_ci	return (void*) vaddr;
3188c2ecf20Sopenharmony_ci}
3198c2ecf20Sopenharmony_ci#endif
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci/**
3228c2ecf20Sopenharmony_ci * kunmap_high - unmap a highmem page into memory
3238c2ecf20Sopenharmony_ci * @page: &struct page to unmap
3248c2ecf20Sopenharmony_ci *
3258c2ecf20Sopenharmony_ci * If ARCH_NEEDS_KMAP_HIGH_GET is not defined then this may be called
3268c2ecf20Sopenharmony_ci * only from user context.
3278c2ecf20Sopenharmony_ci */
3288c2ecf20Sopenharmony_civoid kunmap_high(struct page *page)
3298c2ecf20Sopenharmony_ci{
3308c2ecf20Sopenharmony_ci	unsigned long vaddr;
3318c2ecf20Sopenharmony_ci	unsigned long nr;
3328c2ecf20Sopenharmony_ci	unsigned long flags;
3338c2ecf20Sopenharmony_ci	int need_wakeup;
3348c2ecf20Sopenharmony_ci	unsigned int color = get_pkmap_color(page);
3358c2ecf20Sopenharmony_ci	wait_queue_head_t *pkmap_map_wait;
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci	lock_kmap_any(flags);
3388c2ecf20Sopenharmony_ci	vaddr = (unsigned long)page_address(page);
3398c2ecf20Sopenharmony_ci	BUG_ON(!vaddr);
3408c2ecf20Sopenharmony_ci	nr = PKMAP_NR(vaddr);
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	/*
3438c2ecf20Sopenharmony_ci	 * A count must never go down to zero
3448c2ecf20Sopenharmony_ci	 * without a TLB flush!
3458c2ecf20Sopenharmony_ci	 */
3468c2ecf20Sopenharmony_ci	need_wakeup = 0;
3478c2ecf20Sopenharmony_ci	switch (--pkmap_count[nr]) {
3488c2ecf20Sopenharmony_ci	case 0:
3498c2ecf20Sopenharmony_ci		BUG();
3508c2ecf20Sopenharmony_ci	case 1:
3518c2ecf20Sopenharmony_ci		/*
3528c2ecf20Sopenharmony_ci		 * Avoid an unnecessary wake_up() function call.
3538c2ecf20Sopenharmony_ci		 * The common case is pkmap_count[] == 1, but
3548c2ecf20Sopenharmony_ci		 * no waiters.
3558c2ecf20Sopenharmony_ci		 * The tasks queued in the wait-queue are guarded
3568c2ecf20Sopenharmony_ci		 * by both the lock in the wait-queue-head and by
3578c2ecf20Sopenharmony_ci		 * the kmap_lock.  As the kmap_lock is held here,
3588c2ecf20Sopenharmony_ci		 * no need for the wait-queue-head's lock.  Simply
3598c2ecf20Sopenharmony_ci		 * test if the queue is empty.
3608c2ecf20Sopenharmony_ci		 */
3618c2ecf20Sopenharmony_ci		pkmap_map_wait = get_pkmap_wait_queue_head(color);
3628c2ecf20Sopenharmony_ci		need_wakeup = waitqueue_active(pkmap_map_wait);
3638c2ecf20Sopenharmony_ci	}
3648c2ecf20Sopenharmony_ci	unlock_kmap_any(flags);
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci	/* do wake-up, if needed, race-free outside of the spin lock */
3678c2ecf20Sopenharmony_ci	if (need_wakeup)
3688c2ecf20Sopenharmony_ci		wake_up(pkmap_map_wait);
3698c2ecf20Sopenharmony_ci}
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kunmap_high);
3728c2ecf20Sopenharmony_ci#endif	/* CONFIG_HIGHMEM */
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci#if defined(HASHED_PAGE_VIRTUAL)
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci#define PA_HASH_ORDER	7
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci/*
3798c2ecf20Sopenharmony_ci * Describes one page->virtual association
3808c2ecf20Sopenharmony_ci */
3818c2ecf20Sopenharmony_cistruct page_address_map {
3828c2ecf20Sopenharmony_ci	struct page *page;
3838c2ecf20Sopenharmony_ci	void *virtual;
3848c2ecf20Sopenharmony_ci	struct list_head list;
3858c2ecf20Sopenharmony_ci};
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_cistatic struct page_address_map page_address_maps[LAST_PKMAP];
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci/*
3908c2ecf20Sopenharmony_ci * Hash table bucket
3918c2ecf20Sopenharmony_ci */
3928c2ecf20Sopenharmony_cistatic struct page_address_slot {
3938c2ecf20Sopenharmony_ci	struct list_head lh;			/* List of page_address_maps */
3948c2ecf20Sopenharmony_ci	spinlock_t lock;			/* Protect this bucket's list */
3958c2ecf20Sopenharmony_ci} ____cacheline_aligned_in_smp page_address_htable[1<<PA_HASH_ORDER];
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_cistatic struct page_address_slot *page_slot(const struct page *page)
3988c2ecf20Sopenharmony_ci{
3998c2ecf20Sopenharmony_ci	return &page_address_htable[hash_ptr(page, PA_HASH_ORDER)];
4008c2ecf20Sopenharmony_ci}
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci/**
4038c2ecf20Sopenharmony_ci * page_address - get the mapped virtual address of a page
4048c2ecf20Sopenharmony_ci * @page: &struct page to get the virtual address of
4058c2ecf20Sopenharmony_ci *
4068c2ecf20Sopenharmony_ci * Returns the page's virtual address.
4078c2ecf20Sopenharmony_ci */
4088c2ecf20Sopenharmony_civoid *page_address(const struct page *page)
4098c2ecf20Sopenharmony_ci{
4108c2ecf20Sopenharmony_ci	unsigned long flags;
4118c2ecf20Sopenharmony_ci	void *ret;
4128c2ecf20Sopenharmony_ci	struct page_address_slot *pas;
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ci	if (!PageHighMem(page))
4158c2ecf20Sopenharmony_ci		return lowmem_page_address(page);
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ci	pas = page_slot(page);
4188c2ecf20Sopenharmony_ci	ret = NULL;
4198c2ecf20Sopenharmony_ci	spin_lock_irqsave(&pas->lock, flags);
4208c2ecf20Sopenharmony_ci	if (!list_empty(&pas->lh)) {
4218c2ecf20Sopenharmony_ci		struct page_address_map *pam;
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_ci		list_for_each_entry(pam, &pas->lh, list) {
4248c2ecf20Sopenharmony_ci			if (pam->page == page) {
4258c2ecf20Sopenharmony_ci				ret = pam->virtual;
4268c2ecf20Sopenharmony_ci				goto done;
4278c2ecf20Sopenharmony_ci			}
4288c2ecf20Sopenharmony_ci		}
4298c2ecf20Sopenharmony_ci	}
4308c2ecf20Sopenharmony_cidone:
4318c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&pas->lock, flags);
4328c2ecf20Sopenharmony_ci	return ret;
4338c2ecf20Sopenharmony_ci}
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ciEXPORT_SYMBOL(page_address);
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci/**
4388c2ecf20Sopenharmony_ci * set_page_address - set a page's virtual address
4398c2ecf20Sopenharmony_ci * @page: &struct page to set
4408c2ecf20Sopenharmony_ci * @virtual: virtual address to use
4418c2ecf20Sopenharmony_ci */
4428c2ecf20Sopenharmony_civoid set_page_address(struct page *page, void *virtual)
4438c2ecf20Sopenharmony_ci{
4448c2ecf20Sopenharmony_ci	unsigned long flags;
4458c2ecf20Sopenharmony_ci	struct page_address_slot *pas;
4468c2ecf20Sopenharmony_ci	struct page_address_map *pam;
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	BUG_ON(!PageHighMem(page));
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci	pas = page_slot(page);
4518c2ecf20Sopenharmony_ci	if (virtual) {		/* Add */
4528c2ecf20Sopenharmony_ci		pam = &page_address_maps[PKMAP_NR((unsigned long)virtual)];
4538c2ecf20Sopenharmony_ci		pam->page = page;
4548c2ecf20Sopenharmony_ci		pam->virtual = virtual;
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci		spin_lock_irqsave(&pas->lock, flags);
4578c2ecf20Sopenharmony_ci		list_add_tail(&pam->list, &pas->lh);
4588c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&pas->lock, flags);
4598c2ecf20Sopenharmony_ci	} else {		/* Remove */
4608c2ecf20Sopenharmony_ci		spin_lock_irqsave(&pas->lock, flags);
4618c2ecf20Sopenharmony_ci		list_for_each_entry(pam, &pas->lh, list) {
4628c2ecf20Sopenharmony_ci			if (pam->page == page) {
4638c2ecf20Sopenharmony_ci				list_del(&pam->list);
4648c2ecf20Sopenharmony_ci				spin_unlock_irqrestore(&pas->lock, flags);
4658c2ecf20Sopenharmony_ci				goto done;
4668c2ecf20Sopenharmony_ci			}
4678c2ecf20Sopenharmony_ci		}
4688c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&pas->lock, flags);
4698c2ecf20Sopenharmony_ci	}
4708c2ecf20Sopenharmony_cidone:
4718c2ecf20Sopenharmony_ci	return;
4728c2ecf20Sopenharmony_ci}
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_civoid __init page_address_init(void)
4758c2ecf20Sopenharmony_ci{
4768c2ecf20Sopenharmony_ci	int i;
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) {
4798c2ecf20Sopenharmony_ci		INIT_LIST_HEAD(&page_address_htable[i].lh);
4808c2ecf20Sopenharmony_ci		spin_lock_init(&page_address_htable[i].lock);
4818c2ecf20Sopenharmony_ci	}
4828c2ecf20Sopenharmony_ci}
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci#endif	/* defined(HASHED_PAGE_VIRTUAL) */
485