mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
arm: highmem: Add support for flushing kmap_atomic mappings
The highmem code provides kmap_flush_unused to ensure all kmap mappings are really removed if they are unused. This code does not handle kmap_atomic mappings since they are managed separately. This prevents an issue for any code which relies on having absolutely no mappings for a particular page. Rather than pay the penalty of having CONFIG_DEBUG_HIGHMEM on all the time, add functionality to remove the kmap_atomic mappings in a similar way to kmap_flush_unused. Change-Id: I9d73abad693c18f2daa1647353e7592b255475b0 Signed-off-by: Laura Abbott <lauraa@codeaurora.org> Signed-off-by: Charan Teja Reddy <charante@codeaurora.org>
This commit is contained in:
parent
19e308d6ca
commit
5fa884ffd4
@ -241,6 +241,9 @@ config NEED_RET_TO_USER
|
||||
config ARCH_MTD_XIP
|
||||
bool
|
||||
|
||||
config ARCH_WANT_KMAP_ATOMIC_FLUSH
|
||||
bool
|
||||
|
||||
config VECTORS_BASE
|
||||
hex
|
||||
default 0xffff0000 if MMU || CPU_HIGH_VECTOR
|
||||
@ -568,6 +571,7 @@ config ARCH_QCOM
|
||||
select SPARSE_IRQ
|
||||
select USE_OF
|
||||
select PINCTRL
|
||||
select ARCH_WANT_KMAP_ATOMIC_FLUSH
|
||||
help
|
||||
Support for Qualcomm MSM/QSD based systems. This runs on the
|
||||
apps processor of the MSM/QSD and depends on a shared memory
|
||||
|
@ -10,6 +10,7 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -147,3 +148,58 @@ void *kmap_atomic_pfn(unsigned long pfn)
|
||||
|
||||
return (void *)vaddr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_WANT_KMAP_ATOMIC_FLUSH
|
||||
static void kmap_remove_unused_cpu(int cpu)
|
||||
{
|
||||
int start_idx, idx, type;
|
||||
|
||||
pagefault_disable();
|
||||
type = kmap_atomic_idx();
|
||||
start_idx = type + 1 + KM_TYPE_NR * cpu;
|
||||
|
||||
for (idx = start_idx; idx < KM_TYPE_NR + KM_TYPE_NR * cpu; idx++) {
|
||||
unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||
pte_t ptep;
|
||||
|
||||
ptep = get_top_pte(vaddr);
|
||||
if (ptep)
|
||||
set_top_pte(vaddr, __pte(0));
|
||||
}
|
||||
pagefault_enable();
|
||||
}
|
||||
|
||||
static void kmap_remove_unused(void *unused)
|
||||
{
|
||||
kmap_remove_unused_cpu(smp_processor_id());
|
||||
}
|
||||
|
||||
void kmap_atomic_flush_unused(void)
|
||||
{
|
||||
on_each_cpu(kmap_remove_unused, NULL, 1);
|
||||
}
|
||||
|
||||
static int hotplug_kmap_atomic_callback(struct notifier_block *nfb,
|
||||
unsigned long action, void *hcpu)
|
||||
{
|
||||
switch (action & (~CPU_TASKS_FROZEN)) {
|
||||
case CPU_DYING:
|
||||
kmap_remove_unused_cpu((int)hcpu);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block hotplug_kmap_atomic_notifier = {
|
||||
.notifier_call = hotplug_kmap_atomic_callback,
|
||||
};
|
||||
|
||||
static int __init init_kmap_atomic(void)
|
||||
{
|
||||
return register_hotcpu_notifier(&hotplug_kmap_atomic_notifier);
|
||||
}
|
||||
early_initcall(init_kmap_atomic);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user