aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2014-08-18 20:30:24 -0400
committerChris Zankel <chris@zankel.net>2014-08-18 20:30:24 -0400
commite792290be763932d1b8cdf8a36d7015482a49d07 (patch)
tree2aec72e1556ef099ff9bd535d21d4477e1db9ddb
parent7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9 (diff)
parent9184289c979e78ce466993b53fc951633441e571 (diff)
Merge tag 'xtensa-for-next-20140815' into for_next
Xtensa improvements for 3.17: - support highmem on cores with aliasing data cache. Enable highmem on kc705 by default; - simplify addition of new core variants (no need to modify Kconfig / Makefiles); - improve robustness of unaligned access handler and its interaction with window overflow/underflow exception handlers; - deprecate atomic and spill registers syscalls; - clean up Kconfig: remove orphan MATH_EMULATION, sort 'select' statements; - wire up renameat2 syscall. Various fixes: - fix address checks in dma_{alloc,free}_coherent (runtime BUG); - fix access to THREAD_RA/THREAD_SP/THREAD_DS (debug build breakage); - fix TLBTEMP_BASE_2 region handling in fast_second_level_miss (runtime unrecoverable exception); - fix a6 and a7 handling in fast_syscall_xtensa (runtime userspace register clobbering); - fix kernel/user jump out of fast_unaligned (potential runtime unrecoverable exception); - replace termios IOCTL code definitions with constants (userspace build breakage). Signed-off-by: Chris Zankel <chris@zankel.net>
-rw-r--r--arch/xtensa/Kconfig92
-rw-r--r--arch/xtensa/Makefile7
-rw-r--r--arch/xtensa/boot/dts/kc705.dts5
-rw-r--r--arch/xtensa/configs/common_defconfig1
-rw-r--r--arch/xtensa/configs/iss_defconfig3
-rw-r--r--arch/xtensa/configs/s6105_defconfig1
-rw-r--r--arch/xtensa/include/asm/cacheflush.h2
-rw-r--r--arch/xtensa/include/asm/fixmap.h30
-rw-r--r--arch/xtensa/include/asm/highmem.h40
-rw-r--r--arch/xtensa/include/asm/page.h14
-rw-r--r--arch/xtensa/include/asm/pgtable.h7
-rw-r--r--arch/xtensa/include/asm/uaccess.h5
-rw-r--r--arch/xtensa/include/uapi/asm/ioctls.h19
-rw-r--r--arch/xtensa/include/uapi/asm/unistd.h5
-rw-r--r--arch/xtensa/kernel/align.S128
-rw-r--r--arch/xtensa/kernel/entry.S54
-rw-r--r--arch/xtensa/kernel/pci-dma.c12
-rw-r--r--arch/xtensa/kernel/traps.c5
-rw-r--r--arch/xtensa/kernel/vectors.S8
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S4
-rw-r--r--arch/xtensa/mm/cache.c77
-rw-r--r--arch/xtensa/mm/highmem.c41
-rw-r--r--arch/xtensa/mm/misc.S116
-rw-r--r--arch/xtensa/mm/mmu.c38
24 files changed, 497 insertions, 217 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 3a617af60d46..49c6c3d94449 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -4,24 +4,23 @@ config ZONE_DMA
4config XTENSA 4config XTENSA
5 def_bool y 5 def_bool y
6 select ARCH_WANT_FRAME_POINTERS 6 select ARCH_WANT_FRAME_POINTERS
7 select HAVE_IDE
8 select GENERIC_ATOMIC64
9 select GENERIC_CLOCKEVENTS
10 select VIRT_TO_BUS
11 select GENERIC_IRQ_SHOW
12 select GENERIC_SCHED_CLOCK
13 select MODULES_USE_ELF_RELA
14 select GENERIC_PCI_IOMAP
15 select ARCH_WANT_IPC_PARSE_VERSION 7 select ARCH_WANT_IPC_PARSE_VERSION
16 select ARCH_WANT_OPTIONAL_GPIOLIB 8 select ARCH_WANT_OPTIONAL_GPIOLIB
17 select BUILDTIME_EXTABLE_SORT 9 select BUILDTIME_EXTABLE_SORT
18 select CLONE_BACKWARDS 10 select CLONE_BACKWARDS
19 select IRQ_DOMAIN 11 select COMMON_CLK
20 select HAVE_OPROFILE 12 select GENERIC_ATOMIC64
13 select GENERIC_CLOCKEVENTS
14 select GENERIC_IRQ_SHOW
15 select GENERIC_PCI_IOMAP
16 select GENERIC_SCHED_CLOCK
21 select HAVE_FUNCTION_TRACER 17 select HAVE_FUNCTION_TRACER
22 select HAVE_IRQ_TIME_ACCOUNTING 18 select HAVE_IRQ_TIME_ACCOUNTING
19 select HAVE_OPROFILE
23 select HAVE_PERF_EVENTS 20 select HAVE_PERF_EVENTS
24 select COMMON_CLK 21 select IRQ_DOMAIN
22 select MODULES_USE_ELF_RELA
23 select VIRT_TO_BUS
25 help 24 help
26 Xtensa processors are 32-bit RISC machines designed by Tensilica 25 Xtensa processors are 32-bit RISC machines designed by Tensilica
27 primarily for embedded systems. These processors are both 26 primarily for embedded systems. These processors are both
@@ -62,7 +61,9 @@ config TRACE_IRQFLAGS_SUPPORT
62 def_bool y 61 def_bool y
63 62
64config MMU 63config MMU
65 def_bool n 64 bool
65 default n if !XTENSA_VARIANT_CUSTOM
66 default XTENSA_VARIANT_MMU if XTENSA_VARIANT_CUSTOM
66 67
67config VARIANT_IRQ_SWITCH 68config VARIANT_IRQ_SWITCH
68 def_bool n 69 def_bool n
@@ -102,8 +103,40 @@ config XTENSA_VARIANT_S6000
102 select VARIANT_IRQ_SWITCH 103 select VARIANT_IRQ_SWITCH
103 select ARCH_REQUIRE_GPIOLIB 104 select ARCH_REQUIRE_GPIOLIB
104 select XTENSA_CALIBRATE_CCOUNT 105 select XTENSA_CALIBRATE_CCOUNT
106
107config XTENSA_VARIANT_CUSTOM
108 bool "Custom Xtensa processor configuration"
109 select MAY_HAVE_SMP
110 select HAVE_XTENSA_GPIO32
111 help
112 Select this variant to use a custom Xtensa processor configuration.
113 You will be prompted for a processor variant CORENAME.
105endchoice 114endchoice
106 115
116config XTENSA_VARIANT_CUSTOM_NAME
117 string "Xtensa Processor Custom Core Variant Name"
118 depends on XTENSA_VARIANT_CUSTOM
119 help
120 Provide the name of a custom Xtensa processor variant.
121 This CORENAME selects arch/xtensa/variant/CORENAME.
122 Dont forget you have to select MMU if you have one.
123
124config XTENSA_VARIANT_NAME
125 string
126 default "dc232b" if XTENSA_VARIANT_DC232B
127 default "dc233c" if XTENSA_VARIANT_DC233C
128 default "fsf" if XTENSA_VARIANT_FSF
129 default "s6000" if XTENSA_VARIANT_S6000
130 default XTENSA_VARIANT_CUSTOM_NAME if XTENSA_VARIANT_CUSTOM
131
132config XTENSA_VARIANT_MMU
133 bool "Core variant has a Full MMU (TLB, Pages, Protection, etc)"
134 depends on XTENSA_VARIANT_CUSTOM
135 default y
136 help
137 Build a Conventional Kernel with full MMU support,
138 ie: it supports a TLB with auto-loading, page protection.
139
107config XTENSA_UNALIGNED_USER 140config XTENSA_UNALIGNED_USER
108 bool "Unaligned memory access in use space" 141 bool "Unaligned memory access in use space"
109 help 142 help
@@ -156,13 +189,9 @@ config HOTPLUG_CPU
156 189
157 Say N if you want to disable CPU hotplug. 190 Say N if you want to disable CPU hotplug.
158 191
159config MATH_EMULATION
160 bool "Math emulation"
161 help
162 Can we use information of configuration file?
163
164config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX 192config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
165 bool "Initialize Xtensa MMU inside the Linux kernel code" 193 bool "Initialize Xtensa MMU inside the Linux kernel code"
194 depends on MMU
166 default y 195 default y
167 help 196 help
168 Earlier version initialized the MMU in the exception vector 197 Earlier version initialized the MMU in the exception vector
@@ -192,6 +221,7 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
192 221
193config HIGHMEM 222config HIGHMEM
194 bool "High Memory Support" 223 bool "High Memory Support"
224 depends on MMU
195 help 225 help
196 Linux can use the full amount of RAM in the system by 226 Linux can use the full amount of RAM in the system by
197 default. However, the default MMUv2 setup only maps the 227 default. However, the default MMUv2 setup only maps the
@@ -208,6 +238,32 @@ config HIGHMEM
208 238
209 If unsure, say Y. 239 If unsure, say Y.
210 240
241config FAST_SYSCALL_XTENSA
242 bool "Enable fast atomic syscalls"
243 default n
244 help
245 fast_syscall_xtensa is a syscall that can make atomic operations
246 on UP kernel when processor has no s32c1i support.
247
248 This syscall is deprecated. It may have issues when called with
249 invalid arguments. It is provided only for backwards compatibility.
250 Only enable it if your userspace software requires it.
251
252 If unsure, say N.
253
254config FAST_SYSCALL_SPILL_REGISTERS
255 bool "Enable spill registers syscall"
256 default n
257 help
258 fast_syscall_spill_registers is a syscall that spills all active
259 register windows of a calling userspace task onto its stack.
260
261 This syscall is deprecated. It may have issues when called with
262 invalid arguments. It is provided only for backwards compatibility.
263 Only enable it if your userspace software requires it.
264
265 If unsure, say N.
266
211endmenu 267endmenu
212 268
213config XTENSA_CALIBRATE_CCOUNT 269config XTENSA_CALIBRATE_CCOUNT
@@ -250,12 +306,14 @@ config XTENSA_PLATFORM_ISS
250 306
251config XTENSA_PLATFORM_XT2000 307config XTENSA_PLATFORM_XT2000
252 bool "XT2000" 308 bool "XT2000"
309 select HAVE_IDE
253 help 310 help
254 XT2000 is the name of Tensilica's feature-rich emulation platform. 311 XT2000 is the name of Tensilica's feature-rich emulation platform.
255 This hardware is capable of running a full Linux distribution. 312 This hardware is capable of running a full Linux distribution.
256 313
257config XTENSA_PLATFORM_S6105 314config XTENSA_PLATFORM_S6105
258 bool "S6105" 315 bool "S6105"
316 select HAVE_IDE
259 select SERIAL_CONSOLE 317 select SERIAL_CONSOLE
260 select NO_IOPORT_MAP 318 select NO_IOPORT_MAP
261 319
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 81250ece3062..472533064b46 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -4,6 +4,7 @@
4# for more details. 4# for more details.
5# 5#
6# Copyright (C) 2001 - 2005 Tensilica Inc. 6# Copyright (C) 2001 - 2005 Tensilica Inc.
7# Copyright (C) 2014 Cadence Design Systems Inc.
7# 8#
8# This file is included by the global makefile so that you can add your own 9# This file is included by the global makefile so that you can add your own
9# architecture-specific flags and dependencies. Remember to do have actions 10# architecture-specific flags and dependencies. Remember to do have actions
@@ -13,11 +14,7 @@
13# Core configuration. 14# Core configuration.
14# (Use VAR=<xtensa_config> to use another default compiler.) 15# (Use VAR=<xtensa_config> to use another default compiler.)
15 16
16variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf 17variant-y := $(patsubst "%",%,$(CONFIG_XTENSA_VARIANT_NAME))
17variant-$(CONFIG_XTENSA_VARIANT_DC232B) := dc232b
18variant-$(CONFIG_XTENSA_VARIANT_DC233C) := dc233c
19variant-$(CONFIG_XTENSA_VARIANT_S6000) := s6000
20variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom
21 18
22VARIANT = $(variant-y) 19VARIANT = $(variant-y)
23export VARIANT 20export VARIANT
diff --git a/arch/xtensa/boot/dts/kc705.dts b/arch/xtensa/boot/dts/kc705.dts
index 742a347be67a..c4d17a34ab86 100644
--- a/arch/xtensa/boot/dts/kc705.dts
+++ b/arch/xtensa/boot/dts/kc705.dts
@@ -4,8 +4,11 @@
4 4
5/ { 5/ {
6 compatible = "cdns,xtensa-kc705"; 6 compatible = "cdns,xtensa-kc705";
7 chosen {
8 bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000";
9 };
7 memory@0 { 10 memory@0 {
8 device_type = "memory"; 11 device_type = "memory";
9 reg = <0x00000000 0x08000000>; 12 reg = <0x00000000 0x38000000>;
10 }; 13 };
11}; 14};
diff --git a/arch/xtensa/configs/common_defconfig b/arch/xtensa/configs/common_defconfig
index f6000fe05119..721df1214bc3 100644
--- a/arch/xtensa/configs/common_defconfig
+++ b/arch/xtensa/configs/common_defconfig
@@ -66,7 +66,6 @@ CONFIG_XTENSA_ARCH_LINUX_BE=y
66CONFIG_MMU=y 66CONFIG_MMU=y
67# CONFIG_XTENSA_UNALIGNED_USER is not set 67# CONFIG_XTENSA_UNALIGNED_USER is not set
68# CONFIG_PREEMPT is not set 68# CONFIG_PREEMPT is not set
69# CONFIG_MATH_EMULATION is not set
70# CONFIG_HIGHMEM is not set 69# CONFIG_HIGHMEM is not set
71 70
72# 71#
diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig
index 1493c68352d1..b966baf82cae 100644
--- a/arch/xtensa/configs/iss_defconfig
+++ b/arch/xtensa/configs/iss_defconfig
@@ -146,7 +146,6 @@ CONFIG_XTENSA_VARIANT_FSF=y
146# CONFIG_XTENSA_VARIANT_S6000 is not set 146# CONFIG_XTENSA_VARIANT_S6000 is not set
147# CONFIG_XTENSA_UNALIGNED_USER is not set 147# CONFIG_XTENSA_UNALIGNED_USER is not set
148# CONFIG_PREEMPT is not set 148# CONFIG_PREEMPT is not set
149# CONFIG_MATH_EMULATION is not set
150CONFIG_XTENSA_CALIBRATE_CCOUNT=y 149CONFIG_XTENSA_CALIBRATE_CCOUNT=y
151CONFIG_SERIAL_CONSOLE=y 150CONFIG_SERIAL_CONSOLE=y
152CONFIG_XTENSA_ISS_NETWORK=y 151CONFIG_XTENSA_ISS_NETWORK=y
@@ -308,7 +307,7 @@ CONFIG_MISC_DEVICES=y
308# EEPROM support 307# EEPROM support
309# 308#
310# CONFIG_EEPROM_93CX6 is not set 309# CONFIG_EEPROM_93CX6 is not set
311CONFIG_HAVE_IDE=y 310# CONFIG_HAVE_IDE is not set
312# CONFIG_IDE is not set 311# CONFIG_IDE is not set
313 312
314# 313#
diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig
index 12a492ab6d17..9471265b8ca6 100644
--- a/arch/xtensa/configs/s6105_defconfig
+++ b/arch/xtensa/configs/s6105_defconfig
@@ -109,7 +109,6 @@ CONFIG_VARIANT_IRQ_SWITCH=y
109CONFIG_XTENSA_VARIANT_S6000=y 109CONFIG_XTENSA_VARIANT_S6000=y
110# CONFIG_XTENSA_UNALIGNED_USER is not set 110# CONFIG_XTENSA_UNALIGNED_USER is not set
111CONFIG_PREEMPT=y 111CONFIG_PREEMPT=y
112# CONFIG_MATH_EMULATION is not set
113# CONFIG_HIGHMEM is not set 112# CONFIG_HIGHMEM is not set
114CONFIG_XTENSA_CALIBRATE_CCOUNT=y 113CONFIG_XTENSA_CALIBRATE_CCOUNT=y
115CONFIG_SERIAL_CONSOLE=y 114CONFIG_SERIAL_CONSOLE=y
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h
index 555a98a18453..e72aaca7a77f 100644
--- a/arch/xtensa/include/asm/cacheflush.h
+++ b/arch/xtensa/include/asm/cacheflush.h
@@ -37,6 +37,7 @@
37 * specials for cache aliasing: 37 * specials for cache aliasing:
38 * 38 *
39 * __flush_invalidate_dcache_page_alias(vaddr,paddr) 39 * __flush_invalidate_dcache_page_alias(vaddr,paddr)
40 * __invalidate_dcache_page_alias(vaddr,paddr)
40 * __invalidate_icache_page_alias(vaddr,paddr) 41 * __invalidate_icache_page_alias(vaddr,paddr)
41 */ 42 */
42 43
@@ -62,6 +63,7 @@ extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
62 63
63#if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE) 64#if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE)
64extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long); 65extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
66extern void __invalidate_dcache_page_alias(unsigned long, unsigned long);
65#else 67#else
66static inline void __flush_invalidate_dcache_page_alias(unsigned long virt, 68static inline void __flush_invalidate_dcache_page_alias(unsigned long virt,
67 unsigned long phys) { } 69 unsigned long phys) { }
diff --git a/arch/xtensa/include/asm/fixmap.h b/arch/xtensa/include/asm/fixmap.h
index 9f6c33d0428a..62b507deea9d 100644
--- a/arch/xtensa/include/asm/fixmap.h
+++ b/arch/xtensa/include/asm/fixmap.h
@@ -23,8 +23,8 @@
23 * Here we define all the compile-time 'special' virtual 23 * Here we define all the compile-time 'special' virtual
24 * addresses. The point is to have a constant address at 24 * addresses. The point is to have a constant address at
25 * compile time, but to set the physical address only 25 * compile time, but to set the physical address only
26 * in the boot process. We allocate these special addresses 26 * in the boot process. We allocate these special addresses
27 * from the end of the consistent memory region backwards. 27 * from the start of the consistent memory region upwards.
28 * Also this lets us do fail-safe vmalloc(), we 28 * Also this lets us do fail-safe vmalloc(), we
29 * can guarantee that these special addresses and 29 * can guarantee that these special addresses and
30 * vmalloc()-ed addresses never overlap. 30 * vmalloc()-ed addresses never overlap.
@@ -38,7 +38,8 @@ enum fixed_addresses {
38#ifdef CONFIG_HIGHMEM 38#ifdef CONFIG_HIGHMEM
39 /* reserved pte's for temporary kernel mappings */ 39 /* reserved pte's for temporary kernel mappings */
40 FIX_KMAP_BEGIN, 40 FIX_KMAP_BEGIN,
41 FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, 41 FIX_KMAP_END = FIX_KMAP_BEGIN +
42 (KM_TYPE_NR * NR_CPUS * DCACHE_N_COLORS) - 1,
42#endif 43#endif
43 __end_of_fixed_addresses 44 __end_of_fixed_addresses
44}; 45};
@@ -47,7 +48,28 @@ enum fixed_addresses {
47#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) 48#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
48#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) 49#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK)
49 50
50#include <asm-generic/fixmap.h> 51#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT))
52#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT)
53
54#ifndef __ASSEMBLY__
55/*
56 * 'index to address' translation. If anyone tries to use the idx
57 * directly without translation, we catch the bug with a NULL-deference
58 * kernel oops. Illegal ranges of incoming indices are caught too.
59 */
60static __always_inline unsigned long fix_to_virt(const unsigned int idx)
61{
62 BUILD_BUG_ON(idx >= __end_of_fixed_addresses);
63 return __fix_to_virt(idx);
64}
65
66static inline unsigned long virt_to_fix(const unsigned long vaddr)
67{
68 BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
69 return __virt_to_fix(vaddr);
70}
71
72#endif
51 73
52#define kmap_get_fixmap_pte(vaddr) \ 74#define kmap_get_fixmap_pte(vaddr) \
53 pte_offset_kernel( \ 75 pte_offset_kernel( \
diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h
index 2653ef5d55f1..2c7901edffaf 100644
--- a/arch/xtensa/include/asm/highmem.h
+++ b/arch/xtensa/include/asm/highmem.h
@@ -12,19 +12,55 @@
12#ifndef _XTENSA_HIGHMEM_H 12#ifndef _XTENSA_HIGHMEM_H
13#define _XTENSA_HIGHMEM_H 13#define _XTENSA_HIGHMEM_H
14 14
15#include <linux/wait.h>
15#include <asm/cacheflush.h> 16#include <asm/cacheflush.h>
16#include <asm/fixmap.h> 17#include <asm/fixmap.h>
17#include <asm/kmap_types.h> 18#include <asm/kmap_types.h>
18#include <asm/pgtable.h> 19#include <asm/pgtable.h>
19 20
20#define PKMAP_BASE (FIXADDR_START - PMD_SIZE) 21#define PKMAP_BASE ((FIXADDR_START - \
21#define LAST_PKMAP PTRS_PER_PTE 22 (LAST_PKMAP + 1) * PAGE_SIZE) & PMD_MASK)
23#define LAST_PKMAP (PTRS_PER_PTE * DCACHE_N_COLORS)
22#define LAST_PKMAP_MASK (LAST_PKMAP - 1) 24#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
23#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) 25#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
24#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) 26#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
25 27
26#define kmap_prot PAGE_KERNEL 28#define kmap_prot PAGE_KERNEL
27 29
30#if DCACHE_WAY_SIZE > PAGE_SIZE
31#define get_pkmap_color get_pkmap_color
32static inline int get_pkmap_color(struct page *page)
33{
34 return DCACHE_ALIAS(page_to_phys(page));
35}
36
37extern unsigned int last_pkmap_nr_arr[];
38
39static inline unsigned int get_next_pkmap_nr(unsigned int color)
40{
41 last_pkmap_nr_arr[color] =
42 (last_pkmap_nr_arr[color] + DCACHE_N_COLORS) & LAST_PKMAP_MASK;
43 return last_pkmap_nr_arr[color] + color;
44}
45
46static inline int no_more_pkmaps(unsigned int pkmap_nr, unsigned int color)
47{
48 return pkmap_nr < DCACHE_N_COLORS;
49}
50
51static inline int get_pkmap_entries_count(unsigned int color)
52{
53 return LAST_PKMAP / DCACHE_N_COLORS;
54}
55
56extern wait_queue_head_t pkmap_map_wait_arr[];
57
58static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color)
59{
60 return pkmap_map_wait_arr + color;
61}
62#endif
63
28extern pte_t *pkmap_page_table; 64extern pte_t *pkmap_page_table;
29 65
30void *kmap_high(struct page *page); 66void *kmap_high(struct page *page);
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h
index 47f582333f6b..abe24c6f8b2f 100644
--- a/arch/xtensa/include/asm/page.h
+++ b/arch/xtensa/include/asm/page.h
@@ -78,7 +78,9 @@
78# define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0) 78# define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0)
79#else 79#else
80# define DCACHE_ALIAS_ORDER 0 80# define DCACHE_ALIAS_ORDER 0
81# define DCACHE_ALIAS(a) ((void)(a), 0)
81#endif 82#endif
83#define DCACHE_N_COLORS (1 << DCACHE_ALIAS_ORDER)
82 84
83#if ICACHE_WAY_SIZE > PAGE_SIZE 85#if ICACHE_WAY_SIZE > PAGE_SIZE
84# define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT) 86# define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT)
@@ -134,6 +136,7 @@ static inline __attribute_const__ int get_order(unsigned long size)
134#endif 136#endif
135 137
136struct page; 138struct page;
139struct vm_area_struct;
137extern void clear_page(void *page); 140extern void clear_page(void *page);
138extern void copy_page(void *to, void *from); 141extern void copy_page(void *to, void *from);
139 142
@@ -143,8 +146,15 @@ extern void copy_page(void *to, void *from);
143 */ 146 */
144 147
145#if DCACHE_WAY_SIZE > PAGE_SIZE 148#if DCACHE_WAY_SIZE > PAGE_SIZE
146extern void clear_user_page(void*, unsigned long, struct page*); 149extern void clear_page_alias(void *vaddr, unsigned long paddr);
147extern void copy_user_page(void*, void*, unsigned long, struct page*); 150extern void copy_page_alias(void *to, void *from,
151 unsigned long to_paddr, unsigned long from_paddr);
152
153#define clear_user_highpage clear_user_highpage
154void clear_user_highpage(struct page *page, unsigned long vaddr);
155#define __HAVE_ARCH_COPY_USER_HIGHPAGE
156void copy_user_highpage(struct page *to, struct page *from,
157 unsigned long vaddr, struct vm_area_struct *vma);
148#else 158#else
149# define clear_user_page(page, vaddr, pg) clear_page(page) 159# define clear_user_page(page, vaddr, pg) clear_page(page)
150# define copy_user_page(to, from, vaddr, pg) copy_page(to, from) 160# define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 4b0ca35a93b1..b2173e5da601 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -67,7 +67,12 @@
67#define VMALLOC_START 0xC0000000 67#define VMALLOC_START 0xC0000000
68#define VMALLOC_END 0xC7FEFFFF 68#define VMALLOC_END 0xC7FEFFFF
69#define TLBTEMP_BASE_1 0xC7FF0000 69#define TLBTEMP_BASE_1 0xC7FF0000
70#define TLBTEMP_BASE_2 0xC7FF8000 70#define TLBTEMP_BASE_2 (TLBTEMP_BASE_1 + DCACHE_WAY_SIZE)
71#if 2 * DCACHE_WAY_SIZE > ICACHE_WAY_SIZE
72#define TLBTEMP_SIZE (2 * DCACHE_WAY_SIZE)
73#else
74#define TLBTEMP_SIZE ICACHE_WAY_SIZE
75#endif
71 76
72/* 77/*
73 * For the Xtensa architecture, the PTE layout is as follows: 78 * For the Xtensa architecture, the PTE layout is as follows:
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h
index fd686dc45d1a..c7211e7e182d 100644
--- a/arch/xtensa/include/asm/uaccess.h
+++ b/arch/xtensa/include/asm/uaccess.h
@@ -52,7 +52,12 @@
52 */ 52 */
53 .macro get_fs ad, sp 53 .macro get_fs ad, sp
54 GET_CURRENT(\ad,\sp) 54 GET_CURRENT(\ad,\sp)
55#if THREAD_CURRENT_DS > 1020
56 addi \ad, \ad, TASK_THREAD
57 l32i \ad, \ad, THREAD_CURRENT_DS - TASK_THREAD
58#else
55 l32i \ad, \ad, THREAD_CURRENT_DS 59 l32i \ad, \ad, THREAD_CURRENT_DS
60#endif
56 .endm 61 .endm
57 62
58/* 63/*
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
index b4cb1100c0fb..a47909f0c34b 100644
--- a/arch/xtensa/include/uapi/asm/ioctls.h
+++ b/arch/xtensa/include/uapi/asm/ioctls.h
@@ -28,17 +28,17 @@
28#define TCSETSW 0x5403 28#define TCSETSW 0x5403
29#define TCSETSF 0x5404 29#define TCSETSF 0x5404
30 30
31#define TCGETA _IOR('t', 23, struct termio) 31#define TCGETA 0x80127417 /* _IOR('t', 23, struct termio) */
32#define TCSETA _IOW('t', 24, struct termio) 32#define TCSETA 0x40127418 /* _IOW('t', 24, struct termio) */
33#define TCSETAW _IOW('t', 25, struct termio) 33#define TCSETAW 0x40127419 /* _IOW('t', 25, struct termio) */
34#define TCSETAF _IOW('t', 28, struct termio) 34#define TCSETAF 0x4012741C /* _IOW('t', 28, struct termio) */
35 35
36#define TCSBRK _IO('t', 29) 36#define TCSBRK _IO('t', 29)
37#define TCXONC _IO('t', 30) 37#define TCXONC _IO('t', 30)
38#define TCFLSH _IO('t', 31) 38#define TCFLSH _IO('t', 31)
39 39
40#define TIOCSWINSZ _IOW('t', 103, struct winsize) 40#define TIOCSWINSZ 0x40087467 /* _IOW('t', 103, struct winsize) */
41#define TIOCGWINSZ _IOR('t', 104, struct winsize) 41#define TIOCGWINSZ 0x80087468 /* _IOR('t', 104, struct winsize) */
42#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ 42#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
43#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ 43#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
44#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ 44#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
@@ -88,7 +88,6 @@
88#define TIOCSETD _IOW('T', 35, int) 88#define TIOCSETD _IOW('T', 35, int)
89#define TIOCGETD _IOR('T', 36, int) 89#define TIOCGETD _IOR('T', 36, int)
90#define TCSBRKP _IOW('T', 37, int) /* Needed for POSIX tcsendbreak()*/ 90#define TCSBRKP _IOW('T', 37, int) /* Needed for POSIX tcsendbreak()*/
91#define TIOCTTYGSTRUCT _IOR('T', 38, struct tty_struct) /* For debugging only*/
92#define TIOCSBRK _IO('T', 39) /* BSD compatibility */ 91#define TIOCSBRK _IO('T', 39) /* BSD compatibility */
93#define TIOCCBRK _IO('T', 40) /* BSD compatibility */ 92#define TIOCCBRK _IO('T', 40) /* BSD compatibility */
94#define TIOCGSID _IOR('T', 41, pid_t) /* Return the session ID of FD*/ 93#define TIOCGSID _IOR('T', 41, pid_t) /* Return the session ID of FD*/
@@ -114,8 +113,10 @@
114#define TIOCSERGETLSR _IOR('T', 89, unsigned int) /* Get line status reg. */ 113#define TIOCSERGETLSR _IOR('T', 89, unsigned int) /* Get line status reg. */
115 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ 114 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
116# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ 115# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
117#define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* Get multiport config */ 116#define TIOCSERGETMULTI 0x80a8545a /* Get multiport config */
118#define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */ 117 /* _IOR('T', 90, struct serial_multiport_struct) */
118#define TIOCSERSETMULTI 0x40a8545b /* Set multiport config */
119 /* _IOW('T', 91, struct serial_multiport_struct) */
119 120
120#define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */ 121#define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */
121#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ 122#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h
index b9395529f02d..8883fc877c5c 100644
--- a/arch/xtensa/include/uapi/asm/unistd.h
+++ b/arch/xtensa/include/uapi/asm/unistd.h
@@ -739,7 +739,10 @@ __SYSCALL(334, sys_sched_setattr, 2)
739#define __NR_sched_getattr 335 739#define __NR_sched_getattr 335
740__SYSCALL(335, sys_sched_getattr, 3) 740__SYSCALL(335, sys_sched_getattr, 3)
741 741
742#define __NR_syscall_count 336 742#define __NR_renameat2 336
743__SYSCALL(336, sys_renameat2, 5)
744
745#define __NR_syscall_count 337
743 746
744/* 747/*
745 * sysxtensa syscall handler 748 * sysxtensa syscall handler
diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S
index d4cef6039a5c..890004af03a9 100644
--- a/arch/xtensa/kernel/align.S
+++ b/arch/xtensa/kernel/align.S
@@ -8,6 +8,7 @@
8 * this archive for more details. 8 * this archive for more details.
9 * 9 *
10 * Copyright (C) 2001 - 2005 Tensilica, Inc. 10 * Copyright (C) 2001 - 2005 Tensilica, Inc.
11 * Copyright (C) 2014 Cadence Design Systems Inc.
11 * 12 *
12 * Rewritten by Chris Zankel <chris@zankel.net> 13 * Rewritten by Chris Zankel <chris@zankel.net>
13 * 14 *
@@ -174,6 +175,10 @@ ENTRY(fast_unaligned)
174 s32i a0, a2, PT_AREG2 175 s32i a0, a2, PT_AREG2
175 s32i a3, a2, PT_AREG3 176 s32i a3, a2, PT_AREG3
176 177
178 rsr a3, excsave1
179 movi a4, fast_unaligned_fixup
180 s32i a4, a3, EXC_TABLE_FIXUP
181
177 /* Keep value of SAR in a0 */ 182 /* Keep value of SAR in a0 */
178 183
179 rsr a0, sar 184 rsr a0, sar
@@ -225,10 +230,6 @@ ENTRY(fast_unaligned)
225 addx8 a5, a6, a5 230 addx8 a5, a6, a5
226 jx a5 # jump into table 231 jx a5 # jump into table
227 232
228 /* Invalid instruction, CRITICAL! */
229.Linvalid_instruction_load:
230 j .Linvalid_instruction
231
232 /* Load: Load memory address. */ 233 /* Load: Load memory address. */
233 234
234.Lload: movi a3, ~3 235.Lload: movi a3, ~3
@@ -272,18 +273,6 @@ ENTRY(fast_unaligned)
272 /* Set target register. */ 273 /* Set target register. */
273 274
2741: 2751:
275
276#if XCHAL_HAVE_LOOPS
277 rsr a5, lend # check if we reached LEND
278 bne a7, a5, 1f
279 rsr a5, lcount # and LCOUNT != 0
280 beqz a5, 1f
281 addi a5, a5, -1 # decrement LCOUNT and set
282 rsr a7, lbeg # set PC to LBEGIN
283 wsr a5, lcount
284#endif
285
2861: wsr a7, epc1 # skip load instruction
287 extui a4, a4, INSN_T, 4 # extract target register 276 extui a4, a4, INSN_T, 4 # extract target register
288 movi a5, .Lload_table 277 movi a5, .Lload_table
289 addx8 a4, a4, a5 278 addx8 a4, a4, a5
@@ -326,6 +315,35 @@ ENTRY(fast_unaligned)
326 mov a3, a14 ; _j 1f; .align 8 315 mov a3, a14 ; _j 1f; .align 8
327 mov a3, a15 ; _j 1f; .align 8 316 mov a3, a15 ; _j 1f; .align 8
328 317
318 /* We cannot handle this exception. */
319
320 .extern _kernel_exception
321.Linvalid_instruction_load:
322.Linvalid_instruction_store:
323
324 movi a4, 0
325 rsr a3, excsave1
326 s32i a4, a3, EXC_TABLE_FIXUP
327
328 /* Restore a4...a8 and SAR, set SP, and jump to default exception. */
329
330 l32i a8, a2, PT_AREG8
331 l32i a7, a2, PT_AREG7
332 l32i a6, a2, PT_AREG6
333 l32i a5, a2, PT_AREG5
334 l32i a4, a2, PT_AREG4
335 wsr a0, sar
336 mov a1, a2
337
338 rsr a0, ps
339 bbsi.l a0, PS_UM_BIT, 2f # jump if user mode
340
341 movi a0, _kernel_exception
342 jx a0
343
3442: movi a0, _user_exception
345 jx a0
346
3291: # a7: instruction pointer, a4: instruction, a3: value 3471: # a7: instruction pointer, a4: instruction, a3: value
330 348
331 movi a6, 0 # mask: ffffffff:00000000 349 movi a6, 0 # mask: ffffffff:00000000
@@ -353,17 +371,6 @@ ENTRY(fast_unaligned)
353 /* Get memory address */ 371 /* Get memory address */
354 372
3551: 3731:
356#if XCHAL_HAVE_LOOPS
357 rsr a4, lend # check if we reached LEND
358 bne a7, a4, 1f
359 rsr a4, lcount # and LCOUNT != 0
360 beqz a4, 1f
361 addi a4, a4, -1 # decrement LCOUNT and set
362 rsr a7, lbeg # set PC to LBEGIN
363 wsr a4, lcount
364#endif
365
3661: wsr a7, epc1 # skip store instruction
367 movi a4, ~3 374 movi a4, ~3
368 and a4, a4, a8 # align memory address 375 and a4, a4, a8 # align memory address
369 376
@@ -375,25 +382,25 @@ ENTRY(fast_unaligned)
375#endif 382#endif
376 383
377 __ssa8r a8 384 __ssa8r a8
378 __src_b a7, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE) 385 __src_b a8, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE)
379 __src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE) 386 __src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE)
380#ifdef UNALIGNED_USER_EXCEPTION 387#ifdef UNALIGNED_USER_EXCEPTION
381 l32e a5, a4, -8 388 l32e a5, a4, -8
382#else 389#else
383 l32i a5, a4, 0 # load lower address word 390 l32i a5, a4, 0 # load lower address word
384#endif 391#endif
385 and a5, a5, a7 # mask 392 and a5, a5, a8 # mask
386 __sh a7, a3 # shift value 393 __sh a8, a3 # shift value
387 or a5, a5, a7 # or with original value 394 or a5, a5, a8 # or with original value
388#ifdef UNALIGNED_USER_EXCEPTION 395#ifdef UNALIGNED_USER_EXCEPTION
389 s32e a5, a4, -8 396 s32e a5, a4, -8
390 l32e a7, a4, -4 397 l32e a8, a4, -4
391#else 398#else
392 s32i a5, a4, 0 # store 399 s32i a5, a4, 0 # store
393 l32i a7, a4, 4 # same for upper address word 400 l32i a8, a4, 4 # same for upper address word
394#endif 401#endif
395 __sl a5, a3 402 __sl a5, a3
396 and a6, a7, a6 403 and a6, a8, a6
397 or a6, a6, a5 404 or a6, a6, a5
398#ifdef UNALIGNED_USER_EXCEPTION 405#ifdef UNALIGNED_USER_EXCEPTION
399 s32e a6, a4, -4 406 s32e a6, a4, -4
@@ -401,9 +408,27 @@ ENTRY(fast_unaligned)
401 s32i a6, a4, 4 408 s32i a6, a4, 4
402#endif 409#endif
403 410
404 /* Done. restore stack and return */
405
406.Lexit: 411.Lexit:
412#if XCHAL_HAVE_LOOPS
413 rsr a4, lend # check if we reached LEND
414 bne a7, a4, 1f
415 rsr a4, lcount # and LCOUNT != 0
416 beqz a4, 1f
417 addi a4, a4, -1 # decrement LCOUNT and set
418 rsr a7, lbeg # set PC to LBEGIN
419 wsr a4, lcount
420#endif
421
4221: wsr a7, epc1 # skip emulated instruction
423
424 /* Update icount if we're single-stepping in userspace. */
425 rsr a4, icountlevel
426 beqz a4, 1f
427 bgeui a4, LOCKLEVEL + 1, 1f
428 rsr a4, icount
429 addi a4, a4, 1
430 wsr a4, icount
4311:
407 movi a4, 0 432 movi a4, 0
408 rsr a3, excsave1 433 rsr a3, excsave1
409 s32i a4, a3, EXC_TABLE_FIXUP 434 s32i a4, a3, EXC_TABLE_FIXUP
@@ -424,31 +449,40 @@ ENTRY(fast_unaligned)
424 l32i a2, a2, PT_AREG2 449 l32i a2, a2, PT_AREG2
425 rfe 450 rfe
426 451
427 /* We cannot handle this exception. */ 452ENDPROC(fast_unaligned)
428 453
429 .extern _kernel_exception 454ENTRY(fast_unaligned_fixup)
430.Linvalid_instruction_store:
431.Linvalid_instruction:
432 455
433 /* Restore a4...a8 and SAR, set SP, and jump to default exception. */ 456 l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
457 wsr a3, excsave1
434 458
435 l32i a8, a2, PT_AREG8 459 l32i a8, a2, PT_AREG8
436 l32i a7, a2, PT_AREG7 460 l32i a7, a2, PT_AREG7
437 l32i a6, a2, PT_AREG6 461 l32i a6, a2, PT_AREG6
438 l32i a5, a2, PT_AREG5 462 l32i a5, a2, PT_AREG5
439 l32i a4, a2, PT_AREG4 463 l32i a4, a2, PT_AREG4
464 l32i a0, a2, PT_AREG2
465 xsr a0, depc # restore depc and a0
440 wsr a0, sar 466 wsr a0, sar
441 mov a1, a2 467
468 rsr a0, exccause
469 s32i a0, a2, PT_DEPC # mark as a regular exception
442 470
443 rsr a0, ps 471 rsr a0, ps
444 bbsi.l a2, PS_UM_BIT, 1f # jump if user mode 472 bbsi.l a0, PS_UM_BIT, 1f # jump if user mode
445 473
446 movi a0, _kernel_exception 474 rsr a0, exccause
475 addx4 a0, a0, a3 # find entry in table
476 l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler
477 l32i a3, a2, PT_AREG3
447 jx a0 478 jx a0
448 4791:
4491: movi a0, _user_exception 480 rsr a0, exccause
481 addx4 a0, a0, a3 # find entry in table
482 l32i a0, a0, EXC_TABLE_FAST_USER # load handler
483 l32i a3, a2, PT_AREG3
450 jx a0 484 jx a0
451 485
452ENDPROC(fast_unaligned) 486ENDPROC(fast_unaligned_fixup)
453 487
454#endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ 488#endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index ef7f4990722b..82bbfa5a05b3 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -986,6 +986,8 @@ ENDPROC(fast_syscall_unrecoverable)
986 * j done 986 * j done
987 */ 987 */
988 988
989#ifdef CONFIG_FAST_SYSCALL_XTENSA
990
989#define TRY \ 991#define TRY \
990 .section __ex_table, "a"; \ 992 .section __ex_table, "a"; \
991 .word 66f, 67f; \ 993 .word 66f, 67f; \
@@ -1001,9 +1003,8 @@ ENTRY(fast_syscall_xtensa)
1001 movi a7, 4 # sizeof(unsigned int) 1003 movi a7, 4 # sizeof(unsigned int)
1002 access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp 1004 access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp
1003 1005
1004 addi a6, a6, -1 # assuming SYS_XTENSA_ATOMIC_SET = 1 1006 _bgeui a6, SYS_XTENSA_COUNT, .Lill
1005 _bgeui a6, SYS_XTENSA_COUNT - 1, .Lill 1007 _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP, .Lnswp
1006 _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP - 1, .Lnswp
1007 1008
1008 /* Fall through for ATOMIC_CMP_SWP. */ 1009 /* Fall through for ATOMIC_CMP_SWP. */
1009 1010
@@ -1015,27 +1016,26 @@ TRY s32i a5, a3, 0 # different, modify value
1015 l32i a7, a2, PT_AREG7 # restore a7 1016 l32i a7, a2, PT_AREG7 # restore a7
1016 l32i a0, a2, PT_AREG0 # restore a0 1017 l32i a0, a2, PT_AREG0 # restore a0
1017 movi a2, 1 # and return 1 1018 movi a2, 1 # and return 1
1018 addi a6, a6, 1 # restore a6 (really necessary?)
1019 rfe 1019 rfe
1020 1020
10211: l32i a7, a2, PT_AREG7 # restore a7 10211: l32i a7, a2, PT_AREG7 # restore a7
1022 l32i a0, a2, PT_AREG0 # restore a0 1022 l32i a0, a2, PT_AREG0 # restore a0
1023 movi a2, 0 # return 0 (note that we cannot set 1023 movi a2, 0 # return 0 (note that we cannot set
1024 addi a6, a6, 1 # restore a6 (really necessary?)
1025 rfe 1024 rfe
1026 1025
1027.Lnswp: /* Atomic set, add, and exg_add. */ 1026.Lnswp: /* Atomic set, add, and exg_add. */
1028 1027
1029TRY l32i a7, a3, 0 # orig 1028TRY l32i a7, a3, 0 # orig
1029 addi a6, a6, -SYS_XTENSA_ATOMIC_SET
1030 add a0, a4, a7 # + arg 1030 add a0, a4, a7 # + arg
1031 moveqz a0, a4, a6 # set 1031 moveqz a0, a4, a6 # set
1032 addi a6, a6, SYS_XTENSA_ATOMIC_SET
1032TRY s32i a0, a3, 0 # write new value 1033TRY s32i a0, a3, 0 # write new value
1033 1034
1034 mov a0, a2 1035 mov a0, a2
1035 mov a2, a7 1036 mov a2, a7
1036 l32i a7, a0, PT_AREG7 # restore a7 1037 l32i a7, a0, PT_AREG7 # restore a7
1037 l32i a0, a0, PT_AREG0 # restore a0 1038 l32i a0, a0, PT_AREG0 # restore a0
1038 addi a6, a6, 1 # restore a6 (really necessary?)
1039 rfe 1039 rfe
1040 1040
1041CATCH 1041CATCH
@@ -1044,13 +1044,25 @@ CATCH
1044 movi a2, -EFAULT 1044 movi a2, -EFAULT
1045 rfe 1045 rfe
1046 1046
1047.Lill: l32i a7, a2, PT_AREG0 # restore a7 1047.Lill: l32i a7, a2, PT_AREG7 # restore a7
1048 l32i a0, a2, PT_AREG0 # restore a0 1048 l32i a0, a2, PT_AREG0 # restore a0
1049 movi a2, -EINVAL 1049 movi a2, -EINVAL
1050 rfe 1050 rfe
1051 1051
1052ENDPROC(fast_syscall_xtensa) 1052ENDPROC(fast_syscall_xtensa)
1053 1053
1054#else /* CONFIG_FAST_SYSCALL_XTENSA */
1055
1056ENTRY(fast_syscall_xtensa)
1057
1058 l32i a0, a2, PT_AREG0 # restore a0
1059 movi a2, -ENOSYS
1060 rfe
1061
1062ENDPROC(fast_syscall_xtensa)
1063
1064#endif /* CONFIG_FAST_SYSCALL_XTENSA */
1065
1054 1066
1055/* fast_syscall_spill_registers. 1067/* fast_syscall_spill_registers.
1056 * 1068 *
@@ -1066,6 +1078,8 @@ ENDPROC(fast_syscall_xtensa)
1066 * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler. 1078 * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler.
1067 */ 1079 */
1068 1080
1081#ifdef CONFIG_FAST_SYSCALL_SPILL_REGISTERS
1082
1069ENTRY(fast_syscall_spill_registers) 1083ENTRY(fast_syscall_spill_registers)
1070 1084
1071 /* Register a FIXUP handler (pass current wb as a parameter) */ 1085 /* Register a FIXUP handler (pass current wb as a parameter) */
@@ -1400,6 +1414,18 @@ ENTRY(fast_syscall_spill_registers_fixup_return)
1400 1414
1401ENDPROC(fast_syscall_spill_registers_fixup_return) 1415ENDPROC(fast_syscall_spill_registers_fixup_return)
1402 1416
1417#else /* CONFIG_FAST_SYSCALL_SPILL_REGISTERS */
1418
1419ENTRY(fast_syscall_spill_registers)
1420
1421 l32i a0, a2, PT_AREG0 # restore a0
1422 movi a2, -ENOSYS
1423 rfe
1424
1425ENDPROC(fast_syscall_spill_registers)
1426
1427#endif /* CONFIG_FAST_SYSCALL_SPILL_REGISTERS */
1428
1403#ifdef CONFIG_MMU 1429#ifdef CONFIG_MMU
1404/* 1430/*
1405 * We should never get here. Bail out! 1431 * We should never get here. Bail out!
@@ -1565,7 +1591,7 @@ ENTRY(fast_second_level_miss)
1565 rsr a0, excvaddr 1591 rsr a0, excvaddr
1566 bltu a0, a3, 2f 1592 bltu a0, a3, 2f
1567 1593
1568 addi a1, a0, -(2 << (DCACHE_ALIAS_ORDER + PAGE_SHIFT)) 1594 addi a1, a0, -TLBTEMP_SIZE
1569 bgeu a1, a3, 2f 1595 bgeu a1, a3, 2f
1570 1596
1571 /* Check if we have to restore an ITLB mapping. */ 1597 /* Check if we have to restore an ITLB mapping. */
@@ -1820,7 +1846,6 @@ ENTRY(_switch_to)
1820 1846
1821 entry a1, 16 1847 entry a1, 16
1822 1848
1823 mov a10, a2 # preserve 'prev' (a2)
1824 mov a11, a3 # and 'next' (a3) 1849 mov a11, a3 # and 'next' (a3)
1825 1850
1826 l32i a4, a2, TASK_THREAD_INFO 1851 l32i a4, a2, TASK_THREAD_INFO
@@ -1828,8 +1853,14 @@ ENTRY(_switch_to)
1828 1853
1829 save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER 1854 save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
1830 1855
1831 s32i a0, a10, THREAD_RA # save return address 1856#if THREAD_RA > 1020 || THREAD_SP > 1020
1832 s32i a1, a10, THREAD_SP # save stack pointer 1857 addi a10, a2, TASK_THREAD
1858 s32i a0, a10, THREAD_RA - TASK_THREAD # save return address
1859 s32i a1, a10, THREAD_SP - TASK_THREAD # save stack pointer
1860#else
1861 s32i a0, a2, THREAD_RA # save return address
1862 s32i a1, a2, THREAD_SP # save stack pointer
1863#endif
1833 1864
1834 /* Disable ints while we manipulate the stack pointer. */ 1865 /* Disable ints while we manipulate the stack pointer. */
1835 1866
@@ -1870,7 +1901,6 @@ ENTRY(_switch_to)
1870 load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER 1901 load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
1871 1902
1872 wsr a14, ps 1903 wsr a14, ps
1873 mov a2, a10 # return 'prev'
1874 rsync 1904 rsync
1875 1905
1876 retw 1906 retw
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index 2d9cc6dbfd78..e8b76b8e4b29 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -49,9 +49,8 @@ dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *handle,gfp_t flag)
49 49
50 /* We currently don't support coherent memory outside KSEG */ 50 /* We currently don't support coherent memory outside KSEG */
51 51
52 if (ret < XCHAL_KSEG_CACHED_VADDR 52 BUG_ON(ret < XCHAL_KSEG_CACHED_VADDR ||
53 || ret >= XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE) 53 ret > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1);
54 BUG();
55 54
56 55
57 if (ret != 0) { 56 if (ret != 0) {
@@ -68,10 +67,11 @@ EXPORT_SYMBOL(dma_alloc_coherent);
68void dma_free_coherent(struct device *hwdev, size_t size, 67void dma_free_coherent(struct device *hwdev, size_t size,
69 void *vaddr, dma_addr_t dma_handle) 68 void *vaddr, dma_addr_t dma_handle)
70{ 69{
71 long addr=(long)vaddr+XCHAL_KSEG_CACHED_VADDR-XCHAL_KSEG_BYPASS_VADDR; 70 unsigned long addr = (unsigned long)vaddr +
71 XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR;
72 72
73 if (addr < 0 || addr >= XCHAL_KSEG_SIZE) 73 BUG_ON(addr < XCHAL_KSEG_CACHED_VADDR ||
74 BUG(); 74 addr > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1);
75 75
76 free_pages(addr, get_order(size)); 76 free_pages(addr, get_order(size));
77} 77}
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index eebbfd8c26fc..9d2f45f010ef 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -101,9 +101,8 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
101#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION 101#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
102#ifdef CONFIG_XTENSA_UNALIGNED_USER 102#ifdef CONFIG_XTENSA_UNALIGNED_USER
103{ EXCCAUSE_UNALIGNED, USER, fast_unaligned }, 103{ EXCCAUSE_UNALIGNED, USER, fast_unaligned },
104#else
105{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user },
106#endif 104#endif
105{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user },
107{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, 106{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned },
108#endif 107#endif
109#ifdef CONFIG_MMU 108#ifdef CONFIG_MMU
@@ -264,7 +263,6 @@ do_illegal_instruction(struct pt_regs *regs)
264 */ 263 */
265 264
266#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION 265#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
267#ifndef CONFIG_XTENSA_UNALIGNED_USER
268void 266void
269do_unaligned_user (struct pt_regs *regs) 267do_unaligned_user (struct pt_regs *regs)
270{ 268{
@@ -286,7 +284,6 @@ do_unaligned_user (struct pt_regs *regs)
286 284
287} 285}
288#endif 286#endif
289#endif
290 287
291void 288void
292do_debug(struct pt_regs *regs) 289do_debug(struct pt_regs *regs)
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index 8453e6e39895..1b397a902292 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -454,8 +454,14 @@ _DoubleExceptionVector_WindowOverflow:
454 s32i a0, a2, PT_DEPC 454 s32i a0, a2, PT_DEPC
455 455
456_DoubleExceptionVector_handle_exception: 456_DoubleExceptionVector_handle_exception:
457 addi a0, a0, -EXCCAUSE_UNALIGNED
458 beqz a0, 2f
457 addx4 a0, a0, a3 459 addx4 a0, a0, a3
458 l32i a0, a0, EXC_TABLE_FAST_USER 460 l32i a0, a0, EXC_TABLE_FAST_USER + 4 * EXCCAUSE_UNALIGNED
461 xsr a3, excsave1
462 jx a0
4632:
464 movi a0, user_exception
459 xsr a3, excsave1 465 xsr a3, excsave1
460 jx a0 466 jx a0
461 467
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index d16db6df86f8..fc1bc2ba8d5d 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -269,13 +269,13 @@ SECTIONS
269 .UserExceptionVector.literal) 269 .UserExceptionVector.literal)
270 SECTION_VECTOR (_DoubleExceptionVector_literal, 270 SECTION_VECTOR (_DoubleExceptionVector_literal,
271 .DoubleExceptionVector.literal, 271 .DoubleExceptionVector.literal,
272 DOUBLEEXC_VECTOR_VADDR - 40, 272 DOUBLEEXC_VECTOR_VADDR - 48,
273 SIZEOF(.UserExceptionVector.text), 273 SIZEOF(.UserExceptionVector.text),
274 .UserExceptionVector.text) 274 .UserExceptionVector.text)
275 SECTION_VECTOR (_DoubleExceptionVector_text, 275 SECTION_VECTOR (_DoubleExceptionVector_text,
276 .DoubleExceptionVector.text, 276 .DoubleExceptionVector.text,
277 DOUBLEEXC_VECTOR_VADDR, 277 DOUBLEEXC_VECTOR_VADDR,
278 40, 278 48,
279 .DoubleExceptionVector.literal) 279 .DoubleExceptionVector.literal)
280 280
281 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; 281 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
index 63cbb867dadd..d75aa1476da7 100644
--- a/arch/xtensa/mm/cache.c
+++ b/arch/xtensa/mm/cache.c
@@ -59,9 +59,68 @@
59 * 59 *
60 */ 60 */
61 61
62#if (DCACHE_WAY_SIZE > PAGE_SIZE) && defined(CONFIG_HIGHMEM) 62#if (DCACHE_WAY_SIZE > PAGE_SIZE)
63#error "HIGHMEM is not supported on cores with aliasing cache." 63static inline void kmap_invalidate_coherent(struct page *page,
64#endif 64 unsigned long vaddr)
65{
66 if (!DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) {
67 unsigned long kvaddr;
68
69 if (!PageHighMem(page)) {
70 kvaddr = (unsigned long)page_to_virt(page);
71
72 __invalidate_dcache_page(kvaddr);
73 } else {
74 kvaddr = TLBTEMP_BASE_1 +
75 (page_to_phys(page) & DCACHE_ALIAS_MASK);
76
77 __invalidate_dcache_page_alias(kvaddr,
78 page_to_phys(page));
79 }
80 }
81}
82
83static inline void *coherent_kvaddr(struct page *page, unsigned long base,
84 unsigned long vaddr, unsigned long *paddr)
85{
86 if (PageHighMem(page) || !DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) {
87 *paddr = page_to_phys(page);
88 return (void *)(base + (vaddr & DCACHE_ALIAS_MASK));
89 } else {
90 *paddr = 0;
91 return page_to_virt(page);
92 }
93}
94
95void clear_user_highpage(struct page *page, unsigned long vaddr)
96{
97 unsigned long paddr;
98 void *kvaddr = coherent_kvaddr(page, TLBTEMP_BASE_1, vaddr, &paddr);
99
100 pagefault_disable();
101 kmap_invalidate_coherent(page, vaddr);
102 set_bit(PG_arch_1, &page->flags);
103 clear_page_alias(kvaddr, paddr);
104 pagefault_enable();
105}
106
107void copy_user_highpage(struct page *dst, struct page *src,
108 unsigned long vaddr, struct vm_area_struct *vma)
109{
110 unsigned long dst_paddr, src_paddr;
111 void *dst_vaddr = coherent_kvaddr(dst, TLBTEMP_BASE_1, vaddr,
112 &dst_paddr);
113 void *src_vaddr = coherent_kvaddr(src, TLBTEMP_BASE_2, vaddr,
114 &src_paddr);
115
116 pagefault_disable();
117 kmap_invalidate_coherent(dst, vaddr);
118 set_bit(PG_arch_1, &dst->flags);
119 copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr);
120 pagefault_enable();
121}
122
123#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */
65 124
66#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK 125#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
67 126
@@ -103,7 +162,8 @@ void flush_dcache_page(struct page *page)
103 if (!alias && !mapping) 162 if (!alias && !mapping)
104 return; 163 return;
105 164
106 __flush_invalidate_dcache_page((long)page_address(page)); 165 virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
166 __flush_invalidate_dcache_page_alias(virt, phys);
107 167
108 virt = TLBTEMP_BASE_1 + (temp & DCACHE_ALIAS_MASK); 168 virt = TLBTEMP_BASE_1 + (temp & DCACHE_ALIAS_MASK);
109 169
@@ -168,13 +228,12 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
168#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK 228#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
169 229
170 if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { 230 if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) {
171
172 unsigned long paddr = (unsigned long) page_address(page);
173 unsigned long phys = page_to_phys(page); 231 unsigned long phys = page_to_phys(page);
174 unsigned long tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); 232 unsigned long tmp;
175
176 __flush_invalidate_dcache_page(paddr);
177 233
234 tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK);
235 __flush_invalidate_dcache_page_alias(tmp, phys);
236 tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
178 __flush_invalidate_dcache_page_alias(tmp, phys); 237 __flush_invalidate_dcache_page_alias(tmp, phys);
179 __invalidate_icache_page_alias(tmp, phys); 238 __invalidate_icache_page_alias(tmp, phys);
180 239
diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c
index 17a8c0d6fd17..8cfb71ec0937 100644
--- a/arch/xtensa/mm/highmem.c
+++ b/arch/xtensa/mm/highmem.c
@@ -14,23 +14,45 @@
14 14
15static pte_t *kmap_pte; 15static pte_t *kmap_pte;
16 16
17#if DCACHE_WAY_SIZE > PAGE_SIZE
18unsigned int last_pkmap_nr_arr[DCACHE_N_COLORS];
19wait_queue_head_t pkmap_map_wait_arr[DCACHE_N_COLORS];
20
21static void __init kmap_waitqueues_init(void)
22{
23 unsigned int i;
24
25 for (i = 0; i < ARRAY_SIZE(pkmap_map_wait_arr); ++i)
26 init_waitqueue_head(pkmap_map_wait_arr + i);
27}
28#else
29static inline void kmap_waitqueues_init(void)
30{
31}
32#endif
33
34static inline enum fixed_addresses kmap_idx(int type, unsigned long color)
35{
36 return (type + KM_TYPE_NR * smp_processor_id()) * DCACHE_N_COLORS +
37 color;
38}
39
17void *kmap_atomic(struct page *page) 40void *kmap_atomic(struct page *page)
18{ 41{
19 enum fixed_addresses idx; 42 enum fixed_addresses idx;
20 unsigned long vaddr; 43 unsigned long vaddr;
21 int type;
22 44
23 pagefault_disable(); 45 pagefault_disable();
24 if (!PageHighMem(page)) 46 if (!PageHighMem(page))
25 return page_address(page); 47 return page_address(page);
26 48
27 type = kmap_atomic_idx_push(); 49 idx = kmap_idx(kmap_atomic_idx_push(),
28 idx = type + KM_TYPE_NR * smp_processor_id(); 50 DCACHE_ALIAS(page_to_phys(page)));
29 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 51 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
30#ifdef CONFIG_DEBUG_HIGHMEM 52#ifdef CONFIG_DEBUG_HIGHMEM
31 BUG_ON(!pte_none(*(kmap_pte - idx))); 53 BUG_ON(!pte_none(*(kmap_pte + idx)));
32#endif 54#endif
33 set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC)); 55 set_pte(kmap_pte + idx, mk_pte(page, PAGE_KERNEL_EXEC));
34 56
35 return (void *)vaddr; 57 return (void *)vaddr;
36} 58}
@@ -38,12 +60,10 @@ EXPORT_SYMBOL(kmap_atomic);
38 60
39void __kunmap_atomic(void *kvaddr) 61void __kunmap_atomic(void *kvaddr)
40{ 62{
41 int idx, type;
42
43 if (kvaddr >= (void *)FIXADDR_START && 63 if (kvaddr >= (void *)FIXADDR_START &&
44 kvaddr < (void *)FIXADDR_TOP) { 64 kvaddr < (void *)FIXADDR_TOP) {
45 type = kmap_atomic_idx(); 65 int idx = kmap_idx(kmap_atomic_idx(),
46 idx = type + KM_TYPE_NR * smp_processor_id(); 66 DCACHE_ALIAS((unsigned long)kvaddr));
47 67
48 /* 68 /*
49 * Force other mappings to Oops if they'll try to access this 69 * Force other mappings to Oops if they'll try to access this
@@ -51,7 +71,7 @@ void __kunmap_atomic(void *kvaddr)
51 * is a bad idea also, in case the page changes cacheability 71 * is a bad idea also, in case the page changes cacheability
52 * attributes or becomes a protected page in a hypervisor. 72 * attributes or becomes a protected page in a hypervisor.
53 */ 73 */
54 pte_clear(&init_mm, kvaddr, kmap_pte - idx); 74 pte_clear(&init_mm, kvaddr, kmap_pte + idx);
55 local_flush_tlb_kernel_range((unsigned long)kvaddr, 75 local_flush_tlb_kernel_range((unsigned long)kvaddr,
56 (unsigned long)kvaddr + PAGE_SIZE); 76 (unsigned long)kvaddr + PAGE_SIZE);
57 77
@@ -69,4 +89,5 @@ void __init kmap_init(void)
69 /* cache the first kmap pte */ 89 /* cache the first kmap pte */
70 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); 90 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
71 kmap_pte = kmap_get_fixmap_pte(kmap_vstart); 91 kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
92 kmap_waitqueues_init();
72} 93}
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
index 1f68558dbcc2..11a01c3e9cea 100644
--- a/arch/xtensa/mm/misc.S
+++ b/arch/xtensa/mm/misc.S
@@ -110,41 +110,24 @@ ENTRY(__tlbtemp_mapping_start)
110#if (DCACHE_WAY_SIZE > PAGE_SIZE) 110#if (DCACHE_WAY_SIZE > PAGE_SIZE)
111 111
112/* 112/*
113 * clear_user_page (void *addr, unsigned long vaddr, struct page *page) 113 * clear_page_alias(void *addr, unsigned long paddr)
114 * a2 a3 a4 114 * a2 a3
115 */ 115 */
116 116
117ENTRY(clear_user_page) 117ENTRY(clear_page_alias)
118 118
119 entry a1, 32 119 entry a1, 32
120 120
121 /* Mark page dirty and determine alias. */ 121 /* Skip setting up a temporary DTLB if not aliased low page. */
122 122
123 movi a7, (1 << PG_ARCH_1) 123 movi a5, PAGE_OFFSET
124 l32i a5, a4, PAGE_FLAGS 124 movi a6, 0
125 xor a6, a2, a3 125 beqz a3, 1f
126 extui a3, a3, PAGE_SHIFT, DCACHE_ALIAS_ORDER
127 extui a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER
128 or a5, a5, a7
129 slli a3, a3, PAGE_SHIFT
130 s32i a5, a4, PAGE_FLAGS
131 126
132 /* Skip setting up a temporary DTLB if not aliased. */ 127 /* Setup a temporary DTLB for the addr. */
133
134 beqz a6, 1f
135
136 /* Invalidate kernel page. */
137
138 mov a10, a2
139 call8 __invalidate_dcache_page
140
141 /* Setup a temporary DTLB with the color of the VPN */
142
143 movi a4, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff
144 movi a5, TLBTEMP_BASE_1 # virt
145 add a6, a2, a4 # ppn
146 add a2, a5, a3 # add 'color'
147 128
129 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
130 mov a4, a2
148 wdtlb a6, a2 131 wdtlb a6, a2
149 dsync 132 dsync
150 133
@@ -165,62 +148,43 @@ ENTRY(clear_user_page)
165 148
166 /* We need to invalidate the temporary idtlb entry, if any. */ 149 /* We need to invalidate the temporary idtlb entry, if any. */
167 150
1681: addi a2, a2, -PAGE_SIZE 1511: idtlb a4
169 idtlb a2
170 dsync 152 dsync
171 153
172 retw 154 retw
173 155
174ENDPROC(clear_user_page) 156ENDPROC(clear_page_alias)
175 157
176/* 158/*
177 * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) 159 * copy_page_alias(void *to, void *from,
178 * a2 a3 a4 a5 160 * a2 a3
161 * unsigned long to_paddr, unsigned long from_paddr)
162 * a4 a5
179 */ 163 */
180 164
181ENTRY(copy_user_page) 165ENTRY(copy_page_alias)
182 166
183 entry a1, 32 167 entry a1, 32
184 168
185 /* Mark page dirty and determine alias for destination. */ 169 /* Skip setting up a temporary DTLB for destination if not aliased. */
186
187 movi a8, (1 << PG_ARCH_1)
188 l32i a9, a5, PAGE_FLAGS
189 xor a6, a2, a4
190 xor a7, a3, a4
191 extui a4, a4, PAGE_SHIFT, DCACHE_ALIAS_ORDER
192 extui a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER
193 extui a7, a7, PAGE_SHIFT, DCACHE_ALIAS_ORDER
194 or a9, a9, a8
195 slli a4, a4, PAGE_SHIFT
196 s32i a9, a5, PAGE_FLAGS
197 movi a5, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff
198
199 beqz a6, 1f
200
201 /* Invalidate dcache */
202
203 mov a10, a2
204 call8 __invalidate_dcache_page
205 170
206 /* Setup a temporary DTLB with a matching color. */ 171 movi a6, 0
172 movi a7, 0
173 beqz a4, 1f
207 174
208 movi a8, TLBTEMP_BASE_1 # base 175 /* Setup a temporary DTLB for destination. */
209 add a6, a2, a5 # ppn
210 add a2, a8, a4 # add 'color'
211 176
177 addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)
212 wdtlb a6, a2 178 wdtlb a6, a2
213 dsync 179 dsync
214 180
215 /* Skip setting up a temporary DTLB for destination if not aliased. */ 181 /* Skip setting up a temporary DTLB for source if not aliased. */
216 182
2171: beqz a7, 1f 1831: beqz a5, 1f
218 184
219 /* Setup a temporary DTLB with a matching color. */ 185 /* Setup a temporary DTLB for source. */
220 186
221 movi a8, TLBTEMP_BASE_2 # base 187 addi a7, a5, PAGE_KERNEL
222 add a7, a3, a5 # ppn
223 add a3, a8, a4
224 addi a8, a3, 1 # way1 188 addi a8, a3, 1 # way1
225 189
226 wdtlb a7, a8 190 wdtlb a7, a8
@@ -271,7 +235,7 @@ ENTRY(copy_user_page)
271 235
272 retw 236 retw
273 237
274ENDPROC(copy_user_page) 238ENDPROC(copy_page_alias)
275 239
276#endif 240#endif
277 241
@@ -300,6 +264,30 @@ ENTRY(__flush_invalidate_dcache_page_alias)
300 retw 264 retw
301 265
302ENDPROC(__flush_invalidate_dcache_page_alias) 266ENDPROC(__flush_invalidate_dcache_page_alias)
267
268/*
269 * void __invalidate_dcache_page_alias (addr, phys)
270 * a2 a3
271 */
272
273ENTRY(__invalidate_dcache_page_alias)
274
275 entry sp, 16
276
277 movi a7, 0 # required for exception handler
278 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
279 mov a4, a2
280 wdtlb a6, a2
281 dsync
282
283 ___invalidate_dcache_page a2 a3
284
285 idtlb a4
286 dsync
287
288 retw
289
290ENDPROC(__invalidate_dcache_page_alias)
303#endif 291#endif
304 292
305ENTRY(__tlbtemp_mapping_itlb) 293ENTRY(__tlbtemp_mapping_itlb)
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
index 3429b483d9f8..abe4513eb0dd 100644
--- a/arch/xtensa/mm/mmu.c
+++ b/arch/xtensa/mm/mmu.c
@@ -18,32 +18,38 @@
18#include <asm/io.h> 18#include <asm/io.h>
19 19
20#if defined(CONFIG_HIGHMEM) 20#if defined(CONFIG_HIGHMEM)
21static void * __init init_pmd(unsigned long vaddr) 21static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages)
22{ 22{
23 pgd_t *pgd = pgd_offset_k(vaddr); 23 pgd_t *pgd = pgd_offset_k(vaddr);
24 pmd_t *pmd = pmd_offset(pgd, vaddr); 24 pmd_t *pmd = pmd_offset(pgd, vaddr);
25 pte_t *pte;
26 unsigned long i;
25 27
26 if (pmd_none(*pmd)) { 28 n_pages = ALIGN(n_pages, PTRS_PER_PTE);
27 unsigned i;
28 pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE);
29 29
30 for (i = 0; i < 1024; i++) 30 pr_debug("%s: vaddr: 0x%08lx, n_pages: %ld\n",
31 pte_clear(NULL, 0, pte + i); 31 __func__, vaddr, n_pages);
32 32
33 set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK)); 33 pte = alloc_bootmem_low_pages(n_pages * sizeof(pte_t));
34 BUG_ON(pte != pte_offset_kernel(pmd, 0)); 34
35 pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n", 35 for (i = 0; i < n_pages; ++i)
36 __func__, vaddr, pmd, pte); 36 pte_clear(NULL, 0, pte + i);
37 return pte; 37
38 } else { 38 for (i = 0; i < n_pages; i += PTRS_PER_PTE, ++pmd) {
39 return pte_offset_kernel(pmd, 0); 39 pte_t *cur_pte = pte + i;
40
41 BUG_ON(!pmd_none(*pmd));
42 set_pmd(pmd, __pmd(((unsigned long)cur_pte) & PAGE_MASK));
43 BUG_ON(cur_pte != pte_offset_kernel(pmd, 0));
44 pr_debug("%s: pmd: 0x%p, pte: 0x%p\n",
45 __func__, pmd, cur_pte);
40 } 46 }
47 return pte;
41} 48}
42 49
43static void __init fixedrange_init(void) 50static void __init fixedrange_init(void)
44{ 51{
45 BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE); 52 init_pmd(__fix_to_virt(0), __end_of_fixed_addresses);
46 init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK);
47} 53}
48#endif 54#endif
49 55
@@ -52,7 +58,7 @@ void __init paging_init(void)
52 memset(swapper_pg_dir, 0, PAGE_SIZE); 58 memset(swapper_pg_dir, 0, PAGE_SIZE);
53#ifdef CONFIG_HIGHMEM 59#ifdef CONFIG_HIGHMEM
54 fixedrange_init(); 60 fixedrange_init();
55 pkmap_page_table = init_pmd(PKMAP_BASE); 61 pkmap_page_table = init_pmd(PKMAP_BASE, LAST_PKMAP);
56 kmap_init(); 62 kmap_init();
57#endif 63#endif
58} 64}