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

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
...@@ -82,7 +82,8 @@ Default MMUv2-compatible layout:: ...@@ -82,7 +82,8 @@ Default MMUv2-compatible layout::
+------------------+ +------------------+
| VMALLOC area | VMALLOC_START 0xc0000000 128MB - 64KB | VMALLOC area | VMALLOC_START 0xc0000000 128MB - 64KB
+------------------+ VMALLOC_END +------------------+ VMALLOC_END
| Cache aliasing | TLBTEMP_BASE_1 0xc7ff0000 DCACHE_WAY_SIZE +------------------+
| Cache aliasing | TLBTEMP_BASE_1 0xc8000000 DCACHE_WAY_SIZE
| remap area 1 | | remap area 1 |
+------------------+ +------------------+
| Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE | Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE
...@@ -124,7 +125,8 @@ Default MMUv2-compatible layout:: ...@@ -124,7 +125,8 @@ Default MMUv2-compatible layout::
+------------------+ +------------------+
| VMALLOC area | VMALLOC_START 0xa0000000 128MB - 64KB | VMALLOC area | VMALLOC_START 0xa0000000 128MB - 64KB
+------------------+ VMALLOC_END +------------------+ VMALLOC_END
| Cache aliasing | TLBTEMP_BASE_1 0xa7ff0000 DCACHE_WAY_SIZE +------------------+
| Cache aliasing | TLBTEMP_BASE_1 0xa8000000 DCACHE_WAY_SIZE
| remap area 1 | | remap area 1 |
+------------------+ +------------------+
| Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE | Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE
...@@ -167,7 +169,8 @@ Default MMUv2-compatible layout:: ...@@ -167,7 +169,8 @@ Default MMUv2-compatible layout::
+------------------+ +------------------+
| VMALLOC area | VMALLOC_START 0x90000000 128MB - 64KB | VMALLOC area | VMALLOC_START 0x90000000 128MB - 64KB
+------------------+ VMALLOC_END +------------------+ VMALLOC_END
| Cache aliasing | TLBTEMP_BASE_1 0x97ff0000 DCACHE_WAY_SIZE +------------------+
| Cache aliasing | TLBTEMP_BASE_1 0x98000000 DCACHE_WAY_SIZE
| remap area 1 | | remap area 1 |
+------------------+ +------------------+
| Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE | Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
*/ */
#define VMALLOC_START (XCHAL_KSEG_CACHED_VADDR - 0x10000000) #define VMALLOC_START (XCHAL_KSEG_CACHED_VADDR - 0x10000000)
#define VMALLOC_END (VMALLOC_START + 0x07FEFFFF) #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) #define TLBTEMP_BASE_2 (TLBTEMP_BASE_1 + DCACHE_WAY_SIZE)
#if 2 * DCACHE_WAY_SIZE > ICACHE_WAY_SIZE #if 2 * DCACHE_WAY_SIZE > ICACHE_WAY_SIZE
#define TLBTEMP_SIZE (2 * DCACHE_WAY_SIZE) #define TLBTEMP_SIZE (2 * DCACHE_WAY_SIZE)
......
...@@ -302,7 +302,7 @@ strncpy_from_user(char *dst, const char __user *src, long count) ...@@ -302,7 +302,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
return -EFAULT; return -EFAULT;
} }
#else #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 #endif
/* /*
......
...@@ -70,8 +70,10 @@ static inline void kmap_invalidate_coherent(struct page *page, ...@@ -70,8 +70,10 @@ static inline void kmap_invalidate_coherent(struct page *page,
kvaddr = TLBTEMP_BASE_1 + kvaddr = TLBTEMP_BASE_1 +
(page_to_phys(page) & DCACHE_ALIAS_MASK); (page_to_phys(page) & DCACHE_ALIAS_MASK);
preempt_disable();
__invalidate_dcache_page_alias(kvaddr, __invalidate_dcache_page_alias(kvaddr,
page_to_phys(page)); page_to_phys(page));
preempt_enable();
} }
} }
} }
...@@ -156,6 +158,7 @@ void flush_dcache_page(struct page *page) ...@@ -156,6 +158,7 @@ void flush_dcache_page(struct page *page)
if (!alias && !mapping) if (!alias && !mapping)
return; return;
preempt_disable();
virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK); virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
__flush_invalidate_dcache_page_alias(virt, phys); __flush_invalidate_dcache_page_alias(virt, phys);
...@@ -166,6 +169,7 @@ void flush_dcache_page(struct page *page) ...@@ -166,6 +169,7 @@ void flush_dcache_page(struct page *page)
if (mapping) if (mapping)
__invalidate_icache_page_alias(virt, phys); __invalidate_icache_page_alias(virt, phys);
preempt_enable();
} }
/* There shouldn't be an entry in the cache for this page anymore. */ /* 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, ...@@ -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 phys = page_to_phys(pfn_to_page(pfn));
unsigned long virt = TLBTEMP_BASE_1 + (address & DCACHE_ALIAS_MASK); unsigned long virt = TLBTEMP_BASE_1 + (address & DCACHE_ALIAS_MASK);
preempt_disable();
__flush_invalidate_dcache_page_alias(virt, phys); __flush_invalidate_dcache_page_alias(virt, phys);
__invalidate_icache_page_alias(virt, phys); __invalidate_icache_page_alias(virt, phys);
preempt_enable();
} }
EXPORT_SYMBOL(local_flush_cache_page); EXPORT_SYMBOL(local_flush_cache_page);
...@@ -227,11 +233,13 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) ...@@ -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 phys = page_to_phys(page);
unsigned long tmp; unsigned long tmp;
preempt_disable();
tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK); tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
__flush_invalidate_dcache_page_alias(tmp, phys); __flush_invalidate_dcache_page_alias(tmp, phys);
tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
__flush_invalidate_dcache_page_alias(tmp, phys); __flush_invalidate_dcache_page_alias(tmp, phys);
__invalidate_icache_page_alias(tmp, phys); __invalidate_icache_page_alias(tmp, phys);
preempt_enable();
clear_bit(PG_arch_1, &page->flags); clear_bit(PG_arch_1, &page->flags);
} }
...@@ -265,7 +273,9 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, ...@@ -265,7 +273,9 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
if (alias) { if (alias) {
unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
preempt_disable();
__flush_invalidate_dcache_page_alias(t, phys); __flush_invalidate_dcache_page_alias(t, phys);
preempt_enable();
} }
/* Copy data */ /* Copy data */
...@@ -280,9 +290,11 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, ...@@ -280,9 +290,11 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
if (alias) { if (alias) {
unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
preempt_disable();
__flush_invalidate_dcache_range((unsigned long) dst, len); __flush_invalidate_dcache_range((unsigned long) dst, len);
if ((vma->vm_flags & VM_EXEC) != 0) if ((vma->vm_flags & VM_EXEC) != 0)
__invalidate_icache_page_alias(t, phys); __invalidate_icache_page_alias(t, phys);
preempt_enable();
} else if ((vma->vm_flags & VM_EXEC) != 0) { } else if ((vma->vm_flags & VM_EXEC) != 0) {
__flush_dcache_range((unsigned long)dst,len); __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, ...@@ -304,7 +316,9 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
if (alias) { if (alias) {
unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
preempt_disable();
__flush_invalidate_dcache_page_alias(t, phys); __flush_invalidate_dcache_page_alias(t, phys);
preempt_enable();
} }
memcpy(dst, src, len); memcpy(dst, src, len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment