mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
ANDROID: BACKPORT: mm/vmalloc: Add arch-specific callbacks to track io{remap,unmap} physical pages
Add a pair of hooks (ioremap_phys_range_hook/iounmap_phys_range_hook) that can be implemented by an architecture. Contrary to the existing arch_sync_kernel_mappings(), this one tracks things at the physical address level. This is specially useful in these virtualised environments where the guest has to tell the host whether (and how) it intends to use a MMIO device. Signed-off-by: Marc Zyngier <maz@kernel.org> [willdeacon@: Hook ioremap_page_range() in mm/ioremap.c] Bug: 209580772 Change-Id: I970c2e632cb2b01060d5e66e4194fa9248188f43 Signed-off-by: Will Deacon <willdeacon@google.com>
This commit is contained in:
committed by
Will Deacon
parent
be179b64d0
commit
bd1474cd4c
@@ -21,6 +21,8 @@ void __ioread32_copy(void *to, const void __iomem *from, size_t count);
|
||||
void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
void ioremap_phys_range_hook(phys_addr_t phys_addr, size_t size, pgprot_t prot);
|
||||
void iounmap_phys_range_hook(phys_addr_t phys_addr, size_t size);
|
||||
int ioremap_page_range(unsigned long addr, unsigned long end,
|
||||
phys_addr_t phys_addr, pgprot_t prot);
|
||||
#else
|
||||
|
||||
@@ -888,4 +888,9 @@ config ARCH_HAS_HUGEPD
|
||||
config MAPPING_DIRTY_HELPERS
|
||||
bool
|
||||
|
||||
# Some architectures want callbacks for all IO mappings in order to
|
||||
# track the physical addresses that get used as devices.
|
||||
config ARCH_HAS_IOREMAP_PHYS_HOOKS
|
||||
bool
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -225,6 +225,7 @@ int ioremap_page_range(unsigned long addr,
|
||||
pgd_t *pgd;
|
||||
unsigned long start;
|
||||
unsigned long next;
|
||||
phys_addr_t phys_start = phys_addr;
|
||||
int err;
|
||||
pgtbl_mod_mask mask = 0;
|
||||
|
||||
@@ -246,6 +247,9 @@ int ioremap_page_range(unsigned long addr,
|
||||
if (mask & ARCH_PAGE_TABLE_SYNC_MASK)
|
||||
arch_sync_kernel_mappings(start, end);
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_HAS_IOREMAP_PHYS_HOOKS) && !err)
|
||||
ioremap_phys_range_hook(phys_start, end - start, prot);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <trace/hooks/mm.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/shmparam.h>
|
||||
|
||||
@@ -69,7 +70,6 @@ static void free_work(struct work_struct *w)
|
||||
}
|
||||
|
||||
/*** Page table manipulation functions ***/
|
||||
|
||||
static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
|
||||
pgtbl_mod_mask *mask)
|
||||
{
|
||||
@@ -2263,6 +2263,10 @@ static void __vunmap(const void *addr, int deallocate_pages)
|
||||
|
||||
kasan_poison_vmalloc(area->addr, get_vm_area_size(area));
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_HAS_IOREMAP_PHYS_HOOKS) &&
|
||||
area->flags & VM_IOREMAP)
|
||||
iounmap_phys_range_hook(area->phys_addr, get_vm_area_size(area));
|
||||
|
||||
vm_remove_mappings(area, deallocate_pages);
|
||||
|
||||
if (deallocate_pages) {
|
||||
|
||||
Reference in New Issue
Block a user