Loading arch/arm/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,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 Loading Loading @@ -567,6 +570,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 Loading arch/arm/mm/highmem.c +56 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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
arch/arm/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,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 Loading Loading @@ -567,6 +570,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 Loading
arch/arm/mm/highmem.c +56 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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