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

Commit 0906a3ad authored by Paul Mundt's avatar Paul Mundt
Browse files

sh: Fix up and optimize the kmap_coherent() interface.



This fixes up the kmap_coherent/kunmap_coherent() interface for recent
changes both in the page fault path and the shared cache flushers, as
well as adding in some optimizations.

One of the key things to note here is that the TLB flush itself is
deferred until the unmap, and the call in to update_mmu_cache() itself
goes away, relying on the regular page fault path to handle the lazy
dcache writeback if necessary.

Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent d1af119a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ extern void copy_from_user_page(struct vm_area_struct *vma,

void kmap_coherent_init(void);
void *kmap_coherent(struct page *page, unsigned long addr);
void kunmap_coherent(void);
void kunmap_coherent(void *kvaddr);

#define PG_dcache_dirty	PG_arch_1

+7 −1
Original line number Diff line number Diff line
@@ -409,12 +409,18 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
/* to find an entry in a page-table-directory. */
#define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
#define pgd_offset(mm, address)	((mm)->pgd + pgd_index(address))
#define __pgd_offset(address)	pgd_index(address)

/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address)	pgd_offset(&init_mm, address)

#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
#define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))

/* Find an entry in the third-level page table.. */
#define pte_index(address)	((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define __pte_offset(address)	pte_index(address)

#define pte_offset_kernel(dir, address) \
	((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
#define pte_offset_map(dir, address)		pte_offset_kernel(dir, address)
+5 −0
Original line number Diff line number Diff line
@@ -60,6 +60,9 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
/* To find an entry in a kernel PGD. */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)

#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
#define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))

/*
 * PMD level access routines. Same notes as above.
 */
@@ -80,6 +83,8 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
#define pte_index(address) \
		((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))

#define __pte_offset(address)	pte_index(address)

#define pte_offset_kernel(dir, addr) \
		((pte_t *) ((pmd_val(*(dir))) & PAGE_MASK) + pte_index((addr)))

+4 −4
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
	    !test_bit(PG_dcache_dirty, &page->flags)) {
		void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
		memcpy(vto, src, len);
		kunmap_coherent();
		kunmap_coherent(vto);
	} else {
		memcpy(dst, src, len);
		if (boot_cpu_data.dcache.n_aliases)
@@ -70,7 +70,7 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
	    !test_bit(PG_dcache_dirty, &page->flags)) {
		void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
		memcpy(dst, vfrom, len);
		kunmap_coherent();
		kunmap_coherent(vfrom);
	} else {
		memcpy(dst, src, len);
		if (boot_cpu_data.dcache.n_aliases)
@@ -89,7 +89,7 @@ void copy_user_highpage(struct page *to, struct page *from,
	    !test_bit(PG_dcache_dirty, &from->flags)) {
		vfrom = kmap_coherent(from, vaddr);
		copy_page(vto, vfrom);
		kunmap_coherent();
		kunmap_coherent(vfrom);
	} else {
		vfrom = kmap_atomic(from, KM_USER0);
		copy_page(vto, vfrom);
@@ -150,7 +150,7 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)

			kaddr = kmap_coherent(page, vmaddr);
			__flush_wback_region((void *)kaddr, PAGE_SIZE);
			kunmap_coherent();
			kunmap_coherent(kaddr);
		} else
			__flush_wback_region((void *)addr, PAGE_SIZE);
	}
+2 −2
Original line number Diff line number Diff line
@@ -82,8 +82,8 @@ static noinline int vmalloc_fault(unsigned long address)
	pmd_t *pmd_k;
	pte_t *pte_k;

	/* Make sure we are in vmalloc area: */
	if (!(address >= VMALLOC_START && address < VMALLOC_END))
	/* Make sure we are in vmalloc/module/P3 area: */
	if (!(address >= VMALLOC_START && address < P3_ADDR_MAX))
		return -1;

	/*
Loading