Commit 3494d588 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xtensa-20201119' of git://github.com/jcmvbkbc/linux-xtensa

Pull xtensa fixes from Max Filippov:

 - fix placement of cache alias remapping area

 - disable preemption around cache alias management calls

 - add missing __user annotation to strncpy_from_user argument

* tag 'xtensa-20201119' of git://github.com/jcmvbkbc/linux-xtensa:
  xtensa: uaccess: Add missing __user to strncpy_from_user() prototype
  xtensa: disable preemption around cache alias management calls
  xtensa: fix TLBTEMP area placement
parents 131ad0b6 dc293f21
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -82,7 +82,8 @@ Default MMUv2-compatible layout::
  +------------------+
  | VMALLOC area     |  VMALLOC_START            0xc0000000  128MB - 64KB
  +------------------+  VMALLOC_END
  | Cache aliasing   |  TLBTEMP_BASE_1           0xc7ff0000  DCACHE_WAY_SIZE
  +------------------+
  | Cache aliasing   |  TLBTEMP_BASE_1           0xc8000000  DCACHE_WAY_SIZE
  | remap area 1     |
  +------------------+
  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
@@ -124,7 +125,8 @@ Default MMUv2-compatible layout::
  +------------------+
  | VMALLOC area     |  VMALLOC_START            0xa0000000  128MB - 64KB
  +------------------+  VMALLOC_END
  | Cache aliasing   |  TLBTEMP_BASE_1           0xa7ff0000  DCACHE_WAY_SIZE
  +------------------+
  | Cache aliasing   |  TLBTEMP_BASE_1           0xa8000000  DCACHE_WAY_SIZE
  | remap area 1     |
  +------------------+
  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
@@ -167,7 +169,8 @@ Default MMUv2-compatible layout::
  +------------------+
  | VMALLOC area     |  VMALLOC_START            0x90000000  128MB - 64KB
  +------------------+  VMALLOC_END
  | Cache aliasing   |  TLBTEMP_BASE_1           0x97ff0000  DCACHE_WAY_SIZE
  +------------------+
  | Cache aliasing   |  TLBTEMP_BASE_1           0x98000000  DCACHE_WAY_SIZE
  | remap area 1     |
  +------------------+
  | Cache aliasing   |  TLBTEMP_BASE_2                       DCACHE_WAY_SIZE
+1 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@
 */
#define VMALLOC_START		(XCHAL_KSEG_CACHED_VADDR - 0x10000000)
#define VMALLOC_END		(VMALLOC_START + 0x07FEFFFF)
#define TLBTEMP_BASE_1		(VMALLOC_END + 1)
#define TLBTEMP_BASE_1		(VMALLOC_START + 0x08000000)
#define TLBTEMP_BASE_2		(TLBTEMP_BASE_1 + DCACHE_WAY_SIZE)
#if 2 * DCACHE_WAY_SIZE > ICACHE_WAY_SIZE
#define TLBTEMP_SIZE		(2 * DCACHE_WAY_SIZE)
+1 −1
Original line number Diff line number Diff line
@@ -302,7 +302,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
	return -EFAULT;
}
#else
long strncpy_from_user(char *dst, const char *src, long count);
long strncpy_from_user(char *dst, const char __user *src, long count);
#endif

/*
+14 −0
Original line number Diff line number Diff line
@@ -70,8 +70,10 @@ static inline void kmap_invalidate_coherent(struct page *page,
			kvaddr = TLBTEMP_BASE_1 +
				(page_to_phys(page) & DCACHE_ALIAS_MASK);

			preempt_disable();
			__invalidate_dcache_page_alias(kvaddr,
						       page_to_phys(page));
			preempt_enable();
		}
	}
}
@@ -156,6 +158,7 @@ void flush_dcache_page(struct page *page)
		if (!alias && !mapping)
			return;

		preempt_disable();
		virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
		__flush_invalidate_dcache_page_alias(virt, phys);

@@ -166,6 +169,7 @@ void flush_dcache_page(struct page *page)

		if (mapping)
			__invalidate_icache_page_alias(virt, phys);
		preempt_enable();
	}

	/* There shouldn't be an entry in the cache for this page anymore. */
@@ -199,8 +203,10 @@ void local_flush_cache_page(struct vm_area_struct *vma, unsigned long address,
	unsigned long phys = page_to_phys(pfn_to_page(pfn));
	unsigned long virt = TLBTEMP_BASE_1 + (address & DCACHE_ALIAS_MASK);

	preempt_disable();
	__flush_invalidate_dcache_page_alias(virt, phys);
	__invalidate_icache_page_alias(virt, phys);
	preempt_enable();
}
EXPORT_SYMBOL(local_flush_cache_page);

@@ -227,11 +233,13 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
		unsigned long phys = page_to_phys(page);
		unsigned long tmp;

		preempt_disable();
		tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
		__flush_invalidate_dcache_page_alias(tmp, phys);
		tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
		__flush_invalidate_dcache_page_alias(tmp, phys);
		__invalidate_icache_page_alias(tmp, phys);
		preempt_enable();

		clear_bit(PG_arch_1, &page->flags);
	}
@@ -265,7 +273,9 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,

	if (alias) {
		unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
		preempt_disable();
		__flush_invalidate_dcache_page_alias(t, phys);
		preempt_enable();
	}

	/* Copy data */
@@ -280,9 +290,11 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
	if (alias) {
		unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);

		preempt_disable();
		__flush_invalidate_dcache_range((unsigned long) dst, len);
		if ((vma->vm_flags & VM_EXEC) != 0)
			__invalidate_icache_page_alias(t, phys);
		preempt_enable();

	} else if ((vma->vm_flags & VM_EXEC) != 0) {
		__flush_dcache_range((unsigned long)dst,len);
@@ -304,7 +316,9 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page,

	if (alias) {
		unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
		preempt_disable();
		__flush_invalidate_dcache_page_alias(t, phys);
		preempt_enable();
	}

	memcpy(dst, src, len);