diff options
Diffstat (limited to 'arch')
513 files changed, 10047 insertions, 6760 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 8d2ae24b9f4a..1feb169274fe 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -407,6 +407,12 @@ config CLONE_BACKWARDS2 | |||
407 | help | 407 | help |
408 | Architecture has the first two arguments of clone(2) swapped. | 408 | Architecture has the first two arguments of clone(2) swapped. |
409 | 409 | ||
410 | config CLONE_BACKWARDS3 | ||
411 | bool | ||
412 | help | ||
413 | Architecture has tls passed as the 3rd argument of clone(2), | ||
414 | not the 5th one. | ||
415 | |||
410 | config ODD_RT_SIGACTION | 416 | config ODD_RT_SIGACTION |
411 | bool | 417 | bool |
412 | help | 418 | help |
diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c index b8ce18f485d3..310a4ce1dccc 100644 --- a/arch/alpha/oprofile/common.c +++ b/arch/alpha/oprofile/common.c | |||
@@ -106,7 +106,7 @@ op_axp_stop(void) | |||
106 | } | 106 | } |
107 | 107 | ||
108 | static int | 108 | static int |
109 | op_axp_create_files(struct super_block *sb, struct dentry *root) | 109 | op_axp_create_files(struct dentry *root) |
110 | { | 110 | { |
111 | int i; | 111 | int i; |
112 | 112 | ||
@@ -115,23 +115,23 @@ op_axp_create_files(struct super_block *sb, struct dentry *root) | |||
115 | char buf[4]; | 115 | char buf[4]; |
116 | 116 | ||
117 | snprintf(buf, sizeof buf, "%d", i); | 117 | snprintf(buf, sizeof buf, "%d", i); |
118 | dir = oprofilefs_mkdir(sb, root, buf); | 118 | dir = oprofilefs_mkdir(root, buf); |
119 | 119 | ||
120 | oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); | 120 | oprofilefs_create_ulong(dir, "enabled", &ctr[i].enabled); |
121 | oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); | 121 | oprofilefs_create_ulong(dir, "event", &ctr[i].event); |
122 | oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); | 122 | oprofilefs_create_ulong(dir, "count", &ctr[i].count); |
123 | /* Dummies. */ | 123 | /* Dummies. */ |
124 | oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); | 124 | oprofilefs_create_ulong(dir, "kernel", &ctr[i].kernel); |
125 | oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); | 125 | oprofilefs_create_ulong(dir, "user", &ctr[i].user); |
126 | oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); | 126 | oprofilefs_create_ulong(dir, "unit_mask", &ctr[i].unit_mask); |
127 | } | 127 | } |
128 | 128 | ||
129 | if (model->can_set_proc_mode) { | 129 | if (model->can_set_proc_mode) { |
130 | oprofilefs_create_ulong(sb, root, "enable_pal", | 130 | oprofilefs_create_ulong(root, "enable_pal", |
131 | &sys.enable_pal); | 131 | &sys.enable_pal); |
132 | oprofilefs_create_ulong(sb, root, "enable_kernel", | 132 | oprofilefs_create_ulong(root, "enable_kernel", |
133 | &sys.enable_kernel); | 133 | &sys.enable_kernel); |
134 | oprofilefs_create_ulong(sb, root, "enable_user", | 134 | oprofilefs_create_ulong(root, "enable_user", |
135 | &sys.enable_user); | 135 | &sys.enable_user); |
136 | } | 136 | } |
137 | 137 | ||
diff --git a/arch/arc/lib/strchr-700.S b/arch/arc/lib/strchr-700.S index 99c10475d477..9c548c7cf001 100644 --- a/arch/arc/lib/strchr-700.S +++ b/arch/arc/lib/strchr-700.S | |||
@@ -39,9 +39,18 @@ ARC_ENTRY strchr | |||
39 | ld.a r2,[r0,4] | 39 | ld.a r2,[r0,4] |
40 | sub r12,r6,r7 | 40 | sub r12,r6,r7 |
41 | bic r12,r12,r6 | 41 | bic r12,r12,r6 |
42 | #ifdef __LITTLE_ENDIAN__ | ||
42 | and r7,r12,r4 | 43 | and r7,r12,r4 |
43 | breq r7,0,.Loop ; For speed, we want this branch to be unaligned. | 44 | breq r7,0,.Loop ; For speed, we want this branch to be unaligned. |
44 | b .Lfound_char ; Likewise this one. | 45 | b .Lfound_char ; Likewise this one. |
46 | #else | ||
47 | and r12,r12,r4 | ||
48 | breq r12,0,.Loop ; For speed, we want this branch to be unaligned. | ||
49 | lsr_s r12,r12,7 | ||
50 | bic r2,r7,r6 | ||
51 | b.d .Lfound_char_b | ||
52 | and_s r2,r2,r12 | ||
53 | #endif | ||
45 | ; /* We require this code address to be unaligned for speed... */ | 54 | ; /* We require this code address to be unaligned for speed... */ |
46 | .Laligned: | 55 | .Laligned: |
47 | ld_s r2,[r0] | 56 | ld_s r2,[r0] |
@@ -95,6 +104,7 @@ ARC_ENTRY strchr | |||
95 | lsr r7,r7,7 | 104 | lsr r7,r7,7 |
96 | 105 | ||
97 | bic r2,r7,r6 | 106 | bic r2,r7,r6 |
107 | .Lfound_char_b: | ||
98 | norm r2,r2 | 108 | norm r2,r2 |
99 | sub_s r0,r0,4 | 109 | sub_s r0,r0,4 |
100 | asr_s r2,r2,3 | 110 | asr_s r2,r2,3 |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 43594d5116ef..5d1f5704a284 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -52,6 +52,7 @@ config ARM | |||
52 | select HAVE_REGS_AND_STACK_ACCESS_API | 52 | select HAVE_REGS_AND_STACK_ACCESS_API |
53 | select HAVE_SYSCALL_TRACEPOINTS | 53 | select HAVE_SYSCALL_TRACEPOINTS |
54 | select HAVE_UID16 | 54 | select HAVE_UID16 |
55 | select IRQ_FORCED_THREADING | ||
55 | select KTIME_SCALAR | 56 | select KTIME_SCALAR |
56 | select PERF_USE_VMALLOC | 57 | select PERF_USE_VMALLOC |
57 | select RTC_LIB | 58 | select RTC_LIB |
@@ -1372,6 +1373,15 @@ config ARM_ERRATA_798181 | |||
1372 | which sends an IPI to the CPUs that are running the same ASID | 1373 | which sends an IPI to the CPUs that are running the same ASID |
1373 | as the one being invalidated. | 1374 | as the one being invalidated. |
1374 | 1375 | ||
1376 | config ARM_ERRATA_773022 | ||
1377 | bool "ARM errata: incorrect instructions may be executed from loop buffer" | ||
1378 | depends on CPU_V7 | ||
1379 | help | ||
1380 | This option enables the workaround for the 773022 Cortex-A15 | ||
1381 | (up to r0p4) erratum. In certain rare sequences of code, the | ||
1382 | loop buffer may deliver incorrect instructions. This | ||
1383 | workaround disables the loop buffer to avoid the erratum. | ||
1384 | |||
1375 | endmenu | 1385 | endmenu |
1376 | 1386 | ||
1377 | source "arch/arm/common/Kconfig" | 1387 | source "arch/arm/common/Kconfig" |
@@ -1613,13 +1623,49 @@ config ARCH_NR_GPIO | |||
1613 | 1623 | ||
1614 | source kernel/Kconfig.preempt | 1624 | source kernel/Kconfig.preempt |
1615 | 1625 | ||
1616 | config HZ | 1626 | config HZ_FIXED |
1617 | int | 1627 | int |
1618 | default 200 if ARCH_EBSA110 || ARCH_S3C24XX || ARCH_S5P64X0 || \ | 1628 | default 200 if ARCH_EBSA110 || ARCH_S3C24XX || ARCH_S5P64X0 || \ |
1619 | ARCH_S5PV210 || ARCH_EXYNOS4 | 1629 | ARCH_S5PV210 || ARCH_EXYNOS4 |
1620 | default AT91_TIMER_HZ if ARCH_AT91 | 1630 | default AT91_TIMER_HZ if ARCH_AT91 |
1621 | default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE | 1631 | default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE |
1622 | default 100 | 1632 | |
1633 | choice | ||
1634 | depends on !HZ_FIXED | ||
1635 | prompt "Timer frequency" | ||
1636 | |||
1637 | config HZ_100 | ||
1638 | bool "100 Hz" | ||
1639 | |||
1640 | config HZ_200 | ||
1641 | bool "200 Hz" | ||
1642 | |||
1643 | config HZ_250 | ||
1644 | bool "250 Hz" | ||
1645 | |||
1646 | config HZ_300 | ||
1647 | bool "300 Hz" | ||
1648 | |||
1649 | config HZ_500 | ||
1650 | bool "500 Hz" | ||
1651 | |||
1652 | config HZ_1000 | ||
1653 | bool "1000 Hz" | ||
1654 | |||
1655 | endchoice | ||
1656 | |||
1657 | config HZ | ||
1658 | int | ||
1659 | default HZ_FIXED if HZ_FIXED | ||
1660 | default 100 if HZ_100 | ||
1661 | default 200 if HZ_200 | ||
1662 | default 250 if HZ_250 | ||
1663 | default 300 if HZ_300 | ||
1664 | default 500 if HZ_500 | ||
1665 | default 1000 | ||
1666 | |||
1667 | config SCHED_HRTICK | ||
1668 | def_bool HIGH_RES_TIMERS | ||
1623 | 1669 | ||
1624 | config SCHED_HRTICK | 1670 | config SCHED_HRTICK |
1625 | def_bool HIGH_RES_TIMERS | 1671 | def_bool HIGH_RES_TIMERS |
@@ -1756,6 +1802,9 @@ config HAVE_ARCH_TRANSPARENT_HUGEPAGE | |||
1756 | def_bool y | 1802 | def_bool y |
1757 | depends on ARM_LPAE | 1803 | depends on ARM_LPAE |
1758 | 1804 | ||
1805 | config ARCH_WANT_GENERAL_HUGETLB | ||
1806 | def_bool y | ||
1807 | |||
1759 | source "mm/Kconfig" | 1808 | source "mm/Kconfig" |
1760 | 1809 | ||
1761 | config FORCE_MAX_ZONEORDER | 1810 | config FORCE_MAX_ZONEORDER |
@@ -2064,8 +2113,7 @@ config KEXEC | |||
2064 | 2113 | ||
2065 | It is an ongoing process to be certain the hardware in a machine | 2114 | It is an ongoing process to be certain the hardware in a machine |
2066 | is properly shutdown, so do not be surprised if this code does not | 2115 | is properly shutdown, so do not be surprised if this code does not |
2067 | initially work for you. It may help to enable device hotplugging | 2116 | initially work for you. |
2068 | support. | ||
2069 | 2117 | ||
2070 | config ATAGS_PROC | 2118 | config ATAGS_PROC |
2071 | bool "Export atags in procfs" | 2119 | bool "Export atags in procfs" |
@@ -2175,6 +2223,13 @@ config NEON | |||
2175 | Say Y to include support code for NEON, the ARMv7 Advanced SIMD | 2223 | Say Y to include support code for NEON, the ARMv7 Advanced SIMD |
2176 | Extension. | 2224 | Extension. |
2177 | 2225 | ||
2226 | config KERNEL_MODE_NEON | ||
2227 | bool "Support for NEON in kernel mode" | ||
2228 | default n | ||
2229 | depends on NEON | ||
2230 | help | ||
2231 | Say Y to include support for NEON in kernel mode. | ||
2232 | |||
2178 | endmenu | 2233 | endmenu |
2179 | 2234 | ||
2180 | menu "Userspace binary formats" | 2235 | menu "Userspace binary formats" |
@@ -2199,7 +2254,7 @@ source "kernel/power/Kconfig" | |||
2199 | 2254 | ||
2200 | config ARCH_SUSPEND_POSSIBLE | 2255 | config ARCH_SUSPEND_POSSIBLE |
2201 | depends on !ARCH_S5PC100 | 2256 | depends on !ARCH_S5PC100 |
2202 | depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \ | 2257 | depends on CPU_ARM920T || CPU_ARM926T || CPU_FEROCEON || CPU_SA1100 || \ |
2203 | CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK | 2258 | CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK |
2204 | def_bool y | 2259 | def_bool y |
2205 | 2260 | ||
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 583f4a00ec32..4137529850cb 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -92,6 +92,7 @@ choice | |||
92 | config DEBUG_BCM2835 | 92 | config DEBUG_BCM2835 |
93 | bool "Kernel low-level debugging on BCM2835 PL011 UART" | 93 | bool "Kernel low-level debugging on BCM2835 PL011 UART" |
94 | depends on ARCH_BCM2835 | 94 | depends on ARCH_BCM2835 |
95 | select DEBUG_UART_PL01X | ||
95 | 96 | ||
96 | config DEBUG_CLPS711X_UART1 | 97 | config DEBUG_CLPS711X_UART1 |
97 | bool "Kernel low-level debugging messages via UART1" | 98 | bool "Kernel low-level debugging messages via UART1" |
@@ -110,6 +111,7 @@ choice | |||
110 | config DEBUG_CNS3XXX | 111 | config DEBUG_CNS3XXX |
111 | bool "Kernel Kernel low-level debugging on Cavium Networks CNS3xxx" | 112 | bool "Kernel Kernel low-level debugging on Cavium Networks CNS3xxx" |
112 | depends on ARCH_CNS3XXX | 113 | depends on ARCH_CNS3XXX |
114 | select DEBUG_UART_PL01X | ||
113 | help | 115 | help |
114 | Say Y here if you want the debug print routines to direct | 116 | Say Y here if you want the debug print routines to direct |
115 | their output to the CNS3xxx UART0. | 117 | their output to the CNS3xxx UART0. |
@@ -117,6 +119,7 @@ choice | |||
117 | config DEBUG_DAVINCI_DA8XX_UART1 | 119 | config DEBUG_DAVINCI_DA8XX_UART1 |
118 | bool "Kernel low-level debugging on DaVinci DA8XX using UART1" | 120 | bool "Kernel low-level debugging on DaVinci DA8XX using UART1" |
119 | depends on ARCH_DAVINCI_DA8XX | 121 | depends on ARCH_DAVINCI_DA8XX |
122 | select DEBUG_UART_8250 | ||
120 | help | 123 | help |
121 | Say Y here if you want the debug print routines to direct | 124 | Say Y here if you want the debug print routines to direct |
122 | their output to UART1 serial port on DaVinci DA8XX devices. | 125 | their output to UART1 serial port on DaVinci DA8XX devices. |
@@ -124,6 +127,7 @@ choice | |||
124 | config DEBUG_DAVINCI_DA8XX_UART2 | 127 | config DEBUG_DAVINCI_DA8XX_UART2 |
125 | bool "Kernel low-level debugging on DaVinci DA8XX using UART2" | 128 | bool "Kernel low-level debugging on DaVinci DA8XX using UART2" |
126 | depends on ARCH_DAVINCI_DA8XX | 129 | depends on ARCH_DAVINCI_DA8XX |
130 | select DEBUG_UART_8250 | ||
127 | help | 131 | help |
128 | Say Y here if you want the debug print routines to direct | 132 | Say Y here if you want the debug print routines to direct |
129 | their output to UART2 serial port on DaVinci DA8XX devices. | 133 | their output to UART2 serial port on DaVinci DA8XX devices. |
@@ -131,6 +135,7 @@ choice | |||
131 | config DEBUG_DAVINCI_DMx_UART0 | 135 | config DEBUG_DAVINCI_DMx_UART0 |
132 | bool "Kernel low-level debugging on DaVinci DMx using UART0" | 136 | bool "Kernel low-level debugging on DaVinci DMx using UART0" |
133 | depends on ARCH_DAVINCI_DMx | 137 | depends on ARCH_DAVINCI_DMx |
138 | select DEBUG_UART_8250 | ||
134 | help | 139 | help |
135 | Say Y here if you want the debug print routines to direct | 140 | Say Y here if you want the debug print routines to direct |
136 | their output to UART0 serial port on DaVinci DMx devices. | 141 | their output to UART0 serial port on DaVinci DMx devices. |
@@ -138,6 +143,7 @@ choice | |||
138 | config DEBUG_DAVINCI_TNETV107X_UART1 | 143 | config DEBUG_DAVINCI_TNETV107X_UART1 |
139 | bool "Kernel low-level debugging on DaVinci TNETV107x using UART1" | 144 | bool "Kernel low-level debugging on DaVinci TNETV107x using UART1" |
140 | depends on ARCH_DAVINCI_TNETV107X | 145 | depends on ARCH_DAVINCI_TNETV107X |
146 | select DEBUG_UART_8250 | ||
141 | help | 147 | help |
142 | Say Y here if you want the debug print routines to direct | 148 | Say Y here if you want the debug print routines to direct |
143 | their output to UART1 serial port on DaVinci TNETV107X | 149 | their output to UART1 serial port on DaVinci TNETV107X |
@@ -174,9 +180,26 @@ choice | |||
174 | Say Y here if you want the debug print routines to direct | 180 | Say Y here if you want the debug print routines to direct |
175 | their output to the 8250 at PCI COM1. | 181 | their output to the 8250 at PCI COM1. |
176 | 182 | ||
183 | config DEBUG_HI3620_UART | ||
184 | bool "Hisilicon HI3620 Debug UART" | ||
185 | depends on ARCH_HI3xxx | ||
186 | select DEBUG_UART_PL01X | ||
187 | help | ||
188 | Say Y here if you want kernel low-level debugging support | ||
189 | on HI3620 UART. | ||
190 | |||
191 | config DEBUG_HI3716_UART | ||
192 | bool "Hisilicon Hi3716 Debug UART" | ||
193 | depends on ARCH_HI3xxx | ||
194 | select DEBUG_UART_PL01X | ||
195 | help | ||
196 | Say Y here if you want kernel low-level debugging support | ||
197 | on HI3716 UART. | ||
198 | |||
177 | config DEBUG_HIGHBANK_UART | 199 | config DEBUG_HIGHBANK_UART |
178 | bool "Kernel low-level debugging messages via Highbank UART" | 200 | bool "Kernel low-level debugging messages via Highbank UART" |
179 | depends on ARCH_HIGHBANK | 201 | depends on ARCH_HIGHBANK |
202 | select DEBUG_UART_PL01X | ||
180 | help | 203 | help |
181 | Say Y here if you want the debug print routines to direct | 204 | Say Y here if you want the debug print routines to direct |
182 | their output to the UART on Highbank based devices. | 205 | their output to the UART on Highbank based devices. |
@@ -191,6 +214,7 @@ choice | |||
191 | config DEBUG_IMX23_UART | 214 | config DEBUG_IMX23_UART |
192 | bool "i.MX23 Debug UART" | 215 | bool "i.MX23 Debug UART" |
193 | depends on SOC_IMX23 | 216 | depends on SOC_IMX23 |
217 | select DEBUG_UART_PL01X | ||
194 | help | 218 | help |
195 | Say Y here if you want kernel low-level debugging support | 219 | Say Y here if you want kernel low-level debugging support |
196 | on i.MX23. | 220 | on i.MX23. |
@@ -212,6 +236,7 @@ choice | |||
212 | config DEBUG_IMX28_UART | 236 | config DEBUG_IMX28_UART |
213 | bool "i.MX28 Debug UART" | 237 | bool "i.MX28 Debug UART" |
214 | depends on SOC_IMX28 | 238 | depends on SOC_IMX28 |
239 | select DEBUG_UART_PL01X | ||
215 | help | 240 | help |
216 | Say Y here if you want kernel low-level debugging support | 241 | Say Y here if you want kernel low-level debugging support |
217 | on i.MX28. | 242 | on i.MX28. |
@@ -261,6 +286,7 @@ choice | |||
261 | config DEBUG_KEYSTONE_UART0 | 286 | config DEBUG_KEYSTONE_UART0 |
262 | bool "Kernel low-level debugging on KEYSTONE2 using UART0" | 287 | bool "Kernel low-level debugging on KEYSTONE2 using UART0" |
263 | depends on ARCH_KEYSTONE | 288 | depends on ARCH_KEYSTONE |
289 | select DEBUG_UART_8250 | ||
264 | help | 290 | help |
265 | Say Y here if you want the debug print routines to direct | 291 | Say Y here if you want the debug print routines to direct |
266 | their output to UART0 serial port on KEYSTONE2 devices. | 292 | their output to UART0 serial port on KEYSTONE2 devices. |
@@ -268,6 +294,7 @@ choice | |||
268 | config DEBUG_KEYSTONE_UART1 | 294 | config DEBUG_KEYSTONE_UART1 |
269 | bool "Kernel low-level debugging on KEYSTONE2 using UART1" | 295 | bool "Kernel low-level debugging on KEYSTONE2 using UART1" |
270 | depends on ARCH_KEYSTONE | 296 | depends on ARCH_KEYSTONE |
297 | select DEBUG_UART_8250 | ||
271 | help | 298 | help |
272 | Say Y here if you want the debug print routines to direct | 299 | Say Y here if you want the debug print routines to direct |
273 | their output to UART1 serial port on KEYSTONE2 devices. | 300 | their output to UART1 serial port on KEYSTONE2 devices. |
@@ -275,6 +302,7 @@ choice | |||
275 | config DEBUG_MMP_UART2 | 302 | config DEBUG_MMP_UART2 |
276 | bool "Kernel low-level debugging message via MMP UART2" | 303 | bool "Kernel low-level debugging message via MMP UART2" |
277 | depends on ARCH_MMP | 304 | depends on ARCH_MMP |
305 | select DEBUG_UART_8250 | ||
278 | help | 306 | help |
279 | Say Y here if you want kernel low-level debugging support | 307 | Say Y here if you want kernel low-level debugging support |
280 | on MMP UART2. | 308 | on MMP UART2. |
@@ -282,6 +310,7 @@ choice | |||
282 | config DEBUG_MMP_UART3 | 310 | config DEBUG_MMP_UART3 |
283 | bool "Kernel low-level debugging message via MMP UART3" | 311 | bool "Kernel low-level debugging message via MMP UART3" |
284 | depends on ARCH_MMP | 312 | depends on ARCH_MMP |
313 | select DEBUG_UART_8250 | ||
285 | help | 314 | help |
286 | Say Y here if you want kernel low-level debugging support | 315 | Say Y here if you want kernel low-level debugging support |
287 | on MMP UART3. | 316 | on MMP UART3. |
@@ -326,6 +355,7 @@ choice | |||
326 | config DEBUG_MVEBU_UART | 355 | config DEBUG_MVEBU_UART |
327 | bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)" | 356 | bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)" |
328 | depends on ARCH_MVEBU | 357 | depends on ARCH_MVEBU |
358 | select DEBUG_UART_8250 | ||
329 | help | 359 | help |
330 | Say Y here if you want kernel low-level debugging support | 360 | Say Y here if you want kernel low-level debugging support |
331 | on MVEBU based platforms. | 361 | on MVEBU based platforms. |
@@ -344,6 +374,7 @@ choice | |||
344 | config DEBUG_MVEBU_UART_ALTERNATE | 374 | config DEBUG_MVEBU_UART_ALTERNATE |
345 | bool "Kernel low-level debugging messages via MVEBU UART (new bootloaders)" | 375 | bool "Kernel low-level debugging messages via MVEBU UART (new bootloaders)" |
346 | depends on ARCH_MVEBU | 376 | depends on ARCH_MVEBU |
377 | select DEBUG_UART_8250 | ||
347 | help | 378 | help |
348 | Say Y here if you want kernel low-level debugging support | 379 | Say Y here if you want kernel low-level debugging support |
349 | on MVEBU based platforms. | 380 | on MVEBU based platforms. |
@@ -358,6 +389,7 @@ choice | |||
358 | config DEBUG_NOMADIK_UART | 389 | config DEBUG_NOMADIK_UART |
359 | bool "Kernel low-level debugging messages via NOMADIK UART" | 390 | bool "Kernel low-level debugging messages via NOMADIK UART" |
360 | depends on ARCH_NOMADIK | 391 | depends on ARCH_NOMADIK |
392 | select DEBUG_UART_PL01X | ||
361 | help | 393 | help |
362 | Say Y here if you want kernel low-level debugging support | 394 | Say Y here if you want kernel low-level debugging support |
363 | on NOMADIK based platforms. | 395 | on NOMADIK based platforms. |
@@ -365,6 +397,7 @@ choice | |||
365 | config DEBUG_NSPIRE_CLASSIC_UART | 397 | config DEBUG_NSPIRE_CLASSIC_UART |
366 | bool "Kernel low-level debugging via TI-NSPIRE 8250 UART" | 398 | bool "Kernel low-level debugging via TI-NSPIRE 8250 UART" |
367 | depends on ARCH_NSPIRE | 399 | depends on ARCH_NSPIRE |
400 | select DEBUG_UART_8250 | ||
368 | help | 401 | help |
369 | Say Y here if you want kernel low-level debugging support | 402 | Say Y here if you want kernel low-level debugging support |
370 | on TI-NSPIRE classic models. | 403 | on TI-NSPIRE classic models. |
@@ -372,20 +405,82 @@ choice | |||
372 | config DEBUG_NSPIRE_CX_UART | 405 | config DEBUG_NSPIRE_CX_UART |
373 | bool "Kernel low-level debugging via TI-NSPIRE PL011 UART" | 406 | bool "Kernel low-level debugging via TI-NSPIRE PL011 UART" |
374 | depends on ARCH_NSPIRE | 407 | depends on ARCH_NSPIRE |
408 | select DEBUG_UART_PL01X | ||
375 | help | 409 | help |
376 | Say Y here if you want kernel low-level debugging support | 410 | Say Y here if you want kernel low-level debugging support |
377 | on TI-NSPIRE CX models. | 411 | on TI-NSPIRE CX models. |
378 | 412 | ||
379 | config DEBUG_OMAP2PLUS_UART | 413 | config DEBUG_OMAP2UART1 |
380 | bool "Kernel low-level debugging messages via OMAP2PLUS UART" | 414 | bool "OMAP2/3/4 UART1 (omap2/3 sdp boards and some omap3 boards)" |
381 | depends on ARCH_OMAP2PLUS | 415 | depends on ARCH_OMAP2PLUS |
416 | select DEBUG_OMAP2PLUS_UART | ||
382 | help | 417 | help |
383 | Say Y here if you want kernel low-level debugging support | 418 | This covers at least h4, 2430sdp, 3430sdp, 3630sdp, |
384 | on OMAP2PLUS based platforms. | 419 | omap3 torpedo and 3530 lv som. |
420 | |||
421 | config DEBUG_OMAP2UART2 | ||
422 | bool "Kernel low-level debugging messages via OMAP2/3/4 UART2" | ||
423 | depends on ARCH_OMAP2PLUS | ||
424 | select DEBUG_OMAP2PLUS_UART | ||
425 | |||
426 | config DEBUG_OMAP2UART3 | ||
427 | bool "Kernel low-level debugging messages via OMAP2 UART3 (n8x0)" | ||
428 | depends on ARCH_OMAP2PLUS | ||
429 | select DEBUG_OMAP2PLUS_UART | ||
430 | |||
431 | config DEBUG_OMAP3UART3 | ||
432 | bool "Kernel low-level debugging messages via OMAP3 UART3 (most omap3 boards)" | ||
433 | depends on ARCH_OMAP2PLUS | ||
434 | select DEBUG_OMAP2PLUS_UART | ||
435 | help | ||
436 | This covers at least cm_t3x, beagle, crane, devkit8000, | ||
437 | igep00x0, ldp, n900, n9(50), pandora, overo, touchbook, | ||
438 | and 3517evm. | ||
439 | |||
440 | config DEBUG_OMAP4UART3 | ||
441 | bool "Kernel low-level debugging messages via OMAP4/5 UART3 (omap4 blaze, panda, omap5 sevm)" | ||
442 | depends on ARCH_OMAP2PLUS | ||
443 | select DEBUG_OMAP2PLUS_UART | ||
444 | |||
445 | config DEBUG_OMAP3UART4 | ||
446 | bool "Kernel low-level debugging messages via OMAP36XX UART4" | ||
447 | depends on ARCH_OMAP2PLUS | ||
448 | select DEBUG_OMAP2PLUS_UART | ||
449 | |||
450 | config DEBUG_OMAP4UART4 | ||
451 | bool "Kernel low-level debugging messages via OMAP4/5 UART4" | ||
452 | depends on ARCH_OMAP2PLUS | ||
453 | select DEBUG_OMAP2PLUS_UART | ||
454 | |||
455 | config DEBUG_TI81XXUART1 | ||
456 | bool "Kernel low-level debugging messages via TI81XX UART1 (ti8148evm)" | ||
457 | depends on ARCH_OMAP2PLUS | ||
458 | select DEBUG_OMAP2PLUS_UART | ||
459 | |||
460 | config DEBUG_TI81XXUART2 | ||
461 | bool "Kernel low-level debugging messages via TI81XX UART2" | ||
462 | depends on ARCH_OMAP2PLUS | ||
463 | select DEBUG_OMAP2PLUS_UART | ||
464 | |||
465 | config DEBUG_TI81XXUART3 | ||
466 | bool "Kernel low-level debugging messages via TI81XX UART3 (ti8168evm)" | ||
467 | depends on ARCH_OMAP2PLUS | ||
468 | select DEBUG_OMAP2PLUS_UART | ||
469 | |||
470 | config DEBUG_AM33XXUART1 | ||
471 | bool "Kernel low-level debugging messages via AM33XX UART1" | ||
472 | depends on ARCH_OMAP2PLUS | ||
473 | select DEBUG_OMAP2PLUS_UART | ||
474 | |||
475 | config DEBUG_ZOOM_UART | ||
476 | bool "Kernel low-level debugging messages via Zoom2/3 UART" | ||
477 | depends on ARCH_OMAP2PLUS | ||
478 | select DEBUG_OMAP2PLUS_UART | ||
385 | 479 | ||
386 | config DEBUG_PICOXCELL_UART | 480 | config DEBUG_PICOXCELL_UART |
387 | depends on ARCH_PICOXCELL | 481 | depends on ARCH_PICOXCELL |
388 | bool "Use PicoXcell UART for low-level debug" | 482 | bool "Use PicoXcell UART for low-level debug" |
483 | select DEBUG_UART_8250 | ||
389 | help | 484 | help |
390 | Say Y here if you want kernel low-level debugging support | 485 | Say Y here if you want kernel low-level debugging support |
391 | on PicoXcell based platforms. | 486 | on PicoXcell based platforms. |
@@ -393,6 +488,7 @@ choice | |||
393 | config DEBUG_PXA_UART1 | 488 | config DEBUG_PXA_UART1 |
394 | depends on ARCH_PXA | 489 | depends on ARCH_PXA |
395 | bool "Use PXA UART1 for low-level debug" | 490 | bool "Use PXA UART1 for low-level debug" |
491 | select DEBUG_UART_8250 | ||
396 | help | 492 | help |
397 | Say Y here if you want kernel low-level debugging support | 493 | Say Y here if you want kernel low-level debugging support |
398 | on PXA UART1. | 494 | on PXA UART1. |
@@ -400,6 +496,7 @@ choice | |||
400 | config DEBUG_REALVIEW_STD_PORT | 496 | config DEBUG_REALVIEW_STD_PORT |
401 | bool "RealView Default UART" | 497 | bool "RealView Default UART" |
402 | depends on ARCH_REALVIEW | 498 | depends on ARCH_REALVIEW |
499 | select DEBUG_UART_PL01X | ||
403 | help | 500 | help |
404 | Say Y here if you want the debug print routines to direct | 501 | Say Y here if you want the debug print routines to direct |
405 | their output to the serial port on RealView EB, PB11MP, PBA8 | 502 | their output to the serial port on RealView EB, PB11MP, PBA8 |
@@ -408,14 +505,64 @@ choice | |||
408 | config DEBUG_REALVIEW_PB1176_PORT | 505 | config DEBUG_REALVIEW_PB1176_PORT |
409 | bool "RealView PB1176 UART" | 506 | bool "RealView PB1176 UART" |
410 | depends on MACH_REALVIEW_PB1176 | 507 | depends on MACH_REALVIEW_PB1176 |
508 | select DEBUG_UART_PL01X | ||
411 | help | 509 | help |
412 | Say Y here if you want the debug print routines to direct | 510 | Say Y here if you want the debug print routines to direct |
413 | their output to the standard serial port on the RealView | 511 | their output to the standard serial port on the RealView |
414 | PB1176 platform. | 512 | PB1176 platform. |
415 | 513 | ||
416 | config DEBUG_ROCKCHIP_UART | 514 | config DEBUG_RK29_UART0 |
417 | bool "Kernel low-level debugging messages via Rockchip UART" | 515 | bool "Kernel low-level debugging messages via Rockchip RK29 UART0" |
516 | depends on ARCH_ROCKCHIP | ||
517 | select DEBUG_UART_8250 | ||
518 | help | ||
519 | Say Y here if you want kernel low-level debugging support | ||
520 | on Rockchip based platforms. | ||
521 | |||
522 | config DEBUG_RK29_UART1 | ||
523 | bool "Kernel low-level debugging messages via Rockchip RK29 UART1" | ||
524 | depends on ARCH_ROCKCHIP | ||
525 | select DEBUG_UART_8250 | ||
526 | help | ||
527 | Say Y here if you want kernel low-level debugging support | ||
528 | on Rockchip based platforms. | ||
529 | |||
530 | config DEBUG_RK29_UART2 | ||
531 | bool "Kernel low-level debugging messages via Rockchip RK29 UART2" | ||
532 | depends on ARCH_ROCKCHIP | ||
533 | select DEBUG_UART_8250 | ||
534 | help | ||
535 | Say Y here if you want kernel low-level debugging support | ||
536 | on Rockchip based platforms. | ||
537 | |||
538 | config DEBUG_RK3X_UART0 | ||
539 | bool "Kernel low-level debugging messages via Rockchip RK3X UART0" | ||
540 | depends on ARCH_ROCKCHIP | ||
541 | select DEBUG_UART_8250 | ||
542 | help | ||
543 | Say Y here if you want kernel low-level debugging support | ||
544 | on Rockchip based platforms. | ||
545 | |||
546 | config DEBUG_RK3X_UART1 | ||
547 | bool "Kernel low-level debugging messages via Rockchip RK3X UART1" | ||
548 | depends on ARCH_ROCKCHIP | ||
549 | select DEBUG_UART_8250 | ||
550 | help | ||
551 | Say Y here if you want kernel low-level debugging support | ||
552 | on Rockchip based platforms. | ||
553 | |||
554 | config DEBUG_RK3X_UART2 | ||
555 | bool "Kernel low-level debugging messages via Rockchip RK3X UART2" | ||
556 | depends on ARCH_ROCKCHIP | ||
557 | select DEBUG_UART_8250 | ||
558 | help | ||
559 | Say Y here if you want kernel low-level debugging support | ||
560 | on Rockchip based platforms. | ||
561 | |||
562 | config DEBUG_RK3X_UART3 | ||
563 | bool "Kernel low-level debugging messages via Rockchip RK3X UART3" | ||
418 | depends on ARCH_ROCKCHIP | 564 | depends on ARCH_ROCKCHIP |
565 | select DEBUG_UART_8250 | ||
419 | help | 566 | help |
420 | Say Y here if you want kernel low-level debugging support | 567 | Say Y here if you want kernel low-level debugging support |
421 | on Rockchip based platforms. | 568 | on Rockchip based platforms. |
@@ -471,6 +618,7 @@ choice | |||
471 | config DEBUG_SOCFPGA_UART | 618 | config DEBUG_SOCFPGA_UART |
472 | depends on ARCH_SOCFPGA | 619 | depends on ARCH_SOCFPGA |
473 | bool "Use SOCFPGA UART for low-level debug" | 620 | bool "Use SOCFPGA UART for low-level debug" |
621 | select DEBUG_UART_8250 | ||
474 | help | 622 | help |
475 | Say Y here if you want kernel low-level debugging support | 623 | Say Y here if you want kernel low-level debugging support |
476 | on SOCFPGA based platforms. | 624 | on SOCFPGA based platforms. |
@@ -478,6 +626,7 @@ choice | |||
478 | config DEBUG_SUNXI_UART0 | 626 | config DEBUG_SUNXI_UART0 |
479 | bool "Kernel low-level debugging messages via sunXi UART0" | 627 | bool "Kernel low-level debugging messages via sunXi UART0" |
480 | depends on ARCH_SUNXI | 628 | depends on ARCH_SUNXI |
629 | select DEBUG_UART_8250 | ||
481 | help | 630 | help |
482 | Say Y here if you want kernel low-level debugging support | 631 | Say Y here if you want kernel low-level debugging support |
483 | on Allwinner A1X based platforms on the UART0. | 632 | on Allwinner A1X based platforms on the UART0. |
@@ -485,13 +634,59 @@ choice | |||
485 | config DEBUG_SUNXI_UART1 | 634 | config DEBUG_SUNXI_UART1 |
486 | bool "Kernel low-level debugging messages via sunXi UART1" | 635 | bool "Kernel low-level debugging messages via sunXi UART1" |
487 | depends on ARCH_SUNXI | 636 | depends on ARCH_SUNXI |
637 | select DEBUG_UART_8250 | ||
488 | help | 638 | help |
489 | Say Y here if you want kernel low-level debugging support | 639 | Say Y here if you want kernel low-level debugging support |
490 | on Allwinner A1X based platforms on the UART1. | 640 | on Allwinner A1X based platforms on the UART1. |
491 | 641 | ||
492 | config DEBUG_TEGRA_UART | 642 | config TEGRA_DEBUG_UART_AUTO_ODMDATA |
643 | bool "Kernel low-level debugging messages via Tegra UART via ODMDATA" | ||
644 | depends on ARCH_TEGRA | ||
645 | select DEBUG_TEGRA_UART | ||
646 | help | ||
647 | Automatically determines which UART to use for low-level | ||
648 | debug based on the ODMDATA value. This value is part of | ||
649 | the BCT, and is written to the boot memory device using | ||
650 | nvflash, or other flashing tool. When bits 19:18 are 3, | ||
651 | then bits 17:15 indicate which UART to use; 0/1/2/3/4 | ||
652 | are UART A/B/C/D/E. | ||
653 | |||
654 | config TEGRA_DEBUG_UARTA | ||
655 | bool "Kernel low-level debugging messages via Tegra UART A" | ||
656 | depends on ARCH_TEGRA | ||
657 | select DEBUG_TEGRA_UART | ||
658 | help | ||
659 | Say Y here if you want kernel low-level debugging support | ||
660 | on Tegra based platforms. | ||
661 | |||
662 | config TEGRA_DEBUG_UARTB | ||
663 | bool "Kernel low-level debugging messages via Tegra UART B" | ||
664 | depends on ARCH_TEGRA | ||
665 | select DEBUG_TEGRA_UART | ||
666 | help | ||
667 | Say Y here if you want kernel low-level debugging support | ||
668 | on Tegra based platforms. | ||
669 | |||
670 | config TEGRA_DEBUG_UARTC | ||
671 | bool "Kernel low-level debugging messages via Tegra UART C" | ||
672 | depends on ARCH_TEGRA | ||
673 | select DEBUG_TEGRA_UART | ||
674 | help | ||
675 | Say Y here if you want kernel low-level debugging support | ||
676 | on Tegra based platforms. | ||
677 | |||
678 | config TEGRA_DEBUG_UARTD | ||
679 | bool "Kernel low-level debugging messages via Tegra UART D" | ||
680 | depends on ARCH_TEGRA | ||
681 | select DEBUG_TEGRA_UART | ||
682 | help | ||
683 | Say Y here if you want kernel low-level debugging support | ||
684 | on Tegra based platforms. | ||
685 | |||
686 | config TEGRA_DEBUG_UARTE | ||
687 | bool "Kernel low-level debugging messages via Tegra UART E" | ||
493 | depends on ARCH_TEGRA | 688 | depends on ARCH_TEGRA |
494 | bool "Use Tegra UART for low-level debug" | 689 | select DEBUG_TEGRA_UART |
495 | help | 690 | help |
496 | Say Y here if you want kernel low-level debugging support | 691 | Say Y here if you want kernel low-level debugging support |
497 | on Tegra based platforms. | 692 | on Tegra based platforms. |
@@ -510,19 +705,32 @@ choice | |||
510 | Say Y here if you want the debug print routines to direct | 705 | Say Y here if you want the debug print routines to direct |
511 | their output to the uart1 port on SiRFmarco devices. | 706 | their output to the uart1 port on SiRFmarco devices. |
512 | 707 | ||
513 | config DEBUG_STI_UART | 708 | config STIH41X_DEBUG_ASC2 |
709 | bool "Use StiH415/416 ASC2 UART for low-level debug" | ||
710 | depends on ARCH_STI | ||
711 | select DEBUG_STI_UART | ||
712 | help | ||
713 | Say Y here if you want kernel low-level debugging support | ||
714 | on STiH415/416 based platforms like b2000, which has | ||
715 | default UART wired up to ASC2. | ||
716 | |||
717 | If unsure, say N. | ||
718 | |||
719 | config STIH41X_DEBUG_SBC_ASC1 | ||
720 | bool "Use StiH415/416 SBC ASC1 UART for low-level debug" | ||
514 | depends on ARCH_STI | 721 | depends on ARCH_STI |
515 | bool "Use StiH415/416 ASC for low-level debug" | 722 | select DEBUG_STI_UART |
516 | help | 723 | help |
517 | Say Y here if you want kernel low-level debugging support | 724 | Say Y here if you want kernel low-level debugging support |
518 | on StiH415/416 based platforms like B2000, B2020. | 725 | on STiH415/416 based platforms like b2020. which has |
519 | It support UART2 and SBC_UART1. | 726 | default UART wired up to SBC ASC1. |
520 | 727 | ||
521 | If unsure, say N. | 728 | If unsure, say N. |
522 | 729 | ||
523 | config DEBUG_U300_UART | 730 | config DEBUG_U300_UART |
524 | bool "Kernel low-level debugging messages via U300 UART0" | 731 | bool "Kernel low-level debugging messages via U300 UART0" |
525 | depends on ARCH_U300 | 732 | depends on ARCH_U300 |
733 | select DEBUG_UART_PL01X | ||
526 | help | 734 | help |
527 | Say Y here if you want the debug print routines to direct | 735 | Say Y here if you want the debug print routines to direct |
528 | their output to the uart port on U300 devices. | 736 | their output to the uart port on U300 devices. |
@@ -548,6 +756,7 @@ choice | |||
548 | config DEBUG_VEXPRESS_UART0_CA9 | 756 | config DEBUG_VEXPRESS_UART0_CA9 |
549 | bool "Use PL011 UART0 at 0x10009000 (V2P-CA9 core tile)" | 757 | bool "Use PL011 UART0 at 0x10009000 (V2P-CA9 core tile)" |
550 | depends on ARCH_VEXPRESS | 758 | depends on ARCH_VEXPRESS |
759 | select DEBUG_UART_PL01X | ||
551 | help | 760 | help |
552 | This option selects UART0 at 0x10009000. Except for custom models, | 761 | This option selects UART0 at 0x10009000. Except for custom models, |
553 | this applies only to the V2P-CA9 tile. | 762 | this applies only to the V2P-CA9 tile. |
@@ -555,6 +764,7 @@ choice | |||
555 | config DEBUG_VEXPRESS_UART0_RS1 | 764 | config DEBUG_VEXPRESS_UART0_RS1 |
556 | bool "Use PL011 UART0 at 0x1c090000 (RS1 complaint tiles)" | 765 | bool "Use PL011 UART0 at 0x1c090000 (RS1 complaint tiles)" |
557 | depends on ARCH_VEXPRESS | 766 | depends on ARCH_VEXPRESS |
767 | select DEBUG_UART_PL01X | ||
558 | help | 768 | help |
559 | This option selects UART0 at 0x1c090000. This applies to most | 769 | This option selects UART0 at 0x1c090000. This applies to most |
560 | of the tiles using the RS1 memory map, including all new A-class | 770 | of the tiles using the RS1 memory map, including all new A-class |
@@ -563,6 +773,7 @@ choice | |||
563 | config DEBUG_VEXPRESS_UART0_CRX | 773 | config DEBUG_VEXPRESS_UART0_CRX |
564 | bool "Use PL011 UART0 at 0xb0090000 (Cortex-R compliant tiles)" | 774 | bool "Use PL011 UART0 at 0xb0090000 (Cortex-R compliant tiles)" |
565 | depends on ARCH_VEXPRESS && !MMU | 775 | depends on ARCH_VEXPRESS && !MMU |
776 | select DEBUG_UART_PL01X | ||
566 | help | 777 | help |
567 | This option selects UART0 at 0xb0090000. This is appropriate for | 778 | This option selects UART0 at 0xb0090000. This is appropriate for |
568 | Cortex-R series tiles and SMMs, such as Cortex-R5 and Cortex-R7 | 779 | Cortex-R series tiles and SMMs, such as Cortex-R5 and Cortex-R7 |
@@ -579,7 +790,7 @@ choice | |||
579 | depends on !ARCH_MULTIPLATFORM | 790 | depends on !ARCH_MULTIPLATFORM |
580 | help | 791 | help |
581 | Say Y here if your platform doesn't provide a UART option | 792 | Say Y here if your platform doesn't provide a UART option |
582 | below. This relies on your platform choosing the right UART | 793 | above. This relies on your platform choosing the right UART |
583 | definition internally in order for low-level debugging to | 794 | definition internally in order for low-level debugging to |
584 | work. | 795 | work. |
585 | 796 | ||
@@ -610,11 +821,41 @@ choice | |||
610 | For more details about semihosting, please see | 821 | For more details about semihosting, please see |
611 | chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd. | 822 | chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd. |
612 | 823 | ||
824 | config DEBUG_LL_UART_8250 | ||
825 | bool "Kernel low-level debugging via 8250 UART" | ||
826 | help | ||
827 | Say Y here if you wish the debug print routes to direct | ||
828 | their output to an 8250 UART. You can use this option | ||
829 | to provide the parameters for the 8250 UART rather than | ||
830 | selecting one of the platform specific options above if | ||
831 | you know the parameters for the port. | ||
832 | |||
833 | This option is preferred over the platform specific | ||
834 | options; the platform specific options are deprecated | ||
835 | and will be soon removed. | ||
836 | |||
837 | config DEBUG_LL_UART_PL01X | ||
838 | bool "Kernel low-level debugging via ARM Ltd PL01x Primecell UART" | ||
839 | help | ||
840 | Say Y here if you wish the debug print routes to direct | ||
841 | their output to a PL01x Primecell UART. You can use | ||
842 | this option to provide the parameters for the UART | ||
843 | rather than selecting one of the platform specific | ||
844 | options above if you know the parameters for the port. | ||
845 | |||
846 | This option is preferred over the platform specific | ||
847 | options; the platform specific options are deprecated | ||
848 | and will be soon removed. | ||
849 | |||
613 | endchoice | 850 | endchoice |
614 | 851 | ||
615 | config DEBUG_EXYNOS_UART | 852 | config DEBUG_EXYNOS_UART |
616 | bool | 853 | bool |
617 | 854 | ||
855 | config DEBUG_OMAP2PLUS_UART | ||
856 | bool | ||
857 | depends on ARCH_OMAP2PLUS | ||
858 | |||
618 | config DEBUG_IMX_UART_PORT | 859 | config DEBUG_IMX_UART_PORT |
619 | int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \ | 860 | int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \ |
620 | DEBUG_IMX25_UART || \ | 861 | DEBUG_IMX25_UART || \ |
@@ -631,140 +872,19 @@ config DEBUG_IMX_UART_PORT | |||
631 | Choose UART port on which kernel low-level debug messages | 872 | Choose UART port on which kernel low-level debug messages |
632 | should be output. | 873 | should be output. |
633 | 874 | ||
634 | choice | 875 | config DEBUG_TEGRA_UART |
635 | prompt "Low-level debug console UART" | 876 | bool |
636 | depends on DEBUG_OMAP2PLUS_UART | 877 | depends on ARCH_TEGRA |
637 | |||
638 | config DEBUG_OMAP2UART1 | ||
639 | bool "OMAP2/3/4 UART1 (omap2/3 sdp boards and some omap3 boards)" | ||
640 | help | ||
641 | This covers at least h4, 2430sdp, 3430sdp, 3630sdp, | ||
642 | omap3 torpedo and 3530 lv som. | ||
643 | |||
644 | config DEBUG_OMAP2UART2 | ||
645 | bool "OMAP2/3/4 UART2" | ||
646 | |||
647 | config DEBUG_OMAP2UART3 | ||
648 | bool "OMAP2 UART3 (n8x0)" | ||
649 | |||
650 | config DEBUG_OMAP3UART3 | ||
651 | bool "OMAP3 UART3 (most omap3 boards)" | ||
652 | help | ||
653 | This covers at least cm_t3x, beagle, crane, devkit8000, | ||
654 | igep00x0, ldp, n900, n9(50), pandora, overo, touchbook, | ||
655 | and 3517evm. | ||
656 | |||
657 | config DEBUG_OMAP4UART3 | ||
658 | bool "OMAP4/5 UART3 (omap4 blaze, panda, omap5 sevm)" | ||
659 | |||
660 | config DEBUG_OMAP3UART4 | ||
661 | bool "OMAP36XX UART4" | ||
662 | |||
663 | config DEBUG_OMAP4UART4 | ||
664 | bool "OMAP4/5 UART4" | ||
665 | |||
666 | config DEBUG_TI81XXUART1 | ||
667 | bool "TI81XX UART1 (ti8148evm)" | ||
668 | |||
669 | config DEBUG_TI81XXUART2 | ||
670 | bool "TI81XX UART2" | ||
671 | |||
672 | config DEBUG_TI81XXUART3 | ||
673 | bool "TI81XX UART3 (ti8168evm)" | ||
674 | |||
675 | config DEBUG_AM33XXUART1 | ||
676 | bool "AM33XX UART1" | ||
677 | |||
678 | config DEBUG_ZOOM_UART | ||
679 | bool "Zoom2/3 UART" | ||
680 | endchoice | ||
681 | |||
682 | choice | ||
683 | prompt "Low-level debug console UART" | ||
684 | depends on DEBUG_ROCKCHIP_UART | ||
685 | |||
686 | config DEBUG_RK29_UART0 | ||
687 | bool "RK29 UART0" | ||
688 | |||
689 | config DEBUG_RK29_UART1 | ||
690 | bool "RK29 UART1" | ||
691 | |||
692 | config DEBUG_RK29_UART2 | ||
693 | bool "RK29 UART2" | ||
694 | |||
695 | config DEBUG_RK3X_UART0 | ||
696 | bool "RK3X UART0" | ||
697 | |||
698 | config DEBUG_RK3X_UART1 | ||
699 | bool "RK3X UART1" | ||
700 | |||
701 | config DEBUG_RK3X_UART2 | ||
702 | bool "RK3X UART2" | ||
703 | |||
704 | config DEBUG_RK3X_UART3 | ||
705 | bool "RK3X UART3" | ||
706 | endchoice | ||
707 | |||
708 | choice | ||
709 | prompt "Low-level debug console UART" | ||
710 | depends on DEBUG_LL && DEBUG_TEGRA_UART | ||
711 | |||
712 | config TEGRA_DEBUG_UART_AUTO_ODMDATA | ||
713 | bool "Via ODMDATA" | ||
714 | help | ||
715 | Automatically determines which UART to use for low-level debug based | ||
716 | on the ODMDATA value. This value is part of the BCT, and is written | ||
717 | to the boot memory device using nvflash, or other flashing tool. | ||
718 | When bits 19:18 are 3, then bits 17:15 indicate which UART to use; | ||
719 | 0/1/2/3/4 are UART A/B/C/D/E. | ||
720 | |||
721 | config TEGRA_DEBUG_UARTA | ||
722 | bool "UART A" | ||
723 | |||
724 | config TEGRA_DEBUG_UARTB | ||
725 | bool "UART B" | ||
726 | |||
727 | config TEGRA_DEBUG_UARTC | ||
728 | bool "UART C" | ||
729 | |||
730 | config TEGRA_DEBUG_UARTD | ||
731 | bool "UART D" | ||
732 | |||
733 | config TEGRA_DEBUG_UARTE | ||
734 | bool "UART E" | ||
735 | |||
736 | endchoice | ||
737 | |||
738 | choice | ||
739 | prompt "Low-level debug console UART" | ||
740 | depends on DEBUG_LL && DEBUG_STI_UART | ||
741 | |||
742 | config STIH41X_DEBUG_ASC2 | ||
743 | bool "ASC2 UART" | ||
744 | help | ||
745 | Say Y here if you want kernel low-level debugging support | ||
746 | on STiH415/416 based platforms like b2000, which has | ||
747 | default UART wired up to ASC2. | ||
748 | |||
749 | If unsure, say N. | ||
750 | |||
751 | config STIH41X_DEBUG_SBC_ASC1 | ||
752 | bool "SBC ASC1 UART" | ||
753 | help | ||
754 | Say Y here if you want kernel low-level debugging support | ||
755 | on STiH415/416 based platforms like b2020. which has | ||
756 | default UART wired up to SBC ASC1. | ||
757 | |||
758 | If unsure, say N. | ||
759 | 878 | ||
760 | endchoice | 879 | config DEBUG_STI_UART |
880 | bool | ||
881 | depends on ARCH_STI | ||
761 | 882 | ||
762 | config DEBUG_LL_INCLUDE | 883 | config DEBUG_LL_INCLUDE |
763 | string | 884 | string |
764 | default "debug/bcm2835.S" if DEBUG_BCM2835 | 885 | default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 |
765 | default "debug/cns3xxx.S" if DEBUG_CNS3XXX | 886 | default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X |
766 | default "debug/exynos.S" if DEBUG_EXYNOS_UART | 887 | default "debug/exynos.S" if DEBUG_EXYNOS_UART |
767 | default "debug/highbank.S" if DEBUG_HIGHBANK_UART | ||
768 | default "debug/icedcc.S" if DEBUG_ICEDCC | 888 | default "debug/icedcc.S" if DEBUG_ICEDCC |
769 | default "debug/imx.S" if DEBUG_IMX1_UART || \ | 889 | default "debug/imx.S" if DEBUG_IMX1_UART || \ |
770 | DEBUG_IMX25_UART || \ | 890 | DEBUG_IMX25_UART || \ |
@@ -775,38 +895,170 @@ config DEBUG_LL_INCLUDE | |||
775 | DEBUG_IMX53_UART ||\ | 895 | DEBUG_IMX53_UART ||\ |
776 | DEBUG_IMX6Q_UART || \ | 896 | DEBUG_IMX6Q_UART || \ |
777 | DEBUG_IMX6SL_UART | 897 | DEBUG_IMX6SL_UART |
778 | default "debug/keystone.S" if DEBUG_KEYSTONE_UART0 || \ | ||
779 | DEBUG_KEYSTONE_UART1 | ||
780 | default "debug/mvebu.S" if DEBUG_MVEBU_UART || \ | ||
781 | DEBUG_MVEBU_UART_ALTERNATE | ||
782 | default "debug/mxs.S" if DEBUG_IMX23_UART || DEBUG_IMX28_UART | ||
783 | default "debug/nomadik.S" if DEBUG_NOMADIK_UART | ||
784 | default "debug/nspire.S" if DEBUG_NSPIRE_CX_UART || \ | ||
785 | DEBUG_NSPIRE_CLASSIC_UART | ||
786 | default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART | 898 | default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART |
787 | default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART | ||
788 | default "debug/pxa.S" if DEBUG_PXA_UART1 || DEBUG_MMP_UART2 || \ | ||
789 | DEBUG_MMP_UART3 | ||
790 | default "debug/rockchip.S" if DEBUG_ROCKCHIP_UART | ||
791 | default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1 | 899 | default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1 |
792 | default "debug/socfpga.S" if DEBUG_SOCFPGA_UART | ||
793 | default "debug/sti.S" if DEBUG_STI_UART | 900 | default "debug/sti.S" if DEBUG_STI_UART |
794 | default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1 | ||
795 | default "debug/tegra.S" if DEBUG_TEGRA_UART | 901 | default "debug/tegra.S" if DEBUG_TEGRA_UART |
796 | default "debug/u300.S" if DEBUG_U300_UART | ||
797 | default "debug/ux500.S" if DEBUG_UX500_UART | 902 | default "debug/ux500.S" if DEBUG_UX500_UART |
798 | default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ | 903 | default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT |
799 | DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 || \ | ||
800 | DEBUG_VEXPRESS_UART0_CRX | ||
801 | default "debug/vt8500.S" if DEBUG_VT8500_UART0 | 904 | default "debug/vt8500.S" if DEBUG_VT8500_UART0 |
802 | default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 | 905 | default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 |
803 | default "mach/debug-macro.S" | 906 | default "mach/debug-macro.S" |
804 | 907 | ||
908 | # Compatibility options for PL01x | ||
909 | config DEBUG_UART_PL01X | ||
910 | def_bool ARCH_EP93XX || \ | ||
911 | ARCH_INTEGRATOR || \ | ||
912 | ARCH_SPEAR3XX || \ | ||
913 | ARCH_SPEAR6XX || \ | ||
914 | ARCH_SPEAR13XX || \ | ||
915 | ARCH_VERSATILE | ||
916 | |||
917 | # Compatibility options for 8250 | ||
918 | config DEBUG_UART_8250 | ||
919 | def_bool ARCH_DOVE || ARCH_EBSA110 || \ | ||
920 | (FOOTBRIDGE && !DEBUG_DC21285_PORT) || \ | ||
921 | ARCH_GEMINI || ARCH_IOP13XX || ARCH_IOP32X || \ | ||
922 | ARCH_IOP33X || ARCH_IXP4XX || ARCH_KIRKWOOD || \ | ||
923 | ARCH_LPC32XX || ARCH_MV78XX0 || ARCH_ORION5X || ARCH_RPC | ||
924 | |||
925 | config DEBUG_UART_PHYS | ||
926 | hex "Physical base address of debug UART" | ||
927 | default 0x01c20000 if DEBUG_DAVINCI_DMx_UART0 | ||
928 | default 0x01c28000 if DEBUG_SUNXI_UART0 | ||
929 | default 0x01c28400 if DEBUG_SUNXI_UART1 | ||
930 | default 0x01d0c000 if DEBUG_DAVINCI_DA8XX_UART1 | ||
931 | default 0x01d0d000 if DEBUG_DAVINCI_DA8XX_UART2 | ||
932 | default 0x02530c00 if DEBUG_KEYSTONE_UART0 | ||
933 | default 0x02531000 if DEBUG_KEYSTONE_UART1 | ||
934 | default 0x03010fe0 if ARCH_RPC | ||
935 | default 0x08108300 if DEBUG_DAVINCI_TNETV107X_UART1 | ||
936 | default 0x10009000 if DEBUG_REALVIEW_STD_PORT || DEBUG_CNS3XXX || \ | ||
937 | DEBUG_VEXPRESS_UART0_CA9 | ||
938 | default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT | ||
939 | default 0x10124000 if DEBUG_RK3X_UART0 | ||
940 | default 0x10126000 if DEBUG_RK3X_UART1 | ||
941 | default 0x101f1000 if ARCH_VERSATILE | ||
942 | default 0x101fb000 if DEBUG_NOMADIK_UART | ||
943 | default 0x16000000 if ARCH_INTEGRATOR | ||
944 | default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1 | ||
945 | default 0x20060000 if DEBUG_RK29_UART0 | ||
946 | default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 | ||
947 | default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 | ||
948 | default 0x20201000 if DEBUG_BCM2835 | ||
949 | default 0x40090000 if ARCH_LPC32XX | ||
950 | default 0x40100000 if DEBUG_PXA_UART1 | ||
951 | default 0x42000000 if ARCH_GEMINI | ||
952 | default 0x7c0003f8 if FOOTBRIDGE | ||
953 | default 0x80230000 if DEBUG_PICOXCELL_UART | ||
954 | default 0x80070000 if DEBUG_IMX23_UART | ||
955 | default 0x80074000 if DEBUG_IMX28_UART | ||
956 | default 0x808c0000 if ARCH_EP93XX | ||
957 | default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART | ||
958 | default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX | ||
959 | default 0xc0013000 if DEBUG_U300_UART | ||
960 | default 0xc8000000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN | ||
961 | default 0xc8000003 if ARCH_IXP4XX && CPU_BIG_ENDIAN | ||
962 | default 0xd0000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX | ||
963 | default 0xd0012000 if DEBUG_MVEBU_UART | ||
964 | default 0xd4017000 if DEBUG_MMP_UART2 | ||
965 | default 0xd4018000 if DEBUG_MMP_UART3 | ||
966 | default 0xe0000000 if ARCH_SPEAR13XX | ||
967 | default 0xf0000be0 if ARCH_EBSA110 | ||
968 | default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE | ||
969 | default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \ | ||
970 | ARCH_ORION5X | ||
971 | default 0xf8b00000 if DEBUG_HI3716_UART | ||
972 | default 0xfcb00000 if DEBUG_HI3620_UART | ||
973 | default 0xfe800000 if ARCH_IOP32X | ||
974 | default 0xffc02000 if DEBUG_SOCFPGA_UART | ||
975 | default 0xffd82340 if ARCH_IOP13XX | ||
976 | default 0xfff36000 if DEBUG_HIGHBANK_UART | ||
977 | default 0xfffff700 if ARCH_IOP33X | ||
978 | depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ | ||
979 | DEBUG_UART_8250 || DEBUG_UART_PL01X | ||
980 | |||
981 | config DEBUG_UART_VIRT | ||
982 | hex "Virtual base address of debug UART" | ||
983 | default 0xe0010fe0 if ARCH_RPC | ||
984 | default 0xf0000be0 if ARCH_EBSA110 | ||
985 | default 0xf0009000 if DEBUG_CNS3XXX | ||
986 | default 0xf01fb000 if DEBUG_NOMADIK_UART | ||
987 | default 0xf0201000 if DEBUG_BCM2835 | ||
988 | default 0xf11f1000 if ARCH_VERSATILE | ||
989 | default 0xf1600000 if ARCH_INTEGRATOR | ||
990 | default 0xf1c28000 if DEBUG_SUNXI_UART0 | ||
991 | default 0xf1c28400 if DEBUG_SUNXI_UART1 | ||
992 | default 0xf2100000 if DEBUG_PXA_UART1 | ||
993 | default 0xf4090000 if ARCH_LPC32XX | ||
994 | default 0xf4200000 if ARCH_GEMINI | ||
995 | default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9 | ||
996 | default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1 | ||
997 | default 0xfb009000 if DEBUG_REALVIEW_STD_PORT | ||
998 | default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT | ||
999 | default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX | ||
1000 | default 0xfd000000 if ARCH_SPEAR13XX | ||
1001 | default 0xfd012000 if ARCH_MV78XX0 | ||
1002 | default 0xfde12000 if ARCH_DOVE | ||
1003 | default 0xfe012000 if ARCH_ORION5X | ||
1004 | default 0xfe017000 if DEBUG_MMP_UART2 | ||
1005 | default 0xfe018000 if DEBUG_MMP_UART3 | ||
1006 | default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART | ||
1007 | default 0xfe230000 if DEBUG_PICOXCELL_UART | ||
1008 | default 0xfe800000 if ARCH_IOP32X | ||
1009 | default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HI3716_UART | ||
1010 | default 0xfeb24000 if DEBUG_RK3X_UART0 | ||
1011 | default 0xfeb26000 if DEBUG_RK3X_UART1 | ||
1012 | default 0xfeb30c00 if DEBUG_KEYSTONE_UART0 | ||
1013 | default 0xfeb31000 if DEBUG_KEYSTONE_UART1 | ||
1014 | default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE | ||
1015 | default 0xfed60000 if DEBUG_RK29_UART0 | ||
1016 | default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 | ||
1017 | default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 | ||
1018 | default 0xfec02000 if DEBUG_SOCFPGA_UART | ||
1019 | default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0 | ||
1020 | default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1 | ||
1021 | default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2 | ||
1022 | default 0xfed12000 if ARCH_KIRKWOOD | ||
1023 | default 0xfedc0000 if ARCH_EP93XX | ||
1024 | default 0xfee003f8 if FOOTBRIDGE | ||
1025 | default 0xfee08300 if DEBUG_DAVINCI_TNETV107X_UART1 | ||
1026 | default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART | ||
1027 | default 0xfef36000 if DEBUG_HIGHBANK_UART | ||
1028 | default 0xfee82340 if ARCH_IOP13XX | ||
1029 | default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN | ||
1030 | default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN | ||
1031 | default 0xfefff700 if ARCH_IOP33X | ||
1032 | default 0xff003000 if DEBUG_U300_UART | ||
1033 | default DEBUG_UART_PHYS if !MMU | ||
1034 | depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ | ||
1035 | DEBUG_UART_8250 || DEBUG_UART_PL01X | ||
1036 | |||
1037 | config DEBUG_UART_8250_SHIFT | ||
1038 | int "Register offset shift for the 8250 debug UART" | ||
1039 | depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 | ||
1040 | default 0 if FOOTBRIDGE || ARCH_IOP32X | ||
1041 | default 2 | ||
1042 | |||
1043 | config DEBUG_UART_8250_WORD | ||
1044 | bool "Use 32-bit accesses for 8250 UART" | ||
1045 | depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 | ||
1046 | depends on DEBUG_UART_8250_SHIFT >= 2 | ||
1047 | default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \ | ||
1048 | ARCH_KEYSTONE || \ | ||
1049 | DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ | ||
1050 | DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_DAVINCI_TNETV107X_UART1 | ||
1051 | |||
1052 | config DEBUG_UART_8250_FLOW_CONTROL | ||
1053 | bool "Enable flow control for 8250 UART" | ||
1054 | depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 | ||
1055 | default y if ARCH_EBSA110 || FOOTBRIDGE || ARCH_GEMINI || ARCH_RPC | ||
1056 | |||
805 | config DEBUG_UNCOMPRESS | 1057 | config DEBUG_UNCOMPRESS |
806 | bool | 1058 | bool |
807 | depends on ARCH_MULTIPLATFORM | 1059 | depends on ARCH_MULTIPLATFORM |
808 | default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \ | 1060 | default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \ |
809 | !DEBUG_TEGRA_UART | 1061 | (!DEBUG_TEGRA_UART || !ZBOOT_ROM) |
810 | help | 1062 | help |
811 | This option influences the normal decompressor output for | 1063 | This option influences the normal decompressor output for |
812 | multiplatform kernels. Normally, multiplatform kernels disable | 1064 | multiplatform kernels. Normally, multiplatform kernels disable |
diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts index 444b4ede0d60..d318987d44a1 100644 --- a/arch/arm/boot/dts/am335x-bone.dts +++ b/arch/arm/boot/dts/am335x-bone.dts | |||
@@ -120,6 +120,35 @@ | |||
120 | status = "okay"; | 120 | status = "okay"; |
121 | }; | 121 | }; |
122 | 122 | ||
123 | musb: usb@47400000 { | ||
124 | status = "okay"; | ||
125 | |||
126 | control@44e10000 { | ||
127 | status = "okay"; | ||
128 | }; | ||
129 | |||
130 | usb-phy@47401300 { | ||
131 | status = "okay"; | ||
132 | }; | ||
133 | |||
134 | usb-phy@47401b00 { | ||
135 | status = "okay"; | ||
136 | }; | ||
137 | |||
138 | usb@47401000 { | ||
139 | status = "okay"; | ||
140 | }; | ||
141 | |||
142 | usb@47401800 { | ||
143 | status = "okay"; | ||
144 | dr_mode = "host"; | ||
145 | }; | ||
146 | |||
147 | dma-controller@07402000 { | ||
148 | status = "okay"; | ||
149 | }; | ||
150 | }; | ||
151 | |||
123 | i2c0: i2c@44e0b000 { | 152 | i2c0: i2c@44e0b000 { |
124 | pinctrl-names = "default"; | 153 | pinctrl-names = "default"; |
125 | pinctrl-0 = <&i2c0_pins>; | 154 | pinctrl-0 = <&i2c0_pins>; |
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 3aee1a43782d..e8ec8756e498 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts | |||
@@ -171,6 +171,35 @@ | |||
171 | }; | 171 | }; |
172 | }; | 172 | }; |
173 | 173 | ||
174 | musb: usb@47400000 { | ||
175 | status = "okay"; | ||
176 | |||
177 | control@44e10000 { | ||
178 | status = "okay"; | ||
179 | }; | ||
180 | |||
181 | usb-phy@47401300 { | ||
182 | status = "okay"; | ||
183 | }; | ||
184 | |||
185 | usb-phy@47401b00 { | ||
186 | status = "okay"; | ||
187 | }; | ||
188 | |||
189 | usb@47401000 { | ||
190 | status = "okay"; | ||
191 | }; | ||
192 | |||
193 | usb@47401800 { | ||
194 | status = "okay"; | ||
195 | dr_mode = "host"; | ||
196 | }; | ||
197 | |||
198 | dma-controller@07402000 { | ||
199 | status = "okay"; | ||
200 | }; | ||
201 | }; | ||
202 | |||
174 | i2c1: i2c@4802a000 { | 203 | i2c1: i2c@4802a000 { |
175 | pinctrl-names = "default"; | 204 | pinctrl-names = "default"; |
176 | pinctrl-0 = <&i2c1_pins>; | 205 | pinctrl-0 = <&i2c1_pins>; |
diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index 0c8ad173d2b0..4f339fa91c57 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts | |||
@@ -14,6 +14,7 @@ | |||
14 | /dts-v1/; | 14 | /dts-v1/; |
15 | 15 | ||
16 | #include "am33xx.dtsi" | 16 | #include "am33xx.dtsi" |
17 | #include <dt-bindings/pwm/pwm.h> | ||
17 | 18 | ||
18 | / { | 19 | / { |
19 | model = "TI AM335x EVM-SK"; | 20 | model = "TI AM335x EVM-SK"; |
@@ -207,6 +208,22 @@ | |||
207 | }; | 208 | }; |
208 | }; | 209 | }; |
209 | 210 | ||
211 | musb: usb@47400000 { | ||
212 | status = "okay"; | ||
213 | |||
214 | control@44e10000 { | ||
215 | status = "okay"; | ||
216 | }; | ||
217 | |||
218 | usb-phy@47401300 { | ||
219 | status = "okay"; | ||
220 | }; | ||
221 | |||
222 | usb@47401000 { | ||
223 | status = "okay"; | ||
224 | }; | ||
225 | }; | ||
226 | |||
210 | epwmss2: epwmss@48304000 { | 227 | epwmss2: epwmss@48304000 { |
211 | status = "okay"; | 228 | status = "okay"; |
212 | 229 | ||
@@ -298,7 +315,7 @@ | |||
298 | 315 | ||
299 | backlight { | 316 | backlight { |
300 | compatible = "pwm-backlight"; | 317 | compatible = "pwm-backlight"; |
301 | pwms = <&ecap2 0 50000 1>; | 318 | pwms = <&ecap2 0 50000 PWM_POLARITY_INVERTED>; |
302 | brightness-levels = <0 58 61 66 75 90 125 170 255>; | 319 | brightness-levels = <0 58 61 66 75 90 125 170 255>; |
303 | default-brightness-level = <8>; | 320 | default-brightness-level = <8>; |
304 | }; | 321 | }; |
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 38b446ba1ce1..f9c5da9c7fe1 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi | |||
@@ -26,6 +26,10 @@ | |||
26 | serial5 = &uart5; | 26 | serial5 = &uart5; |
27 | d_can0 = &dcan0; | 27 | d_can0 = &dcan0; |
28 | d_can1 = &dcan1; | 28 | d_can1 = &dcan1; |
29 | usb0 = &usb0; | ||
30 | usb1 = &usb1; | ||
31 | phy0 = &usb0_phy; | ||
32 | phy1 = &usb1_phy; | ||
29 | }; | 33 | }; |
30 | 34 | ||
31 | cpus { | 35 | cpus { |
@@ -333,21 +337,132 @@ | |||
333 | status = "disabled"; | 337 | status = "disabled"; |
334 | }; | 338 | }; |
335 | 339 | ||
336 | usb@47400000 { | 340 | usb: usb@47400000 { |
337 | compatible = "ti,musb-am33xx"; | 341 | compatible = "ti,am33xx-usb"; |
338 | reg = <0x47400000 0x1000 /* usbss */ | 342 | reg = <0x47400000 0x1000>; |
339 | 0x47401000 0x800 /* musb instance 0 */ | 343 | ranges; |
340 | 0x47401800 0x800>; /* musb instance 1 */ | 344 | #address-cells = <1>; |
341 | interrupts = <17 /* usbss */ | 345 | #size-cells = <1>; |
342 | 18 /* musb instance 0 */ | ||
343 | 19>; /* musb instance 1 */ | ||
344 | multipoint = <1>; | ||
345 | num-eps = <16>; | ||
346 | ram-bits = <12>; | ||
347 | port0-mode = <3>; | ||
348 | port1-mode = <3>; | ||
349 | power = <250>; | ||
350 | ti,hwmods = "usb_otg_hs"; | 346 | ti,hwmods = "usb_otg_hs"; |
347 | status = "disabled"; | ||
348 | |||
349 | ctrl_mod: control@44e10000 { | ||
350 | compatible = "ti,am335x-usb-ctrl-module"; | ||
351 | reg = <0x44e10620 0x10 | ||
352 | 0x44e10648 0x4>; | ||
353 | reg-names = "phy_ctrl", "wakeup"; | ||
354 | status = "disabled"; | ||
355 | }; | ||
356 | |||
357 | usb0_phy: usb-phy@47401300 { | ||
358 | compatible = "ti,am335x-usb-phy"; | ||
359 | reg = <0x47401300 0x100>; | ||
360 | reg-names = "phy"; | ||
361 | status = "disabled"; | ||
362 | ti,ctrl_mod = <&ctrl_mod>; | ||
363 | }; | ||
364 | |||
365 | usb0: usb@47401000 { | ||
366 | compatible = "ti,musb-am33xx"; | ||
367 | status = "disabled"; | ||
368 | reg = <0x47401400 0x400 | ||
369 | 0x47401000 0x200>; | ||
370 | reg-names = "mc", "control"; | ||
371 | |||
372 | interrupts = <18>; | ||
373 | interrupt-names = "mc"; | ||
374 | dr_mode = "otg"; | ||
375 | mentor,multipoint = <1>; | ||
376 | mentor,num-eps = <16>; | ||
377 | mentor,ram-bits = <12>; | ||
378 | mentor,power = <500>; | ||
379 | phys = <&usb0_phy>; | ||
380 | |||
381 | dmas = <&cppi41dma 0 0 &cppi41dma 1 0 | ||
382 | &cppi41dma 2 0 &cppi41dma 3 0 | ||
383 | &cppi41dma 4 0 &cppi41dma 5 0 | ||
384 | &cppi41dma 6 0 &cppi41dma 7 0 | ||
385 | &cppi41dma 8 0 &cppi41dma 9 0 | ||
386 | &cppi41dma 10 0 &cppi41dma 11 0 | ||
387 | &cppi41dma 12 0 &cppi41dma 13 0 | ||
388 | &cppi41dma 14 0 &cppi41dma 0 1 | ||
389 | &cppi41dma 1 1 &cppi41dma 2 1 | ||
390 | &cppi41dma 3 1 &cppi41dma 4 1 | ||
391 | &cppi41dma 5 1 &cppi41dma 6 1 | ||
392 | &cppi41dma 7 1 &cppi41dma 8 1 | ||
393 | &cppi41dma 9 1 &cppi41dma 10 1 | ||
394 | &cppi41dma 11 1 &cppi41dma 12 1 | ||
395 | &cppi41dma 13 1 &cppi41dma 14 1>; | ||
396 | dma-names = | ||
397 | "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7", | ||
398 | "rx8", "rx9", "rx10", "rx11", "rx12", "rx13", | ||
399 | "rx14", "rx15", | ||
400 | "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7", | ||
401 | "tx8", "tx9", "tx10", "tx11", "tx12", "tx13", | ||
402 | "tx14", "tx15"; | ||
403 | }; | ||
404 | |||
405 | usb1_phy: usb-phy@47401b00 { | ||
406 | compatible = "ti,am335x-usb-phy"; | ||
407 | reg = <0x47401b00 0x100>; | ||
408 | reg-names = "phy"; | ||
409 | status = "disabled"; | ||
410 | ti,ctrl_mod = <&ctrl_mod>; | ||
411 | }; | ||
412 | |||
413 | usb1: usb@47401800 { | ||
414 | compatible = "ti,musb-am33xx"; | ||
415 | status = "disabled"; | ||
416 | reg = <0x47401c00 0x400 | ||
417 | 0x47401800 0x200>; | ||
418 | reg-names = "mc", "control"; | ||
419 | interrupts = <19>; | ||
420 | interrupt-names = "mc"; | ||
421 | dr_mode = "otg"; | ||
422 | mentor,multipoint = <1>; | ||
423 | mentor,num-eps = <16>; | ||
424 | mentor,ram-bits = <12>; | ||
425 | mentor,power = <500>; | ||
426 | phys = <&usb1_phy>; | ||
427 | |||
428 | dmas = <&cppi41dma 15 0 &cppi41dma 16 0 | ||
429 | &cppi41dma 17 0 &cppi41dma 18 0 | ||
430 | &cppi41dma 19 0 &cppi41dma 20 0 | ||
431 | &cppi41dma 21 0 &cppi41dma 22 0 | ||
432 | &cppi41dma 23 0 &cppi41dma 24 0 | ||
433 | &cppi41dma 25 0 &cppi41dma 26 0 | ||
434 | &cppi41dma 27 0 &cppi41dma 28 0 | ||
435 | &cppi41dma 29 0 &cppi41dma 15 1 | ||
436 | &cppi41dma 16 1 &cppi41dma 17 1 | ||
437 | &cppi41dma 18 1 &cppi41dma 19 1 | ||
438 | &cppi41dma 20 1 &cppi41dma 21 1 | ||
439 | &cppi41dma 22 1 &cppi41dma 23 1 | ||
440 | &cppi41dma 24 1 &cppi41dma 25 1 | ||
441 | &cppi41dma 26 1 &cppi41dma 27 1 | ||
442 | &cppi41dma 28 1 &cppi41dma 29 1>; | ||
443 | dma-names = | ||
444 | "rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7", | ||
445 | "rx8", "rx9", "rx10", "rx11", "rx12", "rx13", | ||
446 | "rx14", "rx15", | ||
447 | "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7", | ||
448 | "tx8", "tx9", "tx10", "tx11", "tx12", "tx13", | ||
449 | "tx14", "tx15"; | ||
450 | }; | ||
451 | |||
452 | cppi41dma: dma-controller@07402000 { | ||
453 | compatible = "ti,am3359-cppi41"; | ||
454 | reg = <0x47400000 0x1000 | ||
455 | 0x47402000 0x1000 | ||
456 | 0x47403000 0x1000 | ||
457 | 0x47404000 0x4000>; | ||
458 | reg-names = "glue", "controller", "scheduler", "queuemgr"; | ||
459 | interrupts = <17>; | ||
460 | interrupt-names = "glue"; | ||
461 | #dma-cells = <2>; | ||
462 | #dma-channels = <30>; | ||
463 | #dma-requests = <256>; | ||
464 | status = "disabled"; | ||
465 | }; | ||
351 | }; | 466 | }; |
352 | 467 | ||
353 | epwmss0: epwmss@48300000 { | 468 | epwmss0: epwmss@48300000 { |
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index d59b70c6a6a0..3d77dbe406f4 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts | |||
@@ -14,11 +14,11 @@ | |||
14 | compatible = "atmel,at91sam9n12ek", "atmel,at91sam9n12", "atmel,at91sam9"; | 14 | compatible = "atmel,at91sam9n12ek", "atmel,at91sam9n12", "atmel,at91sam9"; |
15 | 15 | ||
16 | chosen { | 16 | chosen { |
17 | bootargs = "mem=128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2"; | 17 | bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2"; |
18 | }; | 18 | }; |
19 | 19 | ||
20 | memory { | 20 | memory { |
21 | reg = <0x20000000 0x10000000>; | 21 | reg = <0x20000000 0x8000000>; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | clocks { | 24 | clocks { |
diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi index b753855b2058..49e3c45818c2 100644 --- a/arch/arm/boot/dts/at91sam9x5ek.dtsi +++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi | |||
@@ -94,8 +94,9 @@ | |||
94 | 94 | ||
95 | usb0: ohci@00600000 { | 95 | usb0: ohci@00600000 { |
96 | status = "okay"; | 96 | status = "okay"; |
97 | num-ports = <2>; | 97 | num-ports = <3>; |
98 | atmel,vbus-gpio = <&pioD 19 GPIO_ACTIVE_LOW | 98 | atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW *//* Activate to have access to port A */ |
99 | &pioD 19 GPIO_ACTIVE_LOW | ||
99 | &pioD 20 GPIO_ACTIVE_LOW | 100 | &pioD 20 GPIO_ACTIVE_LOW |
100 | >; | 101 | >; |
101 | }; | 102 | }; |
diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index a0f2721ea583..8678e0c11119 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi | |||
@@ -329,6 +329,12 @@ | |||
329 | sirf,function = "uart0"; | 329 | sirf,function = "uart0"; |
330 | }; | 330 | }; |
331 | }; | 331 | }; |
332 | uart0_noflow_pins_a: uart0@1 { | ||
333 | uart { | ||
334 | sirf,pins = "uart0_nostreamctrlgrp"; | ||
335 | sirf,function = "uart0_nostreamctrl"; | ||
336 | }; | ||
337 | }; | ||
332 | uart1_pins_a: uart1@0 { | 338 | uart1_pins_a: uart1@0 { |
333 | uart { | 339 | uart { |
334 | sirf,pins = "uart1grp"; | 340 | sirf,pins = "uart1grp"; |
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index ef57277fc38f..376090f07231 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi | |||
@@ -405,7 +405,7 @@ | |||
405 | }; | 405 | }; |
406 | 406 | ||
407 | i2s0: i2s@03830000 { | 407 | i2s0: i2s@03830000 { |
408 | compatible = "samsung,i2s-v5"; | 408 | compatible = "samsung,s5pv210-i2s"; |
409 | reg = <0x03830000 0x100>; | 409 | reg = <0x03830000 0x100>; |
410 | dmas = <&pdma0 10 | 410 | dmas = <&pdma0 10 |
411 | &pdma0 9 | 411 | &pdma0 9 |
@@ -415,16 +415,13 @@ | |||
415 | <&clock_audss EXYNOS_I2S_BUS>, | 415 | <&clock_audss EXYNOS_I2S_BUS>, |
416 | <&clock_audss EXYNOS_SCLK_I2S>; | 416 | <&clock_audss EXYNOS_SCLK_I2S>; |
417 | clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; | 417 | clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; |
418 | samsung,supports-6ch; | ||
419 | samsung,supports-rstclr; | ||
420 | samsung,supports-secdai; | ||
421 | samsung,idma-addr = <0x03000000>; | 418 | samsung,idma-addr = <0x03000000>; |
422 | pinctrl-names = "default"; | 419 | pinctrl-names = "default"; |
423 | pinctrl-0 = <&i2s0_bus>; | 420 | pinctrl-0 = <&i2s0_bus>; |
424 | }; | 421 | }; |
425 | 422 | ||
426 | i2s1: i2s@12D60000 { | 423 | i2s1: i2s@12D60000 { |
427 | compatible = "samsung,i2s-v5"; | 424 | compatible = "samsung,s3c6410-i2s"; |
428 | reg = <0x12D60000 0x100>; | 425 | reg = <0x12D60000 0x100>; |
429 | dmas = <&pdma1 12 | 426 | dmas = <&pdma1 12 |
430 | &pdma1 11>; | 427 | &pdma1 11>; |
@@ -436,7 +433,7 @@ | |||
436 | }; | 433 | }; |
437 | 434 | ||
438 | i2s2: i2s@12D70000 { | 435 | i2s2: i2s@12D70000 { |
439 | compatible = "samsung,i2s-v5"; | 436 | compatible = "samsung,s3c6410-i2s"; |
440 | reg = <0x12D70000 0x100>; | 437 | reg = <0x12D70000 0x100>; |
441 | dmas = <&pdma0 12 | 438 | dmas = <&pdma0 12 |
442 | &pdma0 11>; | 439 | &pdma0 11>; |
diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi index ff7f5d855845..586134e2a382 100644 --- a/arch/arm/boot/dts/exynos5440.dtsi +++ b/arch/arm/boot/dts/exynos5440.dtsi | |||
@@ -248,6 +248,7 @@ | |||
248 | #interrupt-cells = <1>; | 248 | #interrupt-cells = <1>; |
249 | interrupt-map-mask = <0 0 0 0>; | 249 | interrupt-map-mask = <0 0 0 0>; |
250 | interrupt-map = <0x0 0 &gic 53>; | 250 | interrupt-map = <0x0 0 &gic 53>; |
251 | num-lanes = <4>; | ||
251 | }; | 252 | }; |
252 | 253 | ||
253 | pcie@2a0000 { | 254 | pcie@2a0000 { |
@@ -267,5 +268,6 @@ | |||
267 | #interrupt-cells = <1>; | 268 | #interrupt-cells = <1>; |
268 | interrupt-map-mask = <0 0 0 0>; | 269 | interrupt-map-mask = <0 0 0 0>; |
269 | interrupt-map = <0x0 0 &gic 56>; | 270 | interrupt-map = <0x0 0 &gic 56>; |
271 | num-lanes = <4>; | ||
270 | }; | 272 | }; |
271 | }; | 273 | }; |
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts index e035f4664b97..15715d921d14 100644 --- a/arch/arm/boot/dts/imx28-evk.dts +++ b/arch/arm/boot/dts/imx28-evk.dts | |||
@@ -220,6 +220,7 @@ | |||
220 | auart0: serial@8006a000 { | 220 | auart0: serial@8006a000 { |
221 | pinctrl-names = "default"; | 221 | pinctrl-names = "default"; |
222 | pinctrl-0 = <&auart0_pins_a>; | 222 | pinctrl-0 = <&auart0_pins_a>; |
223 | fsl,uart-has-rtscts; | ||
223 | status = "okay"; | 224 | status = "okay"; |
224 | }; | 225 | }; |
225 | 226 | ||
diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts index cdc010e0f93e..386d42870215 100644 --- a/arch/arm/boot/dts/msm8660-surf.dts +++ b/arch/arm/boot/dts/msm8660-surf.dts | |||
@@ -38,7 +38,7 @@ | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | serial@19c40000 { | 40 | serial@19c40000 { |
41 | compatible = "qcom,msm-hsuart", "qcom,msm-uart"; | 41 | compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; |
42 | reg = <0x19c40000 0x1000>, | 42 | reg = <0x19c40000 0x1000>, |
43 | <0x19c00000 0x1000>; | 43 | <0x19c00000 0x1000>; |
44 | interrupts = <0 195 0x0>; | 44 | interrupts = <0 195 0x0>; |
diff --git a/arch/arm/boot/dts/msm8960-cdp.dts b/arch/arm/boot/dts/msm8960-cdp.dts index 9c1167b0459b..93e9f7e0b7ad 100644 --- a/arch/arm/boot/dts/msm8960-cdp.dts +++ b/arch/arm/boot/dts/msm8960-cdp.dts | |||
@@ -38,7 +38,7 @@ | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | serial@16440000 { | 40 | serial@16440000 { |
41 | compatible = "qcom,msm-hsuart", "qcom,msm-uart"; | 41 | compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; |
42 | reg = <0x16440000 0x1000>, | 42 | reg = <0x16440000 0x1000>, |
43 | <0x16400000 0x1000>; | 43 | <0x16400000 0x1000>; |
44 | interrupts = <0 154 0x0>; | 44 | interrupts = <0 154 0x0>; |
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index e643620417a9..07be2cd7b318 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi | |||
@@ -644,7 +644,7 @@ | |||
644 | utmi-mode = <2>; | 644 | utmi-mode = <2>; |
645 | ranges; | 645 | ranges; |
646 | dwc3@4a030000 { | 646 | dwc3@4a030000 { |
647 | compatible = "synopsys,dwc3"; | 647 | compatible = "snps,dwc3"; |
648 | reg = <0x4a030000 0x1000>; | 648 | reg = <0x4a030000 0x1000>; |
649 | interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; | 649 | interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; |
650 | usb-phy = <&usb2_phy>, <&usb3_phy>; | 650 | usb-phy = <&usb2_phy>, <&usb3_phy>; |
diff --git a/arch/arm/boot/dts/sama5d3xmb.dtsi b/arch/arm/boot/dts/sama5d3xmb.dtsi index 8a9e05d8a4b8..dba739b6ef36 100644 --- a/arch/arm/boot/dts/sama5d3xmb.dtsi +++ b/arch/arm/boot/dts/sama5d3xmb.dtsi | |||
@@ -81,6 +81,14 @@ | |||
81 | 81 | ||
82 | macb1: ethernet@f802c000 { | 82 | macb1: ethernet@f802c000 { |
83 | phy-mode = "rmii"; | 83 | phy-mode = "rmii"; |
84 | |||
85 | #address-cells = <1>; | ||
86 | #size-cells = <0>; | ||
87 | phy0: ethernet-phy@1 { | ||
88 | interrupt-parent = <&pioE>; | ||
89 | interrupts = <30 IRQ_TYPE_EDGE_FALLING>; | ||
90 | reg = <1>; | ||
91 | }; | ||
84 | }; | 92 | }; |
85 | 93 | ||
86 | pinctrl@fffff200 { | 94 | pinctrl@fffff200 { |
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts index 365760b33a26..c8242533268f 100644 --- a/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/arch/arm/boot/dts/tegra20-seaboard.dts | |||
@@ -566,7 +566,6 @@ | |||
566 | 566 | ||
567 | usb@c5000000 { | 567 | usb@c5000000 { |
568 | status = "okay"; | 568 | status = "okay"; |
569 | nvidia,vbus-gpio = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>; | ||
570 | dr_mode = "otg"; | 569 | dr_mode = "otg"; |
571 | }; | 570 | }; |
572 | 571 | ||
@@ -830,6 +829,8 @@ | |||
830 | regulator-max-microvolt = <5000000>; | 829 | regulator-max-microvolt = <5000000>; |
831 | enable-active-high; | 830 | enable-active-high; |
832 | gpio = <&gpio 24 0>; /* PD0 */ | 831 | gpio = <&gpio 24 0>; /* PD0 */ |
832 | regulator-always-on; | ||
833 | regulator-boot-on; | ||
833 | }; | 834 | }; |
834 | }; | 835 | }; |
835 | 836 | ||
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts index ed4b901b0227..1e9d33adb925 100644 --- a/arch/arm/boot/dts/tegra20-trimslice.dts +++ b/arch/arm/boot/dts/tegra20-trimslice.dts | |||
@@ -312,7 +312,6 @@ | |||
312 | 312 | ||
313 | usb@c5000000 { | 313 | usb@c5000000 { |
314 | status = "okay"; | 314 | status = "okay"; |
315 | nvidia,vbus-gpio = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>; | ||
316 | }; | 315 | }; |
317 | 316 | ||
318 | usb-phy@c5000000 { | 317 | usb-phy@c5000000 { |
@@ -412,6 +411,8 @@ | |||
412 | regulator-max-microvolt = <5000000>; | 411 | regulator-max-microvolt = <5000000>; |
413 | enable-active-high; | 412 | enable-active-high; |
414 | gpio = <&gpio 170 0>; /* PV2 */ | 413 | gpio = <&gpio 170 0>; /* PV2 */ |
414 | regulator-always-on; | ||
415 | regulator-boot-on; | ||
415 | }; | 416 | }; |
416 | }; | 417 | }; |
417 | 418 | ||
diff --git a/arch/arm/boot/dts/tegra20-whistler.dts b/arch/arm/boot/dts/tegra20-whistler.dts index ab67c94db280..c703197dca6e 100644 --- a/arch/arm/boot/dts/tegra20-whistler.dts +++ b/arch/arm/boot/dts/tegra20-whistler.dts | |||
@@ -509,7 +509,6 @@ | |||
509 | 509 | ||
510 | usb@c5000000 { | 510 | usb@c5000000 { |
511 | status = "okay"; | 511 | status = "okay"; |
512 | nvidia,vbus-gpio = <&tca6416 0 GPIO_ACTIVE_HIGH>; | ||
513 | }; | 512 | }; |
514 | 513 | ||
515 | usb-phy@c5000000 { | 514 | usb-phy@c5000000 { |
@@ -519,7 +518,6 @@ | |||
519 | 518 | ||
520 | usb@c5008000 { | 519 | usb@c5008000 { |
521 | status = "okay"; | 520 | status = "okay"; |
522 | nvidia,vbus-gpio = <&tca6416 1 GPIO_ACTIVE_HIGH>; | ||
523 | }; | 521 | }; |
524 | 522 | ||
525 | usb-phy@c5008000 { | 523 | usb-phy@c5008000 { |
@@ -588,6 +586,8 @@ | |||
588 | regulator-max-microvolt = <5000000>; | 586 | regulator-max-microvolt = <5000000>; |
589 | enable-active-high; | 587 | enable-active-high; |
590 | gpio = <&tca6416 0 0>; /* GPIO_PMU0 */ | 588 | gpio = <&tca6416 0 0>; /* GPIO_PMU0 */ |
589 | regulator-always-on; | ||
590 | regulator-boot-on; | ||
591 | }; | 591 | }; |
592 | 592 | ||
593 | vbus3_reg: regulator@3 { | 593 | vbus3_reg: regulator@3 { |
@@ -598,6 +598,8 @@ | |||
598 | regulator-max-microvolt = <5000000>; | 598 | regulator-max-microvolt = <5000000>; |
599 | enable-active-high; | 599 | enable-active-high; |
600 | gpio = <&tca6416 1 0>; /* GPIO_PMU1 */ | 600 | gpio = <&tca6416 1 0>; /* GPIO_PMU1 */ |
601 | regulator-always-on; | ||
602 | regulator-boot-on; | ||
601 | }; | 603 | }; |
602 | }; | 604 | }; |
603 | 605 | ||
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 9653fd8288d2..e4570834512e 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi | |||
@@ -477,13 +477,13 @@ | |||
477 | <&tegra_car TEGRA20_CLK_USBD>; | 477 | <&tegra_car TEGRA20_CLK_USBD>; |
478 | clock-names = "reg", "pll_u", "timer", "utmi-pads"; | 478 | clock-names = "reg", "pll_u", "timer", "utmi-pads"; |
479 | nvidia,has-legacy-mode; | 479 | nvidia,has-legacy-mode; |
480 | hssync_start_delay = <9>; | 480 | nvidia,hssync-start-delay = <9>; |
481 | idle_wait_delay = <17>; | 481 | nvidia,idle-wait-delay = <17>; |
482 | elastic_limit = <16>; | 482 | nvidia,elastic-limit = <16>; |
483 | term_range_adj = <6>; | 483 | nvidia,term-range-adj = <6>; |
484 | xcvr_setup = <9>; | 484 | nvidia,xcvr-setup = <9>; |
485 | xcvr_lsfslew = <1>; | 485 | nvidia,xcvr-lsfslew = <1>; |
486 | xcvr_lsrslew = <1>; | 486 | nvidia,xcvr-lsrslew = <1>; |
487 | status = "disabled"; | 487 | status = "disabled"; |
488 | }; | 488 | }; |
489 | 489 | ||
@@ -527,13 +527,13 @@ | |||
527 | <&tegra_car TEGRA20_CLK_CLK_M>, | 527 | <&tegra_car TEGRA20_CLK_CLK_M>, |
528 | <&tegra_car TEGRA20_CLK_USBD>; | 528 | <&tegra_car TEGRA20_CLK_USBD>; |
529 | clock-names = "reg", "pll_u", "timer", "utmi-pads"; | 529 | clock-names = "reg", "pll_u", "timer", "utmi-pads"; |
530 | hssync_start_delay = <9>; | 530 | nvidia,hssync-start-delay = <9>; |
531 | idle_wait_delay = <17>; | 531 | nvidia,idle-wait-delay = <17>; |
532 | elastic_limit = <16>; | 532 | nvidia,elastic-limit = <16>; |
533 | term_range_adj = <6>; | 533 | nvidia,term-range-adj = <6>; |
534 | xcvr_setup = <9>; | 534 | nvidia,xcvr-setup = <9>; |
535 | xcvr_lsfslew = <2>; | 535 | nvidia,xcvr-lsfslew = <2>; |
536 | xcvr_lsrslew = <2>; | 536 | nvidia,xcvr-lsrslew = <2>; |
537 | status = "disabled"; | 537 | status = "disabled"; |
538 | }; | 538 | }; |
539 | 539 | ||
diff --git a/arch/arm/boot/dts/wm8850-w70v2.dts b/arch/arm/boot/dts/wm8850-w70v2.dts index 90e913fb64be..7a563d2523b0 100644 --- a/arch/arm/boot/dts/wm8850-w70v2.dts +++ b/arch/arm/boot/dts/wm8850-w70v2.dts | |||
@@ -11,13 +11,14 @@ | |||
11 | 11 | ||
12 | /dts-v1/; | 12 | /dts-v1/; |
13 | /include/ "wm8850.dtsi" | 13 | /include/ "wm8850.dtsi" |
14 | #include <dt-bindings/pwm/pwm.h> | ||
14 | 15 | ||
15 | / { | 16 | / { |
16 | model = "Wondermedia WM8850-W70v2 Tablet"; | 17 | model = "Wondermedia WM8850-W70v2 Tablet"; |
17 | 18 | ||
18 | backlight { | 19 | backlight { |
19 | compatible = "pwm-backlight"; | 20 | compatible = "pwm-backlight"; |
20 | pwms = <&pwm 0 50000 1>; /* duty inverted */ | 21 | pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>; |
21 | 22 | ||
22 | brightness-levels = <0 40 60 80 100 130 190 255>; | 23 | brightness-levels = <0 40 60 80 100 130 190 255>; |
23 | default-brightness-level = <5>; | 24 | default-brightness-level = <5>; |
diff --git a/arch/arm/common/mcpm_head.S b/arch/arm/common/mcpm_head.S index 80f033614a1f..39c96df3477a 100644 --- a/arch/arm/common/mcpm_head.S +++ b/arch/arm/common/mcpm_head.S | |||
@@ -151,7 +151,7 @@ mcpm_setup_leave: | |||
151 | 151 | ||
152 | mov r0, #INBOUND_NOT_COMING_UP | 152 | mov r0, #INBOUND_NOT_COMING_UP |
153 | strb r0, [r8, #MCPM_SYNC_CLUSTER_INBOUND] | 153 | strb r0, [r8, #MCPM_SYNC_CLUSTER_INBOUND] |
154 | dsb | 154 | dsb st |
155 | sev | 155 | sev |
156 | 156 | ||
157 | mov r0, r11 | 157 | mov r0, r11 |
diff --git a/arch/arm/common/vlock.S b/arch/arm/common/vlock.S index ff198583f683..8b7df283fedf 100644 --- a/arch/arm/common/vlock.S +++ b/arch/arm/common/vlock.S | |||
@@ -42,7 +42,7 @@ | |||
42 | dmb | 42 | dmb |
43 | mov \rscratch, #0 | 43 | mov \rscratch, #0 |
44 | strb \rscratch, [\rbase, \rcpu] | 44 | strb \rscratch, [\rbase, \rcpu] |
45 | dsb | 45 | dsb st |
46 | sev | 46 | sev |
47 | .endm | 47 | .endm |
48 | 48 | ||
@@ -102,7 +102,7 @@ ENTRY(vlock_unlock) | |||
102 | dmb | 102 | dmb |
103 | mov r1, #VLOCK_OWNER_NONE | 103 | mov r1, #VLOCK_OWNER_NONE |
104 | strb r1, [r0, #VLOCK_OWNER_OFFSET] | 104 | strb r1, [r0, #VLOCK_OWNER_OFFSET] |
105 | dsb | 105 | dsb st |
106 | sev | 106 | sev |
107 | bx lr | 107 | bx lr |
108 | ENDPROC(vlock_unlock) | 108 | ENDPROC(vlock_unlock) |
diff --git a/arch/arm/configs/bockw_defconfig b/arch/arm/configs/bockw_defconfig index 845f5cdf62b5..e7e94948d194 100644 --- a/arch/arm/configs/bockw_defconfig +++ b/arch/arm/configs/bockw_defconfig | |||
@@ -82,6 +82,13 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y | |||
82 | # CONFIG_HWMON is not set | 82 | # CONFIG_HWMON is not set |
83 | CONFIG_I2C=y | 83 | CONFIG_I2C=y |
84 | CONFIG_I2C_RCAR=y | 84 | CONFIG_I2C_RCAR=y |
85 | CONFIG_MEDIA_SUPPORT=y | ||
86 | CONFIG_MEDIA_CAMERA_SUPPORT=y | ||
87 | CONFIG_V4L_PLATFORM_DRIVERS=y | ||
88 | CONFIG_SOC_CAMERA=y | ||
89 | CONFIG_VIDEO_RCAR_VIN=y | ||
90 | # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set | ||
91 | CONFIG_VIDEO_ML86V7667=y | ||
85 | CONFIG_SPI=y | 92 | CONFIG_SPI=y |
86 | CONFIG_SPI_SH_HSPI=y | 93 | CONFIG_SPI_SH_HSPI=y |
87 | CONFIG_USB=y | 94 | CONFIG_USB=y |
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 62e968cac9dc..1f36b823905f 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig | |||
@@ -104,6 +104,7 @@ CONFIG_IP_SCTP=y | |||
104 | CONFIG_VLAN_8021Q=y | 104 | CONFIG_VLAN_8021Q=y |
105 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 105 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
106 | CONFIG_CMA=y | 106 | CONFIG_CMA=y |
107 | CONFIG_DMA_CMA=y | ||
107 | CONFIG_MTD=y | 108 | CONFIG_MTD=y |
108 | CONFIG_MTD_CMDLINE_PARTS=y | 109 | CONFIG_MTD_CMDLINE_PARTS=y |
109 | CONFIG_MTD_BLOCK=y | 110 | CONFIG_MTD_BLOCK=y |
diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig index 494e70aeb9e1..c50e52be4463 100644 --- a/arch/arm/configs/marzen_defconfig +++ b/arch/arm/configs/marzen_defconfig | |||
@@ -84,6 +84,13 @@ CONFIG_GPIO_RCAR=y | |||
84 | CONFIG_THERMAL=y | 84 | CONFIG_THERMAL=y |
85 | CONFIG_RCAR_THERMAL=y | 85 | CONFIG_RCAR_THERMAL=y |
86 | CONFIG_SSB=y | 86 | CONFIG_SSB=y |
87 | CONFIG_MEDIA_SUPPORT=y | ||
88 | CONFIG_MEDIA_CAMERA_SUPPORT=y | ||
89 | CONFIG_V4L_PLATFORM_DRIVERS=y | ||
90 | CONFIG_SOC_CAMERA=y | ||
91 | CONFIG_VIDEO_RCAR_VIN=y | ||
92 | # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set | ||
93 | CONFIG_VIDEO_ADV7180=y | ||
87 | CONFIG_USB=y | 94 | CONFIG_USB=y |
88 | CONFIG_USB_RCAR_PHY=y | 95 | CONFIG_USB_RCAR_PHY=y |
89 | CONFIG_MMC=y | 96 | CONFIG_MMC=y |
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 5339e6a4d639..056b27aafbe6 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig | |||
@@ -78,6 +78,7 @@ CONFIG_MAC80211_RC_PID=y | |||
78 | CONFIG_MAC80211_RC_DEFAULT_PID=y | 78 | CONFIG_MAC80211_RC_DEFAULT_PID=y |
79 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 79 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
80 | CONFIG_CMA=y | 80 | CONFIG_CMA=y |
81 | CONFIG_DMA_CMA=y | ||
81 | CONFIG_CONNECTOR=y | 82 | CONFIG_CONNECTOR=y |
82 | CONFIG_DEVTMPFS=y | 83 | CONFIG_DEVTMPFS=y |
83 | CONFIG_DEVTMPFS_MOUNT=y | 84 | CONFIG_DEVTMPFS_MOUNT=y |
@@ -185,13 +186,11 @@ CONFIG_OMAP2_DSS_RFBI=y | |||
185 | CONFIG_OMAP2_DSS_SDI=y | 186 | CONFIG_OMAP2_DSS_SDI=y |
186 | CONFIG_OMAP2_DSS_DSI=y | 187 | CONFIG_OMAP2_DSS_DSI=y |
187 | CONFIG_FB_OMAP2=m | 188 | CONFIG_FB_OMAP2=m |
188 | CONFIG_PANEL_GENERIC_DPI=m | 189 | CONFIG_DISPLAY_ENCODER_TFP410=m |
189 | CONFIG_PANEL_TFP410=m | 190 | CONFIG_DISPLAY_ENCODER_TPD12S015=m |
190 | CONFIG_PANEL_SHARP_LS037V7DW01=m | 191 | CONFIG_DISPLAY_CONNECTOR_DVI=m |
191 | CONFIG_PANEL_NEC_NL8048HL11_01B=m | 192 | CONFIG_DISPLAY_CONNECTOR_HDMI=m |
192 | CONFIG_PANEL_TAAL=m | 193 | CONFIG_DISPLAY_PANEL_DPI=m |
193 | CONFIG_PANEL_TPO_TD043MTEA1=m | ||
194 | CONFIG_PANEL_ACX565AKM=m | ||
195 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | 194 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
196 | CONFIG_LCD_CLASS_DEVICE=y | 195 | CONFIG_LCD_CLASS_DEVICE=y |
197 | CONFIG_LCD_PLATFORM=y | 196 | CONFIG_LCD_PLATFORM=y |
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index 1effb43dab80..92d0a149aeb5 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig | |||
@@ -79,6 +79,7 @@ CONFIG_DEVTMPFS=y | |||
79 | CONFIG_DEVTMPFS_MOUNT=y | 79 | CONFIG_DEVTMPFS_MOUNT=y |
80 | # CONFIG_FIRMWARE_IN_KERNEL is not set | 80 | # CONFIG_FIRMWARE_IN_KERNEL is not set |
81 | CONFIG_CMA=y | 81 | CONFIG_CMA=y |
82 | CONFIG_DMA_CMA=y | ||
82 | CONFIG_MTD=y | 83 | CONFIG_MTD=y |
83 | CONFIG_MTD_M25P80=y | 84 | CONFIG_MTD_M25P80=y |
84 | CONFIG_PROC_DEVICETREE=y | 85 | CONFIG_PROC_DEVICETREE=y |
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index e406d575c94f..5665134bfa3e 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h | |||
@@ -17,7 +17,8 @@ int arch_timer_arch_init(void); | |||
17 | * nicely work out which register we want, and chuck away the rest of | 17 | * nicely work out which register we want, and chuck away the rest of |
18 | * the code. At least it does so with a recent GCC (4.6.3). | 18 | * the code. At least it does so with a recent GCC (4.6.3). |
19 | */ | 19 | */ |
20 | static inline void arch_timer_reg_write(const int access, const int reg, u32 val) | 20 | static __always_inline |
21 | void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) | ||
21 | { | 22 | { |
22 | if (access == ARCH_TIMER_PHYS_ACCESS) { | 23 | if (access == ARCH_TIMER_PHYS_ACCESS) { |
23 | switch (reg) { | 24 | switch (reg) { |
@@ -28,9 +29,7 @@ static inline void arch_timer_reg_write(const int access, const int reg, u32 val | |||
28 | asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); | 29 | asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); |
29 | break; | 30 | break; |
30 | } | 31 | } |
31 | } | 32 | } else if (access == ARCH_TIMER_VIRT_ACCESS) { |
32 | |||
33 | if (access == ARCH_TIMER_VIRT_ACCESS) { | ||
34 | switch (reg) { | 33 | switch (reg) { |
35 | case ARCH_TIMER_REG_CTRL: | 34 | case ARCH_TIMER_REG_CTRL: |
36 | asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val)); | 35 | asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val)); |
@@ -44,7 +43,8 @@ static inline void arch_timer_reg_write(const int access, const int reg, u32 val | |||
44 | isb(); | 43 | isb(); |
45 | } | 44 | } |
46 | 45 | ||
47 | static inline u32 arch_timer_reg_read(const int access, const int reg) | 46 | static __always_inline |
47 | u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) | ||
48 | { | 48 | { |
49 | u32 val = 0; | 49 | u32 val = 0; |
50 | 50 | ||
@@ -57,9 +57,7 @@ static inline u32 arch_timer_reg_read(const int access, const int reg) | |||
57 | asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); | 57 | asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); |
58 | break; | 58 | break; |
59 | } | 59 | } |
60 | } | 60 | } else if (access == ARCH_TIMER_VIRT_ACCESS) { |
61 | |||
62 | if (access == ARCH_TIMER_VIRT_ACCESS) { | ||
63 | switch (reg) { | 61 | switch (reg) { |
64 | case ARCH_TIMER_REG_CTRL: | 62 | case ARCH_TIMER_REG_CTRL: |
65 | asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val)); | 63 | asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val)); |
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index a5fef710af32..fcc1b5bf6979 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -220,9 +220,9 @@ | |||
220 | #ifdef CONFIG_SMP | 220 | #ifdef CONFIG_SMP |
221 | #if __LINUX_ARM_ARCH__ >= 7 | 221 | #if __LINUX_ARM_ARCH__ >= 7 |
222 | .ifeqs "\mode","arm" | 222 | .ifeqs "\mode","arm" |
223 | ALT_SMP(dmb) | 223 | ALT_SMP(dmb ish) |
224 | .else | 224 | .else |
225 | ALT_SMP(W(dmb)) | 225 | ALT_SMP(W(dmb) ish) |
226 | .endif | 226 | .endif |
227 | #elif __LINUX_ARM_ARCH__ == 6 | 227 | #elif __LINUX_ARM_ARCH__ == 6 |
228 | ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb | 228 | ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb |
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h index 8dcd9c702d90..60f15e274e6d 100644 --- a/arch/arm/include/asm/barrier.h +++ b/arch/arm/include/asm/barrier.h | |||
@@ -14,27 +14,27 @@ | |||
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #if __LINUX_ARM_ARCH__ >= 7 | 16 | #if __LINUX_ARM_ARCH__ >= 7 |
17 | #define isb() __asm__ __volatile__ ("isb" : : : "memory") | 17 | #define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory") |
18 | #define dsb() __asm__ __volatile__ ("dsb" : : : "memory") | 18 | #define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory") |
19 | #define dmb() __asm__ __volatile__ ("dmb" : : : "memory") | 19 | #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory") |
20 | #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 | 20 | #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 |
21 | #define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ | 21 | #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ |
22 | : : "r" (0) : "memory") | 22 | : : "r" (0) : "memory") |
23 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | 23 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ |
24 | : : "r" (0) : "memory") | 24 | : : "r" (0) : "memory") |
25 | #define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ | 25 | #define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ |
26 | : : "r" (0) : "memory") | 26 | : : "r" (0) : "memory") |
27 | #elif defined(CONFIG_CPU_FA526) | 27 | #elif defined(CONFIG_CPU_FA526) |
28 | #define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ | 28 | #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ |
29 | : : "r" (0) : "memory") | 29 | : : "r" (0) : "memory") |
30 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | 30 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ |
31 | : : "r" (0) : "memory") | 31 | : : "r" (0) : "memory") |
32 | #define dmb() __asm__ __volatile__ ("" : : : "memory") | 32 | #define dmb(x) __asm__ __volatile__ ("" : : : "memory") |
33 | #else | 33 | #else |
34 | #define isb() __asm__ __volatile__ ("" : : : "memory") | 34 | #define isb(x) __asm__ __volatile__ ("" : : : "memory") |
35 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | 35 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ |
36 | : : "r" (0) : "memory") | 36 | : : "r" (0) : "memory") |
37 | #define dmb() __asm__ __volatile__ ("" : : : "memory") | 37 | #define dmb(x) __asm__ __volatile__ ("" : : : "memory") |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifdef CONFIG_ARCH_HAS_BARRIERS | 40 | #ifdef CONFIG_ARCH_HAS_BARRIERS |
@@ -42,7 +42,7 @@ | |||
42 | #elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) | 42 | #elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) |
43 | #define mb() do { dsb(); outer_sync(); } while (0) | 43 | #define mb() do { dsb(); outer_sync(); } while (0) |
44 | #define rmb() dsb() | 44 | #define rmb() dsb() |
45 | #define wmb() mb() | 45 | #define wmb() do { dsb(st); outer_sync(); } while (0) |
46 | #else | 46 | #else |
47 | #define mb() barrier() | 47 | #define mb() barrier() |
48 | #define rmb() barrier() | 48 | #define rmb() barrier() |
@@ -54,9 +54,9 @@ | |||
54 | #define smp_rmb() barrier() | 54 | #define smp_rmb() barrier() |
55 | #define smp_wmb() barrier() | 55 | #define smp_wmb() barrier() |
56 | #else | 56 | #else |
57 | #define smp_mb() dmb() | 57 | #define smp_mb() dmb(ish) |
58 | #define smp_rmb() dmb() | 58 | #define smp_rmb() smp_mb() |
59 | #define smp_wmb() dmb() | 59 | #define smp_wmb() dmb(ishst) |
60 | #endif | 60 | #endif |
61 | 61 | ||
62 | #define read_barrier_depends() do { } while(0) | 62 | #define read_barrier_depends() do { } while(0) |
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 17d0ae8672fa..15f2d5bf8875 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -268,8 +268,7 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr | |||
268 | * Harvard caches are synchronised for the user space address range. | 268 | * Harvard caches are synchronised for the user space address range. |
269 | * This is used for the ARM private sys_cacheflush system call. | 269 | * This is used for the ARM private sys_cacheflush system call. |
270 | */ | 270 | */ |
271 | #define flush_cache_user_range(start,end) \ | 271 | #define flush_cache_user_range(s,e) __cpuc_coherent_user_range(s,e) |
272 | __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) | ||
273 | 272 | ||
274 | /* | 273 | /* |
275 | * Perform necessary cache operations to ensure that data previously | 274 | * Perform necessary cache operations to ensure that data previously |
@@ -352,7 +351,7 @@ static inline void flush_cache_vmap(unsigned long start, unsigned long end) | |||
352 | * set_pte_at() called from vmap_pte_range() does not | 351 | * set_pte_at() called from vmap_pte_range() does not |
353 | * have a DSB after cleaning the cache line. | 352 | * have a DSB after cleaning the cache line. |
354 | */ | 353 | */ |
355 | dsb(); | 354 | dsb(ishst); |
356 | } | 355 | } |
357 | 356 | ||
358 | static inline void flush_cache_vunmap(unsigned long start, unsigned long end) | 357 | static inline void flush_cache_vunmap(unsigned long start, unsigned long end) |
diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h index 3ed37b4d93da..e072bb2ba1b1 100644 --- a/arch/arm/include/asm/dma-contiguous.h +++ b/arch/arm/include/asm/dma-contiguous.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define ASMARM_DMA_CONTIGUOUS_H | 2 | #define ASMARM_DMA_CONTIGUOUS_H |
3 | 3 | ||
4 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | #ifdef CONFIG_CMA | 5 | #ifdef CONFIG_DMA_CMA |
6 | 6 | ||
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <asm-generic/dma-contiguous.h> | 8 | #include <asm-generic/dma-contiguous.h> |
diff --git a/arch/arm/include/asm/hardware/debug-8250.S b/arch/arm/include/asm/hardware/debug-8250.S deleted file mode 100644 index 22c689255e6e..000000000000 --- a/arch/arm/include/asm/hardware/debug-8250.S +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/include/asm/hardware/debug-8250.S | ||
3 | * | ||
4 | * Copyright (C) 1994-1999 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/serial_reg.h> | ||
11 | |||
12 | .macro senduart,rd,rx | ||
13 | strb \rd, [\rx, #UART_TX << UART_SHIFT] | ||
14 | .endm | ||
15 | |||
16 | .macro busyuart,rd,rx | ||
17 | 1002: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] | ||
18 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
19 | teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
20 | bne 1002b | ||
21 | .endm | ||
22 | |||
23 | .macro waituart,rd,rx | ||
24 | #ifdef FLOW_CONTROL | ||
25 | 1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] | ||
26 | tst \rd, #UART_MSR_CTS | ||
27 | beq 1001b | ||
28 | #endif | ||
29 | .endm | ||
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 472ac7091003..9b28c41f4ba9 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h | |||
@@ -64,7 +64,7 @@ void kvm_clear_hyp_idmap(void); | |||
64 | 64 | ||
65 | static inline void kvm_set_pte(pte_t *pte, pte_t new_pte) | 65 | static inline void kvm_set_pte(pte_t *pte, pte_t new_pte) |
66 | { | 66 | { |
67 | pte_val(*pte) = new_pte; | 67 | *pte = new_pte; |
68 | /* | 68 | /* |
69 | * flush_pmd_entry just takes a void pointer and cleans the necessary | 69 | * flush_pmd_entry just takes a void pointer and cleans the necessary |
70 | * cache entries, so we can reuse the function for ptes. | 70 | * cache entries, so we can reuse the function for ptes. |
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 441efc491b50..69b879ac0289 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h | |||
@@ -65,12 +65,12 @@ struct machine_desc { | |||
65 | /* | 65 | /* |
66 | * Current machine - only accessible during boot. | 66 | * Current machine - only accessible during boot. |
67 | */ | 67 | */ |
68 | extern struct machine_desc *machine_desc; | 68 | extern const struct machine_desc *machine_desc; |
69 | 69 | ||
70 | /* | 70 | /* |
71 | * Machine type table - also only accessible during boot | 71 | * Machine type table - also only accessible during boot |
72 | */ | 72 | */ |
73 | extern struct machine_desc __arch_info_begin[], __arch_info_end[]; | 73 | extern const struct machine_desc __arch_info_begin[], __arch_info_end[]; |
74 | #define for_each_machine_desc(p) \ | 74 | #define for_each_machine_desc(p) \ |
75 | for (p = __arch_info_begin; p < __arch_info_end; p++) | 75 | for (p = __arch_info_begin; p < __arch_info_end; p++) |
76 | 76 | ||
diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h index 00ca5f92648e..c2f5102ae659 100644 --- a/arch/arm/include/asm/memblock.h +++ b/arch/arm/include/asm/memblock.h | |||
@@ -4,8 +4,7 @@ | |||
4 | struct meminfo; | 4 | struct meminfo; |
5 | struct machine_desc; | 5 | struct machine_desc; |
6 | 6 | ||
7 | extern void arm_memblock_init(struct meminfo *, struct machine_desc *); | 7 | void arm_memblock_init(struct meminfo *, const struct machine_desc *); |
8 | |||
9 | phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align); | 8 | phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align); |
10 | 9 | ||
11 | #endif | 10 | #endif |
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h index 0d3a28dbc8e5..ed690c49ef93 100644 --- a/arch/arm/include/asm/module.h +++ b/arch/arm/include/asm/module.h | |||
@@ -12,6 +12,8 @@ enum { | |||
12 | ARM_SEC_CORE, | 12 | ARM_SEC_CORE, |
13 | ARM_SEC_EXIT, | 13 | ARM_SEC_EXIT, |
14 | ARM_SEC_DEVEXIT, | 14 | ARM_SEC_DEVEXIT, |
15 | ARM_SEC_HOT, | ||
16 | ARM_SEC_UNLIKELY, | ||
15 | ARM_SEC_MAX, | 17 | ARM_SEC_MAX, |
16 | }; | 18 | }; |
17 | 19 | ||
diff --git a/arch/arm/include/asm/neon.h b/arch/arm/include/asm/neon.h new file mode 100644 index 000000000000..8f730fe70093 --- /dev/null +++ b/arch/arm/include/asm/neon.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/include/asm/neon.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <asm/hwcap.h> | ||
12 | |||
13 | #define cpu_has_neon() (!!(elf_hwcap & HWCAP_NEON)) | ||
14 | |||
15 | #ifdef __ARM_NEON__ | ||
16 | |||
17 | /* | ||
18 | * If you are affected by the BUILD_BUG below, it probably means that you are | ||
19 | * using NEON code /and/ calling the kernel_neon_begin() function from the same | ||
20 | * compilation unit. To prevent issues that may arise from GCC reordering or | ||
21 | * generating(1) NEON instructions outside of these begin/end functions, the | ||
22 | * only supported way of using NEON code in the kernel is by isolating it in a | ||
23 | * separate compilation unit, and calling it from another unit from inside a | ||
24 | * kernel_neon_begin/kernel_neon_end pair. | ||
25 | * | ||
26 | * (1) Current GCC (4.7) might generate NEON instructions at O3 level if | ||
27 | * -mpfu=neon is set. | ||
28 | */ | ||
29 | |||
30 | #define kernel_neon_begin() \ | ||
31 | BUILD_BUG_ON_MSG(1, "kernel_neon_begin() called from NEON code") | ||
32 | |||
33 | #else | ||
34 | void kernel_neon_begin(void); | ||
35 | #endif | ||
36 | void kernel_neon_end(void); | ||
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 04aeb02d2e11..be956dbf6bae 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -100,7 +100,7 @@ extern pgprot_t pgprot_s2_device; | |||
100 | #define PAGE_HYP _MOD_PROT(pgprot_kernel, L_PTE_HYP) | 100 | #define PAGE_HYP _MOD_PROT(pgprot_kernel, L_PTE_HYP) |
101 | #define PAGE_HYP_DEVICE _MOD_PROT(pgprot_hyp_device, L_PTE_HYP) | 101 | #define PAGE_HYP_DEVICE _MOD_PROT(pgprot_hyp_device, L_PTE_HYP) |
102 | #define PAGE_S2 _MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY) | 102 | #define PAGE_S2 _MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY) |
103 | #define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_USER | L_PTE_S2_RDONLY) | 103 | #define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDWR) |
104 | 104 | ||
105 | #define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE) | 105 | #define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE) |
106 | #define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN) | 106 | #define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN) |
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index a219227c3e43..4a2985e21969 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h | |||
@@ -15,13 +15,13 @@ | |||
15 | 15 | ||
16 | #ifdef CONFIG_OF | 16 | #ifdef CONFIG_OF |
17 | 17 | ||
18 | extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); | 18 | extern const struct machine_desc *setup_machine_fdt(unsigned int dt_phys); |
19 | extern void arm_dt_memblock_reserve(void); | 19 | extern void arm_dt_memblock_reserve(void); |
20 | extern void __init arm_dt_init_cpu_maps(void); | 20 | extern void __init arm_dt_init_cpu_maps(void); |
21 | 21 | ||
22 | #else /* CONFIG_OF */ | 22 | #else /* CONFIG_OF */ |
23 | 23 | ||
24 | static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys) | 24 | static inline const struct machine_desc *setup_machine_fdt(unsigned int dt_phys) |
25 | { | 25 | { |
26 | return NULL; | 26 | return NULL; |
27 | } | 27 | } |
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index 6462a721ebd4..a252c0bfacf5 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h | |||
@@ -88,4 +88,7 @@ static inline u32 mpidr_hash_size(void) | |||
88 | { | 88 | { |
89 | return 1 << mpidr_hash.bits; | 89 | return 1 << mpidr_hash.bits; |
90 | } | 90 | } |
91 | |||
92 | extern int platform_can_cpu_hotplug(void); | ||
93 | |||
91 | #endif | 94 | #endif |
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index f8b8965666e9..4f2c28060c9a 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h | |||
@@ -46,7 +46,7 @@ static inline void dsb_sev(void) | |||
46 | { | 46 | { |
47 | #if __LINUX_ARM_ARCH__ >= 7 | 47 | #if __LINUX_ARM_ARCH__ >= 7 |
48 | __asm__ __volatile__ ( | 48 | __asm__ __volatile__ ( |
49 | "dsb\n" | 49 | "dsb ishst\n" |
50 | SEV | 50 | SEV |
51 | ); | 51 | ); |
52 | #else | 52 | #else |
@@ -107,7 +107,7 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) | |||
107 | " subs %1, %0, %0, ror #16\n" | 107 | " subs %1, %0, %0, ror #16\n" |
108 | " addeq %0, %0, %4\n" | 108 | " addeq %0, %0, %4\n" |
109 | " strexeq %2, %0, [%3]" | 109 | " strexeq %2, %0, [%3]" |
110 | : "=&r" (slock), "=&r" (contended), "=r" (res) | 110 | : "=&r" (slock), "=&r" (contended), "=&r" (res) |
111 | : "r" (&lock->slock), "I" (1 << TICKET_SHIFT) | 111 | : "r" (&lock->slock), "I" (1 << TICKET_SHIFT) |
112 | : "cc"); | 112 | : "cc"); |
113 | } while (res); | 113 | } while (res); |
@@ -168,17 +168,20 @@ static inline void arch_write_lock(arch_rwlock_t *rw) | |||
168 | 168 | ||
169 | static inline int arch_write_trylock(arch_rwlock_t *rw) | 169 | static inline int arch_write_trylock(arch_rwlock_t *rw) |
170 | { | 170 | { |
171 | unsigned long tmp; | 171 | unsigned long contended, res; |
172 | 172 | ||
173 | __asm__ __volatile__( | 173 | do { |
174 | " ldrex %0, [%1]\n" | 174 | __asm__ __volatile__( |
175 | " teq %0, #0\n" | 175 | " ldrex %0, [%2]\n" |
176 | " strexeq %0, %2, [%1]" | 176 | " mov %1, #0\n" |
177 | : "=&r" (tmp) | 177 | " teq %0, #0\n" |
178 | : "r" (&rw->lock), "r" (0x80000000) | 178 | " strexeq %1, %3, [%2]" |
179 | : "cc"); | 179 | : "=&r" (contended), "=&r" (res) |
180 | : "r" (&rw->lock), "r" (0x80000000) | ||
181 | : "cc"); | ||
182 | } while (res); | ||
180 | 183 | ||
181 | if (tmp == 0) { | 184 | if (!contended) { |
182 | smp_mb(); | 185 | smp_mb(); |
183 | return 1; | 186 | return 1; |
184 | } else { | 187 | } else { |
@@ -254,18 +257,26 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) | |||
254 | 257 | ||
255 | static inline int arch_read_trylock(arch_rwlock_t *rw) | 258 | static inline int arch_read_trylock(arch_rwlock_t *rw) |
256 | { | 259 | { |
257 | unsigned long tmp, tmp2 = 1; | 260 | unsigned long contended, res; |
258 | 261 | ||
259 | __asm__ __volatile__( | 262 | do { |
260 | " ldrex %0, [%2]\n" | 263 | __asm__ __volatile__( |
261 | " adds %0, %0, #1\n" | 264 | " ldrex %0, [%2]\n" |
262 | " strexpl %1, %0, [%2]\n" | 265 | " mov %1, #0\n" |
263 | : "=&r" (tmp), "+r" (tmp2) | 266 | " adds %0, %0, #1\n" |
264 | : "r" (&rw->lock) | 267 | " strexpl %1, %0, [%2]" |
265 | : "cc"); | 268 | : "=&r" (contended), "=&r" (res) |
269 | : "r" (&rw->lock) | ||
270 | : "cc"); | ||
271 | } while (res); | ||
266 | 272 | ||
267 | smp_mb(); | 273 | /* If the lock is negative, then it is already held for write. */ |
268 | return tmp2 == 0; | 274 | if (contended < 0x80000000) { |
275 | smp_mb(); | ||
276 | return 1; | ||
277 | } else { | ||
278 | return 0; | ||
279 | } | ||
269 | } | 280 | } |
270 | 281 | ||
271 | /* read_can_lock - would read_trylock() succeed? */ | 282 | /* read_can_lock - would read_trylock() succeed? */ |
diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h index fa09e6b49bf1..c99e259469f7 100644 --- a/arch/arm/include/asm/switch_to.h +++ b/arch/arm/include/asm/switch_to.h | |||
@@ -4,6 +4,16 @@ | |||
4 | #include <linux/thread_info.h> | 4 | #include <linux/thread_info.h> |
5 | 5 | ||
6 | /* | 6 | /* |
7 | * For v7 SMP cores running a preemptible kernel we may be pre-empted | ||
8 | * during a TLB maintenance operation, so execute an inner-shareable dsb | ||
9 | * to ensure that the maintenance completes in case we migrate to another | ||
10 | * CPU. | ||
11 | */ | ||
12 | #if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) && defined(CONFIG_CPU_V7) | ||
13 | #define finish_arch_switch(prev) dsb(ish) | ||
14 | #endif | ||
15 | |||
16 | /* | ||
7 | * switch_to(prev, next) should switch from task `prev' to `next' | 17 | * switch_to(prev, next) should switch from task `prev' to `next' |
8 | * `prev' will never be the same as `next'. schedule() itself | 18 | * `prev' will never be the same as `next'. schedule() itself |
9 | * contains the memory barrier to tell GCC not to cache `current'. | 19 | * contains the memory barrier to tell GCC not to cache `current'. |
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 2b8114fcba09..df5e13d64f2c 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h | |||
@@ -43,6 +43,16 @@ struct cpu_context_save { | |||
43 | __u32 extra[2]; /* Xscale 'acc' register, etc */ | 43 | __u32 extra[2]; /* Xscale 'acc' register, etc */ |
44 | }; | 44 | }; |
45 | 45 | ||
46 | struct arm_restart_block { | ||
47 | union { | ||
48 | /* For user cache flushing */ | ||
49 | struct { | ||
50 | unsigned long start; | ||
51 | unsigned long end; | ||
52 | } cache; | ||
53 | }; | ||
54 | }; | ||
55 | |||
46 | /* | 56 | /* |
47 | * low level task data that entry.S needs immediate access to. | 57 | * low level task data that entry.S needs immediate access to. |
48 | * __switch_to() assumes cpu_context follows immediately after cpu_domain. | 58 | * __switch_to() assumes cpu_context follows immediately after cpu_domain. |
@@ -68,6 +78,7 @@ struct thread_info { | |||
68 | unsigned long thumbee_state; /* ThumbEE Handler Base register */ | 78 | unsigned long thumbee_state; /* ThumbEE Handler Base register */ |
69 | #endif | 79 | #endif |
70 | struct restart_block restart_block; | 80 | struct restart_block restart_block; |
81 | struct arm_restart_block arm_restart_block; | ||
71 | }; | 82 | }; |
72 | 83 | ||
73 | #define INIT_THREAD_INFO(tsk) \ | 84 | #define INIT_THREAD_INFO(tsk) \ |
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 46e7cfb3e721..0baf7f0d9394 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h | |||
@@ -43,6 +43,7 @@ struct mmu_gather { | |||
43 | struct mm_struct *mm; | 43 | struct mm_struct *mm; |
44 | unsigned int fullmm; | 44 | unsigned int fullmm; |
45 | struct vm_area_struct *vma; | 45 | struct vm_area_struct *vma; |
46 | unsigned long start, end; | ||
46 | unsigned long range_start; | 47 | unsigned long range_start; |
47 | unsigned long range_end; | 48 | unsigned long range_end; |
48 | unsigned int nr; | 49 | unsigned int nr; |
@@ -107,10 +108,12 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb) | |||
107 | } | 108 | } |
108 | 109 | ||
109 | static inline void | 110 | static inline void |
110 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm) | 111 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) |
111 | { | 112 | { |
112 | tlb->mm = mm; | 113 | tlb->mm = mm; |
113 | tlb->fullmm = fullmm; | 114 | tlb->fullmm = !(start | (end+1)); |
115 | tlb->start = start; | ||
116 | tlb->end = end; | ||
114 | tlb->vma = NULL; | 117 | tlb->vma = NULL; |
115 | tlb->max = ARRAY_SIZE(tlb->local); | 118 | tlb->max = ARRAY_SIZE(tlb->local); |
116 | tlb->pages = tlb->local; | 119 | tlb->pages = tlb->local; |
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index f467e9b3f8d5..38960264040c 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h | |||
@@ -319,67 +319,110 @@ extern struct cpu_tlb_fns cpu_tlb; | |||
319 | #define tlb_op(f, regs, arg) __tlb_op(f, "p15, 0, %0, " regs, arg) | 319 | #define tlb_op(f, regs, arg) __tlb_op(f, "p15, 0, %0, " regs, arg) |
320 | #define tlb_l2_op(f, regs, arg) __tlb_op(f, "p15, 1, %0, " regs, arg) | 320 | #define tlb_l2_op(f, regs, arg) __tlb_op(f, "p15, 1, %0, " regs, arg) |
321 | 321 | ||
322 | static inline void local_flush_tlb_all(void) | 322 | static inline void __local_flush_tlb_all(void) |
323 | { | 323 | { |
324 | const int zero = 0; | 324 | const int zero = 0; |
325 | const unsigned int __tlb_flag = __cpu_tlb_flags; | 325 | const unsigned int __tlb_flag = __cpu_tlb_flags; |
326 | 326 | ||
327 | if (tlb_flag(TLB_WB)) | ||
328 | dsb(); | ||
329 | |||
330 | tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); | 327 | tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); |
331 | tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); | 328 | tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); |
332 | tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); | 329 | tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); |
333 | tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero); | 330 | } |
331 | |||
332 | static inline void local_flush_tlb_all(void) | ||
333 | { | ||
334 | const int zero = 0; | ||
335 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
336 | |||
337 | if (tlb_flag(TLB_WB)) | ||
338 | dsb(nshst); | ||
339 | |||
340 | __local_flush_tlb_all(); | ||
341 | tlb_op(TLB_V7_UIS_FULL, "c8, c7, 0", zero); | ||
334 | 342 | ||
335 | if (tlb_flag(TLB_BARRIER)) { | 343 | if (tlb_flag(TLB_BARRIER)) { |
336 | dsb(); | 344 | dsb(nsh); |
337 | isb(); | 345 | isb(); |
338 | } | 346 | } |
339 | } | 347 | } |
340 | 348 | ||
341 | static inline void local_flush_tlb_mm(struct mm_struct *mm) | 349 | static inline void __flush_tlb_all(void) |
342 | { | 350 | { |
343 | const int zero = 0; | 351 | const int zero = 0; |
344 | const int asid = ASID(mm); | ||
345 | const unsigned int __tlb_flag = __cpu_tlb_flags; | 352 | const unsigned int __tlb_flag = __cpu_tlb_flags; |
346 | 353 | ||
347 | if (tlb_flag(TLB_WB)) | 354 | if (tlb_flag(TLB_WB)) |
348 | dsb(); | 355 | dsb(ishst); |
356 | |||
357 | __local_flush_tlb_all(); | ||
358 | tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero); | ||
359 | |||
360 | if (tlb_flag(TLB_BARRIER)) { | ||
361 | dsb(ish); | ||
362 | isb(); | ||
363 | } | ||
364 | } | ||
365 | |||
366 | static inline void __local_flush_tlb_mm(struct mm_struct *mm) | ||
367 | { | ||
368 | const int zero = 0; | ||
369 | const int asid = ASID(mm); | ||
370 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
349 | 371 | ||
350 | if (possible_tlb_flags & (TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { | 372 | if (possible_tlb_flags & (TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { |
351 | if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { | 373 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) { |
352 | tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); | 374 | tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); |
353 | tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); | 375 | tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); |
354 | tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); | 376 | tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); |
355 | } | 377 | } |
356 | put_cpu(); | ||
357 | } | 378 | } |
358 | 379 | ||
359 | tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid); | 380 | tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid); |
360 | tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid); | 381 | tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid); |
361 | tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid); | 382 | tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid); |
383 | } | ||
384 | |||
385 | static inline void local_flush_tlb_mm(struct mm_struct *mm) | ||
386 | { | ||
387 | const int asid = ASID(mm); | ||
388 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
389 | |||
390 | if (tlb_flag(TLB_WB)) | ||
391 | dsb(nshst); | ||
392 | |||
393 | __local_flush_tlb_mm(mm); | ||
394 | tlb_op(TLB_V7_UIS_ASID, "c8, c7, 2", asid); | ||
395 | |||
396 | if (tlb_flag(TLB_BARRIER)) | ||
397 | dsb(nsh); | ||
398 | } | ||
399 | |||
400 | static inline void __flush_tlb_mm(struct mm_struct *mm) | ||
401 | { | ||
402 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
403 | |||
404 | if (tlb_flag(TLB_WB)) | ||
405 | dsb(ishst); | ||
406 | |||
407 | __local_flush_tlb_mm(mm); | ||
362 | #ifdef CONFIG_ARM_ERRATA_720789 | 408 | #ifdef CONFIG_ARM_ERRATA_720789 |
363 | tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", zero); | 409 | tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", 0); |
364 | #else | 410 | #else |
365 | tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", asid); | 411 | tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", ASID(mm)); |
366 | #endif | 412 | #endif |
367 | 413 | ||
368 | if (tlb_flag(TLB_BARRIER)) | 414 | if (tlb_flag(TLB_BARRIER)) |
369 | dsb(); | 415 | dsb(ish); |
370 | } | 416 | } |
371 | 417 | ||
372 | static inline void | 418 | static inline void |
373 | local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | 419 | __local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) |
374 | { | 420 | { |
375 | const int zero = 0; | 421 | const int zero = 0; |
376 | const unsigned int __tlb_flag = __cpu_tlb_flags; | 422 | const unsigned int __tlb_flag = __cpu_tlb_flags; |
377 | 423 | ||
378 | uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); | 424 | uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); |
379 | 425 | ||
380 | if (tlb_flag(TLB_WB)) | ||
381 | dsb(); | ||
382 | |||
383 | if (possible_tlb_flags & (TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && | 426 | if (possible_tlb_flags & (TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && |
384 | cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { | 427 | cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { |
385 | tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); | 428 | tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); |
@@ -392,6 +435,36 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | |||
392 | tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr); | 435 | tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr); |
393 | tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr); | 436 | tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr); |
394 | tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr); | 437 | tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr); |
438 | } | ||
439 | |||
440 | static inline void | ||
441 | local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | ||
442 | { | ||
443 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
444 | |||
445 | uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); | ||
446 | |||
447 | if (tlb_flag(TLB_WB)) | ||
448 | dsb(nshst); | ||
449 | |||
450 | __local_flush_tlb_page(vma, uaddr); | ||
451 | tlb_op(TLB_V7_UIS_PAGE, "c8, c7, 1", uaddr); | ||
452 | |||
453 | if (tlb_flag(TLB_BARRIER)) | ||
454 | dsb(nsh); | ||
455 | } | ||
456 | |||
457 | static inline void | ||
458 | __flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | ||
459 | { | ||
460 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
461 | |||
462 | uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); | ||
463 | |||
464 | if (tlb_flag(TLB_WB)) | ||
465 | dsb(ishst); | ||
466 | |||
467 | __local_flush_tlb_page(vma, uaddr); | ||
395 | #ifdef CONFIG_ARM_ERRATA_720789 | 468 | #ifdef CONFIG_ARM_ERRATA_720789 |
396 | tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK); | 469 | tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK); |
397 | #else | 470 | #else |
@@ -399,19 +472,14 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | |||
399 | #endif | 472 | #endif |
400 | 473 | ||
401 | if (tlb_flag(TLB_BARRIER)) | 474 | if (tlb_flag(TLB_BARRIER)) |
402 | dsb(); | 475 | dsb(ish); |
403 | } | 476 | } |
404 | 477 | ||
405 | static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | 478 | static inline void __local_flush_tlb_kernel_page(unsigned long kaddr) |
406 | { | 479 | { |
407 | const int zero = 0; | 480 | const int zero = 0; |
408 | const unsigned int __tlb_flag = __cpu_tlb_flags; | 481 | const unsigned int __tlb_flag = __cpu_tlb_flags; |
409 | 482 | ||
410 | kaddr &= PAGE_MASK; | ||
411 | |||
412 | if (tlb_flag(TLB_WB)) | ||
413 | dsb(); | ||
414 | |||
415 | tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); | 483 | tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); |
416 | tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); | 484 | tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); |
417 | tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); | 485 | tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); |
@@ -421,26 +489,75 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | |||
421 | tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr); | 489 | tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr); |
422 | tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr); | 490 | tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr); |
423 | tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr); | 491 | tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr); |
492 | } | ||
493 | |||
494 | static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | ||
495 | { | ||
496 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
497 | |||
498 | kaddr &= PAGE_MASK; | ||
499 | |||
500 | if (tlb_flag(TLB_WB)) | ||
501 | dsb(nshst); | ||
502 | |||
503 | __local_flush_tlb_kernel_page(kaddr); | ||
504 | tlb_op(TLB_V7_UIS_PAGE, "c8, c7, 1", kaddr); | ||
505 | |||
506 | if (tlb_flag(TLB_BARRIER)) { | ||
507 | dsb(nsh); | ||
508 | isb(); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | static inline void __flush_tlb_kernel_page(unsigned long kaddr) | ||
513 | { | ||
514 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
515 | |||
516 | kaddr &= PAGE_MASK; | ||
517 | |||
518 | if (tlb_flag(TLB_WB)) | ||
519 | dsb(ishst); | ||
520 | |||
521 | __local_flush_tlb_kernel_page(kaddr); | ||
424 | tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr); | 522 | tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr); |
425 | 523 | ||
426 | if (tlb_flag(TLB_BARRIER)) { | 524 | if (tlb_flag(TLB_BARRIER)) { |
427 | dsb(); | 525 | dsb(ish); |
428 | isb(); | 526 | isb(); |
429 | } | 527 | } |
430 | } | 528 | } |
431 | 529 | ||
530 | /* | ||
531 | * Branch predictor maintenance is paired with full TLB invalidation, so | ||
532 | * there is no need for any barriers here. | ||
533 | */ | ||
534 | static inline void __local_flush_bp_all(void) | ||
535 | { | ||
536 | const int zero = 0; | ||
537 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
538 | |||
539 | if (tlb_flag(TLB_V6_BP)) | ||
540 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero)); | ||
541 | } | ||
542 | |||
432 | static inline void local_flush_bp_all(void) | 543 | static inline void local_flush_bp_all(void) |
433 | { | 544 | { |
434 | const int zero = 0; | 545 | const int zero = 0; |
435 | const unsigned int __tlb_flag = __cpu_tlb_flags; | 546 | const unsigned int __tlb_flag = __cpu_tlb_flags; |
436 | 547 | ||
548 | __local_flush_bp_all(); | ||
437 | if (tlb_flag(TLB_V7_UIS_BP)) | 549 | if (tlb_flag(TLB_V7_UIS_BP)) |
438 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero)); | ||
439 | else if (tlb_flag(TLB_V6_BP)) | ||
440 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero)); | 550 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero)); |
551 | } | ||
441 | 552 | ||
442 | if (tlb_flag(TLB_BARRIER)) | 553 | static inline void __flush_bp_all(void) |
443 | isb(); | 554 | { |
555 | const int zero = 0; | ||
556 | const unsigned int __tlb_flag = __cpu_tlb_flags; | ||
557 | |||
558 | __local_flush_bp_all(); | ||
559 | if (tlb_flag(TLB_V7_UIS_BP)) | ||
560 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero)); | ||
444 | } | 561 | } |
445 | 562 | ||
446 | #include <asm/cputype.h> | 563 | #include <asm/cputype.h> |
@@ -461,7 +578,7 @@ static inline void dummy_flush_tlb_a15_erratum(void) | |||
461 | * Dummy TLBIMVAIS. Using the unmapped address 0 and ASID 0. | 578 | * Dummy TLBIMVAIS. Using the unmapped address 0 and ASID 0. |
462 | */ | 579 | */ |
463 | asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); | 580 | asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); |
464 | dsb(); | 581 | dsb(ish); |
465 | } | 582 | } |
466 | #else | 583 | #else |
467 | static inline int erratum_a15_798181(void) | 584 | static inline int erratum_a15_798181(void) |
@@ -495,7 +612,7 @@ static inline void flush_pmd_entry(void *pmd) | |||
495 | tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd); | 612 | tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd); |
496 | 613 | ||
497 | if (tlb_flag(TLB_WB)) | 614 | if (tlb_flag(TLB_WB)) |
498 | dsb(); | 615 | dsb(ishst); |
499 | } | 616 | } |
500 | 617 | ||
501 | static inline void clean_pmd_entry(void *pmd) | 618 | static inline void clean_pmd_entry(void *pmd) |
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h new file mode 100644 index 000000000000..a53cdb8f068c --- /dev/null +++ b/arch/arm/include/asm/types.h | |||
@@ -0,0 +1,40 @@ | |||
1 | #ifndef _ASM_TYPES_H | ||
2 | #define _ASM_TYPES_H | ||
3 | |||
4 | #include <asm-generic/int-ll64.h> | ||
5 | |||
6 | /* | ||
7 | * The C99 types uintXX_t that are usually defined in 'stdint.h' are not as | ||
8 | * unambiguous on ARM as you would expect. For the types below, there is a | ||
9 | * difference on ARM between GCC built for bare metal ARM, GCC built for glibc | ||
10 | * and the kernel itself, which results in build errors if you try to build with | ||
11 | * -ffreestanding and include 'stdint.h' (such as when you include 'arm_neon.h' | ||
12 | * in order to use NEON intrinsics) | ||
13 | * | ||
14 | * As the typedefs for these types in 'stdint.h' are based on builtin defines | ||
15 | * supplied by GCC, we can tweak these to align with the kernel's idea of those | ||
16 | * types, so 'linux/types.h' and 'stdint.h' can be safely included from the same | ||
17 | * source file (provided that -ffreestanding is used). | ||
18 | * | ||
19 | * int32_t uint32_t uintptr_t | ||
20 | * bare metal GCC long unsigned long unsigned int | ||
21 | * glibc GCC int unsigned int unsigned int | ||
22 | * kernel int unsigned int unsigned long | ||
23 | */ | ||
24 | |||
25 | #ifdef __INT32_TYPE__ | ||
26 | #undef __INT32_TYPE__ | ||
27 | #define __INT32_TYPE__ int | ||
28 | #endif | ||
29 | |||
30 | #ifdef __UINT32_TYPE__ | ||
31 | #undef __UINT32_TYPE__ | ||
32 | #define __UINT32_TYPE__ unsigned int | ||
33 | #endif | ||
34 | |||
35 | #ifdef __UINTPTR_TYPE__ | ||
36 | #undef __UINTPTR_TYPE__ | ||
37 | #define __UINTPTR_TYPE__ unsigned long | ||
38 | #endif | ||
39 | |||
40 | #endif /* _ASM_TYPES_H */ | ||
diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h index fa88d09fa3d9..615781c61627 100644 --- a/arch/arm/include/asm/v7m.h +++ b/arch/arm/include/asm/v7m.h | |||
@@ -15,6 +15,10 @@ | |||
15 | 15 | ||
16 | #define V7M_SCB_VTOR 0x08 | 16 | #define V7M_SCB_VTOR 0x08 |
17 | 17 | ||
18 | #define V7M_SCB_AIRCR 0x0c | ||
19 | #define V7M_SCB_AIRCR_VECTKEY (0x05fa << 16) | ||
20 | #define V7M_SCB_AIRCR_SYSRESETREQ (1 << 2) | ||
21 | |||
18 | #define V7M_SCB_SCR 0x10 | 22 | #define V7M_SCB_SCR 0x10 |
19 | #define V7M_SCB_SCR_SLEEPDEEP (1 << 2) | 23 | #define V7M_SCB_SCR_SLEEPDEEP (1 << 2) |
20 | 24 | ||
@@ -42,3 +46,11 @@ | |||
42 | */ | 46 | */ |
43 | #define EXC_RET_STACK_MASK 0x00000004 | 47 | #define EXC_RET_STACK_MASK 0x00000004 |
44 | #define EXC_RET_THREADMODE_PROCESSSTACK 0xfffffffd | 48 | #define EXC_RET_THREADMODE_PROCESSSTACK 0xfffffffd |
49 | |||
50 | #ifndef __ASSEMBLY__ | ||
51 | |||
52 | enum reboot_mode; | ||
53 | |||
54 | void armv7m_restart(enum reboot_mode mode, const char *cmd); | ||
55 | |||
56 | #endif /* __ASSEMBLY__ */ | ||
diff --git a/arch/arm/include/asm/xor.h b/arch/arm/include/asm/xor.h index 7604673dc427..4ffb26d4cad8 100644 --- a/arch/arm/include/asm/xor.h +++ b/arch/arm/include/asm/xor.h | |||
@@ -7,7 +7,10 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/hardirq.h> | ||
10 | #include <asm-generic/xor.h> | 11 | #include <asm-generic/xor.h> |
12 | #include <asm/hwcap.h> | ||
13 | #include <asm/neon.h> | ||
11 | 14 | ||
12 | #define __XOR(a1, a2) a1 ^= a2 | 15 | #define __XOR(a1, a2) a1 ^= a2 |
13 | 16 | ||
@@ -138,4 +141,74 @@ static struct xor_block_template xor_block_arm4regs = { | |||
138 | xor_speed(&xor_block_arm4regs); \ | 141 | xor_speed(&xor_block_arm4regs); \ |
139 | xor_speed(&xor_block_8regs); \ | 142 | xor_speed(&xor_block_8regs); \ |
140 | xor_speed(&xor_block_32regs); \ | 143 | xor_speed(&xor_block_32regs); \ |
144 | NEON_TEMPLATES; \ | ||
141 | } while (0) | 145 | } while (0) |
146 | |||
147 | #ifdef CONFIG_KERNEL_MODE_NEON | ||
148 | |||
149 | extern struct xor_block_template const xor_block_neon_inner; | ||
150 | |||
151 | static void | ||
152 | xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) | ||
153 | { | ||
154 | if (in_interrupt()) { | ||
155 | xor_arm4regs_2(bytes, p1, p2); | ||
156 | } else { | ||
157 | kernel_neon_begin(); | ||
158 | xor_block_neon_inner.do_2(bytes, p1, p2); | ||
159 | kernel_neon_end(); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | static void | ||
164 | xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, | ||
165 | unsigned long *p3) | ||
166 | { | ||
167 | if (in_interrupt()) { | ||
168 | xor_arm4regs_3(bytes, p1, p2, p3); | ||
169 | } else { | ||
170 | kernel_neon_begin(); | ||
171 | xor_block_neon_inner.do_3(bytes, p1, p2, p3); | ||
172 | kernel_neon_end(); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | static void | ||
177 | xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, | ||
178 | unsigned long *p3, unsigned long *p4) | ||
179 | { | ||
180 | if (in_interrupt()) { | ||
181 | xor_arm4regs_4(bytes, p1, p2, p3, p4); | ||
182 | } else { | ||
183 | kernel_neon_begin(); | ||
184 | xor_block_neon_inner.do_4(bytes, p1, p2, p3, p4); | ||
185 | kernel_neon_end(); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | static void | ||
190 | xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, | ||
191 | unsigned long *p3, unsigned long *p4, unsigned long *p5) | ||
192 | { | ||
193 | if (in_interrupt()) { | ||
194 | xor_arm4regs_5(bytes, p1, p2, p3, p4, p5); | ||
195 | } else { | ||
196 | kernel_neon_begin(); | ||
197 | xor_block_neon_inner.do_5(bytes, p1, p2, p3, p4, p5); | ||
198 | kernel_neon_end(); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | static struct xor_block_template xor_block_neon = { | ||
203 | .name = "neon", | ||
204 | .do_2 = xor_neon_2, | ||
205 | .do_3 = xor_neon_3, | ||
206 | .do_4 = xor_neon_4, | ||
207 | .do_5 = xor_neon_5 | ||
208 | }; | ||
209 | |||
210 | #define NEON_TEMPLATES \ | ||
211 | do { if (cpu_has_neon()) xor_speed(&xor_block_neon); } while (0) | ||
212 | #else | ||
213 | #define NEON_TEMPLATES | ||
214 | #endif | ||
diff --git a/arch/arm/include/debug/8250.S b/arch/arm/include/debug/8250.S new file mode 100644 index 000000000000..7a2baf913aa0 --- /dev/null +++ b/arch/arm/include/debug/8250.S | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * arch/arm/include/debug/8250.S | ||
3 | * | ||
4 | * Copyright (C) 1994-2013 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/serial_reg.h> | ||
11 | |||
12 | .macro addruart, rp, rv, tmp | ||
13 | ldr \rp, =CONFIG_DEBUG_UART_PHYS | ||
14 | ldr \rv, =CONFIG_DEBUG_UART_VIRT | ||
15 | .endm | ||
16 | |||
17 | #ifdef CONFIG_DEBUG_UART_8250_WORD | ||
18 | .macro store, rd, rx:vararg | ||
19 | str \rd, \rx | ||
20 | .endm | ||
21 | |||
22 | .macro load, rd, rx:vararg | ||
23 | ldr \rd, \rx | ||
24 | .endm | ||
25 | #else | ||
26 | .macro store, rd, rx:vararg | ||
27 | strb \rd, \rx | ||
28 | .endm | ||
29 | |||
30 | .macro load, rd, rx:vararg | ||
31 | ldrb \rd, \rx | ||
32 | .endm | ||
33 | #endif | ||
34 | |||
35 | #define UART_SHIFT CONFIG_DEBUG_UART_8250_SHIFT | ||
36 | |||
37 | .macro senduart,rd,rx | ||
38 | store \rd, [\rx, #UART_TX << UART_SHIFT] | ||
39 | .endm | ||
40 | |||
41 | .macro busyuart,rd,rx | ||
42 | 1002: load \rd, [\rx, #UART_LSR << UART_SHIFT] | ||
43 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
44 | teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
45 | bne 1002b | ||
46 | .endm | ||
47 | |||
48 | .macro waituart,rd,rx | ||
49 | #ifdef CONFIG_DEBUG_UART_8250_FLOW_CONTROL | ||
50 | 1001: load \rd, [\rx, #UART_MSR << UART_SHIFT] | ||
51 | tst \rd, #UART_MSR_CTS | ||
52 | beq 1001b | ||
53 | #endif | ||
54 | .endm | ||
diff --git a/arch/arm/include/debug/8250_32.S b/arch/arm/include/debug/8250_32.S deleted file mode 100644 index 8db01eeabbb4..000000000000 --- a/arch/arm/include/debug/8250_32.S +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Picochip Ltd., Jamie Iles | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * Derived from arch/arm/mach-davinci/include/mach/debug-macro.S to use 32-bit | ||
9 | * accesses to the 8250. | ||
10 | */ | ||
11 | |||
12 | #include <linux/serial_reg.h> | ||
13 | |||
14 | .macro senduart,rd,rx | ||
15 | str \rd, [\rx, #UART_TX << UART_SHIFT] | ||
16 | .endm | ||
17 | |||
18 | .macro busyuart,rd,rx | ||
19 | 1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] | ||
20 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
21 | teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
22 | bne 1002b | ||
23 | .endm | ||
24 | |||
25 | /* The UART's don't have any flow control IO's wired up. */ | ||
26 | .macro waituart,rd,rx | ||
27 | .endm | ||
diff --git a/arch/arm/include/debug/bcm2835.S b/arch/arm/include/debug/bcm2835.S deleted file mode 100644 index aed9199bd847..000000000000 --- a/arch/arm/include/debug/bcm2835.S +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Debugging macro include header | ||
3 | * | ||
4 | * Copyright (C) 2010 Broadcom | ||
5 | * Copyright (C) 1994-1999 Russell King | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #define BCM2835_DEBUG_PHYS 0x20201000 | ||
15 | #define BCM2835_DEBUG_VIRT 0xf0201000 | ||
16 | |||
17 | .macro addruart, rp, rv, tmp | ||
18 | ldr \rp, =BCM2835_DEBUG_PHYS | ||
19 | ldr \rv, =BCM2835_DEBUG_VIRT | ||
20 | .endm | ||
21 | |||
22 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/include/debug/cns3xxx.S b/arch/arm/include/debug/cns3xxx.S deleted file mode 100644 index d04c150baa1c..000000000000 --- a/arch/arm/include/debug/cns3xxx.S +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * Debugging macro include header | ||
3 | * | ||
4 | * Copyright 1994-1999 Russell King | ||
5 | * Copyright 2008 Cavium Networks | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This file is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License, Version 2, as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | .macro addruart,rp,rv,tmp | ||
14 | mov \rp, #0x00009000 | ||
15 | orr \rv, \rp, #0xf0000000 @ virtual base | ||
16 | orr \rp, \rp, #0x10000000 | ||
17 | .endm | ||
18 | |||
19 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/include/debug/highbank.S b/arch/arm/include/debug/highbank.S deleted file mode 100644 index 8cad4322a5a2..000000000000 --- a/arch/arm/include/debug/highbank.S +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* | ||
2 | * Debugging macro include header | ||
3 | * | ||
4 | * Copyright (C) 1994-1999 Russell King | ||
5 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | .macro addruart,rp,rv,tmp | ||
13 | ldr \rv, =0xfee36000 | ||
14 | ldr \rp, =0xfff36000 | ||
15 | .endm | ||
16 | |||
17 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/include/debug/keystone.S b/arch/arm/include/debug/keystone.S deleted file mode 100644 index 9aef9ba3f4f0..000000000000 --- a/arch/arm/include/debug/keystone.S +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * Early serial debug output macro for Keystone SOCs | ||
3 | * | ||
4 | * Copyright 2013 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
6 | * | ||
7 | * Based on RMKs low level debug code. | ||
8 | * Copyright (C) 1994-1999 Russell King | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/serial_reg.h> | ||
16 | |||
17 | #define UART_SHIFT 2 | ||
18 | #if defined(CONFIG_DEBUG_KEYSTONE_UART0) | ||
19 | #define UART_PHYS 0x02530c00 | ||
20 | #define UART_VIRT 0xfeb30c00 | ||
21 | #elif defined(CONFIG_DEBUG_KEYSTONE_UART1) | ||
22 | #define UART_PHYS 0x02531000 | ||
23 | #define UART_VIRT 0xfeb31000 | ||
24 | #endif | ||
25 | |||
26 | .macro addruart, rp, rv, tmp | ||
27 | ldr \rv, =UART_VIRT @ physical base address | ||
28 | ldr \rp, =UART_PHYS @ virtual base address | ||
29 | .endm | ||
30 | |||
31 | .macro senduart,rd,rx | ||
32 | str \rd, [\rx, #UART_TX << UART_SHIFT] | ||
33 | .endm | ||
34 | |||
35 | .macro busyuart,rd,rx | ||
36 | 1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] | ||
37 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
38 | teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
39 | bne 1002b | ||
40 | .endm | ||
41 | |||
42 | .macro waituart,rd,rx | ||
43 | .endm | ||
diff --git a/arch/arm/include/debug/mvebu.S b/arch/arm/include/debug/mvebu.S deleted file mode 100644 index 6517311a1c91..000000000000 --- a/arch/arm/include/debug/mvebu.S +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * Early serial output macro for Marvell SoC | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Lior Amsalem <alior@marvell.com> | ||
7 | * Gregory Clement <gregory.clement@free-electrons.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifdef CONFIG_DEBUG_MVEBU_UART_ALTERNATE | ||
15 | #define ARMADA_370_XP_REGS_PHYS_BASE 0xf1000000 | ||
16 | #else | ||
17 | #define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000 | ||
18 | #endif | ||
19 | |||
20 | #define ARMADA_370_XP_REGS_VIRT_BASE 0xfec00000 | ||
21 | |||
22 | .macro addruart, rp, rv, tmp | ||
23 | ldr \rp, =ARMADA_370_XP_REGS_PHYS_BASE | ||
24 | ldr \rv, =ARMADA_370_XP_REGS_VIRT_BASE | ||
25 | orr \rp, \rp, #0x00012000 | ||
26 | orr \rv, \rv, #0x00012000 | ||
27 | .endm | ||
28 | |||
29 | #define UART_SHIFT 2 | ||
30 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/include/debug/mxs.S b/arch/arm/include/debug/mxs.S deleted file mode 100644 index d86951551ca1..000000000000 --- a/arch/arm/include/debug/mxs.S +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* arch/arm/mach-mxs/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copyright (C) 1994-1999 Russell King | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifdef CONFIG_DEBUG_IMX23_UART | ||
15 | #define UART_PADDR 0x80070000 | ||
16 | #elif defined (CONFIG_DEBUG_IMX28_UART) | ||
17 | #define UART_PADDR 0x80074000 | ||
18 | #endif | ||
19 | |||
20 | #define UART_VADDR 0xfe100000 | ||
21 | |||
22 | .macro addruart, rp, rv, tmp | ||
23 | ldr \rp, =UART_PADDR @ physical | ||
24 | ldr \rv, =UART_VADDR @ virtual | ||
25 | .endm | ||
26 | |||
27 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/include/debug/nomadik.S b/arch/arm/include/debug/nomadik.S deleted file mode 100644 index 735417922ce2..000000000000 --- a/arch/arm/include/debug/nomadik.S +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * Debugging macro include header | ||
3 | * | ||
4 | * Copyright (C) 1994-1999 Russell King | ||
5 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | .macro addruart, rp, rv, tmp | ||
14 | mov \rp, #0x00100000 | ||
15 | add \rp, \rp, #0x000fb000 | ||
16 | add \rv, \rp, #0xf0000000 @ virtual base | ||
17 | add \rp, \rp, #0x10000000 @ physical base address | ||
18 | .endm | ||
19 | |||
20 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/include/debug/nspire.S b/arch/arm/include/debug/nspire.S deleted file mode 100644 index 886fd276fcbc..000000000000 --- a/arch/arm/include/debug/nspire.S +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/include/debug/nspire.S | ||
3 | * | ||
4 | * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #define NSPIRE_EARLY_UART_PHYS_BASE 0x90020000 | ||
13 | #define NSPIRE_EARLY_UART_VIRT_BASE 0xfee20000 | ||
14 | |||
15 | .macro addruart, rp, rv, tmp | ||
16 | ldr \rp, =(NSPIRE_EARLY_UART_PHYS_BASE) @ physical base address | ||
17 | ldr \rv, =(NSPIRE_EARLY_UART_VIRT_BASE) @ virtual base address | ||
18 | .endm | ||
19 | |||
20 | |||
21 | #ifdef CONFIG_DEBUG_NSPIRE_CX_UART | ||
22 | #include <asm/hardware/debug-pl01x.S> | ||
23 | #endif | ||
24 | |||
25 | #ifdef CONFIG_DEBUG_NSPIRE_CLASSIC_UART | ||
26 | #define UART_SHIFT 2 | ||
27 | #include <asm/hardware/debug-8250.S> | ||
28 | #endif | ||
diff --git a/arch/arm/include/debug/picoxcell.S b/arch/arm/include/debug/picoxcell.S deleted file mode 100644 index bc1f07c49cd4..000000000000 --- a/arch/arm/include/debug/picoxcell.S +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Picochip Ltd., Jamie Iles | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #define UART_SHIFT 2 | ||
11 | #define PICOXCELL_UART1_BASE 0x80230000 | ||
12 | #define PHYS_TO_IO(x) (((x) & 0x00ffffff) | 0xfe000000) | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | ldr \rv, =PHYS_TO_IO(PICOXCELL_UART1_BASE) | ||
16 | ldr \rp, =PICOXCELL_UART1_BASE | ||
17 | .endm | ||
18 | |||
19 | #include "8250_32.S" | ||
diff --git a/arch/arm/include/asm/hardware/debug-pl01x.S b/arch/arm/include/debug/pl01x.S index f9fd083eff63..37c6895b87e6 100644 --- a/arch/arm/include/asm/hardware/debug-pl01x.S +++ b/arch/arm/include/debug/pl01x.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* arch/arm/include/asm/hardware/debug-pl01x.S | 1 | /* arch/arm/include/debug/pl01x.S |
2 | * | 2 | * |
3 | * Debugging macro include header | 3 | * Debugging macro include header |
4 | * | 4 | * |
@@ -12,6 +12,13 @@ | |||
12 | */ | 12 | */ |
13 | #include <linux/amba/serial.h> | 13 | #include <linux/amba/serial.h> |
14 | 14 | ||
15 | #ifdef CONFIG_DEBUG_UART_PHYS | ||
16 | .macro addruart, rp, rv, tmp | ||
17 | ldr \rp, =CONFIG_DEBUG_UART_PHYS | ||
18 | ldr \rv, =CONFIG_DEBUG_UART_VIRT | ||
19 | .endm | ||
20 | #endif | ||
21 | |||
15 | .macro senduart,rd,rx | 22 | .macro senduart,rd,rx |
16 | strb \rd, [\rx, #UART01x_DR] | 23 | strb \rd, [\rx, #UART01x_DR] |
17 | .endm | 24 | .endm |
diff --git a/arch/arm/include/debug/pxa.S b/arch/arm/include/debug/pxa.S deleted file mode 100644 index e1e795aa3d7f..000000000000 --- a/arch/arm/include/debug/pxa.S +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | * Early serial output macro for Marvell PXA/MMP SoC | ||
3 | * | ||
4 | * Copyright (C) 1994-1999 Russell King | ||
5 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
6 | * | ||
7 | * Copyright (C) 2013 Haojian Zhuang | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #if defined(CONFIG_DEBUG_PXA_UART1) | ||
15 | #define PXA_UART_REG_PHYS_BASE 0x40100000 | ||
16 | #define PXA_UART_REG_VIRT_BASE 0xf2100000 | ||
17 | #elif defined(CONFIG_DEBUG_MMP_UART2) | ||
18 | #define PXA_UART_REG_PHYS_BASE 0xd4017000 | ||
19 | #define PXA_UART_REG_VIRT_BASE 0xfe017000 | ||
20 | #elif defined(CONFIG_DEBUG_MMP_UART3) | ||
21 | #define PXA_UART_REG_PHYS_BASE 0xd4018000 | ||
22 | #define PXA_UART_REG_VIRT_BASE 0xfe018000 | ||
23 | #else | ||
24 | #error "Select uart for DEBUG_LL" | ||
25 | #endif | ||
26 | |||
27 | .macro addruart, rp, rv, tmp | ||
28 | ldr \rp, =PXA_UART_REG_PHYS_BASE | ||
29 | ldr \rv, =PXA_UART_REG_VIRT_BASE | ||
30 | .endm | ||
31 | |||
32 | #define UART_SHIFT 2 | ||
33 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/include/debug/rockchip.S b/arch/arm/include/debug/rockchip.S deleted file mode 100644 index cfd883e69588..000000000000 --- a/arch/arm/include/debug/rockchip.S +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* | ||
2 | * Early serial output macro for Rockchip SoCs | ||
3 | * | ||
4 | * Copyright (C) 2012 Maxime Ripard | ||
5 | * | ||
6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #if defined(CONFIG_DEBUG_RK29_UART0) | ||
14 | #define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20060000 | ||
15 | #define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed60000 | ||
16 | #elif defined(CONFIG_DEBUG_RK29_UART1) | ||
17 | #define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20064000 | ||
18 | #define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed64000 | ||
19 | #elif defined(CONFIG_DEBUG_RK29_UART2) | ||
20 | #define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20068000 | ||
21 | #define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed68000 | ||
22 | #elif defined(CONFIG_DEBUG_RK3X_UART0) | ||
23 | #define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x10124000 | ||
24 | #define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfeb24000 | ||
25 | #elif defined(CONFIG_DEBUG_RK3X_UART1) | ||
26 | #define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x10126000 | ||
27 | #define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfeb26000 | ||
28 | #elif defined(CONFIG_DEBUG_RK3X_UART2) | ||
29 | #define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20064000 | ||
30 | #define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed64000 | ||
31 | #elif defined(CONFIG_DEBUG_RK3X_UART3) | ||
32 | #define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20068000 | ||
33 | #define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed68000 | ||
34 | #endif | ||
35 | |||
36 | .macro addruart, rp, rv, tmp | ||
37 | ldr \rp, =ROCKCHIP_UART_DEBUG_PHYS_BASE | ||
38 | ldr \rv, =ROCKCHIP_UART_DEBUG_VIRT_BASE | ||
39 | .endm | ||
40 | |||
41 | #define UART_SHIFT 2 | ||
42 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/include/debug/socfpga.S b/arch/arm/include/debug/socfpga.S deleted file mode 100644 index 966b2f994946..000000000000 --- a/arch/arm/include/debug/socfpga.S +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1994-1999 Russell King | ||
3 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #define UART_SHIFT 2 | ||
11 | #define DEBUG_LL_UART_OFFSET 0x00002000 | ||
12 | |||
13 | .macro addruart, rp, rv, tmp | ||
14 | mov \rp, #DEBUG_LL_UART_OFFSET | ||
15 | orr \rp, \rp, #0x00c00000 | ||
16 | orr \rv, \rp, #0xfe000000 @ virtual base | ||
17 | orr \rp, \rp, #0xff000000 @ physical base | ||
18 | .endm | ||
19 | |||
20 | #include "8250_32.S" | ||
21 | |||
diff --git a/arch/arm/include/debug/sunxi.S b/arch/arm/include/debug/sunxi.S deleted file mode 100644 index 04eb56d5db2c..000000000000 --- a/arch/arm/include/debug/sunxi.S +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | * Early serial output macro for Allwinner A1X SoCs | ||
3 | * | ||
4 | * Copyright (C) 2012 Maxime Ripard | ||
5 | * | ||
6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #if defined(CONFIG_DEBUG_SUNXI_UART0) | ||
14 | #define SUNXI_UART_DEBUG_PHYS_BASE 0x01c28000 | ||
15 | #define SUNXI_UART_DEBUG_VIRT_BASE 0xf1c28000 | ||
16 | #elif defined(CONFIG_DEBUG_SUNXI_UART1) | ||
17 | #define SUNXI_UART_DEBUG_PHYS_BASE 0x01c28400 | ||
18 | #define SUNXI_UART_DEBUG_VIRT_BASE 0xf1c28400 | ||
19 | #endif | ||
20 | |||
21 | .macro addruart, rp, rv, tmp | ||
22 | ldr \rp, =SUNXI_UART_DEBUG_PHYS_BASE | ||
23 | ldr \rv, =SUNXI_UART_DEBUG_VIRT_BASE | ||
24 | .endm | ||
25 | |||
26 | #define UART_SHIFT 2 | ||
27 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/include/debug/tegra.S b/arch/arm/include/debug/tegra.S index 883d7c22fd9d..be6a720dd183 100644 --- a/arch/arm/include/debug/tegra.S +++ b/arch/arm/include/debug/tegra.S | |||
@@ -221,3 +221,32 @@ | |||
221 | 1002: | 221 | 1002: |
222 | #endif | 222 | #endif |
223 | .endm | 223 | .endm |
224 | |||
225 | /* | ||
226 | * Storage for the state maintained by the macros above. | ||
227 | * | ||
228 | * In the kernel proper, this data is located in arch/arm/mach-tegra/common.c. | ||
229 | * That's because this header is included from multiple files, and we only | ||
230 | * want a single copy of the data. In particular, the UART probing code above | ||
231 | * assumes it's running using physical addresses. This is true when this file | ||
232 | * is included from head.o, but not when included from debug.o. So we need | ||
233 | * to share the probe results between the two copies, rather than having | ||
234 | * to re-run the probing again later. | ||
235 | * | ||
236 | * In the decompressor, we put the symbol/storage right here, since common.c | ||
237 | * isn't included in the decompressor build. This symbol gets put in .text | ||
238 | * even though it's really data, since .data is discarded from the | ||
239 | * decompressor. Luckily, .text is writeable in the decompressor, unless | ||
240 | * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug. | ||
241 | */ | ||
242 | #if defined(ZIMAGE) | ||
243 | tegra_uart_config: | ||
244 | /* Debug UART initialization required */ | ||
245 | .word 1 | ||
246 | /* Debug UART physical address */ | ||
247 | .word 0 | ||
248 | /* Debug UART virtual address */ | ||
249 | .word 0 | ||
250 | /* Scratch space for debug macro */ | ||
251 | .word 0 | ||
252 | #endif | ||
diff --git a/arch/arm/include/debug/u300.S b/arch/arm/include/debug/u300.S deleted file mode 100644 index 6f04f08a203c..000000000000 --- a/arch/arm/include/debug/u300.S +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-2013 ST-Ericsson AB | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Debugging macro include header. | ||
5 | * Author: Linus Walleij <linus.walleij@stericsson.com> | ||
6 | */ | ||
7 | #define U300_SLOW_PER_PHYS_BASE 0xc0010000 | ||
8 | #define U300_SLOW_PER_VIRT_BASE 0xff000000 | ||
9 | |||
10 | .macro addruart, rp, rv, tmp | ||
11 | /* If we move the address using MMU, use this. */ | ||
12 | ldr \rp, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address | ||
13 | ldr \rv, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address | ||
14 | orr \rp, \rp, #0x00003000 | ||
15 | orr \rv, \rv, #0x00003000 | ||
16 | .endm | ||
17 | |||
18 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/include/debug/ux500.S b/arch/arm/include/debug/ux500.S index fbd24beeb1fa..aa7f63a8b5e0 100644 --- a/arch/arm/include/debug/ux500.S +++ b/arch/arm/include/debug/ux500.S | |||
@@ -45,4 +45,4 @@ | |||
45 | ldr \rv, =UART_VIRT_BASE @ yes, virtual address | 45 | ldr \rv, =UART_VIRT_BASE @ yes, virtual address |
46 | .endm | 46 | .endm |
47 | 47 | ||
48 | #include <asm/hardware/debug-pl01x.S> | 48 | #include <debug/pl01x.S> |
diff --git a/arch/arm/include/debug/vexpress.S b/arch/arm/include/debug/vexpress.S index acafb229e2b6..524acd5a223e 100644 --- a/arch/arm/include/debug/vexpress.S +++ b/arch/arm/include/debug/vexpress.S | |||
@@ -47,51 +47,5 @@ | |||
47 | 47 | ||
48 | .endm | 48 | .endm |
49 | 49 | ||
50 | #include <asm/hardware/debug-pl01x.S> | 50 | #include <debug/pl01x.S> |
51 | |||
52 | #elif defined(CONFIG_DEBUG_VEXPRESS_UART0_CA9) | ||
53 | |||
54 | .macro addruart,rp,rv,tmp | ||
55 | mov \rp, #DEBUG_LL_UART_OFFSET | ||
56 | orr \rv, \rp, #DEBUG_LL_VIRT_BASE | ||
57 | orr \rp, \rp, #DEBUG_LL_PHYS_BASE | ||
58 | .endm | ||
59 | |||
60 | #include <asm/hardware/debug-pl01x.S> | ||
61 | |||
62 | #elif defined(CONFIG_DEBUG_VEXPRESS_UART0_RS1) | ||
63 | |||
64 | .macro addruart,rp,rv,tmp | ||
65 | mov \rp, #DEBUG_LL_UART_OFFSET_RS1 | ||
66 | orr \rv, \rp, #DEBUG_LL_VIRT_BASE | ||
67 | orr \rp, \rp, #DEBUG_LL_PHYS_BASE_RS1 | ||
68 | .endm | ||
69 | |||
70 | #include <asm/hardware/debug-pl01x.S> | ||
71 | |||
72 | #elif defined(CONFIG_DEBUG_VEXPRESS_UART0_CRX) | ||
73 | |||
74 | .macro addruart,rp,tmp,tmp2 | ||
75 | ldr \rp, =DEBUG_LL_UART_PHYS_CRX | ||
76 | .endm | ||
77 | |||
78 | #include <asm/hardware/debug-pl01x.S> | ||
79 | |||
80 | #else /* CONFIG_DEBUG_LL_UART_NONE */ | ||
81 | |||
82 | .macro addruart, rp, rv, tmp | ||
83 | /* Safe dummy values */ | ||
84 | mov \rp, #0 | ||
85 | mov \rv, #DEBUG_LL_VIRT_BASE | ||
86 | .endm | ||
87 | |||
88 | .macro senduart,rd,rx | ||
89 | .endm | ||
90 | |||
91 | .macro waituart,rd,rx | ||
92 | .endm | ||
93 | |||
94 | .macro busyuart,rd,rx | ||
95 | .endm | ||
96 | |||
97 | #endif | 51 | #endif |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 86d10dd47dc4..5140df5f23aa 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -24,7 +24,7 @@ obj-$(CONFIG_ATAGS_PROC) += atags_proc.o | |||
24 | obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o | 24 | obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o |
25 | 25 | ||
26 | ifeq ($(CONFIG_CPU_V7M),y) | 26 | ifeq ($(CONFIG_CPU_V7M),y) |
27 | obj-y += entry-v7m.o | 27 | obj-y += entry-v7m.o v7m.o |
28 | else | 28 | else |
29 | obj-y += entry-armv.o | 29 | obj-y += entry-armv.o |
30 | endif | 30 | endif |
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h index 9edc9692332d..ec4164da6e30 100644 --- a/arch/arm/kernel/atags.h +++ b/arch/arm/kernel/atags.h | |||
@@ -7,9 +7,10 @@ static inline void save_atags(struct tag *tags) { } | |||
7 | void convert_to_tag_list(struct tag *tags); | 7 | void convert_to_tag_list(struct tag *tags); |
8 | 8 | ||
9 | #ifdef CONFIG_ATAGS | 9 | #ifdef CONFIG_ATAGS |
10 | struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr); | 10 | const struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, |
11 | unsigned int machine_nr); | ||
11 | #else | 12 | #else |
12 | static inline struct machine_desc * | 13 | static inline const struct machine_desc * |
13 | setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) | 14 | setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) |
14 | { | 15 | { |
15 | early_print("no ATAGS support: can't continue\n"); | 16 | early_print("no ATAGS support: can't continue\n"); |
diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c index 14512e6931d8..8c14de8180c0 100644 --- a/arch/arm/kernel/atags_parse.c +++ b/arch/arm/kernel/atags_parse.c | |||
@@ -178,11 +178,11 @@ static void __init squash_mem_tags(struct tag *tag) | |||
178 | tag->hdr.tag = ATAG_NONE; | 178 | tag->hdr.tag = ATAG_NONE; |
179 | } | 179 | } |
180 | 180 | ||
181 | struct machine_desc * __init setup_machine_tags(phys_addr_t __atags_pointer, | 181 | const struct machine_desc * __init |
182 | unsigned int machine_nr) | 182 | setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) |
183 | { | 183 | { |
184 | struct tag *tags = (struct tag *)&default_tags; | 184 | struct tag *tags = (struct tag *)&default_tags; |
185 | struct machine_desc *mdesc = NULL, *p; | 185 | const struct machine_desc *mdesc = NULL, *p; |
186 | char *from = default_command_line; | 186 | char *from = default_command_line; |
187 | 187 | ||
188 | default_tags.mem.start = PHYS_OFFSET; | 188 | default_tags.mem.start = PHYS_OFFSET; |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 261fcc826169..88e14d74b6de 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -525,11 +525,6 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw) | |||
525 | * Assign resources. | 525 | * Assign resources. |
526 | */ | 526 | */ |
527 | pci_bus_assign_resources(bus); | 527 | pci_bus_assign_resources(bus); |
528 | |||
529 | /* | ||
530 | * Enable bridges | ||
531 | */ | ||
532 | pci_enable_bridges(bus); | ||
533 | } | 528 | } |
534 | 529 | ||
535 | /* | 530 | /* |
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 5859c8bc727c..f35906b3d8c9 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c | |||
@@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void) | |||
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
172 | bool arch_match_cpu_phys_id(int cpu, u64 phys_id) | ||
173 | { | ||
174 | return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu); | ||
175 | } | ||
176 | |||
172 | /** | 177 | /** |
173 | * setup_machine_fdt - Machine setup when an dtb was passed to the kernel | 178 | * setup_machine_fdt - Machine setup when an dtb was passed to the kernel |
174 | * @dt_phys: physical address of dt blob | 179 | * @dt_phys: physical address of dt blob |
@@ -176,10 +181,10 @@ void __init arm_dt_init_cpu_maps(void) | |||
176 | * If a dtb was passed to the kernel in r2, then use it to choose the | 181 | * If a dtb was passed to the kernel in r2, then use it to choose the |
177 | * correct machine_desc and to setup the system. | 182 | * correct machine_desc and to setup the system. |
178 | */ | 183 | */ |
179 | struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) | 184 | const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) |
180 | { | 185 | { |
181 | struct boot_param_header *devtree; | 186 | struct boot_param_header *devtree; |
182 | struct machine_desc *mdesc, *mdesc_best = NULL; | 187 | const struct machine_desc *mdesc, *mdesc_best = NULL; |
183 | unsigned int score, mdesc_score = ~1; | 188 | unsigned int score, mdesc_score = ~1; |
184 | unsigned long dt_root; | 189 | unsigned long dt_root; |
185 | const char *model; | 190 | const char *model; |
@@ -188,7 +193,7 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) | |||
188 | DT_MACHINE_START(GENERIC_DT, "Generic DT based system") | 193 | DT_MACHINE_START(GENERIC_DT, "Generic DT based system") |
189 | MACHINE_END | 194 | MACHINE_END |
190 | 195 | ||
191 | mdesc_best = (struct machine_desc *)&__mach_desc_GENERIC_DT; | 196 | mdesc_best = &__mach_desc_GENERIC_DT; |
192 | #endif | 197 | #endif |
193 | 198 | ||
194 | if (!dt_phys) | 199 | if (!dt_phys) |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d40d0ef389db..9cbe70c8b0ef 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -357,7 +357,8 @@ ENDPROC(__pabt_svc) | |||
357 | .endm | 357 | .endm |
358 | 358 | ||
359 | .macro kuser_cmpxchg_check | 359 | .macro kuser_cmpxchg_check |
360 | #if !defined(CONFIG_CPU_32v6K) && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) | 360 | #if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \ |
361 | !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) | ||
361 | #ifndef CONFIG_MMU | 362 | #ifndef CONFIG_MMU |
362 | #warning "NPTL on non MMU needs fixing" | 363 | #warning "NPTL on non MMU needs fixing" |
363 | #else | 364 | #else |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 94104bf69719..74ad15d1a065 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -442,10 +442,10 @@ local_restart: | |||
442 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine | 442 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine |
443 | 443 | ||
444 | add r1, sp, #S_OFF | 444 | add r1, sp, #S_OFF |
445 | 2: mov why, #0 @ no longer a real syscall | ||
446 | cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) | 445 | cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) |
447 | eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back | 446 | eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back |
448 | bcs arm_syscall | 447 | bcs arm_syscall |
448 | 2: mov why, #0 @ no longer a real syscall | ||
449 | b sys_ni_syscall @ not private func | 449 | b sys_ni_syscall @ not private func |
450 | 450 | ||
451 | #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) | 451 | #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) |
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 25442f451148..918875d96d5d 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c | |||
@@ -84,17 +84,14 @@ int show_fiq_list(struct seq_file *p, int prec) | |||
84 | 84 | ||
85 | void set_fiq_handler(void *start, unsigned int length) | 85 | void set_fiq_handler(void *start, unsigned int length) |
86 | { | 86 | { |
87 | #if defined(CONFIG_CPU_USE_DOMAINS) | ||
88 | void *base = (void *)0xffff0000; | ||
89 | #else | ||
90 | void *base = vectors_page; | 87 | void *base = vectors_page; |
91 | #endif | ||
92 | unsigned offset = FIQ_OFFSET; | 88 | unsigned offset = FIQ_OFFSET; |
93 | 89 | ||
94 | memcpy(base + offset, start, length); | 90 | memcpy(base + offset, start, length); |
91 | if (!cache_is_vipt_nonaliasing()) | ||
92 | flush_icache_range((unsigned long)base + offset, offset + | ||
93 | length); | ||
95 | flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length); | 94 | flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length); |
96 | if (!vectors_high()) | ||
97 | flush_icache_range(offset, offset + length); | ||
98 | } | 95 | } |
99 | 96 | ||
100 | int claim_fiq(struct fiq_handler *f) | 97 | int claim_fiq(struct fiq_handler *f) |
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 4fb074c446bf..57221e349a7c 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/mmu_context.h> | 15 | #include <asm/mmu_context.h> |
16 | #include <asm/cacheflush.h> | 16 | #include <asm/cacheflush.h> |
17 | #include <asm/mach-types.h> | 17 | #include <asm/mach-types.h> |
18 | #include <asm/smp_plat.h> | ||
18 | #include <asm/system_misc.h> | 19 | #include <asm/system_misc.h> |
19 | 20 | ||
20 | extern const unsigned char relocate_new_kernel[]; | 21 | extern const unsigned char relocate_new_kernel[]; |
@@ -39,6 +40,14 @@ int machine_kexec_prepare(struct kimage *image) | |||
39 | int i, err; | 40 | int i, err; |
40 | 41 | ||
41 | /* | 42 | /* |
43 | * Validate that if the current HW supports SMP, then the SW supports | ||
44 | * and implements CPU hotplug for the current HW. If not, we won't be | ||
45 | * able to kexec reliably, so fail the prepare operation. | ||
46 | */ | ||
47 | if (num_possible_cpus() > 1 && !platform_can_cpu_hotplug()) | ||
48 | return -EINVAL; | ||
49 | |||
50 | /* | ||
42 | * No segment at default ATAGs address. try to locate | 51 | * No segment at default ATAGs address. try to locate |
43 | * a dtb using magic. | 52 | * a dtb using magic. |
44 | */ | 53 | */ |
@@ -73,6 +82,7 @@ void machine_crash_nonpanic_core(void *unused) | |||
73 | crash_save_cpu(®s, smp_processor_id()); | 82 | crash_save_cpu(®s, smp_processor_id()); |
74 | flush_cache_all(); | 83 | flush_cache_all(); |
75 | 84 | ||
85 | set_cpu_online(smp_processor_id(), false); | ||
76 | atomic_dec(&waiting_for_crash_ipi); | 86 | atomic_dec(&waiting_for_crash_ipi); |
77 | while (1) | 87 | while (1) |
78 | cpu_relax(); | 88 | cpu_relax(); |
@@ -134,10 +144,13 @@ void machine_kexec(struct kimage *image) | |||
134 | unsigned long reboot_code_buffer_phys; | 144 | unsigned long reboot_code_buffer_phys; |
135 | void *reboot_code_buffer; | 145 | void *reboot_code_buffer; |
136 | 146 | ||
137 | if (num_online_cpus() > 1) { | 147 | /* |
138 | pr_err("kexec: error: multiple CPUs still online\n"); | 148 | * This can only happen if machine_shutdown() failed to disable some |
139 | return; | 149 | * CPU, and that can only happen if the checks in |
140 | } | 150 | * machine_kexec_prepare() were not correct. If this fails, we can't |
151 | * reliably kexec anyway, so BUG_ON is appropriate. | ||
152 | */ | ||
153 | BUG_ON(num_online_cpus() > 1); | ||
141 | 154 | ||
142 | page_list = image->head & PAGE_MASK; | 155 | page_list = image->head & PAGE_MASK; |
143 | 156 | ||
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 85c3fb6c93c2..084dc8896986 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
@@ -292,12 +292,20 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
292 | maps[ARM_SEC_CORE].unw_sec = s; | 292 | maps[ARM_SEC_CORE].unw_sec = s; |
293 | else if (strcmp(".ARM.exidx.exit.text", secname) == 0) | 293 | else if (strcmp(".ARM.exidx.exit.text", secname) == 0) |
294 | maps[ARM_SEC_EXIT].unw_sec = s; | 294 | maps[ARM_SEC_EXIT].unw_sec = s; |
295 | else if (strcmp(".ARM.exidx.text.unlikely", secname) == 0) | ||
296 | maps[ARM_SEC_UNLIKELY].unw_sec = s; | ||
297 | else if (strcmp(".ARM.exidx.text.hot", secname) == 0) | ||
298 | maps[ARM_SEC_HOT].unw_sec = s; | ||
295 | else if (strcmp(".init.text", secname) == 0) | 299 | else if (strcmp(".init.text", secname) == 0) |
296 | maps[ARM_SEC_INIT].txt_sec = s; | 300 | maps[ARM_SEC_INIT].txt_sec = s; |
297 | else if (strcmp(".text", secname) == 0) | 301 | else if (strcmp(".text", secname) == 0) |
298 | maps[ARM_SEC_CORE].txt_sec = s; | 302 | maps[ARM_SEC_CORE].txt_sec = s; |
299 | else if (strcmp(".exit.text", secname) == 0) | 303 | else if (strcmp(".exit.text", secname) == 0) |
300 | maps[ARM_SEC_EXIT].txt_sec = s; | 304 | maps[ARM_SEC_EXIT].txt_sec = s; |
305 | else if (strcmp(".text.unlikely", secname) == 0) | ||
306 | maps[ARM_SEC_UNLIKELY].txt_sec = s; | ||
307 | else if (strcmp(".text.hot", secname) == 0) | ||
308 | maps[ARM_SEC_HOT].txt_sec = s; | ||
301 | } | 309 | } |
302 | 310 | ||
303 | for (i = 0; i < ARM_SEC_MAX; i++) | 311 | for (i = 0; i < ARM_SEC_MAX; i++) |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index d9f5cd4e533f..e186ee1e63f6 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -53,7 +53,12 @@ armpmu_map_cache_event(const unsigned (*cache_map) | |||
53 | static int | 53 | static int |
54 | armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) | 54 | armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) |
55 | { | 55 | { |
56 | int mapping = (*event_map)[config]; | 56 | int mapping; |
57 | |||
58 | if (config >= PERF_COUNT_HW_MAX) | ||
59 | return -EINVAL; | ||
60 | |||
61 | mapping = (*event_map)[config]; | ||
57 | return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; | 62 | return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; |
58 | } | 63 | } |
59 | 64 | ||
@@ -253,6 +258,9 @@ validate_event(struct pmu_hw_events *hw_events, | |||
253 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | 258 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); |
254 | struct pmu *leader_pmu = event->group_leader->pmu; | 259 | struct pmu *leader_pmu = event->group_leader->pmu; |
255 | 260 | ||
261 | if (is_software_event(event)) | ||
262 | return 1; | ||
263 | |||
256 | if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) | 264 | if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) |
257 | return 1; | 265 | return 1; |
258 | 266 | ||
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index aebe0e99c153..8d6147b2001f 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c | |||
@@ -118,7 +118,8 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler) | |||
118 | continue; | 118 | continue; |
119 | } | 119 | } |
120 | 120 | ||
121 | err = request_irq(irq, handler, IRQF_NOBALANCING, "arm-pmu", | 121 | err = request_irq(irq, handler, |
122 | IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu", | ||
122 | cpu_pmu); | 123 | cpu_pmu); |
123 | if (err) { | 124 | if (err) { |
124 | pr_err("unable to request IRQ%d for ARM PMU counters\n", | 125 | pr_err("unable to request IRQ%d for ARM PMU counters\n", |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 536c85fe72a8..94f6b05f9e24 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -462,7 +462,7 @@ int in_gate_area_no_mm(unsigned long addr) | |||
462 | { | 462 | { |
463 | return in_gate_area(NULL, addr); | 463 | return in_gate_area(NULL, addr); |
464 | } | 464 | } |
465 | #define is_gate_vma(vma) ((vma) = &gate_vma) | 465 | #define is_gate_vma(vma) ((vma) == &gate_vma) |
466 | #else | 466 | #else |
467 | #define is_gate_vma(vma) 0 | 467 | #define is_gate_vma(vma) 0 |
468 | #endif | 468 | #endif |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index afc2489ee13b..0e1e2b3afa45 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -72,10 +72,10 @@ static int __init fpe_setup(char *line) | |||
72 | __setup("fpe=", fpe_setup); | 72 | __setup("fpe=", fpe_setup); |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | extern void paging_init(struct machine_desc *desc); | 75 | extern void paging_init(const struct machine_desc *desc); |
76 | extern void sanity_check_meminfo(void); | 76 | extern void sanity_check_meminfo(void); |
77 | extern enum reboot_mode reboot_mode; | 77 | extern enum reboot_mode reboot_mode; |
78 | extern void setup_dma_zone(struct machine_desc *desc); | 78 | extern void setup_dma_zone(const struct machine_desc *desc); |
79 | 79 | ||
80 | unsigned int processor_id; | 80 | unsigned int processor_id; |
81 | EXPORT_SYMBOL(processor_id); | 81 | EXPORT_SYMBOL(processor_id); |
@@ -139,7 +139,7 @@ EXPORT_SYMBOL(elf_platform); | |||
139 | static const char *cpu_name; | 139 | static const char *cpu_name; |
140 | static const char *machine_name; | 140 | static const char *machine_name; |
141 | static char __initdata cmd_line[COMMAND_LINE_SIZE]; | 141 | static char __initdata cmd_line[COMMAND_LINE_SIZE]; |
142 | struct machine_desc *machine_desc __initdata; | 142 | const struct machine_desc *machine_desc __initdata; |
143 | 143 | ||
144 | static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; | 144 | static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; |
145 | #define ENDIANNESS ((char)endian_test.l) | 145 | #define ENDIANNESS ((char)endian_test.l) |
@@ -607,7 +607,7 @@ static void __init setup_processor(void) | |||
607 | 607 | ||
608 | void __init dump_machine_table(void) | 608 | void __init dump_machine_table(void) |
609 | { | 609 | { |
610 | struct machine_desc *p; | 610 | const struct machine_desc *p; |
611 | 611 | ||
612 | early_print("Available machine support:\n\nID (hex)\tNAME\n"); | 612 | early_print("Available machine support:\n\nID (hex)\tNAME\n"); |
613 | for_each_machine_desc(p) | 613 | for_each_machine_desc(p) |
@@ -694,7 +694,7 @@ static int __init early_mem(char *p) | |||
694 | } | 694 | } |
695 | early_param("mem", early_mem); | 695 | early_param("mem", early_mem); |
696 | 696 | ||
697 | static void __init request_standard_resources(struct machine_desc *mdesc) | 697 | static void __init request_standard_resources(const struct machine_desc *mdesc) |
698 | { | 698 | { |
699 | struct memblock_region *region; | 699 | struct memblock_region *region; |
700 | struct resource *res; | 700 | struct resource *res; |
@@ -852,7 +852,7 @@ void __init hyp_mode_check(void) | |||
852 | 852 | ||
853 | void __init setup_arch(char **cmdline_p) | 853 | void __init setup_arch(char **cmdline_p) |
854 | { | 854 | { |
855 | struct machine_desc *mdesc; | 855 | const struct machine_desc *mdesc; |
856 | 856 | ||
857 | setup_processor(); | 857 | setup_processor(); |
858 | mdesc = setup_machine_fdt(__atags_pointer); | 858 | mdesc = setup_machine_fdt(__atags_pointer); |
@@ -994,15 +994,6 @@ static int c_show(struct seq_file *m, void *v) | |||
994 | seq_printf(m, "model name\t: %s rev %d (%s)\n", | 994 | seq_printf(m, "model name\t: %s rev %d (%s)\n", |
995 | cpu_name, cpuid & 15, elf_platform); | 995 | cpu_name, cpuid & 15, elf_platform); |
996 | 996 | ||
997 | #if defined(CONFIG_SMP) | ||
998 | seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", | ||
999 | per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ), | ||
1000 | (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100); | ||
1001 | #else | ||
1002 | seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", | ||
1003 | loops_per_jiffy / (500000/HZ), | ||
1004 | (loops_per_jiffy / (5000/HZ)) % 100); | ||
1005 | #endif | ||
1006 | /* dump out the processor features */ | 997 | /* dump out the processor features */ |
1007 | seq_puts(m, "Features\t: "); | 998 | seq_puts(m, "Features\t: "); |
1008 | 999 | ||
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index c2b4f8f0be9a..92d10e503746 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -145,6 +145,16 @@ int boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
145 | return -ENOSYS; | 145 | return -ENOSYS; |
146 | } | 146 | } |
147 | 147 | ||
148 | int platform_can_cpu_hotplug(void) | ||
149 | { | ||
150 | #ifdef CONFIG_HOTPLUG_CPU | ||
151 | if (smp_ops.cpu_kill) | ||
152 | return 1; | ||
153 | #endif | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
148 | #ifdef CONFIG_HOTPLUG_CPU | 158 | #ifdef CONFIG_HOTPLUG_CPU |
149 | static void percpu_timer_stop(void); | 159 | static void percpu_timer_stop(void); |
150 | 160 | ||
@@ -388,17 +398,8 @@ asmlinkage void secondary_start_kernel(void) | |||
388 | 398 | ||
389 | void __init smp_cpus_done(unsigned int max_cpus) | 399 | void __init smp_cpus_done(unsigned int max_cpus) |
390 | { | 400 | { |
391 | int cpu; | 401 | printk(KERN_INFO "SMP: Total of %d processors activated.\n", |
392 | unsigned long bogosum = 0; | 402 | num_online_cpus()); |
393 | |||
394 | for_each_online_cpu(cpu) | ||
395 | bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; | ||
396 | |||
397 | printk(KERN_INFO "SMP: Total of %d processors activated " | ||
398 | "(%lu.%02lu BogoMIPS).\n", | ||
399 | num_online_cpus(), | ||
400 | bogosum / (500000/HZ), | ||
401 | (bogosum / (5000/HZ)) % 100); | ||
402 | 403 | ||
403 | hyp_mode_check(); | 404 | hyp_mode_check(); |
404 | } | 405 | } |
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c index c2edfff573c2..83ccca303df8 100644 --- a/arch/arm/kernel/smp_tlb.c +++ b/arch/arm/kernel/smp_tlb.c | |||
@@ -104,7 +104,7 @@ void flush_tlb_all(void) | |||
104 | if (tlb_ops_need_broadcast()) | 104 | if (tlb_ops_need_broadcast()) |
105 | on_each_cpu(ipi_flush_tlb_all, NULL, 1); | 105 | on_each_cpu(ipi_flush_tlb_all, NULL, 1); |
106 | else | 106 | else |
107 | local_flush_tlb_all(); | 107 | __flush_tlb_all(); |
108 | broadcast_tlb_a15_erratum(); | 108 | broadcast_tlb_a15_erratum(); |
109 | } | 109 | } |
110 | 110 | ||
@@ -113,7 +113,7 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
113 | if (tlb_ops_need_broadcast()) | 113 | if (tlb_ops_need_broadcast()) |
114 | on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); | 114 | on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); |
115 | else | 115 | else |
116 | local_flush_tlb_mm(mm); | 116 | __flush_tlb_mm(mm); |
117 | broadcast_tlb_mm_a15_erratum(mm); | 117 | broadcast_tlb_mm_a15_erratum(mm); |
118 | } | 118 | } |
119 | 119 | ||
@@ -126,7 +126,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | |||
126 | on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, | 126 | on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, |
127 | &ta, 1); | 127 | &ta, 1); |
128 | } else | 128 | } else |
129 | local_flush_tlb_page(vma, uaddr); | 129 | __flush_tlb_page(vma, uaddr); |
130 | broadcast_tlb_mm_a15_erratum(vma->vm_mm); | 130 | broadcast_tlb_mm_a15_erratum(vma->vm_mm); |
131 | } | 131 | } |
132 | 132 | ||
@@ -137,7 +137,7 @@ void flush_tlb_kernel_page(unsigned long kaddr) | |||
137 | ta.ta_start = kaddr; | 137 | ta.ta_start = kaddr; |
138 | on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); | 138 | on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); |
139 | } else | 139 | } else |
140 | local_flush_tlb_kernel_page(kaddr); | 140 | __flush_tlb_kernel_page(kaddr); |
141 | broadcast_tlb_a15_erratum(); | 141 | broadcast_tlb_a15_erratum(); |
142 | } | 142 | } |
143 | 143 | ||
@@ -173,5 +173,5 @@ void flush_bp_all(void) | |||
173 | if (tlb_ops_need_broadcast()) | 173 | if (tlb_ops_need_broadcast()) |
174 | on_each_cpu(ipi_flush_bp_all, NULL, 1); | 174 | on_each_cpu(ipi_flush_bp_all, NULL, 1); |
175 | else | 175 | else |
176 | local_flush_bp_all(); | 176 | __flush_bp_all(); |
177 | } | 177 | } |
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index c5a59546a256..85a87370f144 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c | |||
@@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = { | |||
74 | {NULL, }, | 74 | {NULL, }, |
75 | }; | 75 | }; |
76 | 76 | ||
77 | struct cpu_capacity { | 77 | unsigned long *__cpu_capacity; |
78 | unsigned long hwid; | 78 | #define cpu_capacity(cpu) __cpu_capacity[cpu] |
79 | unsigned long capacity; | ||
80 | }; | ||
81 | |||
82 | struct cpu_capacity *cpu_capacity; | ||
83 | 79 | ||
84 | unsigned long middle_capacity = 1; | 80 | unsigned long middle_capacity = 1; |
85 | 81 | ||
@@ -100,15 +96,19 @@ static void __init parse_dt_topology(void) | |||
100 | unsigned long capacity = 0; | 96 | unsigned long capacity = 0; |
101 | int alloc_size, cpu = 0; | 97 | int alloc_size, cpu = 0; |
102 | 98 | ||
103 | alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity); | 99 | alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity); |
104 | cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT); | 100 | __cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT); |
105 | 101 | ||
106 | while ((cn = of_find_node_by_type(cn, "cpu"))) { | 102 | for_each_possible_cpu(cpu) { |
107 | const u32 *rate, *reg; | 103 | const u32 *rate; |
108 | int len; | 104 | int len; |
109 | 105 | ||
110 | if (cpu >= num_possible_cpus()) | 106 | /* too early to use cpu->of_node */ |
111 | break; | 107 | cn = of_get_cpu_node(cpu, NULL); |
108 | if (!cn) { | ||
109 | pr_err("missing device node for CPU %d\n", cpu); | ||
110 | continue; | ||
111 | } | ||
112 | 112 | ||
113 | for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++) | 113 | for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++) |
114 | if (of_device_is_compatible(cn, cpu_eff->compatible)) | 114 | if (of_device_is_compatible(cn, cpu_eff->compatible)) |
@@ -124,12 +124,6 @@ static void __init parse_dt_topology(void) | |||
124 | continue; | 124 | continue; |
125 | } | 125 | } |
126 | 126 | ||
127 | reg = of_get_property(cn, "reg", &len); | ||
128 | if (!reg || len != 4) { | ||
129 | pr_err("%s missing reg property\n", cn->full_name); | ||
130 | continue; | ||
131 | } | ||
132 | |||
133 | capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency; | 127 | capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency; |
134 | 128 | ||
135 | /* Save min capacity of the system */ | 129 | /* Save min capacity of the system */ |
@@ -140,13 +134,9 @@ static void __init parse_dt_topology(void) | |||
140 | if (capacity > max_capacity) | 134 | if (capacity > max_capacity) |
141 | max_capacity = capacity; | 135 | max_capacity = capacity; |
142 | 136 | ||
143 | cpu_capacity[cpu].capacity = capacity; | 137 | cpu_capacity(cpu) = capacity; |
144 | cpu_capacity[cpu++].hwid = be32_to_cpup(reg); | ||
145 | } | 138 | } |
146 | 139 | ||
147 | if (cpu < num_possible_cpus()) | ||
148 | cpu_capacity[cpu].hwid = (unsigned long)(-1); | ||
149 | |||
150 | /* If min and max capacities are equals, we bypass the update of the | 140 | /* If min and max capacities are equals, we bypass the update of the |
151 | * cpu_scale because all CPUs have the same capacity. Otherwise, we | 141 | * cpu_scale because all CPUs have the same capacity. Otherwise, we |
152 | * compute a middle_capacity factor that will ensure that the capacity | 142 | * compute a middle_capacity factor that will ensure that the capacity |
@@ -154,9 +144,7 @@ static void __init parse_dt_topology(void) | |||
154 | * SCHED_POWER_SCALE, which is the default value, but with the | 144 | * SCHED_POWER_SCALE, which is the default value, but with the |
155 | * constraint explained near table_efficiency[]. | 145 | * constraint explained near table_efficiency[]. |
156 | */ | 146 | */ |
157 | if (min_capacity == max_capacity) | 147 | if (4*max_capacity < (3*(max_capacity + min_capacity))) |
158 | cpu_capacity[0].hwid = (unsigned long)(-1); | ||
159 | else if (4*max_capacity < (3*(max_capacity + min_capacity))) | ||
160 | middle_capacity = (min_capacity + max_capacity) | 148 | middle_capacity = (min_capacity + max_capacity) |
161 | >> (SCHED_POWER_SHIFT+1); | 149 | >> (SCHED_POWER_SHIFT+1); |
162 | else | 150 | else |
@@ -170,23 +158,12 @@ static void __init parse_dt_topology(void) | |||
170 | * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the | 158 | * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the |
171 | * function returns directly for SMP system. | 159 | * function returns directly for SMP system. |
172 | */ | 160 | */ |
173 | void update_cpu_power(unsigned int cpu, unsigned long hwid) | 161 | void update_cpu_power(unsigned int cpu) |
174 | { | 162 | { |
175 | unsigned int idx = 0; | 163 | if (!cpu_capacity(cpu)) |
176 | |||
177 | /* look for the cpu's hwid in the cpu capacity table */ | ||
178 | for (idx = 0; idx < num_possible_cpus(); idx++) { | ||
179 | if (cpu_capacity[idx].hwid == hwid) | ||
180 | break; | ||
181 | |||
182 | if (cpu_capacity[idx].hwid == -1) | ||
183 | return; | ||
184 | } | ||
185 | |||
186 | if (idx == num_possible_cpus()) | ||
187 | return; | 164 | return; |
188 | 165 | ||
189 | set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity); | 166 | set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity); |
190 | 167 | ||
191 | printk(KERN_INFO "CPU%u: update cpu_power %lu\n", | 168 | printk(KERN_INFO "CPU%u: update cpu_power %lu\n", |
192 | cpu, arch_scale_freq_power(NULL, cpu)); | 169 | cpu, arch_scale_freq_power(NULL, cpu)); |
@@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid) | |||
194 | 171 | ||
195 | #else | 172 | #else |
196 | static inline void parse_dt_topology(void) {} | 173 | static inline void parse_dt_topology(void) {} |
197 | static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {} | 174 | static inline void update_cpu_power(unsigned int cpuid) {} |
198 | #endif | 175 | #endif |
199 | 176 | ||
200 | /* | 177 | /* |
@@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid) | |||
281 | 258 | ||
282 | update_siblings_masks(cpuid); | 259 | update_siblings_masks(cpuid); |
283 | 260 | ||
284 | update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK); | 261 | update_cpu_power(cpuid); |
285 | 262 | ||
286 | printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", | 263 | printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", |
287 | cpuid, cpu_topology[cpuid].thread_id, | 264 | cpuid, cpu_topology[cpuid].thread_id, |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index ab517fcce21b..8fcda140358d 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -497,28 +497,64 @@ static int bad_syscall(int n, struct pt_regs *regs) | |||
497 | return regs->ARM_r0; | 497 | return regs->ARM_r0; |
498 | } | 498 | } |
499 | 499 | ||
500 | static long do_cache_op_restart(struct restart_block *); | ||
501 | |||
500 | static inline int | 502 | static inline int |
501 | do_cache_op(unsigned long start, unsigned long end, int flags) | 503 | __do_cache_op(unsigned long start, unsigned long end) |
502 | { | 504 | { |
503 | struct mm_struct *mm = current->active_mm; | 505 | int ret; |
504 | struct vm_area_struct *vma; | 506 | unsigned long chunk = PAGE_SIZE; |
507 | |||
508 | do { | ||
509 | if (signal_pending(current)) { | ||
510 | struct thread_info *ti = current_thread_info(); | ||
511 | |||
512 | ti->restart_block = (struct restart_block) { | ||
513 | .fn = do_cache_op_restart, | ||
514 | }; | ||
515 | |||
516 | ti->arm_restart_block = (struct arm_restart_block) { | ||
517 | { | ||
518 | .cache = { | ||
519 | .start = start, | ||
520 | .end = end, | ||
521 | }, | ||
522 | }, | ||
523 | }; | ||
524 | |||
525 | return -ERESTART_RESTARTBLOCK; | ||
526 | } | ||
527 | |||
528 | ret = flush_cache_user_range(start, start + chunk); | ||
529 | if (ret) | ||
530 | return ret; | ||
505 | 531 | ||
532 | cond_resched(); | ||
533 | start += chunk; | ||
534 | } while (start < end); | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static long do_cache_op_restart(struct restart_block *unused) | ||
540 | { | ||
541 | struct arm_restart_block *restart_block; | ||
542 | |||
543 | restart_block = ¤t_thread_info()->arm_restart_block; | ||
544 | return __do_cache_op(restart_block->cache.start, | ||
545 | restart_block->cache.end); | ||
546 | } | ||
547 | |||
548 | static inline int | ||
549 | do_cache_op(unsigned long start, unsigned long end, int flags) | ||
550 | { | ||
506 | if (end < start || flags) | 551 | if (end < start || flags) |
507 | return -EINVAL; | 552 | return -EINVAL; |
508 | 553 | ||
509 | down_read(&mm->mmap_sem); | 554 | if (!access_ok(VERIFY_READ, start, end - start)) |
510 | vma = find_vma(mm, start); | 555 | return -EFAULT; |
511 | if (vma && vma->vm_start < end) { | ||
512 | if (start < vma->vm_start) | ||
513 | start = vma->vm_start; | ||
514 | if (end > vma->vm_end) | ||
515 | end = vma->vm_end; | ||
516 | 556 | ||
517 | up_read(&mm->mmap_sem); | 557 | return __do_cache_op(start, end); |
518 | return flush_cache_user_range(start, end); | ||
519 | } | ||
520 | up_read(&mm->mmap_sem); | ||
521 | return -EINVAL; | ||
522 | } | 558 | } |
523 | 559 | ||
524 | /* | 560 | /* |
diff --git a/arch/arm/kernel/v7m.c b/arch/arm/kernel/v7m.c new file mode 100644 index 000000000000..4d2cba94f5cc --- /dev/null +++ b/arch/arm/kernel/v7m.c | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Uwe Kleine-Koenig for Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it under | ||
5 | * the terms of the GNU General Public License version 2 as published by the | ||
6 | * Free Software Foundation. | ||
7 | */ | ||
8 | #include <linux/io.h> | ||
9 | #include <linux/reboot.h> | ||
10 | #include <asm/barrier.h> | ||
11 | #include <asm/v7m.h> | ||
12 | |||
13 | void armv7m_restart(enum reboot_mode mode, const char *cmd) | ||
14 | { | ||
15 | dsb(); | ||
16 | __raw_writel(V7M_SCB_AIRCR_VECTKEY | V7M_SCB_AIRCR_SYSRESETREQ, | ||
17 | BASEADDR_V7M_SCB + V7M_SCB_AIRCR); | ||
18 | dsb(); | ||
19 | } | ||
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 741f66a2edbd..9c697db2787e 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -219,6 +219,10 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
219 | return -EINVAL; | 219 | return -EINVAL; |
220 | } | 220 | } |
221 | 221 | ||
222 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
223 | { | ||
224 | } | ||
225 | |||
222 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 226 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
223 | struct kvm_memory_slot *memslot, | 227 | struct kvm_memory_slot *memslot, |
224 | struct kvm_userspace_memory_region *mem, | 228 | struct kvm_userspace_memory_region *mem, |
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index 4a5199070430..db9cf692d4dd 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c | |||
@@ -146,7 +146,11 @@ static bool pm_fake(struct kvm_vcpu *vcpu, | |||
146 | #define access_pmintenclr pm_fake | 146 | #define access_pmintenclr pm_fake |
147 | 147 | ||
148 | /* Architected CP15 registers. | 148 | /* Architected CP15 registers. |
149 | * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 | 149 | * CRn denotes the primary register number, but is copied to the CRm in the |
150 | * user space API for 64-bit register access in line with the terminology used | ||
151 | * in the ARM ARM. | ||
152 | * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit | ||
153 | * registers preceding 32-bit ones. | ||
150 | */ | 154 | */ |
151 | static const struct coproc_reg cp15_regs[] = { | 155 | static const struct coproc_reg cp15_regs[] = { |
152 | /* CSSELR: swapped by interrupt.S. */ | 156 | /* CSSELR: swapped by interrupt.S. */ |
@@ -154,8 +158,8 @@ static const struct coproc_reg cp15_regs[] = { | |||
154 | NULL, reset_unknown, c0_CSSELR }, | 158 | NULL, reset_unknown, c0_CSSELR }, |
155 | 159 | ||
156 | /* TTBR0/TTBR1: swapped by interrupt.S. */ | 160 | /* TTBR0/TTBR1: swapped by interrupt.S. */ |
157 | { CRm( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 }, | 161 | { CRm64( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 }, |
158 | { CRm( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 }, | 162 | { CRm64( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 }, |
159 | 163 | ||
160 | /* TTBCR: swapped by interrupt.S. */ | 164 | /* TTBCR: swapped by interrupt.S. */ |
161 | { CRn( 2), CRm( 0), Op1( 0), Op2( 2), is32, | 165 | { CRn( 2), CRm( 0), Op1( 0), Op2( 2), is32, |
@@ -182,7 +186,7 @@ static const struct coproc_reg cp15_regs[] = { | |||
182 | NULL, reset_unknown, c6_IFAR }, | 186 | NULL, reset_unknown, c6_IFAR }, |
183 | 187 | ||
184 | /* PAR swapped by interrupt.S */ | 188 | /* PAR swapped by interrupt.S */ |
185 | { CRn( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR }, | 189 | { CRm64( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR }, |
186 | 190 | ||
187 | /* | 191 | /* |
188 | * DC{C,I,CI}SW operations: | 192 | * DC{C,I,CI}SW operations: |
@@ -399,12 +403,13 @@ static bool index_to_params(u64 id, struct coproc_params *params) | |||
399 | | KVM_REG_ARM_OPC1_MASK)) | 403 | | KVM_REG_ARM_OPC1_MASK)) |
400 | return false; | 404 | return false; |
401 | params->is_64bit = true; | 405 | params->is_64bit = true; |
402 | params->CRm = ((id & KVM_REG_ARM_CRM_MASK) | 406 | /* CRm to CRn: see cp15_to_index for details */ |
407 | params->CRn = ((id & KVM_REG_ARM_CRM_MASK) | ||
403 | >> KVM_REG_ARM_CRM_SHIFT); | 408 | >> KVM_REG_ARM_CRM_SHIFT); |
404 | params->Op1 = ((id & KVM_REG_ARM_OPC1_MASK) | 409 | params->Op1 = ((id & KVM_REG_ARM_OPC1_MASK) |
405 | >> KVM_REG_ARM_OPC1_SHIFT); | 410 | >> KVM_REG_ARM_OPC1_SHIFT); |
406 | params->Op2 = 0; | 411 | params->Op2 = 0; |
407 | params->CRn = 0; | 412 | params->CRm = 0; |
408 | return true; | 413 | return true; |
409 | default: | 414 | default: |
410 | return false; | 415 | return false; |
@@ -898,7 +903,14 @@ static u64 cp15_to_index(const struct coproc_reg *reg) | |||
898 | if (reg->is_64) { | 903 | if (reg->is_64) { |
899 | val |= KVM_REG_SIZE_U64; | 904 | val |= KVM_REG_SIZE_U64; |
900 | val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT); | 905 | val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT); |
901 | val |= (reg->CRm << KVM_REG_ARM_CRM_SHIFT); | 906 | /* |
907 | * CRn always denotes the primary coproc. reg. nr. for the | ||
908 | * in-kernel representation, but the user space API uses the | ||
909 | * CRm for the encoding, because it is modelled after the | ||
910 | * MRRC/MCRR instructions: see the ARM ARM rev. c page | ||
911 | * B3-1445 | ||
912 | */ | ||
913 | val |= (reg->CRn << KVM_REG_ARM_CRM_SHIFT); | ||
902 | } else { | 914 | } else { |
903 | val |= KVM_REG_SIZE_U32; | 915 | val |= KVM_REG_SIZE_U32; |
904 | val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT); | 916 | val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT); |
diff --git a/arch/arm/kvm/coproc.h b/arch/arm/kvm/coproc.h index b7301d3e4799..0461d5c8d3de 100644 --- a/arch/arm/kvm/coproc.h +++ b/arch/arm/kvm/coproc.h | |||
@@ -135,6 +135,8 @@ static inline int cmp_reg(const struct coproc_reg *i1, | |||
135 | return -1; | 135 | return -1; |
136 | if (i1->CRn != i2->CRn) | 136 | if (i1->CRn != i2->CRn) |
137 | return i1->CRn - i2->CRn; | 137 | return i1->CRn - i2->CRn; |
138 | if (i1->is_64 != i2->is_64) | ||
139 | return i2->is_64 - i1->is_64; | ||
138 | if (i1->CRm != i2->CRm) | 140 | if (i1->CRm != i2->CRm) |
139 | return i1->CRm - i2->CRm; | 141 | return i1->CRm - i2->CRm; |
140 | if (i1->Op1 != i2->Op1) | 142 | if (i1->Op1 != i2->Op1) |
@@ -145,6 +147,7 @@ static inline int cmp_reg(const struct coproc_reg *i1, | |||
145 | 147 | ||
146 | #define CRn(_x) .CRn = _x | 148 | #define CRn(_x) .CRn = _x |
147 | #define CRm(_x) .CRm = _x | 149 | #define CRm(_x) .CRm = _x |
150 | #define CRm64(_x) .CRn = _x, .CRm = 0 | ||
148 | #define Op1(_x) .Op1 = _x | 151 | #define Op1(_x) .Op1 = _x |
149 | #define Op2(_x) .Op2 = _x | 152 | #define Op2(_x) .Op2 = _x |
150 | #define is64 .is_64 = true | 153 | #define is64 .is_64 = true |
diff --git a/arch/arm/kvm/coproc_a15.c b/arch/arm/kvm/coproc_a15.c index 685063a6d0cf..cf93472b9dd6 100644 --- a/arch/arm/kvm/coproc_a15.c +++ b/arch/arm/kvm/coproc_a15.c | |||
@@ -114,7 +114,11 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu, | |||
114 | 114 | ||
115 | /* | 115 | /* |
116 | * A15-specific CP15 registers. | 116 | * A15-specific CP15 registers. |
117 | * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 | 117 | * CRn denotes the primary register number, but is copied to the CRm in the |
118 | * user space API for 64-bit register access in line with the terminology used | ||
119 | * in the ARM ARM. | ||
120 | * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit | ||
121 | * registers preceding 32-bit ones. | ||
118 | */ | 122 | */ |
119 | static const struct coproc_reg a15_regs[] = { | 123 | static const struct coproc_reg a15_regs[] = { |
120 | /* MPIDR: we use VMPIDR for guest access. */ | 124 | /* MPIDR: we use VMPIDR for guest access. */ |
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S index f048338135f7..1b9844d369cc 100644 --- a/arch/arm/kvm/init.S +++ b/arch/arm/kvm/init.S | |||
@@ -142,7 +142,7 @@ target: @ We're now in the trampoline code, switch page tables | |||
142 | 142 | ||
143 | @ Invalidate the old TLBs | 143 | @ Invalidate the old TLBs |
144 | mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH | 144 | mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH |
145 | dsb | 145 | dsb ish |
146 | 146 | ||
147 | eret | 147 | eret |
148 | 148 | ||
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index 16cd4ba5d7fd..ddc15539bad2 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S | |||
@@ -55,7 +55,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa) | |||
55 | mcrr p15, 6, r2, r3, c2 @ Write VTTBR | 55 | mcrr p15, 6, r2, r3, c2 @ Write VTTBR |
56 | isb | 56 | isb |
57 | mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored) | 57 | mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored) |
58 | dsb | 58 | dsb ish |
59 | isb | 59 | isb |
60 | mov r2, #0 | 60 | mov r2, #0 |
61 | mov r3, #0 | 61 | mov r3, #0 |
@@ -79,7 +79,7 @@ ENTRY(__kvm_flush_vm_context) | |||
79 | mcr p15, 4, r0, c8, c3, 4 | 79 | mcr p15, 4, r0, c8, c3, 4 |
80 | /* Invalidate instruction caches Inner Shareable (ICIALLUIS) */ | 80 | /* Invalidate instruction caches Inner Shareable (ICIALLUIS) */ |
81 | mcr p15, 0, r0, c7, c1, 0 | 81 | mcr p15, 0, r0, c7, c1, 0 |
82 | dsb | 82 | dsb ish |
83 | isb @ Not necessary if followed by eret | 83 | isb @ Not necessary if followed by eret |
84 | 84 | ||
85 | bx lr | 85 | bx lr |
@@ -492,10 +492,10 @@ __kvm_hyp_code_end: | |||
492 | .section ".rodata" | 492 | .section ".rodata" |
493 | 493 | ||
494 | und_die_str: | 494 | und_die_str: |
495 | .ascii "unexpected undefined exception in Hyp mode at: %#08x" | 495 | .ascii "unexpected undefined exception in Hyp mode at: %#08x\n" |
496 | pabt_die_str: | 496 | pabt_die_str: |
497 | .ascii "unexpected prefetch abort in Hyp mode at: %#08x" | 497 | .ascii "unexpected prefetch abort in Hyp mode at: %#08x\n" |
498 | dabt_die_str: | 498 | dabt_die_str: |
499 | .ascii "unexpected data abort in Hyp mode at: %#08x" | 499 | .ascii "unexpected data abort in Hyp mode at: %#08x\n" |
500 | svc_die_str: | 500 | svc_die_str: |
501 | .ascii "unexpected HVC/SVC trap in Hyp mode at: %#08x" | 501 | .ascii "unexpected HVC/SVC trap in Hyp mode at: %#08x\n" |
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c index b8e06b7a2833..0c25d9487d53 100644 --- a/arch/arm/kvm/mmio.c +++ b/arch/arm/kvm/mmio.c | |||
@@ -63,7 +63,8 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
63 | static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | 63 | static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, |
64 | struct kvm_exit_mmio *mmio) | 64 | struct kvm_exit_mmio *mmio) |
65 | { | 65 | { |
66 | unsigned long rt, len; | 66 | unsigned long rt; |
67 | int len; | ||
67 | bool is_write, sign_extend; | 68 | bool is_write, sign_extend; |
68 | 69 | ||
69 | if (kvm_vcpu_dabt_isextabt(vcpu)) { | 70 | if (kvm_vcpu_dabt_isextabt(vcpu)) { |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index ca6bea4859b4..b0de86b56c13 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -85,6 +85,12 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc) | |||
85 | return p; | 85 | return p; |
86 | } | 86 | } |
87 | 87 | ||
88 | static bool page_empty(void *ptr) | ||
89 | { | ||
90 | struct page *ptr_page = virt_to_page(ptr); | ||
91 | return page_count(ptr_page) == 1; | ||
92 | } | ||
93 | |||
88 | static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr) | 94 | static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr) |
89 | { | 95 | { |
90 | pmd_t *pmd_table = pmd_offset(pud, 0); | 96 | pmd_t *pmd_table = pmd_offset(pud, 0); |
@@ -103,12 +109,6 @@ static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr) | |||
103 | put_page(virt_to_page(pmd)); | 109 | put_page(virt_to_page(pmd)); |
104 | } | 110 | } |
105 | 111 | ||
106 | static bool pmd_empty(pmd_t *pmd) | ||
107 | { | ||
108 | struct page *pmd_page = virt_to_page(pmd); | ||
109 | return page_count(pmd_page) == 1; | ||
110 | } | ||
111 | |||
112 | static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr) | 112 | static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr) |
113 | { | 113 | { |
114 | if (pte_present(*pte)) { | 114 | if (pte_present(*pte)) { |
@@ -118,12 +118,6 @@ static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr) | |||
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
121 | static bool pte_empty(pte_t *pte) | ||
122 | { | ||
123 | struct page *pte_page = virt_to_page(pte); | ||
124 | return page_count(pte_page) == 1; | ||
125 | } | ||
126 | |||
127 | static void unmap_range(struct kvm *kvm, pgd_t *pgdp, | 121 | static void unmap_range(struct kvm *kvm, pgd_t *pgdp, |
128 | unsigned long long start, u64 size) | 122 | unsigned long long start, u64 size) |
129 | { | 123 | { |
@@ -132,37 +126,37 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, | |||
132 | pmd_t *pmd; | 126 | pmd_t *pmd; |
133 | pte_t *pte; | 127 | pte_t *pte; |
134 | unsigned long long addr = start, end = start + size; | 128 | unsigned long long addr = start, end = start + size; |
135 | u64 range; | 129 | u64 next; |
136 | 130 | ||
137 | while (addr < end) { | 131 | while (addr < end) { |
138 | pgd = pgdp + pgd_index(addr); | 132 | pgd = pgdp + pgd_index(addr); |
139 | pud = pud_offset(pgd, addr); | 133 | pud = pud_offset(pgd, addr); |
140 | if (pud_none(*pud)) { | 134 | if (pud_none(*pud)) { |
141 | addr += PUD_SIZE; | 135 | addr = pud_addr_end(addr, end); |
142 | continue; | 136 | continue; |
143 | } | 137 | } |
144 | 138 | ||
145 | pmd = pmd_offset(pud, addr); | 139 | pmd = pmd_offset(pud, addr); |
146 | if (pmd_none(*pmd)) { | 140 | if (pmd_none(*pmd)) { |
147 | addr += PMD_SIZE; | 141 | addr = pmd_addr_end(addr, end); |
148 | continue; | 142 | continue; |
149 | } | 143 | } |
150 | 144 | ||
151 | pte = pte_offset_kernel(pmd, addr); | 145 | pte = pte_offset_kernel(pmd, addr); |
152 | clear_pte_entry(kvm, pte, addr); | 146 | clear_pte_entry(kvm, pte, addr); |
153 | range = PAGE_SIZE; | 147 | next = addr + PAGE_SIZE; |
154 | 148 | ||
155 | /* If we emptied the pte, walk back up the ladder */ | 149 | /* If we emptied the pte, walk back up the ladder */ |
156 | if (pte_empty(pte)) { | 150 | if (page_empty(pte)) { |
157 | clear_pmd_entry(kvm, pmd, addr); | 151 | clear_pmd_entry(kvm, pmd, addr); |
158 | range = PMD_SIZE; | 152 | next = pmd_addr_end(addr, end); |
159 | if (pmd_empty(pmd)) { | 153 | if (page_empty(pmd) && !page_empty(pud)) { |
160 | clear_pud_entry(kvm, pud, addr); | 154 | clear_pud_entry(kvm, pud, addr); |
161 | range = PUD_SIZE; | 155 | next = pud_addr_end(addr, end); |
162 | } | 156 | } |
163 | } | 157 | } |
164 | 158 | ||
165 | addr += range; | 159 | addr = next; |
166 | } | 160 | } |
167 | } | 161 | } |
168 | 162 | ||
@@ -495,7 +489,6 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, | |||
495 | 489 | ||
496 | for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) { | 490 | for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) { |
497 | pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE); | 491 | pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE); |
498 | kvm_set_s2pte_writable(&pte); | ||
499 | 492 | ||
500 | ret = mmu_topup_memory_cache(&cache, 2, 2); | 493 | ret = mmu_topup_memory_cache(&cache, 2, 2); |
501 | if (ret) | 494 | if (ret) |
diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c index b7840e7aa452..71e08baee209 100644 --- a/arch/arm/kvm/reset.c +++ b/arch/arm/kvm/reset.c | |||
@@ -40,7 +40,7 @@ static struct kvm_regs a15_regs_reset = { | |||
40 | }; | 40 | }; |
41 | 41 | ||
42 | static const struct kvm_irq_level a15_vtimer_irq = { | 42 | static const struct kvm_irq_level a15_vtimer_irq = { |
43 | .irq = 27, | 43 | { .irq = 27 }, |
44 | .level = 1, | 44 | .level = 1, |
45 | }; | 45 | }; |
46 | 46 | ||
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h index a8e73ed5ad5b..b1d640f78623 100644 --- a/arch/arm/kvm/trace.h +++ b/arch/arm/kvm/trace.h | |||
@@ -59,10 +59,9 @@ TRACE_EVENT(kvm_guest_fault, | |||
59 | __entry->ipa = ipa; | 59 | __entry->ipa = ipa; |
60 | ), | 60 | ), |
61 | 61 | ||
62 | TP_printk("guest fault at PC %#08lx (hxfar %#08lx, " | 62 | TP_printk("ipa %#llx, hsr %#08lx, hxfar %#08lx, pc %#08lx", |
63 | "ipa %#16llx, hsr %#08lx", | 63 | __entry->ipa, __entry->hsr, |
64 | __entry->vcpu_pc, __entry->hxfar, | 64 | __entry->hxfar, __entry->vcpu_pc) |
65 | __entry->ipa, __entry->hsr) | ||
66 | ); | 65 | ); |
67 | 66 | ||
68 | TRACE_EVENT(kvm_irq_line, | 67 | TRACE_EVENT(kvm_irq_line, |
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index af72969820b4..aaf3a8731136 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile | |||
@@ -45,3 +45,9 @@ lib-$(CONFIG_ARCH_SHARK) += io-shark.o | |||
45 | 45 | ||
46 | $(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S | 46 | $(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S |
47 | $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S | 47 | $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S |
48 | |||
49 | ifeq ($(CONFIG_KERNEL_MODE_NEON),y) | ||
50 | NEON_FLAGS := -mfloat-abi=softfp -mfpu=neon | ||
51 | CFLAGS_xor-neon.o += $(NEON_FLAGS) | ||
52 | lib-$(CONFIG_XOR_BLOCKS) += xor-neon.o | ||
53 | endif | ||
diff --git a/arch/arm/lib/xor-neon.c b/arch/arm/lib/xor-neon.c new file mode 100644 index 000000000000..f485e5a2af4b --- /dev/null +++ b/arch/arm/lib/xor-neon.c | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/xor-neon.c | ||
3 | * | ||
4 | * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/raid/xor.h> | ||
12 | |||
13 | #ifndef __ARM_NEON__ | ||
14 | #error You should compile this file with '-mfloat-abi=softfp -mfpu=neon' | ||
15 | #endif | ||
16 | |||
17 | /* | ||
18 | * Pull in the reference implementations while instructing GCC (through | ||
19 | * -ftree-vectorize) to attempt to exploit implicit parallelism and emit | ||
20 | * NEON instructions. | ||
21 | */ | ||
22 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) | ||
23 | #pragma GCC optimize "tree-vectorize" | ||
24 | #else | ||
25 | /* | ||
26 | * While older versions of GCC do not generate incorrect code, they fail to | ||
27 | * recognize the parallel nature of these functions, and emit plain ARM code, | ||
28 | * which is known to be slower than the optimized ARM code in asm-arm/xor.h. | ||
29 | */ | ||
30 | #warning This code requires at least version 4.6 of GCC | ||
31 | #endif | ||
32 | |||
33 | #pragma GCC diagnostic ignored "-Wunused-variable" | ||
34 | #include <asm-generic/xor.h> | ||
35 | |||
36 | struct xor_block_template const xor_block_neon_inner = { | ||
37 | .name = "__inner_neon__", | ||
38 | .do_2 = xor_8regs_2, | ||
39 | .do_3 = xor_8regs_3, | ||
40 | .do_4 = xor_8regs_4, | ||
41 | .do_5 = xor_8regs_5, | ||
42 | }; | ||
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index 2abee6626aac..916e5a142917 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c | |||
@@ -227,6 +227,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
227 | CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk), | 227 | CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk), |
228 | CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk), | 228 | CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk), |
229 | CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), | 229 | CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), |
230 | CLKDEV_CON_DEV_ID("usart", "f8040000.serial", &uart0_clk), | ||
231 | CLKDEV_CON_DEV_ID("usart", "f8044000.serial", &uart1_clk), | ||
230 | CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), | 232 | CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), |
231 | CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), | 233 | CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), |
232 | CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk), | 234 | CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk), |
diff --git a/arch/arm/mach-at91/include/mach/at91_adc.h b/arch/arm/mach-at91/include/mach/at91_adc.h index 8e7ed5c90817..048a57f76bd3 100644 --- a/arch/arm/mach-at91/include/mach/at91_adc.h +++ b/arch/arm/mach-at91/include/mach/at91_adc.h | |||
@@ -28,9 +28,12 @@ | |||
28 | #define AT91_ADC_TRGSEL_EXTERNAL (6 << 1) | 28 | #define AT91_ADC_TRGSEL_EXTERNAL (6 << 1) |
29 | #define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */ | 29 | #define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */ |
30 | #define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */ | 30 | #define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */ |
31 | #define AT91_ADC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ | 31 | #define AT91_ADC_PRESCAL_9260 (0x3f << 8) /* Prescalar Rate Selection */ |
32 | #define AT91_ADC_PRESCAL_9G45 (0xff << 8) | ||
32 | #define AT91_ADC_PRESCAL_(x) ((x) << 8) | 33 | #define AT91_ADC_PRESCAL_(x) ((x) << 8) |
33 | #define AT91_ADC_STARTUP (0x1f << 16) /* Startup Up Time */ | 34 | #define AT91_ADC_STARTUP_9260 (0x1f << 16) /* Startup Up Time */ |
35 | #define AT91_ADC_STARTUP_9G45 (0x7f << 16) | ||
36 | #define AT91_ADC_STARTUP_9X5 (0xf << 16) | ||
34 | #define AT91_ADC_STARTUP_(x) ((x) << 16) | 37 | #define AT91_ADC_STARTUP_(x) ((x) << 16) |
35 | #define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */ | 38 | #define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */ |
36 | #define AT91_ADC_SHTIM_(x) ((x) << 24) | 39 | #define AT91_ADC_SHTIM_(x) ((x) << 24) |
@@ -48,6 +51,9 @@ | |||
48 | #define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */ | 51 | #define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */ |
49 | #define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */ | 52 | #define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */ |
50 | 53 | ||
54 | #define AT91_ADC_SR_9X5 0x30 /* Status Register for 9x5 */ | ||
55 | #define AT91_ADC_SR_DRDY_9X5 (1 << 24) /* Data Ready */ | ||
56 | |||
51 | #define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */ | 57 | #define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */ |
52 | #define AT91_ADC_LDATA (0x3ff) | 58 | #define AT91_ADC_LDATA (0x3ff) |
53 | 59 | ||
@@ -58,4 +64,10 @@ | |||
58 | #define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */ | 64 | #define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */ |
59 | #define AT91_ADC_DATA (0x3ff) | 65 | #define AT91_ADC_DATA (0x3ff) |
60 | 66 | ||
67 | #define AT91_ADC_CDR0_9X5 (0x50) /* Channel Data Register 0 for 9X5 */ | ||
68 | |||
69 | #define AT91_ADC_TRGR_9260 AT91_ADC_MR | ||
70 | #define AT91_ADC_TRGR_9G45 0x08 | ||
71 | #define AT91_ADC_TRGR_9X5 0xC0 | ||
72 | |||
61 | #endif | 73 | #endif |
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index bea6793a7ede..9f09f45835f8 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c | |||
@@ -1249,12 +1249,10 @@ static struct vpif_capture_config da850_vpif_capture_config = { | |||
1249 | 1249 | ||
1250 | static struct adv7343_platform_data adv7343_pdata = { | 1250 | static struct adv7343_platform_data adv7343_pdata = { |
1251 | .mode_config = { | 1251 | .mode_config = { |
1252 | .dac_3 = 1, | 1252 | .dac = { 1, 1, 1 }, |
1253 | .dac_2 = 1, | ||
1254 | .dac_1 = 1, | ||
1255 | }, | 1253 | }, |
1256 | .sd_config = { | 1254 | .sd_config = { |
1257 | .sd_dac_out1 = 1, | 1255 | .sd_dac_out = { 1 }, |
1258 | }, | 1256 | }, |
1259 | }; | 1257 | }; |
1260 | 1258 | ||
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index dff4ddc5ef81..139e42da25f0 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c | |||
@@ -75,6 +75,7 @@ static struct davinci_nand_pdata davinci_nand_data = { | |||
75 | .parts = davinci_nand_partitions, | 75 | .parts = davinci_nand_partitions, |
76 | .nr_parts = ARRAY_SIZE(davinci_nand_partitions), | 76 | .nr_parts = ARRAY_SIZE(davinci_nand_partitions), |
77 | .ecc_mode = NAND_ECC_HW_SYNDROME, | 77 | .ecc_mode = NAND_ECC_HW_SYNDROME, |
78 | .ecc_bits = 4, | ||
78 | .bbt_options = NAND_BBT_USE_FLASH, | 79 | .bbt_options = NAND_BBT_USE_FLASH, |
79 | }; | 80 | }; |
80 | 81 | ||
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index a33686a6fbb2..fa4bfaf952d8 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c | |||
@@ -153,6 +153,7 @@ static struct davinci_nand_pdata davinci_evm_nandflash_data = { | |||
153 | .parts = davinci_evm_nandflash_partition, | 153 | .parts = davinci_evm_nandflash_partition, |
154 | .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition), | 154 | .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition), |
155 | .ecc_mode = NAND_ECC_HW, | 155 | .ecc_mode = NAND_ECC_HW, |
156 | .ecc_bits = 1, | ||
156 | .bbt_options = NAND_BBT_USE_FLASH, | 157 | .bbt_options = NAND_BBT_USE_FLASH, |
157 | .timing = &davinci_evm_nandflash_timing, | 158 | .timing = &davinci_evm_nandflash_timing, |
158 | }; | 159 | }; |
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index fbb8e5ab1dc1..0c005e876cac 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c | |||
@@ -90,6 +90,7 @@ static struct davinci_nand_pdata davinci_nand_data = { | |||
90 | .parts = davinci_nand_partitions, | 90 | .parts = davinci_nand_partitions, |
91 | .nr_parts = ARRAY_SIZE(davinci_nand_partitions), | 91 | .nr_parts = ARRAY_SIZE(davinci_nand_partitions), |
92 | .ecc_mode = NAND_ECC_HW, | 92 | .ecc_mode = NAND_ECC_HW, |
93 | .ecc_bits = 1, | ||
93 | .options = 0, | 94 | .options = 0, |
94 | }; | 95 | }; |
95 | 96 | ||
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 2bc112adf565..808233b60e3d 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c | |||
@@ -88,6 +88,7 @@ static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = { | |||
88 | .parts = davinci_ntosd2_nandflash_partition, | 88 | .parts = davinci_ntosd2_nandflash_partition, |
89 | .nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition), | 89 | .nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition), |
90 | .ecc_mode = NAND_ECC_HW, | 90 | .ecc_mode = NAND_ECC_HW, |
91 | .ecc_bits = 1, | ||
91 | .bbt_options = NAND_BBT_USE_FLASH, | 92 | .bbt_options = NAND_BBT_USE_FLASH, |
92 | }; | 93 | }; |
93 | 94 | ||
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index 36aef3a7dedb..f1ac1c94ac0f 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c | |||
@@ -65,7 +65,7 @@ static struct cpuidle_driver davinci_idle_driver = { | |||
65 | .states[1] = { | 65 | .states[1] = { |
66 | .enter = davinci_enter_idle, | 66 | .enter = davinci_enter_idle, |
67 | .exit_latency = 10, | 67 | .exit_latency = 10, |
68 | .target_residency = 100000, | 68 | .target_residency = 10000, |
69 | .flags = CPUIDLE_FLAG_TIME_VALID, | 69 | .flags = CPUIDLE_FLAG_TIME_VALID, |
70 | .name = "DDR SR", | 70 | .name = "DDR SR", |
71 | .desc = "WFI and DDR Self Refresh", | 71 | .desc = "WFI and DDR Self Refresh", |
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S deleted file mode 100644 index b18b8ebc6508..000000000000 --- a/arch/arm/mach-davinci/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | /* | ||
2 | * Debugging macro for DaVinci | ||
3 | * | ||
4 | * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> | ||
5 | * | ||
6 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | |||
12 | /* Modifications | ||
13 | * Jan 2009 Chaithrika U S Added senduart, busyuart, waituart | ||
14 | * macros, based on debug-8250.S file | ||
15 | * but using 32-bit accesses required for | ||
16 | * some davinci devices. | ||
17 | */ | ||
18 | |||
19 | #include <linux/serial_reg.h> | ||
20 | |||
21 | #include <mach/serial.h> | ||
22 | |||
23 | #define UART_SHIFT 2 | ||
24 | |||
25 | #if defined(CONFIG_DEBUG_DAVINCI_DMx_UART0) | ||
26 | #define UART_BASE DAVINCI_UART0_BASE | ||
27 | #elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART1) | ||
28 | #define UART_BASE DA8XX_UART1_BASE | ||
29 | #elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART2) | ||
30 | #define UART_BASE DA8XX_UART2_BASE | ||
31 | #elif defined(CONFIG_DEBUG_DAVINCI_TNETV107X_UART1) | ||
32 | #define UART_BASE TNETV107X_UART2_BASE | ||
33 | #define UART_VIRTBASE TNETV107X_UART2_VIRT | ||
34 | #else | ||
35 | #error "Select a specifc port for DEBUG_LL" | ||
36 | #endif | ||
37 | |||
38 | #ifndef UART_VIRTBASE | ||
39 | #define UART_VIRTBASE IO_ADDRESS(UART_BASE) | ||
40 | #endif | ||
41 | |||
42 | .macro addruart, rp, rv, tmp | ||
43 | ldr \rp, =UART_BASE | ||
44 | ldr \rv, =UART_VIRTBASE | ||
45 | .endm | ||
46 | |||
47 | .macro senduart,rd,rx | ||
48 | str \rd, [\rx, #UART_TX << UART_SHIFT] | ||
49 | .endm | ||
50 | |||
51 | .macro busyuart,rd,rx | ||
52 | 1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] | ||
53 | and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
54 | teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | ||
55 | bne 1002b | ||
56 | .endm | ||
57 | |||
58 | .macro waituart,rd,rx | ||
59 | #ifdef FLOW_CONTROL | ||
60 | 1001: ldr \rd, [\rx, #UART_MSR << UART_SHIFT] | ||
61 | tst \rd, #UART_MSR_CTS | ||
62 | beq 1001b | ||
63 | #endif | ||
64 | .endm | ||
65 | |||
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 00247c771313..304f069ebf50 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c | |||
@@ -108,8 +108,8 @@ static void __init dove_clk_init(void) | |||
108 | orion_clkdev_add(NULL, "sdhci-dove.1", sdio1); | 108 | orion_clkdev_add(NULL, "sdhci-dove.1", sdio1); |
109 | orion_clkdev_add(NULL, "orion_nand", nand); | 109 | orion_clkdev_add(NULL, "orion_nand", nand); |
110 | orion_clkdev_add(NULL, "cafe1000-ccic.0", camera); | 110 | orion_clkdev_add(NULL, "cafe1000-ccic.0", camera); |
111 | orion_clkdev_add(NULL, "kirkwood-i2s.0", i2s0); | 111 | orion_clkdev_add(NULL, "mvebu-audio.0", i2s0); |
112 | orion_clkdev_add(NULL, "kirkwood-i2s.1", i2s1); | 112 | orion_clkdev_add(NULL, "mvebu-audio.1", i2s1); |
113 | orion_clkdev_add(NULL, "mv_crypto", crypto); | 113 | orion_clkdev_add(NULL, "mv_crypto", crypto); |
114 | orion_clkdev_add(NULL, "dove-ac97", ac97); | 114 | orion_clkdev_add(NULL, "dove-ac97", ac97); |
115 | orion_clkdev_add(NULL, "dove-pdma", pdma); | 115 | orion_clkdev_add(NULL, "dove-pdma", pdma); |
diff --git a/arch/arm/mach-dove/include/mach/debug-macro.S b/arch/arm/mach-dove/include/mach/debug-macro.S deleted file mode 100644 index 5929cbc59161..000000000000 --- a/arch/arm/mach-dove/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-dove/include/mach/debug-macro.S | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <mach/bridge-regs.h> | ||
10 | |||
11 | .macro addruart, rp, rv, tmp | ||
12 | ldr \rp, =DOVE_SB_REGS_PHYS_BASE | ||
13 | ldr \rv, =DOVE_SB_REGS_VIRT_BASE | ||
14 | orr \rp, \rp, #0x00012000 | ||
15 | orr \rv, \rv, #0x00012000 | ||
16 | .endm | ||
17 | |||
18 | #define UART_SHIFT 2 | ||
19 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-ebsa110/include/mach/debug-macro.S b/arch/arm/mach-ebsa110/include/mach/debug-macro.S deleted file mode 100644 index bb02c05e6812..000000000000 --- a/arch/arm/mach-ebsa110/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* arch/arm/mach-ebsa110/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copyright (C) 1994-1999 Russell King | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | **/ | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | mov \rp, #0xf0000000 | ||
16 | orr \rp, \rp, #0x00000be0 | ||
17 | mov \rp, \rv | ||
18 | .endm | ||
19 | |||
20 | #define UART_SHIFT 2 | ||
21 | #define FLOW_CONTROL | ||
22 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index fe3c1fa5462b..93e54fd4e3d5 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig | |||
@@ -194,20 +194,6 @@ config MACH_VISION_EP9307 | |||
194 | Say 'Y' here if you want your kernel to support the | 194 | Say 'Y' here if you want your kernel to support the |
195 | Vision Engraving Systems EP9307 SoM. | 195 | Vision Engraving Systems EP9307 SoM. |
196 | 196 | ||
197 | choice | ||
198 | prompt "Select a UART for early kernel messages" | ||
199 | |||
200 | config EP93XX_EARLY_UART1 | ||
201 | bool "UART1" | ||
202 | |||
203 | config EP93XX_EARLY_UART2 | ||
204 | bool "UART2" | ||
205 | |||
206 | config EP93XX_EARLY_UART3 | ||
207 | bool "UART3" | ||
208 | |||
209 | endchoice | ||
210 | |||
211 | endmenu | 197 | endmenu |
212 | 198 | ||
213 | endif | 199 | endif |
diff --git a/arch/arm/mach-ep93xx/include/mach/debug-macro.S b/arch/arm/mach-ep93xx/include/mach/debug-macro.S deleted file mode 100644 index af54e43132cf..000000000000 --- a/arch/arm/mach-ep93xx/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ep93xx/include/mach/debug-macro.S | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or (at | ||
10 | * your option) any later version. | ||
11 | */ | ||
12 | #include <mach/ep93xx-regs.h> | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | ldr \rp, =EP93XX_APB_PHYS_BASE @ Physical base | ||
16 | ldr \rv, =EP93XX_APB_VIRT_BASE @ virtual base | ||
17 | orr \rp, \rp, #0x000c0000 | ||
18 | orr \rv, \rv, #0x000c0000 | ||
19 | .endm | ||
20 | |||
21 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/uncompress.h b/arch/arm/mach-ep93xx/include/mach/uncompress.h index b5cc77d2380b..03c42e5400d2 100644 --- a/arch/arm/mach-ep93xx/include/mach/uncompress.h +++ b/arch/arm/mach-ep93xx/include/mach/uncompress.h | |||
@@ -31,18 +31,8 @@ static void __raw_writel(unsigned int value, unsigned int ptr) | |||
31 | *((volatile unsigned int *)ptr) = value; | 31 | *((volatile unsigned int *)ptr) = value; |
32 | } | 32 | } |
33 | 33 | ||
34 | #if defined(CONFIG_EP93XX_EARLY_UART1) | 34 | #define PHYS_UART_DATA (CONFIG_DEBUG_UART_PHYS + 0x00) |
35 | #define UART_BASE EP93XX_UART1_PHYS_BASE | 35 | #define PHYS_UART_FLAG (CONFIG_DEBUG_UART_PHYS + 0x18) |
36 | #elif defined(CONFIG_EP93XX_EARLY_UART2) | ||
37 | #define UART_BASE EP93XX_UART2_PHYS_BASE | ||
38 | #elif defined(CONFIG_EP93XX_EARLY_UART3) | ||
39 | #define UART_BASE EP93XX_UART3_PHYS_BASE | ||
40 | #else | ||
41 | #define UART_BASE EP93XX_UART1_PHYS_BASE | ||
42 | #endif | ||
43 | |||
44 | #define PHYS_UART_DATA (UART_BASE + 0x00) | ||
45 | #define PHYS_UART_FLAG (UART_BASE + 0x18) | ||
46 | #define UART_FLAG_TXFF 0x20 | 36 | #define UART_FLAG_TXFF 0x20 |
47 | 37 | ||
48 | static inline void putc(int c) | 38 | static inline void putc(int c) |
diff --git a/arch/arm/mach-footbridge/include/mach/debug-macro.S b/arch/arm/mach-footbridge/include/mach/debug-macro.S index c169f0c99b2a..02247f313e94 100644 --- a/arch/arm/mach-footbridge/include/mach/debug-macro.S +++ b/arch/arm/mach-footbridge/include/mach/debug-macro.S | |||
@@ -13,20 +13,6 @@ | |||
13 | 13 | ||
14 | #include <asm/hardware/dec21285.h> | 14 | #include <asm/hardware/dec21285.h> |
15 | 15 | ||
16 | #ifndef CONFIG_DEBUG_DC21285_PORT | ||
17 | /* For NetWinder debugging */ | ||
18 | .macro addruart, rp, rv, tmp | ||
19 | mov \rp, #0x000003f8 | ||
20 | orr \rv, \rp, #0xfe000000 @ virtual | ||
21 | orr \rv, \rv, #0x00e00000 @ virtual | ||
22 | orr \rp, \rp, #0x7c000000 @ physical | ||
23 | .endm | ||
24 | |||
25 | #define UART_SHIFT 0 | ||
26 | #define FLOW_CONTROL | ||
27 | #include <asm/hardware/debug-8250.S> | ||
28 | |||
29 | #else | ||
30 | #include <mach/hardware.h> | 16 | #include <mach/hardware.h> |
31 | /* For EBSA285 debugging */ | 17 | /* For EBSA285 debugging */ |
32 | .equ dc21285_high, ARMCSR_BASE & 0xff000000 | 18 | .equ dc21285_high, ARMCSR_BASE & 0xff000000 |
@@ -54,4 +40,3 @@ | |||
54 | 40 | ||
55 | .macro waituart,rd,rx | 41 | .macro waituart,rd,rx |
56 | .endm | 42 | .endm |
57 | #endif | ||
diff --git a/arch/arm/mach-gemini/include/mach/debug-macro.S b/arch/arm/mach-gemini/include/mach/debug-macro.S deleted file mode 100644 index 837670763b85..000000000000 --- a/arch/arm/mach-gemini/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Debugging macro include header | ||
3 | * | ||
4 | * Copyright (C) 1994-1999 Russell King | ||
5 | * Copyright (C) 2001-2006 Storlink, Corp. | ||
6 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #include <mach/hardware.h> | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | ldr \rp, =GEMINI_UART_BASE @ physical | ||
16 | ldr \rv, =IO_ADDRESS(GEMINI_UART_BASE) @ virtual | ||
17 | .endm | ||
18 | |||
19 | #define UART_SHIFT 2 | ||
20 | #define FLOW_CONTROL | ||
21 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 7be13f8e69a0..a02f275a198d 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev) | |||
254 | { | 254 | { |
255 | struct device_node *np; | 255 | struct device_node *np; |
256 | 256 | ||
257 | np = of_find_node_by_path("/cpus/cpu@0"); | 257 | np = of_node_get(cpu_dev->of_node); |
258 | if (!np) { | 258 | if (!np) { |
259 | pr_warn("failed to find cpu0 node\n"); | 259 | pr_warn("failed to find cpu0 node\n"); |
260 | return; | 260 | return; |
261 | } | 261 | } |
262 | 262 | ||
263 | cpu_dev->of_node = np; | ||
264 | if (of_init_opp_table(cpu_dev)) { | 263 | if (of_init_opp_table(cpu_dev)) { |
265 | pr_warn("failed to init OPP table\n"); | 264 | pr_warn("failed to init OPP table\n"); |
266 | goto put_node; | 265 | goto put_node; |
diff --git a/arch/arm/mach-integrator/include/mach/debug-macro.S b/arch/arm/mach-integrator/include/mach/debug-macro.S deleted file mode 100644 index 411b116077e4..000000000000 --- a/arch/arm/mach-integrator/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* arch/arm/mach-integrator/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copyright (C) 1994-1999 Russell King | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | mov \rp, #0x16000000 @ physical base address | ||
16 | mov \rv, #0xf0000000 @ virtual base | ||
17 | add \rv, \rv, #0x16000000 >> 4 | ||
18 | .endm | ||
19 | |||
20 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/mach-iop13xx/include/mach/debug-macro.S b/arch/arm/mach-iop13xx/include/mach/debug-macro.S deleted file mode 100644 index d869a6f67e5c..000000000000 --- a/arch/arm/mach-iop13xx/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-iop13xx/include/mach/debug-macro.S | ||
3 | * | ||
4 | * Debugging macro include header | ||
5 | * | ||
6 | * Copyright (C) 1994-1999 Russell King | ||
7 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | mov \rp, #0x00002300 | ||
16 | orr \rp, \rp, #0x00000040 | ||
17 | orr \rv, \rp, #0xfe000000 @ virtual | ||
18 | orr \rv, \rv, #0x00e80000 | ||
19 | orr \rp, \rp, #0xff000000 @ physical | ||
20 | orr \rp, \rp, #0x00d80000 | ||
21 | .endm | ||
22 | |||
23 | #define UART_SHIFT 2 | ||
24 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-iop32x/include/mach/debug-macro.S b/arch/arm/mach-iop32x/include/mach/debug-macro.S deleted file mode 100644 index 363bdf90b34d..000000000000 --- a/arch/arm/mach-iop32x/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-iop32x/include/mach/debug-macro.S | ||
3 | * | ||
4 | * Debugging macro include header | ||
5 | * | ||
6 | * Copyright (C) 1994-1999 Russell King | ||
7 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | mov \rp, #0xfe000000 @ physical as well as virtual | ||
16 | orr \rp, \rp, #0x00800000 @ location of the UART | ||
17 | mov \rv, \rp | ||
18 | .endm | ||
19 | |||
20 | #define UART_SHIFT 0 | ||
21 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-iop33x/include/mach/debug-macro.S b/arch/arm/mach-iop33x/include/mach/debug-macro.S deleted file mode 100644 index 361be1f6026e..000000000000 --- a/arch/arm/mach-iop33x/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-iop33x/include/mach/debug-macro.S | ||
3 | * | ||
4 | * Debugging macro include header | ||
5 | * | ||
6 | * Copyright (C) 1994-1999 Russell King | ||
7 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | mov \rp, #0x00ff0000 | ||
16 | orr \rp, \rp, #0x0000f700 | ||
17 | orr \rv, #0xfe000000 @ virtual | ||
18 | orr \rp, #0xff000000 @ physical | ||
19 | .endm | ||
20 | |||
21 | #define UART_SHIFT 2 | ||
22 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S deleted file mode 100644 index ff686cbc5df4..000000000000 --- a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | /* arch/arm/mach-ixp4xx/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copyright (C) 1994-1999 Russell King | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | .macro addruart, rp, rv, tmp | ||
14 | #ifdef __ARMEB__ | ||
15 | mov \rp, #3 @ Uart regs are at off set of 3 if | ||
16 | @ byte writes used - Big Endian. | ||
17 | #else | ||
18 | mov \rp, #0 | ||
19 | #endif | ||
20 | orr \rv, \rp, #0xfe000000 @ virtual | ||
21 | orr \rv, \rv, #0x00f00000 | ||
22 | orr \rp, \rp, #0xc8000000 @ physical | ||
23 | .endm | ||
24 | |||
25 | #define UART_SHIFT 2 | ||
26 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index e9238b5567ee..1663de090984 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
@@ -264,7 +264,7 @@ void __init kirkwood_clk_init(void) | |||
264 | orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1); | 264 | orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1); |
265 | orion_clkdev_add("0", "pcie", pex0); | 265 | orion_clkdev_add("0", "pcie", pex0); |
266 | orion_clkdev_add("1", "pcie", pex1); | 266 | orion_clkdev_add("1", "pcie", pex1); |
267 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); | 267 | orion_clkdev_add(NULL, "mvebu-audio", audio); |
268 | orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit); | 268 | orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit); |
269 | orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".1", runit); | 269 | orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".1", runit); |
270 | 270 | ||
@@ -560,7 +560,7 @@ void __init kirkwood_timer_init(void) | |||
560 | /***************************************************************************** | 560 | /***************************************************************************** |
561 | * Audio | 561 | * Audio |
562 | ****************************************************************************/ | 562 | ****************************************************************************/ |
563 | static struct resource kirkwood_i2s_resources[] = { | 563 | static struct resource kirkwood_audio_resources[] = { |
564 | [0] = { | 564 | [0] = { |
565 | .start = AUDIO_PHYS_BASE, | 565 | .start = AUDIO_PHYS_BASE, |
566 | .end = AUDIO_PHYS_BASE + SZ_16K - 1, | 566 | .end = AUDIO_PHYS_BASE + SZ_16K - 1, |
@@ -573,29 +573,23 @@ static struct resource kirkwood_i2s_resources[] = { | |||
573 | }, | 573 | }, |
574 | }; | 574 | }; |
575 | 575 | ||
576 | static struct kirkwood_asoc_platform_data kirkwood_i2s_data = { | 576 | static struct kirkwood_asoc_platform_data kirkwood_audio_data = { |
577 | .burst = 128, | 577 | .burst = 128, |
578 | }; | 578 | }; |
579 | 579 | ||
580 | static struct platform_device kirkwood_i2s_device = { | 580 | static struct platform_device kirkwood_audio_device = { |
581 | .name = "kirkwood-i2s", | 581 | .name = "mvebu-audio", |
582 | .id = -1, | 582 | .id = -1, |
583 | .num_resources = ARRAY_SIZE(kirkwood_i2s_resources), | 583 | .num_resources = ARRAY_SIZE(kirkwood_audio_resources), |
584 | .resource = kirkwood_i2s_resources, | 584 | .resource = kirkwood_audio_resources, |
585 | .dev = { | 585 | .dev = { |
586 | .platform_data = &kirkwood_i2s_data, | 586 | .platform_data = &kirkwood_audio_data, |
587 | }, | 587 | }, |
588 | }; | 588 | }; |
589 | 589 | ||
590 | static struct platform_device kirkwood_pcm_device = { | ||
591 | .name = "kirkwood-pcm-audio", | ||
592 | .id = -1, | ||
593 | }; | ||
594 | |||
595 | void __init kirkwood_audio_init(void) | 590 | void __init kirkwood_audio_init(void) |
596 | { | 591 | { |
597 | platform_device_register(&kirkwood_i2s_device); | 592 | platform_device_register(&kirkwood_audio_device); |
598 | platform_device_register(&kirkwood_pcm_device); | ||
599 | } | 593 | } |
600 | 594 | ||
601 | /***************************************************************************** | 595 | /***************************************************************************** |
diff --git a/arch/arm/mach-kirkwood/include/mach/debug-macro.S b/arch/arm/mach-kirkwood/include/mach/debug-macro.S deleted file mode 100644 index f785d401a607..000000000000 --- a/arch/arm/mach-kirkwood/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-kirkwood/include/mach/debug-macro.S | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <mach/bridge-regs.h> | ||
10 | |||
11 | .macro addruart, rp, rv, tmp | ||
12 | ldr \rp, =KIRKWOOD_REGS_PHYS_BASE | ||
13 | ldr \rv, =KIRKWOOD_REGS_VIRT_BASE | ||
14 | orr \rp, \rp, #0x00012000 | ||
15 | orr \rv, \rv, #0x00012000 | ||
16 | .endm | ||
17 | |||
18 | #define UART_SHIFT 2 | ||
19 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-lpc32xx/include/mach/debug-macro.S b/arch/arm/mach-lpc32xx/include/mach/debug-macro.S deleted file mode 100644 index 351bd6c84909..000000000000 --- a/arch/arm/mach-lpc32xx/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-lpc32xx/include/mach/debug-macro.S | ||
3 | * | ||
4 | * Author: Kevin Wells <kevin.wells@nxp.com> | ||
5 | * | ||
6 | * Copyright (C) 2010 NXP Semiconductors | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * Debug output is hardcoded to standard UART 5 | ||
21 | */ | ||
22 | |||
23 | .macro addruart, rp, rv, tmp | ||
24 | ldreq \rp, =0x40090000 | ||
25 | ldrne \rv, =0xF4090000 | ||
26 | .endm | ||
27 | |||
28 | #define UART_SHIFT 2 | ||
29 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c index 6d50fb964863..d83404d4b328 100644 --- a/arch/arm/mach-msm/devices-msm7x00.c +++ b/arch/arm/mach-msm/devices-msm7x00.c | |||
@@ -456,9 +456,9 @@ static struct clk_pcom_desc msm_clocks_7x01a[] = { | |||
456 | CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), | 456 | CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), |
457 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), | 457 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), |
458 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), | 458 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), |
459 | CLK_PCOM("uart_clk", UART1_CLK, "msm_serial.0", OFF), | 459 | CLK_PCOM("core", UART1_CLK, "msm_serial.0", OFF), |
460 | CLK_PCOM("uart_clk", UART2_CLK, "msm_serial.1", 0), | 460 | CLK_PCOM("core", UART2_CLK, "msm_serial.1", 0), |
461 | CLK_PCOM("uart_clk", UART3_CLK, "msm_serial.2", OFF), | 461 | CLK_PCOM("core", UART3_CLK, "msm_serial.2", OFF), |
462 | CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF), | 462 | CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF), |
463 | CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0), | 463 | CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0), |
464 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, "msm_hsusb", OFF), | 464 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, "msm_hsusb", OFF), |
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c index d4db75acff56..14e286948f69 100644 --- a/arch/arm/mach-msm/devices-msm7x30.c +++ b/arch/arm/mach-msm/devices-msm7x30.c | |||
@@ -211,7 +211,7 @@ static struct clk_pcom_desc msm_clocks_7x30[] = { | |||
211 | CLK_PCOM("spi_pclk", SPI_P_CLK, NULL, 0), | 211 | CLK_PCOM("spi_pclk", SPI_P_CLK, NULL, 0), |
212 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), | 212 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), |
213 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), | 213 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), |
214 | CLK_PCOM("uart_clk", UART2_CLK, "msm_serial.1", 0), | 214 | CLK_PCOM("core", UART2_CLK, "msm_serial.1", 0), |
215 | CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0), | 215 | CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0), |
216 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), | 216 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), |
217 | CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF), | 217 | CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF), |
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c index f5518112284b..2ed89b25d304 100644 --- a/arch/arm/mach-msm/devices-qsd8x50.c +++ b/arch/arm/mach-msm/devices-qsd8x50.c | |||
@@ -358,9 +358,9 @@ static struct clk_pcom_desc msm_clocks_8x50[] = { | |||
358 | CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), | 358 | CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), |
359 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), | 359 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), |
360 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), | 360 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), |
361 | CLK_PCOM("uart_clk", UART1_CLK, NULL, OFF), | 361 | CLK_PCOM("core", UART1_CLK, NULL, OFF), |
362 | CLK_PCOM("uart_clk", UART2_CLK, NULL, 0), | 362 | CLK_PCOM("core", UART2_CLK, NULL, 0), |
363 | CLK_PCOM("uart_clk", UART3_CLK, "msm_serial.2", OFF), | 363 | CLK_PCOM("core", UART3_CLK, "msm_serial.2", OFF), |
364 | CLK_PCOM("uartdm_clk", UART1DM_CLK, NULL, OFF), | 364 | CLK_PCOM("uartdm_clk", UART1DM_CLK, NULL, OFF), |
365 | CLK_PCOM("uartdm_clk", UART2DM_CLK, NULL, 0), | 365 | CLK_PCOM("uartdm_clk", UART2DM_CLK, NULL, 0), |
366 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), | 366 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), |
diff --git a/arch/arm/mach-mv78xx0/include/mach/debug-macro.S b/arch/arm/mach-mv78xx0/include/mach/debug-macro.S deleted file mode 100644 index a7df02b049b7..000000000000 --- a/arch/arm/mach-mv78xx0/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-mv78xx0/include/mach/debug-macro.S | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <mach/mv78xx0.h> | ||
10 | |||
11 | .macro addruart, rp, rv, tmp | ||
12 | ldr \rp, =MV78XX0_REGS_PHYS_BASE | ||
13 | ldr \rv, =MV78XX0_REGS_VIRT_BASE | ||
14 | orr \rp, \rp, #0x00012000 | ||
15 | orr \rv, \rv, #0x00012000 | ||
16 | .endm | ||
17 | |||
18 | #define UART_SHIFT 2 | ||
19 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index ce81d3031405..594b63db4215 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c | |||
@@ -29,45 +29,40 @@ | |||
29 | #include "pmsu.h" | 29 | #include "pmsu.h" |
30 | #include "coherency.h" | 30 | #include "coherency.h" |
31 | 31 | ||
32 | static struct clk *__init get_cpu_clk(int cpu) | ||
33 | { | ||
34 | struct clk *cpu_clk; | ||
35 | struct device_node *np = of_get_cpu_node(cpu, NULL); | ||
36 | |||
37 | if (WARN(!np, "missing cpu node\n")) | ||
38 | return NULL; | ||
39 | cpu_clk = of_clk_get(np, 0); | ||
40 | if (WARN_ON(IS_ERR(cpu_clk))) | ||
41 | return NULL; | ||
42 | return cpu_clk; | ||
43 | } | ||
44 | |||
32 | void __init set_secondary_cpus_clock(void) | 45 | void __init set_secondary_cpus_clock(void) |
33 | { | 46 | { |
34 | int thiscpu; | 47 | int thiscpu, cpu; |
35 | unsigned long rate; | 48 | unsigned long rate; |
36 | struct clk *cpu_clk = NULL; | 49 | struct clk *cpu_clk; |
37 | struct device_node *np = NULL; | ||
38 | 50 | ||
39 | thiscpu = smp_processor_id(); | 51 | thiscpu = smp_processor_id(); |
40 | for_each_node_by_type(np, "cpu") { | 52 | cpu_clk = get_cpu_clk(thiscpu); |
41 | int err; | 53 | if (!cpu_clk) |
42 | int cpu; | ||
43 | |||
44 | err = of_property_read_u32(np, "reg", &cpu); | ||
45 | if (WARN_ON(err)) | ||
46 | return; | ||
47 | |||
48 | if (cpu == thiscpu) { | ||
49 | cpu_clk = of_clk_get(np, 0); | ||
50 | break; | ||
51 | } | ||
52 | } | ||
53 | if (WARN_ON(IS_ERR(cpu_clk))) | ||
54 | return; | 54 | return; |
55 | clk_prepare_enable(cpu_clk); | 55 | clk_prepare_enable(cpu_clk); |
56 | rate = clk_get_rate(cpu_clk); | 56 | rate = clk_get_rate(cpu_clk); |
57 | 57 | ||
58 | /* set all the other CPU clk to the same rate than the boot CPU */ | 58 | /* set all the other CPU clk to the same rate than the boot CPU */ |
59 | for_each_node_by_type(np, "cpu") { | 59 | for_each_possible_cpu(cpu) { |
60 | int err; | 60 | if (cpu == thiscpu) |
61 | int cpu; | 61 | continue; |
62 | 62 | cpu_clk = get_cpu_clk(cpu); | |
63 | err = of_property_read_u32(np, "reg", &cpu); | 63 | if (!cpu_clk) |
64 | if (WARN_ON(err)) | ||
65 | return; | 64 | return; |
66 | 65 | clk_set_rate(cpu_clk, rate); | |
67 | if (cpu != thiscpu) { | ||
68 | cpu_clk = of_clk_get(np, 0); | ||
69 | clk_set_rate(cpu_clk, rate); | ||
70 | } | ||
71 | } | 66 | } |
72 | } | 67 | } |
73 | 68 | ||
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 244d8a5aa54b..c711ad6ac067 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c | |||
@@ -100,39 +100,52 @@ static struct platform_device sdp2430_flash_device = { | |||
100 | .resource = &sdp2430_flash_resource, | 100 | .resource = &sdp2430_flash_resource, |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static struct platform_device *sdp2430_devices[] __initdata = { | ||
104 | &sdp2430_flash_device, | ||
105 | }; | ||
106 | |||
107 | /* LCD */ | 103 | /* LCD */ |
108 | #define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91 | 104 | #define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91 |
109 | #define SDP2430_LCD_PANEL_ENABLE_GPIO 154 | 105 | #define SDP2430_LCD_PANEL_ENABLE_GPIO 154 |
110 | 106 | ||
111 | static struct panel_generic_dpi_data sdp2430_panel_data = { | 107 | static const struct display_timing sdp2430_lcd_videomode = { |
112 | .name = "nec_nl2432dr22-11b", | 108 | .pixelclock = { 0, 5400000, 0 }, |
113 | .num_gpios = 2, | 109 | |
114 | .gpios = { | 110 | .hactive = { 0, 240, 0 }, |
115 | SDP2430_LCD_PANEL_ENABLE_GPIO, | 111 | .hfront_porch = { 0, 3, 0 }, |
116 | SDP2430_LCD_PANEL_BACKLIGHT_GPIO, | 112 | .hback_porch = { 0, 39, 0 }, |
117 | }, | 113 | .hsync_len = { 0, 3, 0 }, |
114 | |||
115 | .vactive = { 0, 320, 0 }, | ||
116 | .vfront_porch = { 0, 2, 0 }, | ||
117 | .vback_porch = { 0, 7, 0 }, | ||
118 | .vsync_len = { 0, 1, 0 }, | ||
119 | |||
120 | .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | | ||
121 | DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, | ||
118 | }; | 122 | }; |
119 | 123 | ||
120 | static struct omap_dss_device sdp2430_lcd_device = { | 124 | static struct panel_dpi_platform_data sdp2430_lcd_pdata = { |
121 | .name = "lcd", | 125 | .name = "lcd", |
122 | .driver_name = "generic_dpi_panel", | 126 | .source = "dpi.0", |
123 | .type = OMAP_DISPLAY_TYPE_DPI, | 127 | |
124 | .phy.dpi.data_lines = 16, | 128 | .data_lines = 16, |
125 | .data = &sdp2430_panel_data, | 129 | |
130 | .display_timing = &sdp2430_lcd_videomode, | ||
131 | |||
132 | .enable_gpio = SDP2430_LCD_PANEL_ENABLE_GPIO, | ||
133 | .backlight_gpio = SDP2430_LCD_PANEL_BACKLIGHT_GPIO, | ||
126 | }; | 134 | }; |
127 | 135 | ||
128 | static struct omap_dss_device *sdp2430_dss_devices[] = { | 136 | static struct platform_device sdp2430_lcd_device = { |
129 | &sdp2430_lcd_device, | 137 | .name = "panel-dpi", |
138 | .id = 0, | ||
139 | .dev.platform_data = &sdp2430_lcd_pdata, | ||
130 | }; | 140 | }; |
131 | 141 | ||
132 | static struct omap_dss_board_info sdp2430_dss_data = { | 142 | static struct omap_dss_board_info sdp2430_dss_data = { |
133 | .num_devices = ARRAY_SIZE(sdp2430_dss_devices), | 143 | .default_display_name = "lcd", |
134 | .devices = sdp2430_dss_devices, | 144 | }; |
135 | .default_device = &sdp2430_lcd_device, | 145 | |
146 | static struct platform_device *sdp2430_devices[] __initdata = { | ||
147 | &sdp2430_flash_device, | ||
148 | &sdp2430_lcd_device, | ||
136 | }; | 149 | }; |
137 | 150 | ||
138 | #if IS_ENABLED(CONFIG_SMC91X) | 151 | #if IS_ENABLED(CONFIG_SMC91X) |
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 23b004afa3f8..d95d0ef1354a 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c | |||
@@ -126,53 +126,65 @@ static void __init sdp3430_display_init(void) | |||
126 | 126 | ||
127 | } | 127 | } |
128 | 128 | ||
129 | static struct panel_sharp_ls037v7dw01_data sdp3430_lcd_data = { | 129 | static struct panel_sharp_ls037v7dw01_platform_data sdp3430_lcd_pdata = { |
130 | .resb_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO, | 130 | .name = "lcd", |
131 | .ini_gpio = -1, | 131 | .source = "dpi.0", |
132 | .mo_gpio = -1, | 132 | |
133 | .lr_gpio = -1, | 133 | .data_lines = 16, |
134 | .ud_gpio = -1, | 134 | |
135 | .resb_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO, | ||
136 | .ini_gpio = -1, | ||
137 | .mo_gpio = -1, | ||
138 | .lr_gpio = -1, | ||
139 | .ud_gpio = -1, | ||
140 | }; | ||
141 | |||
142 | static struct platform_device sdp3430_lcd_device = { | ||
143 | .name = "panel-sharp-ls037v7dw01", | ||
144 | .id = 0, | ||
145 | .dev.platform_data = &sdp3430_lcd_pdata, | ||
135 | }; | 146 | }; |
136 | 147 | ||
137 | static struct omap_dss_device sdp3430_lcd_device = { | 148 | static struct connector_dvi_platform_data sdp3430_dvi_connector_pdata = { |
138 | .name = "lcd", | 149 | .name = "dvi", |
139 | .driver_name = "sharp_ls_panel", | 150 | .source = "tfp410.0", |
140 | .type = OMAP_DISPLAY_TYPE_DPI, | 151 | .i2c_bus_num = -1, |
141 | .phy.dpi.data_lines = 16, | ||
142 | .data = &sdp3430_lcd_data, | ||
143 | }; | 152 | }; |
144 | 153 | ||
145 | static struct tfp410_platform_data dvi_panel = { | 154 | static struct platform_device sdp3430_dvi_connector_device = { |
146 | .power_down_gpio = -1, | 155 | .name = "connector-dvi", |
147 | .i2c_bus_num = -1, | 156 | .id = 0, |
157 | .dev.platform_data = &sdp3430_dvi_connector_pdata, | ||
148 | }; | 158 | }; |
149 | 159 | ||
150 | static struct omap_dss_device sdp3430_dvi_device = { | 160 | static struct encoder_tfp410_platform_data sdp3430_tfp410_pdata = { |
151 | .name = "dvi", | 161 | .name = "tfp410.0", |
152 | .type = OMAP_DISPLAY_TYPE_DPI, | 162 | .source = "dpi.0", |
153 | .driver_name = "tfp410", | 163 | .data_lines = 24, |
154 | .data = &dvi_panel, | 164 | .power_down_gpio = -1, |
155 | .phy.dpi.data_lines = 24, | ||
156 | }; | 165 | }; |
157 | 166 | ||
158 | static struct omap_dss_device sdp3430_tv_device = { | 167 | static struct platform_device sdp3430_tfp410_device = { |
159 | .name = "tv", | 168 | .name = "tfp410", |
160 | .driver_name = "venc", | 169 | .id = 0, |
161 | .type = OMAP_DISPLAY_TYPE_VENC, | 170 | .dev.platform_data = &sdp3430_tfp410_pdata, |
162 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
163 | }; | 171 | }; |
164 | 172 | ||
173 | static struct connector_atv_platform_data sdp3430_tv_pdata = { | ||
174 | .name = "tv", | ||
175 | .source = "venc.0", | ||
176 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
177 | .invert_polarity = false, | ||
178 | }; | ||
165 | 179 | ||
166 | static struct omap_dss_device *sdp3430_dss_devices[] = { | 180 | static struct platform_device sdp3430_tv_connector_device = { |
167 | &sdp3430_lcd_device, | 181 | .name = "connector-analog-tv", |
168 | &sdp3430_dvi_device, | 182 | .id = 0, |
169 | &sdp3430_tv_device, | 183 | .dev.platform_data = &sdp3430_tv_pdata, |
170 | }; | 184 | }; |
171 | 185 | ||
172 | static struct omap_dss_board_info sdp3430_dss_data = { | 186 | static struct omap_dss_board_info sdp3430_dss_data = { |
173 | .num_devices = ARRAY_SIZE(sdp3430_dss_devices), | 187 | .default_display_name = "lcd", |
174 | .devices = sdp3430_dss_devices, | ||
175 | .default_device = &sdp3430_lcd_device, | ||
176 | }; | 188 | }; |
177 | 189 | ||
178 | static struct omap2_hsmmc_info mmc[] = { | 190 | static struct omap2_hsmmc_info mmc[] = { |
@@ -583,6 +595,11 @@ static void __init omap_3430sdp_init(void) | |||
583 | omap_hsmmc_init(mmc); | 595 | omap_hsmmc_init(mmc); |
584 | omap3430_i2c_init(); | 596 | omap3430_i2c_init(); |
585 | omap_display_init(&sdp3430_dss_data); | 597 | omap_display_init(&sdp3430_dss_data); |
598 | platform_device_register(&sdp3430_lcd_device); | ||
599 | platform_device_register(&sdp3430_tfp410_device); | ||
600 | platform_device_register(&sdp3430_dvi_connector_device); | ||
601 | platform_device_register(&sdp3430_tv_connector_device); | ||
602 | |||
586 | if (omap_rev() > OMAP3430_REV_ES1_0) | 603 | if (omap_rev() > OMAP3430_REV_ES1_0) |
587 | gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV2; | 604 | gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV2; |
588 | else | 605 | else |
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index d63f14b534b5..8cc2c9e9fb03 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c | |||
@@ -120,56 +120,95 @@ static int __init am3517_evm_i2c_init(void) | |||
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static struct panel_generic_dpi_data lcd_panel = { | 123 | static const struct display_timing am3517_evm_lcd_videomode = { |
124 | .name = "sharp_lq", | 124 | .pixelclock = { 0, 9000000, 0 }, |
125 | .num_gpios = 3, | 125 | |
126 | .gpios = { | 126 | .hactive = { 0, 480, 0 }, |
127 | LCD_PANEL_PWR, | 127 | .hfront_porch = { 0, 3, 0 }, |
128 | LCD_PANEL_BKLIGHT_PWR, | 128 | .hback_porch = { 0, 2, 0 }, |
129 | LCD_PANEL_PWM, | 129 | .hsync_len = { 0, 42, 0 }, |
130 | }, | 130 | |
131 | .vactive = { 0, 272, 0 }, | ||
132 | .vfront_porch = { 0, 3, 0 }, | ||
133 | .vback_porch = { 0, 2, 0 }, | ||
134 | .vsync_len = { 0, 11, 0 }, | ||
135 | |||
136 | .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | | ||
137 | DISPLAY_FLAGS_DE_LOW | DISPLAY_FLAGS_PIXDATA_POSEDGE, | ||
138 | }; | ||
139 | |||
140 | static struct panel_dpi_platform_data am3517_evm_lcd_pdata = { | ||
141 | .name = "lcd", | ||
142 | .source = "dpi.0", | ||
143 | |||
144 | .data_lines = 16, | ||
145 | |||
146 | .display_timing = &am3517_evm_lcd_videomode, | ||
147 | |||
148 | .enable_gpio = LCD_PANEL_PWR, | ||
149 | .backlight_gpio = LCD_PANEL_BKLIGHT_PWR, | ||
150 | }; | ||
151 | |||
152 | static struct platform_device am3517_evm_lcd_device = { | ||
153 | .name = "panel-dpi", | ||
154 | .id = 0, | ||
155 | .dev.platform_data = &am3517_evm_lcd_pdata, | ||
131 | }; | 156 | }; |
132 | 157 | ||
133 | static struct omap_dss_device am3517_evm_lcd_device = { | 158 | static struct connector_dvi_platform_data am3517_evm_dvi_connector_pdata = { |
134 | .type = OMAP_DISPLAY_TYPE_DPI, | 159 | .name = "dvi", |
135 | .name = "lcd", | 160 | .source = "tfp410.0", |
136 | .driver_name = "generic_dpi_panel", | 161 | .i2c_bus_num = -1, |
137 | .data = &lcd_panel, | ||
138 | .phy.dpi.data_lines = 16, | ||
139 | }; | 162 | }; |
140 | 163 | ||
141 | static struct omap_dss_device am3517_evm_tv_device = { | 164 | static struct platform_device am3517_evm_dvi_connector_device = { |
142 | .type = OMAP_DISPLAY_TYPE_VENC, | 165 | .name = "connector-dvi", |
143 | .name = "tv", | 166 | .id = 0, |
144 | .driver_name = "venc", | 167 | .dev.platform_data = &am3517_evm_dvi_connector_pdata, |
145 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
146 | }; | 168 | }; |
147 | 169 | ||
148 | static struct tfp410_platform_data dvi_panel = { | 170 | static struct encoder_tfp410_platform_data am3517_evm_tfp410_pdata = { |
149 | .power_down_gpio = -1, | 171 | .name = "tfp410.0", |
150 | .i2c_bus_num = -1, | 172 | .source = "dpi.0", |
173 | .data_lines = 24, | ||
174 | .power_down_gpio = -1, | ||
151 | }; | 175 | }; |
152 | 176 | ||
153 | static struct omap_dss_device am3517_evm_dvi_device = { | 177 | static struct platform_device am3517_evm_tfp410_device = { |
154 | .type = OMAP_DISPLAY_TYPE_DPI, | 178 | .name = "tfp410", |
155 | .name = "dvi", | 179 | .id = 0, |
156 | .driver_name = "tfp410", | 180 | .dev.platform_data = &am3517_evm_tfp410_pdata, |
157 | .data = &dvi_panel, | ||
158 | .phy.dpi.data_lines = 24, | ||
159 | }; | 181 | }; |
160 | 182 | ||
161 | static struct omap_dss_device *am3517_evm_dss_devices[] = { | 183 | static struct connector_atv_platform_data am3517_evm_tv_pdata = { |
162 | &am3517_evm_lcd_device, | 184 | .name = "tv", |
163 | &am3517_evm_tv_device, | 185 | .source = "venc.0", |
164 | &am3517_evm_dvi_device, | 186 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, |
187 | .invert_polarity = false, | ||
188 | }; | ||
189 | |||
190 | static struct platform_device am3517_evm_tv_connector_device = { | ||
191 | .name = "connector-analog-tv", | ||
192 | .id = 0, | ||
193 | .dev.platform_data = &am3517_evm_tv_pdata, | ||
165 | }; | 194 | }; |
166 | 195 | ||
167 | static struct omap_dss_board_info am3517_evm_dss_data = { | 196 | static struct omap_dss_board_info am3517_evm_dss_data = { |
168 | .num_devices = ARRAY_SIZE(am3517_evm_dss_devices), | 197 | .default_display_name = "lcd", |
169 | .devices = am3517_evm_dss_devices, | ||
170 | .default_device = &am3517_evm_lcd_device, | ||
171 | }; | 198 | }; |
172 | 199 | ||
200 | static void __init am3517_evm_display_init(void) | ||
201 | { | ||
202 | gpio_request_one(LCD_PANEL_PWM, GPIOF_OUT_INIT_HIGH, "lcd panel pwm"); | ||
203 | |||
204 | omap_display_init(&am3517_evm_dss_data); | ||
205 | |||
206 | platform_device_register(&am3517_evm_tfp410_device); | ||
207 | platform_device_register(&am3517_evm_dvi_connector_device); | ||
208 | platform_device_register(&am3517_evm_lcd_device); | ||
209 | platform_device_register(&am3517_evm_tv_connector_device); | ||
210 | } | ||
211 | |||
173 | /* | 212 | /* |
174 | * Board initialization | 213 | * Board initialization |
175 | */ | 214 | */ |
@@ -295,7 +334,9 @@ static void __init am3517_evm_init(void) | |||
295 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); | 334 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); |
296 | 335 | ||
297 | am3517_evm_i2c_init(); | 336 | am3517_evm_i2c_init(); |
298 | omap_display_init(&am3517_evm_dss_data); | 337 | |
338 | am3517_evm_display_init(); | ||
339 | |||
299 | omap_serial_init(); | 340 | omap_serial_init(); |
300 | omap_sdrc_init(NULL, NULL); | 341 | omap_sdrc_init(NULL, NULL); |
301 | 342 | ||
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index d4622ed26252..33d159e2386e 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c | |||
@@ -190,52 +190,81 @@ static inline void cm_t35_init_nand(void) {} | |||
190 | #define CM_T35_LCD_BL_GPIO 58 | 190 | #define CM_T35_LCD_BL_GPIO 58 |
191 | #define CM_T35_DVI_EN_GPIO 54 | 191 | #define CM_T35_DVI_EN_GPIO 54 |
192 | 192 | ||
193 | static struct panel_generic_dpi_data lcd_panel = { | 193 | static const struct display_timing cm_t35_lcd_videomode = { |
194 | .name = "toppoly_tdo35s", | 194 | .pixelclock = { 0, 26000000, 0 }, |
195 | .num_gpios = 1, | 195 | |
196 | .gpios = { | 196 | .hactive = { 0, 480, 0 }, |
197 | CM_T35_LCD_BL_GPIO, | 197 | .hfront_porch = { 0, 104, 0 }, |
198 | }, | 198 | .hback_porch = { 0, 8, 0 }, |
199 | .hsync_len = { 0, 8, 0 }, | ||
200 | |||
201 | .vactive = { 0, 640, 0 }, | ||
202 | .vfront_porch = { 0, 4, 0 }, | ||
203 | .vback_porch = { 0, 2, 0 }, | ||
204 | .vsync_len = { 0, 2, 0 }, | ||
205 | |||
206 | .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | | ||
207 | DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE, | ||
208 | }; | ||
209 | |||
210 | static struct panel_dpi_platform_data cm_t35_lcd_pdata = { | ||
211 | .name = "lcd", | ||
212 | .source = "dpi.0", | ||
213 | |||
214 | .data_lines = 18, | ||
215 | |||
216 | .display_timing = &cm_t35_lcd_videomode, | ||
217 | |||
218 | .enable_gpio = -1, | ||
219 | .backlight_gpio = CM_T35_LCD_BL_GPIO, | ||
220 | }; | ||
221 | |||
222 | static struct platform_device cm_t35_lcd_device = { | ||
223 | .name = "panel-dpi", | ||
224 | .id = 0, | ||
225 | .dev.platform_data = &cm_t35_lcd_pdata, | ||
199 | }; | 226 | }; |
200 | 227 | ||
201 | static struct omap_dss_device cm_t35_lcd_device = { | 228 | static struct connector_dvi_platform_data cm_t35_dvi_connector_pdata = { |
202 | .name = "lcd", | 229 | .name = "dvi", |
203 | .type = OMAP_DISPLAY_TYPE_DPI, | 230 | .source = "tfp410.0", |
204 | .driver_name = "generic_dpi_panel", | 231 | .i2c_bus_num = -1, |
205 | .data = &lcd_panel, | ||
206 | .phy.dpi.data_lines = 18, | ||
207 | }; | 232 | }; |
208 | 233 | ||
209 | static struct tfp410_platform_data dvi_panel = { | 234 | static struct platform_device cm_t35_dvi_connector_device = { |
210 | .power_down_gpio = CM_T35_DVI_EN_GPIO, | 235 | .name = "connector-dvi", |
211 | .i2c_bus_num = -1, | 236 | .id = 0, |
237 | .dev.platform_data = &cm_t35_dvi_connector_pdata, | ||
212 | }; | 238 | }; |
213 | 239 | ||
214 | static struct omap_dss_device cm_t35_dvi_device = { | 240 | static struct encoder_tfp410_platform_data cm_t35_tfp410_pdata = { |
215 | .name = "dvi", | 241 | .name = "tfp410.0", |
216 | .type = OMAP_DISPLAY_TYPE_DPI, | 242 | .source = "dpi.0", |
217 | .driver_name = "tfp410", | 243 | .data_lines = 24, |
218 | .data = &dvi_panel, | 244 | .power_down_gpio = CM_T35_DVI_EN_GPIO, |
219 | .phy.dpi.data_lines = 24, | ||
220 | }; | 245 | }; |
221 | 246 | ||
222 | static struct omap_dss_device cm_t35_tv_device = { | 247 | static struct platform_device cm_t35_tfp410_device = { |
223 | .name = "tv", | 248 | .name = "tfp410", |
224 | .driver_name = "venc", | 249 | .id = 0, |
225 | .type = OMAP_DISPLAY_TYPE_VENC, | 250 | .dev.platform_data = &cm_t35_tfp410_pdata, |
226 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
227 | }; | 251 | }; |
228 | 252 | ||
229 | static struct omap_dss_device *cm_t35_dss_devices[] = { | 253 | static struct connector_atv_platform_data cm_t35_tv_pdata = { |
230 | &cm_t35_lcd_device, | 254 | .name = "tv", |
231 | &cm_t35_dvi_device, | 255 | .source = "venc.0", |
232 | &cm_t35_tv_device, | 256 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, |
257 | .invert_polarity = false, | ||
258 | }; | ||
259 | |||
260 | static struct platform_device cm_t35_tv_connector_device = { | ||
261 | .name = "connector-analog-tv", | ||
262 | .id = 0, | ||
263 | .dev.platform_data = &cm_t35_tv_pdata, | ||
233 | }; | 264 | }; |
234 | 265 | ||
235 | static struct omap_dss_board_info cm_t35_dss_data = { | 266 | static struct omap_dss_board_info cm_t35_dss_data = { |
236 | .num_devices = ARRAY_SIZE(cm_t35_dss_devices), | 267 | .default_display_name = "dvi", |
237 | .devices = cm_t35_dss_devices, | ||
238 | .default_device = &cm_t35_dvi_device, | ||
239 | }; | 268 | }; |
240 | 269 | ||
241 | static struct omap2_mcspi_device_config tdo24m_mcspi_config = { | 270 | static struct omap2_mcspi_device_config tdo24m_mcspi_config = { |
@@ -280,6 +309,11 @@ static void __init cm_t35_init_display(void) | |||
280 | pr_err("CM-T35: failed to register DSS device\n"); | 309 | pr_err("CM-T35: failed to register DSS device\n"); |
281 | gpio_free(CM_T35_LCD_EN_GPIO); | 310 | gpio_free(CM_T35_LCD_EN_GPIO); |
282 | } | 311 | } |
312 | |||
313 | platform_device_register(&cm_t35_tfp410_device); | ||
314 | platform_device_register(&cm_t35_dvi_connector_device); | ||
315 | platform_device_register(&cm_t35_lcd_device); | ||
316 | platform_device_register(&cm_t35_tv_connector_device); | ||
283 | } | 317 | } |
284 | 318 | ||
285 | static struct regulator_consumer_supply cm_t35_vmmc1_supply[] = { | 319 | static struct regulator_consumer_supply cm_t35_vmmc1_supply[] = { |
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index f1d91ba5d1ac..cdc4fb9960a9 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c | |||
@@ -112,50 +112,81 @@ static struct regulator_consumer_supply devkit8000_vio_supply[] = { | |||
112 | REGULATOR_SUPPLY("vcc", "spi2.0"), | 112 | REGULATOR_SUPPLY("vcc", "spi2.0"), |
113 | }; | 113 | }; |
114 | 114 | ||
115 | static struct panel_generic_dpi_data lcd_panel = { | 115 | static const struct display_timing devkit8000_lcd_videomode = { |
116 | .name = "innolux_at070tn83", | 116 | .pixelclock = { 0, 40000000, 0 }, |
117 | /* gpios filled in code */ | 117 | |
118 | .hactive = { 0, 800, 0 }, | ||
119 | .hfront_porch = { 0, 1, 0 }, | ||
120 | .hback_porch = { 0, 1, 0 }, | ||
121 | .hsync_len = { 0, 48, 0 }, | ||
122 | |||
123 | .vactive = { 0, 480, 0 }, | ||
124 | .vfront_porch = { 0, 12, 0 }, | ||
125 | .vback_porch = { 0, 25, 0 }, | ||
126 | .vsync_len = { 0, 3, 0 }, | ||
127 | |||
128 | .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | | ||
129 | DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, | ||
118 | }; | 130 | }; |
119 | 131 | ||
120 | static struct omap_dss_device devkit8000_lcd_device = { | 132 | static struct panel_dpi_platform_data devkit8000_lcd_pdata = { |
121 | .name = "lcd", | 133 | .name = "lcd", |
122 | .type = OMAP_DISPLAY_TYPE_DPI, | 134 | .source = "dpi.0", |
123 | .driver_name = "generic_dpi_panel", | 135 | |
124 | .data = &lcd_panel, | 136 | .data_lines = 24, |
125 | .phy.dpi.data_lines = 24, | 137 | |
138 | .display_timing = &devkit8000_lcd_videomode, | ||
139 | |||
140 | .enable_gpio = -1, /* filled in code */ | ||
141 | .backlight_gpio = -1, | ||
126 | }; | 142 | }; |
127 | 143 | ||
128 | static struct tfp410_platform_data dvi_panel = { | 144 | static struct platform_device devkit8000_lcd_device = { |
129 | .power_down_gpio = -1, | 145 | .name = "panel-dpi", |
130 | .i2c_bus_num = 1, | 146 | .id = 0, |
147 | .dev.platform_data = &devkit8000_lcd_pdata, | ||
131 | }; | 148 | }; |
132 | 149 | ||
133 | static struct omap_dss_device devkit8000_dvi_device = { | 150 | static struct connector_dvi_platform_data devkit8000_dvi_connector_pdata = { |
134 | .name = "dvi", | 151 | .name = "dvi", |
135 | .type = OMAP_DISPLAY_TYPE_DPI, | 152 | .source = "tfp410.0", |
136 | .driver_name = "tfp410", | 153 | .i2c_bus_num = 1, |
137 | .data = &dvi_panel, | ||
138 | .phy.dpi.data_lines = 24, | ||
139 | }; | 154 | }; |
140 | 155 | ||
141 | static struct omap_dss_device devkit8000_tv_device = { | 156 | static struct platform_device devkit8000_dvi_connector_device = { |
142 | .name = "tv", | 157 | .name = "connector-dvi", |
143 | .driver_name = "venc", | 158 | .id = 0, |
144 | .type = OMAP_DISPLAY_TYPE_VENC, | 159 | .dev.platform_data = &devkit8000_dvi_connector_pdata, |
145 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
146 | }; | 160 | }; |
147 | 161 | ||
162 | static struct encoder_tfp410_platform_data devkit8000_tfp410_pdata = { | ||
163 | .name = "tfp410.0", | ||
164 | .source = "dpi.0", | ||
165 | .data_lines = 24, | ||
166 | .power_down_gpio = -1, /* filled in code */ | ||
167 | }; | ||
148 | 168 | ||
149 | static struct omap_dss_device *devkit8000_dss_devices[] = { | 169 | static struct platform_device devkit8000_tfp410_device = { |
150 | &devkit8000_lcd_device, | 170 | .name = "tfp410", |
151 | &devkit8000_dvi_device, | 171 | .id = 0, |
152 | &devkit8000_tv_device, | 172 | .dev.platform_data = &devkit8000_tfp410_pdata, |
173 | }; | ||
174 | |||
175 | static struct connector_atv_platform_data devkit8000_tv_pdata = { | ||
176 | .name = "tv", | ||
177 | .source = "venc.0", | ||
178 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
179 | .invert_polarity = false, | ||
180 | }; | ||
181 | |||
182 | static struct platform_device devkit8000_tv_connector_device = { | ||
183 | .name = "connector-analog-tv", | ||
184 | .id = 0, | ||
185 | .dev.platform_data = &devkit8000_tv_pdata, | ||
153 | }; | 186 | }; |
154 | 187 | ||
155 | static struct omap_dss_board_info devkit8000_dss_data = { | 188 | static struct omap_dss_board_info devkit8000_dss_data = { |
156 | .num_devices = ARRAY_SIZE(devkit8000_dss_devices), | 189 | .default_display_name = "lcd", |
157 | .devices = devkit8000_dss_devices, | ||
158 | .default_device = &devkit8000_lcd_device, | ||
159 | }; | 190 | }; |
160 | 191 | ||
161 | static uint32_t board_keymap[] = { | 192 | static uint32_t board_keymap[] = { |
@@ -204,11 +235,10 @@ static int devkit8000_twl_gpio_setup(struct device *dev, | |||
204 | gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; | 235 | gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; |
205 | 236 | ||
206 | /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */ | 237 | /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */ |
207 | lcd_panel.num_gpios = 1; | 238 | devkit8000_lcd_pdata.enable_gpio = gpio + TWL4030_GPIO_MAX + 0; |
208 | lcd_panel.gpios[0] = gpio + TWL4030_GPIO_MAX + 0; | ||
209 | 239 | ||
210 | /* gpio + 7 is "DVI_PD" (out, active low) */ | 240 | /* gpio + 7 is "DVI_PD" (out, active low) */ |
211 | dvi_panel.power_down_gpio = gpio + 7; | 241 | devkit8000_tfp410_pdata.power_down_gpio = gpio + 7; |
212 | 242 | ||
213 | return 0; | 243 | return 0; |
214 | } | 244 | } |
@@ -413,6 +443,10 @@ static struct platform_device *devkit8000_devices[] __initdata = { | |||
413 | &leds_gpio, | 443 | &leds_gpio, |
414 | &keys_gpio, | 444 | &keys_gpio, |
415 | &omap_dm9000_dev, | 445 | &omap_dm9000_dev, |
446 | &devkit8000_lcd_device, | ||
447 | &devkit8000_tfp410_device, | ||
448 | &devkit8000_dvi_connector_device, | ||
449 | &devkit8000_tv_connector_device, | ||
416 | }; | 450 | }; |
417 | 451 | ||
418 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 452 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 69c0acf5aa63..87e41a8b8d46 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
@@ -194,30 +194,48 @@ static struct platform_device h4_flash_device = { | |||
194 | .resource = &h4_flash_resource, | 194 | .resource = &h4_flash_resource, |
195 | }; | 195 | }; |
196 | 196 | ||
197 | static struct platform_device *h4_devices[] __initdata = { | 197 | static const struct display_timing cm_t35_lcd_videomode = { |
198 | &h4_flash_device, | 198 | .pixelclock = { 0, 6250000, 0 }, |
199 | |||
200 | .hactive = { 0, 240, 0 }, | ||
201 | .hfront_porch = { 0, 15, 0 }, | ||
202 | .hback_porch = { 0, 60, 0 }, | ||
203 | .hsync_len = { 0, 15, 0 }, | ||
204 | |||
205 | .vactive = { 0, 320, 0 }, | ||
206 | .vfront_porch = { 0, 1, 0 }, | ||
207 | .vback_porch = { 0, 1, 0 }, | ||
208 | .vsync_len = { 0, 1, 0 }, | ||
209 | |||
210 | .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH | | ||
211 | DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, | ||
199 | }; | 212 | }; |
200 | 213 | ||
201 | static struct panel_generic_dpi_data h4_panel_data = { | 214 | static struct panel_dpi_platform_data cm_t35_lcd_pdata = { |
202 | .name = "h4", | 215 | .name = "lcd", |
216 | .source = "dpi.0", | ||
217 | |||
218 | .data_lines = 16, | ||
219 | |||
220 | .display_timing = &cm_t35_lcd_videomode, | ||
221 | |||
222 | .enable_gpio = -1, | ||
223 | .backlight_gpio = -1, | ||
203 | }; | 224 | }; |
204 | 225 | ||
205 | static struct omap_dss_device h4_lcd_device = { | 226 | static struct platform_device cm_t35_lcd_device = { |
206 | .name = "lcd", | 227 | .name = "panel-dpi", |
207 | .driver_name = "generic_dpi_panel", | 228 | .id = 0, |
208 | .type = OMAP_DISPLAY_TYPE_DPI, | 229 | .dev.platform_data = &cm_t35_lcd_pdata, |
209 | .phy.dpi.data_lines = 16, | ||
210 | .data = &h4_panel_data, | ||
211 | }; | 230 | }; |
212 | 231 | ||
213 | static struct omap_dss_device *h4_dss_devices[] = { | 232 | static struct platform_device *h4_devices[] __initdata = { |
214 | &h4_lcd_device, | 233 | &h4_flash_device, |
234 | &cm_t35_lcd_device, | ||
215 | }; | 235 | }; |
216 | 236 | ||
217 | static struct omap_dss_board_info h4_dss_data = { | 237 | static struct omap_dss_board_info h4_dss_data = { |
218 | .num_devices = ARRAY_SIZE(h4_dss_devices), | 238 | .default_display_name = "lcd", |
219 | .devices = h4_dss_devices, | ||
220 | .default_device = &h4_lcd_device, | ||
221 | }; | 239 | }; |
222 | 240 | ||
223 | /* 2420 Sysboot setup (2430 is different) */ | 241 | /* 2420 Sysboot setup (2430 is different) */ |
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 87e65dde8e13..06dbb2d3d38b 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
@@ -429,31 +429,39 @@ static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = { | |||
429 | .setup = igep_twl_gpio_setup, | 429 | .setup = igep_twl_gpio_setup, |
430 | }; | 430 | }; |
431 | 431 | ||
432 | static struct tfp410_platform_data dvi_panel = { | 432 | static struct connector_dvi_platform_data omap3stalker_dvi_connector_pdata = { |
433 | .i2c_bus_num = 3, | 433 | .name = "dvi", |
434 | .power_down_gpio = IGEP2_GPIO_DVI_PUP, | 434 | .source = "tfp410.0", |
435 | .i2c_bus_num = 3, | ||
435 | }; | 436 | }; |
436 | 437 | ||
437 | static struct omap_dss_device igep2_dvi_device = { | 438 | static struct platform_device omap3stalker_dvi_connector_device = { |
438 | .type = OMAP_DISPLAY_TYPE_DPI, | 439 | .name = "connector-dvi", |
439 | .name = "dvi", | 440 | .id = 0, |
440 | .driver_name = "tfp410", | 441 | .dev.platform_data = &omap3stalker_dvi_connector_pdata, |
441 | .data = &dvi_panel, | ||
442 | .phy.dpi.data_lines = 24, | ||
443 | }; | 442 | }; |
444 | 443 | ||
445 | static struct omap_dss_device *igep2_dss_devices[] = { | 444 | static struct encoder_tfp410_platform_data omap3stalker_tfp410_pdata = { |
446 | &igep2_dvi_device | 445 | .name = "tfp410.0", |
446 | .source = "dpi.0", | ||
447 | .data_lines = 24, | ||
448 | .power_down_gpio = IGEP2_GPIO_DVI_PUP, | ||
449 | }; | ||
450 | |||
451 | static struct platform_device omap3stalker_tfp410_device = { | ||
452 | .name = "tfp410", | ||
453 | .id = 0, | ||
454 | .dev.platform_data = &omap3stalker_tfp410_pdata, | ||
447 | }; | 455 | }; |
448 | 456 | ||
449 | static struct omap_dss_board_info igep2_dss_data = { | 457 | static struct omap_dss_board_info igep2_dss_data = { |
450 | .num_devices = ARRAY_SIZE(igep2_dss_devices), | 458 | .default_display_name = "dvi", |
451 | .devices = igep2_dss_devices, | ||
452 | .default_device = &igep2_dvi_device, | ||
453 | }; | 459 | }; |
454 | 460 | ||
455 | static struct platform_device *igep_devices[] __initdata = { | 461 | static struct platform_device *igep_devices[] __initdata = { |
456 | &igep_vwlan_device, | 462 | &igep_vwlan_device, |
463 | &omap3stalker_tfp410_device, | ||
464 | &omap3stalker_dvi_connector_device, | ||
457 | }; | 465 | }; |
458 | 466 | ||
459 | static int igep2_keymap[] = { | 467 | static int igep2_keymap[] = { |
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 62e4f701b63b..dd8da2c5399f 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c | |||
@@ -184,45 +184,70 @@ static inline void __init ldp_init_smsc911x(void) | |||
184 | #define LCD_PANEL_RESET_GPIO 55 | 184 | #define LCD_PANEL_RESET_GPIO 55 |
185 | #define LCD_PANEL_QVGA_GPIO 56 | 185 | #define LCD_PANEL_QVGA_GPIO 56 |
186 | 186 | ||
187 | static struct panel_generic_dpi_data ldp_panel_data = { | 187 | static const struct display_timing ldp_lcd_videomode = { |
188 | .name = "nec_nl2432dr22-11b", | 188 | .pixelclock = { 0, 5400000, 0 }, |
189 | .num_gpios = 4, | 189 | |
190 | /* gpios filled in code */ | 190 | .hactive = { 0, 240, 0 }, |
191 | .hfront_porch = { 0, 3, 0 }, | ||
192 | .hback_porch = { 0, 39, 0 }, | ||
193 | .hsync_len = { 0, 3, 0 }, | ||
194 | |||
195 | .vactive = { 0, 320, 0 }, | ||
196 | .vfront_porch = { 0, 2, 0 }, | ||
197 | .vback_porch = { 0, 7, 0 }, | ||
198 | .vsync_len = { 0, 1, 0 }, | ||
199 | |||
200 | .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | | ||
201 | DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, | ||
191 | }; | 202 | }; |
192 | 203 | ||
193 | static struct omap_dss_device ldp_lcd_device = { | 204 | static struct panel_dpi_platform_data ldp_lcd_pdata = { |
194 | .name = "lcd", | 205 | .name = "lcd", |
195 | .driver_name = "generic_dpi_panel", | 206 | .source = "dpi.0", |
196 | .type = OMAP_DISPLAY_TYPE_DPI, | 207 | |
197 | .phy.dpi.data_lines = 18, | 208 | .data_lines = 18, |
198 | .data = &ldp_panel_data, | 209 | |
210 | .display_timing = &ldp_lcd_videomode, | ||
211 | |||
212 | .enable_gpio = -1, /* filled in code */ | ||
213 | .backlight_gpio = -1, /* filled in code */ | ||
199 | }; | 214 | }; |
200 | 215 | ||
201 | static struct omap_dss_device *ldp_dss_devices[] = { | 216 | static struct platform_device ldp_lcd_device = { |
202 | &ldp_lcd_device, | 217 | .name = "panel-dpi", |
218 | .id = 0, | ||
219 | .dev.platform_data = &ldp_lcd_pdata, | ||
203 | }; | 220 | }; |
204 | 221 | ||
205 | static struct omap_dss_board_info ldp_dss_data = { | 222 | static struct omap_dss_board_info ldp_dss_data = { |
206 | .num_devices = ARRAY_SIZE(ldp_dss_devices), | 223 | .default_display_name = "lcd", |
207 | .devices = ldp_dss_devices, | ||
208 | .default_device = &ldp_lcd_device, | ||
209 | }; | 224 | }; |
210 | 225 | ||
211 | static void __init ldp_display_init(void) | 226 | static void __init ldp_display_init(void) |
212 | { | 227 | { |
213 | ldp_panel_data.gpios[2] = LCD_PANEL_RESET_GPIO; | 228 | int r; |
214 | ldp_panel_data.gpios[3] = LCD_PANEL_QVGA_GPIO; | 229 | |
230 | static struct gpio gpios[] __initdata = { | ||
231 | {LCD_PANEL_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "LCD RESET"}, | ||
232 | {LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "LCD QVGA"}, | ||
233 | }; | ||
234 | |||
235 | r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); | ||
236 | if (r) { | ||
237 | pr_err("Cannot request LCD GPIOs, error %d\n", r); | ||
238 | return; | ||
239 | } | ||
215 | 240 | ||
216 | omap_display_init(&ldp_dss_data); | 241 | omap_display_init(&ldp_dss_data); |
217 | } | 242 | } |
218 | 243 | ||
219 | static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) | 244 | static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) |
220 | { | 245 | { |
221 | ldp_panel_data.gpios[0] = gpio + 7; | 246 | /* LCD enable GPIO */ |
222 | ldp_panel_data.gpio_invert[0] = true; | 247 | ldp_lcd_pdata.enable_gpio = gpio + 7; |
223 | 248 | ||
224 | ldp_panel_data.gpios[1] = gpio + 15; | 249 | /* Backlight enable GPIO */ |
225 | ldp_panel_data.gpio_invert[1] = true; | 250 | ldp_lcd_pdata.backlight_gpio = gpio + 15; |
226 | 251 | ||
227 | return 0; | 252 | return 0; |
228 | } | 253 | } |
@@ -322,6 +347,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = { | |||
322 | 347 | ||
323 | static struct platform_device *ldp_devices[] __initdata = { | 348 | static struct platform_device *ldp_devices[] __initdata = { |
324 | &ldp_gpio_keys_device, | 349 | &ldp_gpio_keys_device, |
350 | &ldp_lcd_device, | ||
325 | }; | 351 | }; |
326 | 352 | ||
327 | #ifdef CONFIG_OMAP_MUX | 353 | #ifdef CONFIG_OMAP_MUX |
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index f6eeb87e4e95..827d15009a86 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c | |||
@@ -122,11 +122,7 @@ static struct musb_hdrc_config musb_config = { | |||
122 | }; | 122 | }; |
123 | 123 | ||
124 | static struct musb_hdrc_platform_data tusb_data = { | 124 | static struct musb_hdrc_platform_data tusb_data = { |
125 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
126 | .mode = MUSB_OTG, | 125 | .mode = MUSB_OTG, |
127 | #else | ||
128 | .mode = MUSB_HOST, | ||
129 | #endif | ||
130 | .set_power = tusb_set_power, | 126 | .set_power = tusb_set_power, |
131 | .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */ | 127 | .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */ |
132 | .power = 100, /* Max 100 mA VBUS for host mode */ | 128 | .power = 100, /* Max 100 mA VBUS for host mode */ |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 04c116555412..f26918467efc 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/mtd/nand.h> | 33 | #include <linux/mtd/nand.h> |
34 | #include <linux/mmc/host.h> | 34 | #include <linux/mmc/host.h> |
35 | #include <linux/usb/phy.h> | 35 | #include <linux/usb/phy.h> |
36 | #include <linux/usb/nop-usb-xceiv.h> | 36 | #include <linux/usb/usb_phy_gen_xceiv.h> |
37 | 37 | ||
38 | #include <linux/regulator/machine.h> | 38 | #include <linux/regulator/machine.h> |
39 | #include <linux/i2c/twl.h> | 39 | #include <linux/i2c/twl.h> |
@@ -225,35 +225,46 @@ static struct mtd_partition omap3beagle_nand_partitions[] = { | |||
225 | 225 | ||
226 | /* DSS */ | 226 | /* DSS */ |
227 | 227 | ||
228 | static struct tfp410_platform_data dvi_panel = { | 228 | static struct connector_dvi_platform_data beagle_dvi_connector_pdata = { |
229 | .i2c_bus_num = 3, | 229 | .name = "dvi", |
230 | .power_down_gpio = -1, | 230 | .source = "tfp410.0", |
231 | .i2c_bus_num = 3, | ||
231 | }; | 232 | }; |
232 | 233 | ||
233 | static struct omap_dss_device beagle_dvi_device = { | 234 | static struct platform_device beagle_dvi_connector_device = { |
234 | .type = OMAP_DISPLAY_TYPE_DPI, | 235 | .name = "connector-dvi", |
235 | .name = "dvi", | 236 | .id = 0, |
236 | .driver_name = "tfp410", | 237 | .dev.platform_data = &beagle_dvi_connector_pdata, |
237 | .data = &dvi_panel, | ||
238 | .phy.dpi.data_lines = 24, | ||
239 | }; | 238 | }; |
240 | 239 | ||
241 | static struct omap_dss_device beagle_tv_device = { | 240 | static struct encoder_tfp410_platform_data beagle_tfp410_pdata = { |
241 | .name = "tfp410.0", | ||
242 | .source = "dpi.0", | ||
243 | .data_lines = 24, | ||
244 | .power_down_gpio = -1, | ||
245 | }; | ||
246 | |||
247 | static struct platform_device beagle_tfp410_device = { | ||
248 | .name = "tfp410", | ||
249 | .id = 0, | ||
250 | .dev.platform_data = &beagle_tfp410_pdata, | ||
251 | }; | ||
252 | |||
253 | static struct connector_atv_platform_data beagle_tv_pdata = { | ||
242 | .name = "tv", | 254 | .name = "tv", |
243 | .driver_name = "venc", | 255 | .source = "venc.0", |
244 | .type = OMAP_DISPLAY_TYPE_VENC, | 256 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, |
245 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | 257 | .invert_polarity = false, |
246 | }; | 258 | }; |
247 | 259 | ||
248 | static struct omap_dss_device *beagle_dss_devices[] = { | 260 | static struct platform_device beagle_tv_connector_device = { |
249 | &beagle_dvi_device, | 261 | .name = "connector-analog-tv", |
250 | &beagle_tv_device, | 262 | .id = 0, |
263 | .dev.platform_data = &beagle_tv_pdata, | ||
251 | }; | 264 | }; |
252 | 265 | ||
253 | static struct omap_dss_board_info beagle_dss_data = { | 266 | static struct omap_dss_board_info beagle_dss_data = { |
254 | .num_devices = ARRAY_SIZE(beagle_dss_devices), | 267 | .default_display_name = "dvi", |
255 | .devices = beagle_dss_devices, | ||
256 | .default_device = &beagle_dvi_device, | ||
257 | }; | 268 | }; |
258 | 269 | ||
259 | #include "sdram-micron-mt46h32m32lf-6.h" | 270 | #include "sdram-micron-mt46h32m32lf-6.h" |
@@ -279,7 +290,7 @@ static struct regulator_consumer_supply beagle_vsim_supply[] = { | |||
279 | static struct gpio_led gpio_leds[]; | 290 | static struct gpio_led gpio_leds[]; |
280 | 291 | ||
281 | /* PHY's VCC regulator might be added later, so flag that we need it */ | 292 | /* PHY's VCC regulator might be added later, so flag that we need it */ |
282 | static struct nop_usb_xceiv_platform_data hsusb2_phy_data = { | 293 | static struct usb_phy_gen_xceiv_platform_data hsusb2_phy_data = { |
283 | .needs_vcc = true, | 294 | .needs_vcc = true, |
284 | }; | 295 | }; |
285 | 296 | ||
@@ -332,7 +343,11 @@ static int beagle_twl_gpio_setup(struct device *dev, | |||
332 | if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) | 343 | if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) |
333 | pr_err("%s: unable to configure EHCI_nOC\n", __func__); | 344 | pr_err("%s: unable to configure EHCI_nOC\n", __func__); |
334 | } | 345 | } |
335 | dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio; | 346 | beagle_tfp410_pdata.power_down_gpio = beagle_config.dvi_pd_gpio; |
347 | |||
348 | platform_device_register(&beagle_tfp410_device); | ||
349 | platform_device_register(&beagle_dvi_connector_device); | ||
350 | platform_device_register(&beagle_tv_connector_device); | ||
336 | 351 | ||
337 | /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */ | 352 | /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */ |
338 | phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX; | 353 | phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX; |
@@ -547,6 +562,7 @@ static void __init omap3_beagle_init(void) | |||
547 | if (gpio_is_valid(beagle_config.dvi_pd_gpio)) | 562 | if (gpio_is_valid(beagle_config.dvi_pd_gpio)) |
548 | omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT); | 563 | omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT); |
549 | omap_display_init(&beagle_dss_data); | 564 | omap_display_init(&beagle_dss_data); |
565 | |||
550 | omap_serial_init(); | 566 | omap_serial_init(); |
551 | omap_sdrc_init(mt46h32m32lf6_sdrc_params, | 567 | omap_sdrc_init(mt46h32m32lf6_sdrc_params, |
552 | mt46h32m32lf6_sdrc_params); | 568 | mt46h32m32lf6_sdrc_params); |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 8c026269baca..18143873346c 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/i2c/twl.h> | 33 | #include <linux/i2c/twl.h> |
34 | #include <linux/usb/otg.h> | 34 | #include <linux/usb/otg.h> |
35 | #include <linux/usb/musb.h> | 35 | #include <linux/usb/musb.h> |
36 | #include <linux/usb/nop-usb-xceiv.h> | 36 | #include <linux/usb/usb_phy_gen_xceiv.h> |
37 | #include <linux/smsc911x.h> | 37 | #include <linux/smsc911x.h> |
38 | 38 | ||
39 | #include <linux/wl12xx.h> | 39 | #include <linux/wl12xx.h> |
@@ -166,14 +166,6 @@ static inline void __init omap3evm_init_smsc911x(void) { return; } | |||
166 | */ | 166 | */ |
167 | #define OMAP3EVM_DVI_PANEL_EN_GPIO 199 | 167 | #define OMAP3EVM_DVI_PANEL_EN_GPIO 199 |
168 | 168 | ||
169 | static struct panel_sharp_ls037v7dw01_data omap3_evm_lcd_data = { | ||
170 | .resb_gpio = OMAP3EVM_LCD_PANEL_RESB, | ||
171 | .ini_gpio = OMAP3EVM_LCD_PANEL_INI, | ||
172 | .mo_gpio = OMAP3EVM_LCD_PANEL_QVGA, | ||
173 | .lr_gpio = OMAP3EVM_LCD_PANEL_LR, | ||
174 | .ud_gpio = OMAP3EVM_LCD_PANEL_UD, | ||
175 | }; | ||
176 | |||
177 | #ifdef CONFIG_BROKEN | 169 | #ifdef CONFIG_BROKEN |
178 | static void __init omap3_evm_display_init(void) | 170 | static void __init omap3_evm_display_init(void) |
179 | { | 171 | { |
@@ -196,44 +188,65 @@ static void __init omap3_evm_display_init(void) | |||
196 | } | 188 | } |
197 | #endif | 189 | #endif |
198 | 190 | ||
199 | static struct omap_dss_device omap3_evm_lcd_device = { | 191 | static struct panel_sharp_ls037v7dw01_platform_data omap3_evm_lcd_pdata = { |
200 | .name = "lcd", | 192 | .name = "lcd", |
201 | .driver_name = "sharp_ls_panel", | 193 | .source = "dpi.0", |
202 | .type = OMAP_DISPLAY_TYPE_DPI, | 194 | |
203 | .phy.dpi.data_lines = 18, | 195 | .data_lines = 18, |
204 | .data = &omap3_evm_lcd_data, | 196 | |
197 | .resb_gpio = OMAP3EVM_LCD_PANEL_RESB, | ||
198 | .ini_gpio = OMAP3EVM_LCD_PANEL_INI, | ||
199 | .mo_gpio = OMAP3EVM_LCD_PANEL_QVGA, | ||
200 | .lr_gpio = OMAP3EVM_LCD_PANEL_LR, | ||
201 | .ud_gpio = OMAP3EVM_LCD_PANEL_UD, | ||
202 | }; | ||
203 | |||
204 | static struct platform_device omap3_evm_lcd_device = { | ||
205 | .name = "panel-sharp-ls037v7dw01", | ||
206 | .id = 0, | ||
207 | .dev.platform_data = &omap3_evm_lcd_pdata, | ||
208 | }; | ||
209 | |||
210 | static struct connector_dvi_platform_data omap3_evm_dvi_connector_pdata = { | ||
211 | .name = "dvi", | ||
212 | .source = "tfp410.0", | ||
213 | .i2c_bus_num = -1, | ||
214 | }; | ||
215 | |||
216 | static struct platform_device omap3_evm_dvi_connector_device = { | ||
217 | .name = "connector-dvi", | ||
218 | .id = 0, | ||
219 | .dev.platform_data = &omap3_evm_dvi_connector_pdata, | ||
205 | }; | 220 | }; |
206 | 221 | ||
207 | static struct omap_dss_device omap3_evm_tv_device = { | 222 | static struct encoder_tfp410_platform_data omap3_evm_tfp410_pdata = { |
208 | .name = "tv", | 223 | .name = "tfp410.0", |
209 | .driver_name = "venc", | 224 | .source = "dpi.0", |
210 | .type = OMAP_DISPLAY_TYPE_VENC, | 225 | .data_lines = 24, |
211 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | 226 | .power_down_gpio = OMAP3EVM_DVI_PANEL_EN_GPIO, |
212 | }; | 227 | }; |
213 | 228 | ||
214 | static struct tfp410_platform_data dvi_panel = { | 229 | static struct platform_device omap3_evm_tfp410_device = { |
215 | .power_down_gpio = OMAP3EVM_DVI_PANEL_EN_GPIO, | 230 | .name = "tfp410", |
216 | .i2c_bus_num = -1, | 231 | .id = 0, |
232 | .dev.platform_data = &omap3_evm_tfp410_pdata, | ||
217 | }; | 233 | }; |
218 | 234 | ||
219 | static struct omap_dss_device omap3_evm_dvi_device = { | 235 | static struct connector_atv_platform_data omap3_evm_tv_pdata = { |
220 | .name = "dvi", | 236 | .name = "tv", |
221 | .type = OMAP_DISPLAY_TYPE_DPI, | 237 | .source = "venc.0", |
222 | .driver_name = "tfp410", | 238 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, |
223 | .data = &dvi_panel, | 239 | .invert_polarity = false, |
224 | .phy.dpi.data_lines = 24, | ||
225 | }; | 240 | }; |
226 | 241 | ||
227 | static struct omap_dss_device *omap3_evm_dss_devices[] = { | 242 | static struct platform_device omap3_evm_tv_connector_device = { |
228 | &omap3_evm_lcd_device, | 243 | .name = "connector-analog-tv", |
229 | &omap3_evm_tv_device, | 244 | .id = 0, |
230 | &omap3_evm_dvi_device, | 245 | .dev.platform_data = &omap3_evm_tv_pdata, |
231 | }; | 246 | }; |
232 | 247 | ||
233 | static struct omap_dss_board_info omap3_evm_dss_data = { | 248 | static struct omap_dss_board_info omap3_evm_dss_data = { |
234 | .num_devices = ARRAY_SIZE(omap3_evm_dss_devices), | 249 | .default_display_name = "lcd", |
235 | .devices = omap3_evm_dss_devices, | ||
236 | .default_device = &omap3_evm_lcd_device, | ||
237 | }; | 250 | }; |
238 | 251 | ||
239 | static struct regulator_consumer_supply omap3evm_vmmc1_supply[] = { | 252 | static struct regulator_consumer_supply omap3evm_vmmc1_supply[] = { |
@@ -468,7 +481,7 @@ struct wl12xx_platform_data omap3evm_wlan_data __initdata = { | |||
468 | static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = { | 481 | static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = { |
469 | REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"), /* OMAP ISP */ | 482 | REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"), /* OMAP ISP */ |
470 | REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"), /* OMAP ISP */ | 483 | REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"), /* OMAP ISP */ |
471 | REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"), /* hsusb port 2 */ | 484 | REGULATOR_SUPPLY("vcc", "usb_phy_gen_xceiv.2"), /* hsusb port 2 */ |
472 | REGULATOR_SUPPLY("vaux2", NULL), | 485 | REGULATOR_SUPPLY("vaux2", NULL), |
473 | }; | 486 | }; |
474 | 487 | ||
@@ -678,6 +691,10 @@ static void __init omap3_evm_init(void) | |||
678 | omap3_evm_i2c_init(); | 691 | omap3_evm_i2c_init(); |
679 | 692 | ||
680 | omap_display_init(&omap3_evm_dss_data); | 693 | omap_display_init(&omap3_evm_dss_data); |
694 | platform_device_register(&omap3_evm_lcd_device); | ||
695 | platform_device_register(&omap3_evm_tfp410_device); | ||
696 | platform_device_register(&omap3_evm_dvi_connector_device); | ||
697 | platform_device_register(&omap3_evm_tv_connector_device); | ||
681 | 698 | ||
682 | omap_serial_init(); | 699 | omap_serial_init(); |
683 | omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL); | 700 | omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL); |
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index b1547a0edfcd..de1bc6bbe585 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
@@ -231,34 +231,21 @@ static struct twl4030_keypad_data pandora_kp_data = { | |||
231 | .rep = 1, | 231 | .rep = 1, |
232 | }; | 232 | }; |
233 | 233 | ||
234 | static struct panel_tpo_td043_data lcd_data = { | 234 | static struct connector_atv_platform_data pandora_tv_pdata = { |
235 | .nreset_gpio = 157, | 235 | .name = "tv", |
236 | }; | 236 | .source = "venc.0", |
237 | 237 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, | |
238 | static struct omap_dss_device pandora_lcd_device = { | 238 | .invert_polarity = false, |
239 | .name = "lcd", | ||
240 | .driver_name = "tpo_td043mtea1_panel", | ||
241 | .type = OMAP_DISPLAY_TYPE_DPI, | ||
242 | .phy.dpi.data_lines = 24, | ||
243 | .data = &lcd_data, | ||
244 | }; | ||
245 | |||
246 | static struct omap_dss_device pandora_tv_device = { | ||
247 | .name = "tv", | ||
248 | .driver_name = "venc", | ||
249 | .type = OMAP_DISPLAY_TYPE_VENC, | ||
250 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
251 | }; | 239 | }; |
252 | 240 | ||
253 | static struct omap_dss_device *pandora_dss_devices[] = { | 241 | static struct platform_device pandora_tv_connector_device = { |
254 | &pandora_lcd_device, | 242 | .name = "connector-analog-tv", |
255 | &pandora_tv_device, | 243 | .id = 0, |
244 | .dev.platform_data = &pandora_tv_pdata, | ||
256 | }; | 245 | }; |
257 | 246 | ||
258 | static struct omap_dss_board_info pandora_dss_data = { | 247 | static struct omap_dss_board_info pandora_dss_data = { |
259 | .num_devices = ARRAY_SIZE(pandora_dss_devices), | 248 | .default_display_name = "lcd", |
260 | .devices = pandora_dss_devices, | ||
261 | .default_device = &pandora_lcd_device, | ||
262 | }; | 249 | }; |
263 | 250 | ||
264 | static void pandora_wl1251_init_card(struct mmc_card *card) | 251 | static void pandora_wl1251_init_card(struct mmc_card *card) |
@@ -348,11 +335,11 @@ static struct regulator_consumer_supply pandora_vdds_supplies[] = { | |||
348 | }; | 335 | }; |
349 | 336 | ||
350 | static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = { | 337 | static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = { |
351 | REGULATOR_SUPPLY("vcc", "display0"), | 338 | REGULATOR_SUPPLY("vcc", "spi1.1"), |
352 | }; | 339 | }; |
353 | 340 | ||
354 | static struct regulator_consumer_supply pandora_usb_phy_supply[] = { | 341 | static struct regulator_consumer_supply pandora_usb_phy_supply[] = { |
355 | REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"), /* hsusb port 2 */ | 342 | REGULATOR_SUPPLY("vcc", "usb_phy_gen_xceiv.2"), /* hsusb port 2 */ |
356 | }; | 343 | }; |
357 | 344 | ||
358 | /* ads7846 on SPI and 2 nub controllers on I2C */ | 345 | /* ads7846 on SPI and 2 nub controllers on I2C */ |
@@ -529,13 +516,21 @@ static int __init omap3pandora_i2c_init(void) | |||
529 | return 0; | 516 | return 0; |
530 | } | 517 | } |
531 | 518 | ||
519 | static struct panel_tpo_td043mtea1_platform_data pandora_lcd_pdata = { | ||
520 | .name = "lcd", | ||
521 | .source = "dpi.0", | ||
522 | |||
523 | .data_lines = 24, | ||
524 | .nreset_gpio = 157, | ||
525 | }; | ||
526 | |||
532 | static struct spi_board_info omap3pandora_spi_board_info[] __initdata = { | 527 | static struct spi_board_info omap3pandora_spi_board_info[] __initdata = { |
533 | { | 528 | { |
534 | .modalias = "tpo_td043mtea1_panel_spi", | 529 | .modalias = "panel-tpo-td043mtea1", |
535 | .bus_num = 1, | 530 | .bus_num = 1, |
536 | .chip_select = 1, | 531 | .chip_select = 1, |
537 | .max_speed_hz = 375000, | 532 | .max_speed_hz = 375000, |
538 | .platform_data = &pandora_lcd_device, | 533 | .platform_data = &pandora_lcd_pdata, |
539 | } | 534 | } |
540 | }; | 535 | }; |
541 | 536 | ||
@@ -580,6 +575,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = { | |||
580 | &pandora_keys_gpio, | 575 | &pandora_keys_gpio, |
581 | &pandora_vwlan_device, | 576 | &pandora_vwlan_device, |
582 | &pandora_backlight, | 577 | &pandora_backlight, |
578 | &pandora_tv_connector_device, | ||
583 | }; | 579 | }; |
584 | 580 | ||
585 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 581 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index d37e6b187ae4..ba8342fef799 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c | |||
@@ -93,40 +93,50 @@ static void __init omap3_stalker_display_init(void) | |||
93 | { | 93 | { |
94 | return; | 94 | return; |
95 | } | 95 | } |
96 | static struct connector_dvi_platform_data omap3stalker_dvi_connector_pdata = { | ||
97 | .name = "dvi", | ||
98 | .source = "tfp410.0", | ||
99 | .i2c_bus_num = -1, | ||
100 | }; | ||
96 | 101 | ||
97 | static struct omap_dss_device omap3_stalker_tv_device = { | 102 | static struct platform_device omap3stalker_dvi_connector_device = { |
98 | .name = "tv", | 103 | .name = "connector-dvi", |
99 | .driver_name = "venc", | 104 | .id = 0, |
100 | .type = OMAP_DISPLAY_TYPE_VENC, | 105 | .dev.platform_data = &omap3stalker_dvi_connector_pdata, |
101 | #if defined(CONFIG_OMAP2_VENC_OUT_TYPE_SVIDEO) | ||
102 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
103 | #elif defined(CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE) | ||
104 | .u.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE, | ||
105 | #endif | ||
106 | }; | 106 | }; |
107 | 107 | ||
108 | static struct tfp410_platform_data dvi_panel = { | 108 | static struct encoder_tfp410_platform_data omap3stalker_tfp410_pdata = { |
109 | .power_down_gpio = DSS_ENABLE_GPIO, | 109 | .name = "tfp410.0", |
110 | .i2c_bus_num = -1, | 110 | .source = "dpi.0", |
111 | .data_lines = 24, | ||
112 | .power_down_gpio = DSS_ENABLE_GPIO, | ||
111 | }; | 113 | }; |
112 | 114 | ||
113 | static struct omap_dss_device omap3_stalker_dvi_device = { | 115 | static struct platform_device omap3stalker_tfp410_device = { |
114 | .name = "dvi", | 116 | .name = "tfp410", |
115 | .type = OMAP_DISPLAY_TYPE_DPI, | 117 | .id = 0, |
116 | .driver_name = "tfp410", | 118 | .dev.platform_data = &omap3stalker_tfp410_pdata, |
117 | .data = &dvi_panel, | 119 | }; |
118 | .phy.dpi.data_lines = 24, | 120 | |
121 | static struct connector_atv_platform_data omap3stalker_tv_pdata = { | ||
122 | .name = "tv", | ||
123 | .source = "venc.0", | ||
124 | #if defined(CONFIG_OMAP2_VENC_OUT_TYPE_SVIDEO) | ||
125 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
126 | #elif defined(CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE) | ||
127 | .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE, | ||
128 | #endif | ||
129 | .invert_polarity = false, | ||
119 | }; | 130 | }; |
120 | 131 | ||
121 | static struct omap_dss_device *omap3_stalker_dss_devices[] = { | 132 | static struct platform_device omap3stalker_tv_connector_device = { |
122 | &omap3_stalker_tv_device, | 133 | .name = "connector-analog-tv", |
123 | &omap3_stalker_dvi_device, | 134 | .id = 0, |
135 | .dev.platform_data = &omap3stalker_tv_pdata, | ||
124 | }; | 136 | }; |
125 | 137 | ||
126 | static struct omap_dss_board_info omap3_stalker_dss_data = { | 138 | static struct omap_dss_board_info omap3_stalker_dss_data = { |
127 | .num_devices = ARRAY_SIZE(omap3_stalker_dss_devices), | 139 | .default_display_name = "dvi", |
128 | .devices = omap3_stalker_dss_devices, | ||
129 | .default_device = &omap3_stalker_dvi_device, | ||
130 | }; | 140 | }; |
131 | 141 | ||
132 | static struct regulator_consumer_supply omap3stalker_vmmc1_supply[] = { | 142 | static struct regulator_consumer_supply omap3stalker_vmmc1_supply[] = { |
@@ -356,6 +366,9 @@ static struct usbhs_phy_data phy_data[] __initdata = { | |||
356 | 366 | ||
357 | static struct platform_device *omap3_stalker_devices[] __initdata = { | 367 | static struct platform_device *omap3_stalker_devices[] __initdata = { |
358 | &keys_gpio, | 368 | &keys_gpio, |
369 | &omap3stalker_tfp410_device, | ||
370 | &omap3stalker_dvi_connector_device, | ||
371 | &omap3stalker_tv_connector_device, | ||
359 | }; | 372 | }; |
360 | 373 | ||
361 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 374 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 5748b5d06c23..f6d384111911 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
@@ -72,6 +72,9 @@ | |||
72 | #define OVERO_SMSC911X2_CS 4 | 72 | #define OVERO_SMSC911X2_CS 4 |
73 | #define OVERO_SMSC911X2_GPIO 65 | 73 | #define OVERO_SMSC911X2_GPIO 65 |
74 | 74 | ||
75 | /* whether to register LCD35 instead of LCD43 */ | ||
76 | static bool overo_use_lcd35; | ||
77 | |||
75 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ | 78 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ |
76 | defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) | 79 | defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) |
77 | 80 | ||
@@ -149,78 +152,94 @@ static inline void __init overo_init_smsc911x(void) { return; } | |||
149 | #define OVERO_GPIO_LCD_EN 144 | 152 | #define OVERO_GPIO_LCD_EN 144 |
150 | #define OVERO_GPIO_LCD_BL 145 | 153 | #define OVERO_GPIO_LCD_BL 145 |
151 | 154 | ||
152 | static struct tfp410_platform_data dvi_panel = { | 155 | static struct connector_atv_platform_data overo_tv_pdata = { |
153 | .i2c_bus_num = 3, | 156 | .name = "tv", |
154 | .power_down_gpio = -1, | 157 | .source = "venc.0", |
158 | .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO, | ||
159 | .invert_polarity = false, | ||
155 | }; | 160 | }; |
156 | 161 | ||
157 | static struct omap_dss_device overo_dvi_device = { | 162 | static struct platform_device overo_tv_connector_device = { |
158 | .name = "dvi", | 163 | .name = "connector-analog-tv", |
159 | .type = OMAP_DISPLAY_TYPE_DPI, | 164 | .id = 0, |
160 | .driver_name = "tfp410", | 165 | .dev.platform_data = &overo_tv_pdata, |
161 | .data = &dvi_panel, | ||
162 | .phy.dpi.data_lines = 24, | ||
163 | }; | 166 | }; |
164 | 167 | ||
165 | static struct omap_dss_device overo_tv_device = { | 168 | static const struct display_timing overo_lcd43_videomode = { |
166 | .name = "tv", | 169 | .pixelclock = { 0, 9200000, 0 }, |
167 | .driver_name = "venc", | 170 | |
168 | .type = OMAP_DISPLAY_TYPE_VENC, | 171 | .hactive = { 0, 480, 0 }, |
169 | .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, | 172 | .hfront_porch = { 0, 8, 0 }, |
173 | .hback_porch = { 0, 4, 0 }, | ||
174 | .hsync_len = { 0, 41, 0 }, | ||
175 | |||
176 | .vactive = { 0, 272, 0 }, | ||
177 | .vfront_porch = { 0, 4, 0 }, | ||
178 | .vback_porch = { 0, 2, 0 }, | ||
179 | .vsync_len = { 0, 10, 0 }, | ||
180 | |||
181 | .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | | ||
182 | DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, | ||
170 | }; | 183 | }; |
171 | 184 | ||
172 | static struct panel_generic_dpi_data lcd43_panel = { | 185 | static struct panel_dpi_platform_data overo_lcd43_pdata = { |
173 | .name = "samsung_lte430wq_f0c", | 186 | .name = "lcd43", |
174 | .num_gpios = 2, | 187 | .source = "dpi.0", |
175 | .gpios = { | 188 | |
176 | OVERO_GPIO_LCD_EN, | 189 | .data_lines = 24, |
177 | OVERO_GPIO_LCD_BL | 190 | |
178 | }, | 191 | .display_timing = &overo_lcd43_videomode, |
192 | |||
193 | .enable_gpio = OVERO_GPIO_LCD_EN, | ||
194 | .backlight_gpio = OVERO_GPIO_LCD_BL, | ||
179 | }; | 195 | }; |
180 | 196 | ||
181 | static struct omap_dss_device overo_lcd43_device = { | 197 | static struct platform_device overo_lcd43_device = { |
182 | .name = "lcd43", | 198 | .name = "panel-dpi", |
183 | .type = OMAP_DISPLAY_TYPE_DPI, | 199 | .id = 0, |
184 | .driver_name = "generic_dpi_panel", | 200 | .dev.platform_data = &overo_lcd43_pdata, |
185 | .data = &lcd43_panel, | ||
186 | .phy.dpi.data_lines = 24, | ||
187 | }; | 201 | }; |
188 | 202 | ||
189 | #if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ | 203 | static struct connector_dvi_platform_data overo_dvi_connector_pdata = { |
190 | defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) | 204 | .name = "dvi", |
191 | static struct panel_generic_dpi_data lcd35_panel = { | 205 | .source = "tfp410.0", |
192 | .num_gpios = 2, | 206 | .i2c_bus_num = 3, |
193 | .gpios = { | ||
194 | OVERO_GPIO_LCD_EN, | ||
195 | OVERO_GPIO_LCD_BL | ||
196 | }, | ||
197 | }; | 207 | }; |
198 | 208 | ||
199 | static struct omap_dss_device overo_lcd35_device = { | 209 | static struct platform_device overo_dvi_connector_device = { |
200 | .type = OMAP_DISPLAY_TYPE_DPI, | 210 | .name = "connector-dvi", |
201 | .name = "lcd35", | 211 | .id = 0, |
202 | .driver_name = "lgphilips_lb035q02_panel", | 212 | .dev.platform_data = &overo_dvi_connector_pdata, |
203 | .phy.dpi.data_lines = 24, | ||
204 | .data = &lcd35_panel, | ||
205 | }; | 213 | }; |
206 | #endif | ||
207 | 214 | ||
208 | static struct omap_dss_device *overo_dss_devices[] = { | 215 | static struct encoder_tfp410_platform_data overo_tfp410_pdata = { |
209 | &overo_dvi_device, | 216 | .name = "tfp410.0", |
210 | &overo_tv_device, | 217 | .source = "dpi.0", |
211 | #if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ | 218 | .data_lines = 24, |
212 | defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) | 219 | .power_down_gpio = -1, |
213 | &overo_lcd35_device, | 220 | }; |
214 | #endif | 221 | |
215 | &overo_lcd43_device, | 222 | static struct platform_device overo_tfp410_device = { |
223 | .name = "tfp410", | ||
224 | .id = 0, | ||
225 | .dev.platform_data = &overo_tfp410_pdata, | ||
216 | }; | 226 | }; |
217 | 227 | ||
218 | static struct omap_dss_board_info overo_dss_data = { | 228 | static struct omap_dss_board_info overo_dss_data = { |
219 | .num_devices = ARRAY_SIZE(overo_dss_devices), | 229 | .default_display_name = "lcd43", |
220 | .devices = overo_dss_devices, | ||
221 | .default_device = &overo_dvi_device, | ||
222 | }; | 230 | }; |
223 | 231 | ||
232 | static void __init overo_display_init(void) | ||
233 | { | ||
234 | omap_display_init(&overo_dss_data); | ||
235 | |||
236 | if (!overo_use_lcd35) | ||
237 | platform_device_register(&overo_lcd43_device); | ||
238 | platform_device_register(&overo_tfp410_device); | ||
239 | platform_device_register(&overo_dvi_connector_device); | ||
240 | platform_device_register(&overo_tv_connector_device); | ||
241 | } | ||
242 | |||
224 | static struct mtd_partition overo_nand_partitions[] = { | 243 | static struct mtd_partition overo_nand_partitions[] = { |
225 | { | 244 | { |
226 | .name = "xloader", | 245 | .name = "xloader", |
@@ -408,24 +427,41 @@ static int __init overo_i2c_init(void) | |||
408 | return 0; | 427 | return 0; |
409 | } | 428 | } |
410 | 429 | ||
430 | static struct panel_lb035q02_platform_data overo_lcd35_pdata = { | ||
431 | .name = "lcd35", | ||
432 | .source = "dpi.0", | ||
433 | |||
434 | .data_lines = 24, | ||
435 | |||
436 | .enable_gpio = OVERO_GPIO_LCD_EN, | ||
437 | .backlight_gpio = OVERO_GPIO_LCD_BL, | ||
438 | }; | ||
439 | |||
440 | /* | ||
441 | * NOTE: We need to add either the lgphilips panel, or the lcd43 panel. The | ||
442 | * selection is done based on the overo_use_lcd35 field. If new SPI | ||
443 | * devices are added here, extra work is needed to make only the lgphilips panel | ||
444 | * affected by the overo_use_lcd35 field. | ||
445 | */ | ||
411 | static struct spi_board_info overo_spi_board_info[] __initdata = { | 446 | static struct spi_board_info overo_spi_board_info[] __initdata = { |
412 | #if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ | ||
413 | defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) | ||
414 | { | 447 | { |
415 | .modalias = "lgphilips_lb035q02_panel-spi", | 448 | .modalias = "panel_lgphilips_lb035q02", |
416 | .bus_num = 1, | 449 | .bus_num = 1, |
417 | .chip_select = 1, | 450 | .chip_select = 1, |
418 | .max_speed_hz = 500000, | 451 | .max_speed_hz = 500000, |
419 | .mode = SPI_MODE_3, | 452 | .mode = SPI_MODE_3, |
453 | .platform_data = &overo_lcd35_pdata, | ||
420 | }, | 454 | }, |
421 | #endif | ||
422 | }; | 455 | }; |
423 | 456 | ||
424 | static int __init overo_spi_init(void) | 457 | static int __init overo_spi_init(void) |
425 | { | 458 | { |
426 | overo_ads7846_init(); | 459 | overo_ads7846_init(); |
427 | spi_register_board_info(overo_spi_board_info, | 460 | |
428 | ARRAY_SIZE(overo_spi_board_info)); | 461 | if (overo_use_lcd35) { |
462 | spi_register_board_info(overo_spi_board_info, | ||
463 | ARRAY_SIZE(overo_spi_board_info)); | ||
464 | } | ||
429 | return 0; | 465 | return 0; |
430 | } | 466 | } |
431 | 467 | ||
@@ -463,11 +499,13 @@ static void __init overo_init(void) | |||
463 | { | 499 | { |
464 | int ret; | 500 | int ret; |
465 | 501 | ||
502 | if (strstr(boot_command_line, "omapdss.def_disp=lcd35")) | ||
503 | overo_use_lcd35 = true; | ||
504 | |||
466 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | 505 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); |
467 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); | 506 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); |
468 | overo_i2c_init(); | 507 | overo_i2c_init(); |
469 | omap_hsmmc_init(mmc); | 508 | omap_hsmmc_init(mmc); |
470 | omap_display_init(&overo_dss_data); | ||
471 | omap_serial_init(); | 509 | omap_serial_init(); |
472 | omap_sdrc_init(mt46h32m32lf6_sdrc_params, | 510 | omap_sdrc_init(mt46h32m32lf6_sdrc_params, |
473 | mt46h32m32lf6_sdrc_params); | 511 | mt46h32m32lf6_sdrc_params); |
@@ -484,6 +522,8 @@ static void __init overo_init(void) | |||
484 | overo_init_keys(); | 522 | overo_init_keys(); |
485 | omap_twl4030_audio_init("overo", NULL); | 523 | omap_twl4030_audio_init("overo", NULL); |
486 | 524 | ||
525 | overo_display_init(); | ||
526 | |||
487 | /* Ensure SDRC pins are mux'd for self-refresh */ | 527 | /* Ensure SDRC pins are mux'd for self-refresh */ |
488 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); | 528 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); |
489 | omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); | 529 | omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); |
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 9c2dd102fbbb..c3270c0f1fce 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <linux/platform_data/tsl2563.h> | 45 | #include <linux/platform_data/tsl2563.h> |
46 | #include <linux/lis3lv02d.h> | 46 | #include <linux/lis3lv02d.h> |
47 | 47 | ||
48 | #include <video/omap-panel-data.h> | ||
49 | |||
48 | #if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE) | 50 | #if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE) |
49 | #include <media/ir-rx51.h> | 51 | #include <media/ir-rx51.h> |
50 | #endif | 52 | #endif |
@@ -226,6 +228,15 @@ static struct lp55xx_platform_data rx51_lp5523_platform_data = { | |||
226 | }; | 228 | }; |
227 | #endif | 229 | #endif |
228 | 230 | ||
231 | #define RX51_LCD_RESET_GPIO 90 | ||
232 | |||
233 | static struct panel_acx565akm_platform_data acx_pdata = { | ||
234 | .name = "lcd", | ||
235 | .source = "sdi.0", | ||
236 | .reset_gpio = RX51_LCD_RESET_GPIO, | ||
237 | .datapairs = 2, | ||
238 | }; | ||
239 | |||
229 | static struct omap2_mcspi_device_config wl1251_mcspi_config = { | 240 | static struct omap2_mcspi_device_config wl1251_mcspi_config = { |
230 | .turbo_mode = 0, | 241 | .turbo_mode = 0, |
231 | }; | 242 | }; |
@@ -254,6 +265,7 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { | |||
254 | .chip_select = 2, | 265 | .chip_select = 2, |
255 | .max_speed_hz = 6000000, | 266 | .max_speed_hz = 6000000, |
256 | .controller_data = &mipid_mcspi_config, | 267 | .controller_data = &mipid_mcspi_config, |
268 | .platform_data = &acx_pdata, | ||
257 | }, | 269 | }, |
258 | [RX51_SPI_TSC2005] = { | 270 | [RX51_SPI_TSC2005] = { |
259 | .modalias = "tsc2005", | 271 | .modalias = "tsc2005", |
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c index bdd1e3a179e1..43a90c8d6837 100644 --- a/arch/arm/mach-omap2/board-rx51-video.c +++ b/arch/arm/mach-omap2/board-rx51-video.c | |||
@@ -29,34 +29,21 @@ | |||
29 | 29 | ||
30 | #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) | 30 | #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) |
31 | 31 | ||
32 | static struct panel_acx565akm_data lcd_data = { | 32 | static struct connector_atv_platform_data rx51_tv_pdata = { |
33 | .reset_gpio = RX51_LCD_RESET_GPIO, | 33 | .name = "tv", |
34 | .source = "venc.0", | ||
35 | .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE, | ||
36 | .invert_polarity = false, | ||
34 | }; | 37 | }; |
35 | 38 | ||
36 | static struct omap_dss_device rx51_lcd_device = { | 39 | static struct platform_device rx51_tv_connector_device = { |
37 | .name = "lcd", | 40 | .name = "connector-analog-tv", |
38 | .driver_name = "panel-acx565akm", | 41 | .id = 0, |
39 | .type = OMAP_DISPLAY_TYPE_SDI, | 42 | .dev.platform_data = &rx51_tv_pdata, |
40 | .phy.sdi.datapairs = 2, | ||
41 | .data = &lcd_data, | ||
42 | }; | ||
43 | |||
44 | static struct omap_dss_device rx51_tv_device = { | ||
45 | .name = "tv", | ||
46 | .type = OMAP_DISPLAY_TYPE_VENC, | ||
47 | .driver_name = "venc", | ||
48 | .phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE, | ||
49 | }; | ||
50 | |||
51 | static struct omap_dss_device *rx51_dss_devices[] = { | ||
52 | &rx51_lcd_device, | ||
53 | &rx51_tv_device, | ||
54 | }; | 43 | }; |
55 | 44 | ||
56 | static struct omap_dss_board_info rx51_dss_board_info = { | 45 | static struct omap_dss_board_info rx51_dss_board_info = { |
57 | .num_devices = ARRAY_SIZE(rx51_dss_devices), | 46 | .default_display_name = "lcd", |
58 | .devices = rx51_dss_devices, | ||
59 | .default_device = &rx51_lcd_device, | ||
60 | }; | 47 | }; |
61 | 48 | ||
62 | static int __init rx51_video_init(void) | 49 | static int __init rx51_video_init(void) |
@@ -71,6 +58,8 @@ static int __init rx51_video_init(void) | |||
71 | 58 | ||
72 | omap_display_init(&rx51_dss_board_info); | 59 | omap_display_init(&rx51_dss_board_info); |
73 | 60 | ||
61 | platform_device_register(&rx51_tv_connector_device); | ||
62 | |||
74 | return 0; | 63 | return 0; |
75 | } | 64 | } |
76 | 65 | ||
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index d2ea68ea678a..7735105561d8 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c | |||
@@ -85,7 +85,7 @@ static struct omap_board_mux board_mux[] __initdata = { | |||
85 | 85 | ||
86 | static struct omap_musb_board_data musb_board_data = { | 86 | static struct omap_musb_board_data musb_board_data = { |
87 | .interface_type = MUSB_INTERFACE_ULPI, | 87 | .interface_type = MUSB_INTERFACE_ULPI, |
88 | .mode = MUSB_PERIPHERAL, | 88 | .mode = MUSB_OTG, |
89 | .power = 0, | 89 | .power = 0, |
90 | }; | 90 | }; |
91 | 91 | ||
diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c index c2a079cb76fc..3d8ecc1e05bd 100644 --- a/arch/arm/mach-omap2/board-zoom-display.c +++ b/arch/arm/mach-omap2/board-zoom-display.c | |||
@@ -25,32 +25,23 @@ | |||
25 | #define LCD_PANEL_RESET_GPIO_PILOT 55 | 25 | #define LCD_PANEL_RESET_GPIO_PILOT 55 |
26 | #define LCD_PANEL_QVGA_GPIO 56 | 26 | #define LCD_PANEL_QVGA_GPIO 56 |
27 | 27 | ||
28 | static struct panel_nec_nl8048_data zoom_lcd_data = { | 28 | static struct panel_nec_nl8048hl11_platform_data zoom_lcd_pdata = { |
29 | /* res_gpio filled in code */ | 29 | .name = "lcd", |
30 | .qvga_gpio = LCD_PANEL_QVGA_GPIO, | 30 | .source = "dpi.0", |
31 | }; | ||
32 | 31 | ||
33 | static struct omap_dss_device zoom_lcd_device = { | 32 | .data_lines = 24, |
34 | .name = "lcd", | ||
35 | .driver_name = "NEC_8048_panel", | ||
36 | .type = OMAP_DISPLAY_TYPE_DPI, | ||
37 | .phy.dpi.data_lines = 24, | ||
38 | .data = &zoom_lcd_data, | ||
39 | }; | ||
40 | 33 | ||
41 | static struct omap_dss_device *zoom_dss_devices[] = { | 34 | .res_gpio = -1, /* filled in code */ |
42 | &zoom_lcd_device, | 35 | .qvga_gpio = LCD_PANEL_QVGA_GPIO, |
43 | }; | 36 | }; |
44 | 37 | ||
45 | static struct omap_dss_board_info zoom_dss_data = { | 38 | static struct omap_dss_board_info zoom_dss_data = { |
46 | .num_devices = ARRAY_SIZE(zoom_dss_devices), | 39 | .default_display_name = "lcd", |
47 | .devices = zoom_dss_devices, | ||
48 | .default_device = &zoom_lcd_device, | ||
49 | }; | 40 | }; |
50 | 41 | ||
51 | static void __init zoom_lcd_panel_init(void) | 42 | static void __init zoom_lcd_panel_init(void) |
52 | { | 43 | { |
53 | zoom_lcd_data.res_gpio = (omap_rev() > OMAP3430_REV_ES3_0) ? | 44 | zoom_lcd_pdata.res_gpio = (omap_rev() > OMAP3430_REV_ES3_0) ? |
54 | LCD_PANEL_RESET_GPIO_PROD : | 45 | LCD_PANEL_RESET_GPIO_PROD : |
55 | LCD_PANEL_RESET_GPIO_PILOT; | 46 | LCD_PANEL_RESET_GPIO_PILOT; |
56 | } | 47 | } |
@@ -61,19 +52,20 @@ static struct omap2_mcspi_device_config dss_lcd_mcspi_config = { | |||
61 | 52 | ||
62 | static struct spi_board_info nec_8048_spi_board_info[] __initdata = { | 53 | static struct spi_board_info nec_8048_spi_board_info[] __initdata = { |
63 | [0] = { | 54 | [0] = { |
64 | .modalias = "nec_8048_spi", | 55 | .modalias = "panel-nec-nl8048hl11", |
65 | .bus_num = 1, | 56 | .bus_num = 1, |
66 | .chip_select = 2, | 57 | .chip_select = 2, |
67 | .max_speed_hz = 375000, | 58 | .max_speed_hz = 375000, |
68 | .controller_data = &dss_lcd_mcspi_config, | 59 | .controller_data = &dss_lcd_mcspi_config, |
60 | .platform_data = &zoom_lcd_pdata, | ||
69 | }, | 61 | }, |
70 | }; | 62 | }; |
71 | 63 | ||
72 | void __init zoom_display_init(void) | 64 | void __init zoom_display_init(void) |
73 | { | 65 | { |
74 | omap_display_init(&zoom_dss_data); | 66 | omap_display_init(&zoom_dss_data); |
67 | zoom_lcd_panel_init(); | ||
75 | spi_register_board_info(nec_8048_spi_board_info, | 68 | spi_register_board_info(nec_8048_spi_board_info, |
76 | ARRAY_SIZE(nec_8048_spi_board_info)); | 69 | ARRAY_SIZE(nec_8048_spi_board_info)); |
77 | zoom_lcd_panel_init(); | ||
78 | } | 70 | } |
79 | 71 | ||
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index ff37be1f6f93..03a0516c7f67 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
@@ -400,7 +400,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) | |||
400 | 400 | ||
401 | /* Create devices for DPI and SDI */ | 401 | /* Create devices for DPI and SDI */ |
402 | 402 | ||
403 | pdev = create_simple_dss_pdev("omapdss_dpi", -1, | 403 | pdev = create_simple_dss_pdev("omapdss_dpi", 0, |
404 | board_data, sizeof(*board_data), dss_pdev); | 404 | board_data, sizeof(*board_data), dss_pdev); |
405 | if (IS_ERR(pdev)) { | 405 | if (IS_ERR(pdev)) { |
406 | pr_err("Could not build platform_device for omapdss_dpi\n"); | 406 | pr_err("Could not build platform_device for omapdss_dpi\n"); |
@@ -408,7 +408,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) | |||
408 | } | 408 | } |
409 | 409 | ||
410 | if (cpu_is_omap34xx()) { | 410 | if (cpu_is_omap34xx()) { |
411 | pdev = create_simple_dss_pdev("omapdss_sdi", -1, | 411 | pdev = create_simple_dss_pdev("omapdss_sdi", 0, |
412 | board_data, sizeof(*board_data), dss_pdev); | 412 | board_data, sizeof(*board_data), dss_pdev); |
413 | if (IS_ERR(pdev)) { | 413 | if (IS_ERR(pdev)) { |
414 | pr_err("Could not build platform_device for omapdss_sdi\n"); | 414 | pr_err("Could not build platform_device for omapdss_sdi\n"); |
diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c index 043e5705f2a6..bf89effa4c99 100644 --- a/arch/arm/mach-omap2/dss-common.c +++ b/arch/arm/mach-omap2/dss-common.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <linux/platform_device.h> | ||
28 | 29 | ||
29 | #include <video/omapdss.h> | 30 | #include <video/omapdss.h> |
30 | #include <video/omap-panel-data.h> | 31 | #include <video/omap-panel-data.h> |
@@ -37,70 +38,76 @@ | |||
37 | #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ | 38 | #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ |
38 | #define HDMI_GPIO_HPD 63 /* Hotplug detect */ | 39 | #define HDMI_GPIO_HPD 63 /* Hotplug detect */ |
39 | 40 | ||
40 | /* Display DVI */ | ||
41 | #define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0 | 41 | #define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0 |
42 | 42 | ||
43 | /* Using generic display panel */ | 43 | /* DVI Connector */ |
44 | static struct tfp410_platform_data omap4_dvi_panel = { | 44 | static struct connector_dvi_platform_data omap4_panda_dvi_connector_pdata = { |
45 | .i2c_bus_num = 2, | 45 | .name = "dvi", |
46 | .power_down_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO, | 46 | .source = "tfp410.0", |
47 | .i2c_bus_num = 2, | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | static struct omap_dss_device omap4_panda_dvi_device = { | 50 | static struct platform_device omap4_panda_dvi_connector_device = { |
50 | .type = OMAP_DISPLAY_TYPE_DPI, | 51 | .name = "connector-dvi", |
51 | .name = "dvi", | 52 | .id = 0, |
52 | .driver_name = "tfp410", | 53 | .dev.platform_data = &omap4_panda_dvi_connector_pdata, |
53 | .data = &omap4_dvi_panel, | ||
54 | .phy.dpi.data_lines = 24, | ||
55 | .channel = OMAP_DSS_CHANNEL_LCD2, | ||
56 | }; | 54 | }; |
57 | 55 | ||
58 | static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { | 56 | /* TFP410 DPI-to-DVI chip */ |
57 | static struct encoder_tfp410_platform_data omap4_panda_tfp410_pdata = { | ||
58 | .name = "tfp410.0", | ||
59 | .source = "dpi.0", | ||
60 | .data_lines = 24, | ||
61 | .power_down_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO, | ||
62 | }; | ||
63 | |||
64 | static struct platform_device omap4_panda_tfp410_device = { | ||
65 | .name = "tfp410", | ||
66 | .id = 0, | ||
67 | .dev.platform_data = &omap4_panda_tfp410_pdata, | ||
68 | }; | ||
69 | |||
70 | /* HDMI Connector */ | ||
71 | static struct connector_hdmi_platform_data omap4_panda_hdmi_connector_pdata = { | ||
72 | .name = "hdmi", | ||
73 | .source = "tpd12s015.0", | ||
74 | }; | ||
75 | |||
76 | static struct platform_device omap4_panda_hdmi_connector_device = { | ||
77 | .name = "connector-hdmi", | ||
78 | .id = 0, | ||
79 | .dev.platform_data = &omap4_panda_hdmi_connector_pdata, | ||
80 | }; | ||
81 | |||
82 | /* TPD12S015 HDMI ESD protection & level shifter chip */ | ||
83 | static struct encoder_tpd12s015_platform_data omap4_panda_tpd_pdata = { | ||
84 | .name = "tpd12s015.0", | ||
85 | .source = "hdmi.0", | ||
86 | |||
59 | .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, | 87 | .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, |
60 | .ls_oe_gpio = HDMI_GPIO_LS_OE, | 88 | .ls_oe_gpio = HDMI_GPIO_LS_OE, |
61 | .hpd_gpio = HDMI_GPIO_HPD, | 89 | .hpd_gpio = HDMI_GPIO_HPD, |
62 | }; | 90 | }; |
63 | 91 | ||
64 | static struct omap_dss_device omap4_panda_hdmi_device = { | 92 | static struct platform_device omap4_panda_tpd_device = { |
65 | .name = "hdmi", | 93 | .name = "tpd12s015", |
66 | .driver_name = "hdmi_panel", | 94 | .id = 0, |
67 | .type = OMAP_DISPLAY_TYPE_HDMI, | 95 | .dev.platform_data = &omap4_panda_tpd_pdata, |
68 | .channel = OMAP_DSS_CHANNEL_DIGIT, | ||
69 | .data = &omap4_panda_hdmi_data, | ||
70 | }; | ||
71 | |||
72 | static struct omap_dss_device *omap4_panda_dss_devices[] = { | ||
73 | &omap4_panda_dvi_device, | ||
74 | &omap4_panda_hdmi_device, | ||
75 | }; | 96 | }; |
76 | 97 | ||
77 | static struct omap_dss_board_info omap4_panda_dss_data = { | 98 | static struct omap_dss_board_info omap4_panda_dss_data = { |
78 | .num_devices = ARRAY_SIZE(omap4_panda_dss_devices), | 99 | .default_display_name = "dvi", |
79 | .devices = omap4_panda_dss_devices, | ||
80 | .default_device = &omap4_panda_dvi_device, | ||
81 | }; | 100 | }; |
82 | 101 | ||
83 | void __init omap4_panda_display_init(void) | 102 | void __init omap4_panda_display_init_of(void) |
84 | { | 103 | { |
85 | omap_display_init(&omap4_panda_dss_data); | 104 | omap_display_init(&omap4_panda_dss_data); |
86 | 105 | ||
87 | /* | 106 | platform_device_register(&omap4_panda_tfp410_device); |
88 | * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and | 107 | platform_device_register(&omap4_panda_dvi_connector_device); |
89 | * later have external pull up on the HDMI I2C lines | ||
90 | */ | ||
91 | if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) | ||
92 | omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); | ||
93 | else | ||
94 | omap_hdmi_init(0); | ||
95 | |||
96 | omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); | ||
97 | omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); | ||
98 | omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); | ||
99 | } | ||
100 | 108 | ||
101 | void __init omap4_panda_display_init_of(void) | 109 | platform_device_register(&omap4_panda_tpd_device); |
102 | { | 110 | platform_device_register(&omap4_panda_hdmi_connector_device); |
103 | omap_display_init(&omap4_panda_dss_data); | ||
104 | } | 111 | } |
105 | 112 | ||
106 | 113 | ||
@@ -109,93 +116,73 @@ void __init omap4_panda_display_init_of(void) | |||
109 | #define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */ | 116 | #define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */ |
110 | #define DLP_POWER_ON_GPIO 40 | 117 | #define DLP_POWER_ON_GPIO 40 |
111 | 118 | ||
112 | static struct nokia_dsi_panel_data dsi1_panel = { | 119 | static struct panel_dsicm_platform_data dsi1_panel = { |
113 | .name = "taal", | 120 | .name = "lcd", |
114 | .reset_gpio = 102, | 121 | .source = "dsi.0", |
115 | .use_ext_te = false, | 122 | .reset_gpio = 102, |
116 | .ext_te_gpio = 101, | 123 | .use_ext_te = false, |
117 | .esd_interval = 0, | 124 | .ext_te_gpio = 101, |
118 | .pin_config = { | 125 | .pin_config = { |
119 | .num_pins = 6, | 126 | .num_pins = 6, |
120 | .pins = { 0, 1, 2, 3, 4, 5 }, | 127 | .pins = { 0, 1, 2, 3, 4, 5 }, |
121 | }, | ||
122 | }; | ||
123 | |||
124 | static struct omap_dss_device sdp4430_lcd_device = { | ||
125 | .name = "lcd", | ||
126 | .driver_name = "taal", | ||
127 | .type = OMAP_DISPLAY_TYPE_DSI, | ||
128 | .data = &dsi1_panel, | ||
129 | .phy.dsi = { | ||
130 | .module = 0, | ||
131 | }, | 128 | }, |
132 | .channel = OMAP_DSS_CHANNEL_LCD, | ||
133 | }; | 129 | }; |
134 | 130 | ||
135 | static struct nokia_dsi_panel_data dsi2_panel = { | 131 | static struct platform_device sdp4430_lcd_device = { |
136 | .name = "taal", | 132 | .name = "panel-dsi-cm", |
137 | .reset_gpio = 104, | 133 | .id = 0, |
138 | .use_ext_te = false, | 134 | .dev.platform_data = &dsi1_panel, |
139 | .ext_te_gpio = 103, | ||
140 | .esd_interval = 0, | ||
141 | .pin_config = { | ||
142 | .num_pins = 6, | ||
143 | .pins = { 0, 1, 2, 3, 4, 5 }, | ||
144 | }, | ||
145 | }; | 135 | }; |
146 | 136 | ||
147 | static struct omap_dss_device sdp4430_lcd2_device = { | 137 | static struct panel_dsicm_platform_data dsi2_panel = { |
148 | .name = "lcd2", | 138 | .name = "lcd2", |
149 | .driver_name = "taal", | 139 | .source = "dsi.1", |
150 | .type = OMAP_DISPLAY_TYPE_DSI, | 140 | .reset_gpio = 104, |
151 | .data = &dsi2_panel, | 141 | .use_ext_te = false, |
152 | .phy.dsi = { | 142 | .ext_te_gpio = 103, |
153 | 143 | .pin_config = { | |
154 | .module = 1, | 144 | .num_pins = 6, |
145 | .pins = { 0, 1, 2, 3, 4, 5 }, | ||
155 | }, | 146 | }, |
156 | .channel = OMAP_DSS_CHANNEL_LCD2, | ||
157 | }; | 147 | }; |
158 | 148 | ||
159 | static struct omap_dss_hdmi_data sdp4430_hdmi_data = { | 149 | static struct platform_device sdp4430_lcd2_device = { |
160 | .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, | 150 | .name = "panel-dsi-cm", |
161 | .ls_oe_gpio = HDMI_GPIO_LS_OE, | 151 | .id = 1, |
162 | .hpd_gpio = HDMI_GPIO_HPD, | 152 | .dev.platform_data = &dsi2_panel, |
163 | }; | 153 | }; |
164 | 154 | ||
165 | static struct omap_dss_device sdp4430_hdmi_device = { | 155 | /* HDMI Connector */ |
166 | .name = "hdmi", | 156 | static struct connector_hdmi_platform_data sdp4430_hdmi_connector_pdata = { |
167 | .driver_name = "hdmi_panel", | 157 | .name = "hdmi", |
168 | .type = OMAP_DISPLAY_TYPE_HDMI, | 158 | .source = "tpd12s015.0", |
169 | .channel = OMAP_DSS_CHANNEL_DIGIT, | ||
170 | .data = &sdp4430_hdmi_data, | ||
171 | }; | 159 | }; |
172 | 160 | ||
173 | static struct picodlp_panel_data sdp4430_picodlp_pdata = { | 161 | static struct platform_device sdp4430_hdmi_connector_device = { |
174 | .picodlp_adapter_id = 2, | 162 | .name = "connector-hdmi", |
175 | .emu_done_gpio = 44, | 163 | .id = 0, |
176 | .pwrgood_gpio = 45, | 164 | .dev.platform_data = &sdp4430_hdmi_connector_pdata, |
177 | }; | 165 | }; |
178 | 166 | ||
179 | static struct omap_dss_device sdp4430_picodlp_device = { | 167 | /* TPD12S015 HDMI ESD protection & level shifter chip */ |
180 | .name = "picodlp", | 168 | static struct encoder_tpd12s015_platform_data sdp4430_tpd_pdata = { |
181 | .driver_name = "picodlp_panel", | 169 | .name = "tpd12s015.0", |
182 | .type = OMAP_DISPLAY_TYPE_DPI, | 170 | .source = "hdmi.0", |
183 | .phy.dpi.data_lines = 24, | 171 | |
184 | .channel = OMAP_DSS_CHANNEL_LCD2, | 172 | .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD, |
185 | .data = &sdp4430_picodlp_pdata, | 173 | .ls_oe_gpio = HDMI_GPIO_LS_OE, |
174 | .hpd_gpio = HDMI_GPIO_HPD, | ||
186 | }; | 175 | }; |
187 | 176 | ||
188 | static struct omap_dss_device *sdp4430_dss_devices[] = { | 177 | static struct platform_device sdp4430_tpd_device = { |
189 | &sdp4430_lcd_device, | 178 | .name = "tpd12s015", |
190 | &sdp4430_lcd2_device, | 179 | .id = 0, |
191 | &sdp4430_hdmi_device, | 180 | .dev.platform_data = &sdp4430_tpd_pdata, |
192 | &sdp4430_picodlp_device, | ||
193 | }; | 181 | }; |
194 | 182 | ||
183 | |||
195 | static struct omap_dss_board_info sdp4430_dss_data = { | 184 | static struct omap_dss_board_info sdp4430_dss_data = { |
196 | .num_devices = ARRAY_SIZE(sdp4430_dss_devices), | 185 | .default_display_name = "lcd", |
197 | .devices = sdp4430_dss_devices, | ||
198 | .default_device = &sdp4430_lcd_device, | ||
199 | }; | 186 | }; |
200 | 187 | ||
201 | /* | 188 | /* |
@@ -204,7 +191,7 @@ static struct omap_dss_board_info sdp4430_dss_data = { | |||
204 | * used by picodlp on the 4430sdp platform. Keep this gpio disabled as LCD2 is | 191 | * used by picodlp on the 4430sdp platform. Keep this gpio disabled as LCD2 is |
205 | * selected by default | 192 | * selected by default |
206 | */ | 193 | */ |
207 | void __init omap_4430sdp_display_init(void) | 194 | void __init omap_4430sdp_display_init_of(void) |
208 | { | 195 | { |
209 | int r; | 196 | int r; |
210 | 197 | ||
@@ -219,33 +206,10 @@ void __init omap_4430sdp_display_init(void) | |||
219 | pr_err("%s: Could not get DLP POWER ON GPIO\n", __func__); | 206 | pr_err("%s: Could not get DLP POWER ON GPIO\n", __func__); |
220 | 207 | ||
221 | omap_display_init(&sdp4430_dss_data); | 208 | omap_display_init(&sdp4430_dss_data); |
222 | /* | ||
223 | * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and | ||
224 | * later have external pull up on the HDMI I2C lines | ||
225 | */ | ||
226 | if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) | ||
227 | omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); | ||
228 | else | ||
229 | omap_hdmi_init(0); | ||
230 | |||
231 | omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); | ||
232 | omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); | ||
233 | omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); | ||
234 | } | ||
235 | |||
236 | void __init omap_4430sdp_display_init_of(void) | ||
237 | { | ||
238 | int r; | ||
239 | 209 | ||
240 | r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH, | 210 | platform_device_register(&sdp4430_lcd_device); |
241 | "display_sel"); | 211 | platform_device_register(&sdp4430_lcd2_device); |
242 | if (r) | ||
243 | pr_err("%s: Could not get display_sel GPIO\n", __func__); | ||
244 | |||
245 | r = gpio_request_one(DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW, | ||
246 | "DLP POWER ON"); | ||
247 | if (r) | ||
248 | pr_err("%s: Could not get DLP POWER ON GPIO\n", __func__); | ||
249 | 212 | ||
250 | omap_display_init(&sdp4430_dss_data); | 213 | platform_device_register(&sdp4430_tpd_device); |
214 | platform_device_register(&sdp4430_hdmi_connector_device); | ||
251 | } | 215 | } |
diff --git a/arch/arm/mach-omap2/dss-common.h b/arch/arm/mach-omap2/dss-common.h index 915f6fff5106..c28fe3c03588 100644 --- a/arch/arm/mach-omap2/dss-common.h +++ b/arch/arm/mach-omap2/dss-common.h | |||
@@ -6,9 +6,7 @@ | |||
6 | * This file will be removed when DSS supports DT. | 6 | * This file will be removed when DSS supports DT. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | void __init omap4_panda_display_init(void); | ||
10 | void __init omap4_panda_display_init_of(void); | 9 | void __init omap4_panda_display_init_of(void); |
11 | void __init omap_4430sdp_display_init(void); | ||
12 | void __init omap_4430sdp_display_init_of(void); | 10 | void __init omap_4430sdp_display_init_of(void); |
13 | 11 | ||
14 | #endif | 12 | #endif |
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index d940e53dd9f2..b456b4471f35 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c | |||
@@ -181,7 +181,7 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata, | |||
181 | sizeof(struct omap_i2c_bus_platform_data)); | 181 | sizeof(struct omap_i2c_bus_platform_data)); |
182 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); | 182 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); |
183 | 183 | ||
184 | return PTR_RET(pdev); | 184 | return PTR_ERR_OR_ZERO(pdev); |
185 | } | 185 | } |
186 | 186 | ||
187 | static int __init omap_i2c_cmdline(void) | 187 | static int __init omap_i2c_cmdline(void) |
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 2eb19d4d0aa1..e83a6a4b184a 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
30 | #include <linux/usb/phy.h> | 30 | #include <linux/usb/phy.h> |
31 | #include <linux/usb/nop-usb-xceiv.h> | 31 | #include <linux/usb/usb_phy_gen_xceiv.h> |
32 | 32 | ||
33 | #include "soc.h" | 33 | #include "soc.h" |
34 | #include "omap_device.h" | 34 | #include "omap_device.h" |
@@ -349,7 +349,7 @@ static struct fixed_voltage_config hsusb_reg_config = { | |||
349 | /* .init_data filled later */ | 349 | /* .init_data filled later */ |
350 | }; | 350 | }; |
351 | 351 | ||
352 | static const char *nop_name = "nop_usb_xceiv"; /* NOP PHY driver */ | 352 | static const char *nop_name = "usb_phy_gen_xceiv"; /* NOP PHY driver */ |
353 | static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */ | 353 | static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */ |
354 | 354 | ||
355 | /** | 355 | /** |
@@ -460,9 +460,9 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) | |||
460 | pdevinfo.name = nop_name; | 460 | pdevinfo.name = nop_name; |
461 | pdevinfo.id = phy->port; | 461 | pdevinfo.id = phy->port; |
462 | pdevinfo.data = phy->platform_data; | 462 | pdevinfo.data = phy->platform_data; |
463 | pdevinfo.size_data = sizeof(struct nop_usb_xceiv_platform_data); | 463 | pdevinfo.size_data = |
464 | 464 | sizeof(struct usb_phy_gen_xceiv_platform_data); | |
465 | scnprintf(phy_id, MAX_STR, "nop_usb_xceiv.%d", | 465 | scnprintf(phy_id, MAX_STR, "usb_phy_gen_xceiv.%d", |
466 | phy->port); | 466 | phy->port); |
467 | pdev = platform_device_register_full(&pdevinfo); | 467 | pdev = platform_device_register_full(&pdevinfo); |
468 | if (IS_ERR(pdev)) { | 468 | if (IS_ERR(pdev)) { |
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 8c4de2708cf2..bc897231bd10 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c | |||
@@ -38,11 +38,8 @@ static struct musb_hdrc_config musb_config = { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct musb_hdrc_platform_data musb_plat = { | 40 | static struct musb_hdrc_platform_data musb_plat = { |
41 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
42 | .mode = MUSB_OTG, | 41 | .mode = MUSB_OTG, |
43 | #else | 42 | |
44 | .mode = MUSB_HOST, | ||
45 | #endif | ||
46 | /* .clock is set dynamically */ | 43 | /* .clock is set dynamically */ |
47 | .config = &musb_config, | 44 | .config = &musb_config, |
48 | 45 | ||
diff --git a/arch/arm/mach-orion5x/include/mach/debug-macro.S b/arch/arm/mach-orion5x/include/mach/debug-macro.S deleted file mode 100644 index f340ed8f8dd0..000000000000 --- a/arch/arm/mach-orion5x/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-orion5x/include/mach/debug-macro.S | ||
3 | * | ||
4 | * Debugging macro include header | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <mach/orion5x.h> | ||
12 | |||
13 | .macro addruart, rp, rv, tmp | ||
14 | ldr \rp, =ORION5X_REGS_PHYS_BASE | ||
15 | ldr \rv, =ORION5X_REGS_VIRT_BASE | ||
16 | orr \rp, \rp, #0x00012000 | ||
17 | orr \rv, \rv, #0x00012000 | ||
18 | .endm | ||
19 | |||
20 | #define UART_SHIFT 2 | ||
21 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c index 2c70f74fed5d..e110b6d4ae8c 100644 --- a/arch/arm/mach-prima2/common.c +++ b/arch/arm/mach-prima2/common.c | |||
@@ -42,7 +42,6 @@ static const char *atlas6_dt_match[] __initdata = { | |||
42 | 42 | ||
43 | DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)") | 43 | DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)") |
44 | /* Maintainer: Barry Song <baohua.song@csr.com> */ | 44 | /* Maintainer: Barry Song <baohua.song@csr.com> */ |
45 | .nr_irqs = 128, | ||
46 | .map_io = sirfsoc_map_io, | 45 | .map_io = sirfsoc_map_io, |
47 | .init_time = sirfsoc_init_time, | 46 | .init_time = sirfsoc_init_time, |
48 | .init_late = sirfsoc_init_late, | 47 | .init_late = sirfsoc_init_late, |
@@ -59,7 +58,6 @@ static const char *prima2_dt_match[] __initdata = { | |||
59 | 58 | ||
60 | DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") | 59 | DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") |
61 | /* Maintainer: Barry Song <baohua.song@csr.com> */ | 60 | /* Maintainer: Barry Song <baohua.song@csr.com> */ |
62 | .nr_irqs = 128, | ||
63 | .map_io = sirfsoc_map_io, | 61 | .map_io = sirfsoc_map_io, |
64 | .init_time = sirfsoc_init_time, | 62 | .init_time = sirfsoc_init_time, |
65 | .dma_zone_size = SZ_256M, | 63 | .dma_zone_size = SZ_256M, |
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index fe31bfcbb8df..c98511c5abd1 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c | |||
@@ -73,9 +73,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = { | |||
73 | 73 | ||
74 | static struct mcp251x_platform_data mcp251x_info = { | 74 | static struct mcp251x_platform_data mcp251x_info = { |
75 | .oscillator_frequency = 16E6, | 75 | .oscillator_frequency = 16E6, |
76 | .board_specific_setup = NULL, | ||
77 | .power_enable = NULL, | ||
78 | .transceiver_enable = NULL | ||
79 | }; | 76 | }; |
80 | 77 | ||
81 | static struct spi_board_info mcp251x_board_info[] = { | 78 | static struct spi_board_info mcp251x_board_info[] = { |
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index f5d436434566..04a0aea23873 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/i2c/pca953x.h> | 29 | #include <linux/i2c/pca953x.h> |
30 | #include <linux/apm-emulation.h> | 30 | #include <linux/apm-emulation.h> |
31 | #include <linux/can/platform/mcp251x.h> | 31 | #include <linux/can/platform/mcp251x.h> |
32 | #include <linux/regulator/fixed.h> | ||
33 | #include <linux/regulator/machine.h> | ||
32 | 34 | ||
33 | #include <asm/mach-types.h> | 35 | #include <asm/mach-types.h> |
34 | #include <asm/suspend.h> | 36 | #include <asm/suspend.h> |
@@ -391,33 +393,34 @@ static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = { | |||
391 | }; | 393 | }; |
392 | 394 | ||
393 | /* CAN bus on SPI */ | 395 | /* CAN bus on SPI */ |
394 | static int zeus_mcp2515_setup(struct spi_device *sdev) | 396 | static struct regulator_consumer_supply can_regulator_consumer = |
395 | { | 397 | REGULATOR_SUPPLY("vdd", "spi3.0"); |
396 | int err; | ||
397 | |||
398 | err = gpio_request(ZEUS_CAN_SHDN_GPIO, "CAN shutdown"); | ||
399 | if (err) | ||
400 | return err; | ||
401 | 398 | ||
402 | err = gpio_direction_output(ZEUS_CAN_SHDN_GPIO, 1); | 399 | static struct regulator_init_data can_regulator_init_data = { |
403 | if (err) { | 400 | .constraints = { |
404 | gpio_free(ZEUS_CAN_SHDN_GPIO); | 401 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
405 | return err; | 402 | }, |
406 | } | 403 | .consumer_supplies = &can_regulator_consumer, |
404 | .num_consumer_supplies = 1, | ||
405 | }; | ||
407 | 406 | ||
408 | return 0; | 407 | static struct fixed_voltage_config can_regulator_pdata = { |
409 | } | 408 | .supply_name = "CAN_SHDN", |
409 | .microvolts = 3300000, | ||
410 | .gpio = ZEUS_CAN_SHDN_GPIO, | ||
411 | .init_data = &can_regulator_init_data, | ||
412 | }; | ||
410 | 413 | ||
411 | static int zeus_mcp2515_transceiver_enable(int enable) | 414 | static struct platform_device can_regulator_device = { |
412 | { | 415 | .name = "reg-fixed-volage", |
413 | gpio_set_value(ZEUS_CAN_SHDN_GPIO, !enable); | 416 | .id = -1, |
414 | return 0; | 417 | .dev = { |
415 | } | 418 | .platform_data = &can_regulator_pdata, |
419 | }, | ||
420 | }; | ||
416 | 421 | ||
417 | static struct mcp251x_platform_data zeus_mcp2515_pdata = { | 422 | static struct mcp251x_platform_data zeus_mcp2515_pdata = { |
418 | .oscillator_frequency = 16*1000*1000, | 423 | .oscillator_frequency = 16*1000*1000, |
419 | .board_specific_setup = zeus_mcp2515_setup, | ||
420 | .power_enable = zeus_mcp2515_transceiver_enable, | ||
421 | }; | 424 | }; |
422 | 425 | ||
423 | static struct spi_board_info zeus_spi_board_info[] = { | 426 | static struct spi_board_info zeus_spi_board_info[] = { |
@@ -516,6 +519,7 @@ static struct platform_device *zeus_devices[] __initdata = { | |||
516 | &zeus_leds_device, | 519 | &zeus_leds_device, |
517 | &zeus_pcmcia_device, | 520 | &zeus_pcmcia_device, |
518 | &zeus_max6369_device, | 521 | &zeus_max6369_device, |
522 | &can_regulator_device, | ||
519 | }; | 523 | }; |
520 | 524 | ||
521 | /* AC'97 */ | 525 | /* AC'97 */ |
diff --git a/arch/arm/mach-realview/include/mach/debug-macro.S b/arch/arm/mach-realview/include/mach/debug-macro.S deleted file mode 100644 index 8cc372dc66a8..000000000000 --- a/arch/arm/mach-realview/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | /* arch/arm/mach-realview/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copyright (C) 1994-1999 Russell King | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifdef CONFIG_DEBUG_REALVIEW_STD_PORT | ||
14 | #define DEBUG_LL_UART_OFFSET 0x00009000 | ||
15 | #elif defined(CONFIG_DEBUG_REALVIEW_PB1176_PORT) | ||
16 | #define DEBUG_LL_UART_OFFSET 0x0010c000 | ||
17 | #endif | ||
18 | |||
19 | #ifndef DEBUG_LL_UART_OFFSET | ||
20 | #error "Unknown RealView platform" | ||
21 | #endif | ||
22 | |||
23 | .macro addruart, rp, rv, tmp | ||
24 | mov \rp, #DEBUG_LL_UART_OFFSET | ||
25 | orr \rv, \rp, #0xfb000000 @ virtual base | ||
26 | orr \rp, \rp, #0x10000000 @ physical base | ||
27 | .endm | ||
28 | |||
29 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/mach-rpc/include/mach/debug-macro.S b/arch/arm/mach-rpc/include/mach/debug-macro.S deleted file mode 100644 index 6d28cc99b124..000000000000 --- a/arch/arm/mach-rpc/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | /* arch/arm/mach-rpc/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copyright (C) 1994-1999 Russell King | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | mov \rp, #0x00010000 | ||
16 | orr \rp, \rp, #0x00000fe0 | ||
17 | orr \rv, \rp, #0xe0000000 @ virtual | ||
18 | orr \rp, \rp, #0x03000000 @ physical | ||
19 | .endm | ||
20 | |||
21 | #define UART_SHIFT 2 | ||
22 | #define FLOW_CONTROL | ||
23 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index c5be60d85e4b..3a6ffa250fb1 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c | |||
@@ -358,7 +358,6 @@ static struct platform_device usbhsf_device = { | |||
358 | static struct sh_eth_plat_data sh_eth_platdata = { | 358 | static struct sh_eth_plat_data sh_eth_platdata = { |
359 | .phy = 0x00, /* LAN8710A */ | 359 | .phy = 0x00, /* LAN8710A */ |
360 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 360 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
361 | .register_type = SH_ETH_REG_GIGABIT, | ||
362 | .phy_interface = PHY_INTERFACE_MODE_MII, | 361 | .phy_interface = PHY_INTERFACE_MODE_MII, |
363 | }; | 362 | }; |
364 | 363 | ||
diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index 3354a85c90f7..35dd7f201a16 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2013 Renesas Solutions Corp. | 4 | * Copyright (C) 2013 Renesas Solutions Corp. |
5 | * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 5 | * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
6 | * Copyright (C) 2013 Cogent Embedded, Inc. | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -28,6 +29,7 @@ | |||
28 | #include <linux/smsc911x.h> | 29 | #include <linux/smsc911x.h> |
29 | #include <linux/spi/spi.h> | 30 | #include <linux/spi/spi.h> |
30 | #include <linux/spi/flash.h> | 31 | #include <linux/spi/flash.h> |
32 | #include <media/soc_camera.h> | ||
31 | #include <mach/common.h> | 33 | #include <mach/common.h> |
32 | #include <mach/irqs.h> | 34 | #include <mach/irqs.h> |
33 | #include <mach/r8a7778.h> | 35 | #include <mach/r8a7778.h> |
@@ -89,7 +91,6 @@ static struct sh_mobile_sdhi_info sdhi0_info = { | |||
89 | static struct sh_eth_plat_data ether_platform_data __initdata = { | 91 | static struct sh_eth_plat_data ether_platform_data __initdata = { |
90 | .phy = 0x01, | 92 | .phy = 0x01, |
91 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 93 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
92 | .register_type = SH_ETH_REG_FAST_RCAR, | ||
93 | .phy_interface = PHY_INTERFACE_MODE_RMII, | 94 | .phy_interface = PHY_INTERFACE_MODE_RMII, |
94 | /* | 95 | /* |
95 | * Although the LINK signal is available on the board, it's connected to | 96 | * Although the LINK signal is available on the board, it's connected to |
@@ -143,6 +144,25 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = { | |||
143 | MMC_CAP_NEEDS_POLL, | 144 | MMC_CAP_NEEDS_POLL, |
144 | }; | 145 | }; |
145 | 146 | ||
147 | static struct rcar_vin_platform_data vin_platform_data __initdata = { | ||
148 | .flags = RCAR_VIN_BT656, | ||
149 | }; | ||
150 | |||
151 | /* In the default configuration both decoders reside on I2C bus 0 */ | ||
152 | #define BOCKW_CAMERA(idx) \ | ||
153 | static struct i2c_board_info camera##idx##_info = { \ | ||
154 | I2C_BOARD_INFO("ml86v7667", 0x41 + 2 * (idx)), \ | ||
155 | }; \ | ||
156 | \ | ||
157 | static struct soc_camera_link iclink##idx##_ml86v7667 __initdata = { \ | ||
158 | .bus_id = idx, \ | ||
159 | .i2c_adapter_id = 0, \ | ||
160 | .board_info = &camera##idx##_info, \ | ||
161 | } | ||
162 | |||
163 | BOCKW_CAMERA(0); | ||
164 | BOCKW_CAMERA(1); | ||
165 | |||
146 | static const struct pinctrl_map bockw_pinctrl_map[] = { | 166 | static const struct pinctrl_map bockw_pinctrl_map[] = { |
147 | /* Ether */ | 167 | /* Ether */ |
148 | PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778", | 168 | PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778", |
@@ -174,6 +194,16 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { | |||
174 | "sdhi0_cd", "sdhi0"), | 194 | "sdhi0_cd", "sdhi0"), |
175 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778", | 195 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778", |
176 | "sdhi0_wp", "sdhi0"), | 196 | "sdhi0_wp", "sdhi0"), |
197 | /* VIN0 */ | ||
198 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.0", "pfc-r8a7778", | ||
199 | "vin0_clk", "vin0"), | ||
200 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.0", "pfc-r8a7778", | ||
201 | "vin0_data8", "vin0"), | ||
202 | /* VIN1 */ | ||
203 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.1", "pfc-r8a7778", | ||
204 | "vin1_clk", "vin1"), | ||
205 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7778-vin.1", "pfc-r8a7778", | ||
206 | "vin1_data8", "vin1"), | ||
177 | }; | 207 | }; |
178 | 208 | ||
179 | #define FPGA 0x18200000 | 209 | #define FPGA 0x18200000 |
@@ -192,6 +222,16 @@ static void __init bockw_init(void) | |||
192 | r8a7778_add_i2c_device(0); | 222 | r8a7778_add_i2c_device(0); |
193 | r8a7778_add_hspi_device(0); | 223 | r8a7778_add_hspi_device(0); |
194 | r8a7778_add_mmc_device(&sh_mmcif_plat); | 224 | r8a7778_add_mmc_device(&sh_mmcif_plat); |
225 | r8a7778_add_vin_device(0, &vin_platform_data); | ||
226 | /* VIN1 has a pin conflict with Ether */ | ||
227 | if (!IS_ENABLED(CONFIG_SH_ETH)) | ||
228 | r8a7778_add_vin_device(1, &vin_platform_data); | ||
229 | platform_device_register_data(&platform_bus, "soc-camera-pdrv", 0, | ||
230 | &iclink0_ml86v7667, | ||
231 | sizeof(iclink0_ml86v7667)); | ||
232 | platform_device_register_data(&platform_bus, "soc-camera-pdrv", 1, | ||
233 | &iclink1_ml86v7667, | ||
234 | sizeof(iclink1_ml86v7667)); | ||
195 | 235 | ||
196 | i2c_register_board_info(0, i2c0_devices, | 236 | i2c_register_board_info(0, i2c0_devices, |
197 | ARRAY_SIZE(i2c0_devices)); | 237 | ARRAY_SIZE(i2c0_devices)); |
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index a7d1010505bf..ca7fb2e63c60 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * marzen board support | 2 | * marzen board support |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Renesas Solutions Corp. | 4 | * Copyright (C) 2011, 2013 Renesas Solutions Corp. |
5 | * Copyright (C) 2011 Magnus Damm | 5 | * Copyright (C) 2011 Magnus Damm |
6 | * Copyright (C) 2013 Cogent Embedded, Inc. | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -37,6 +38,7 @@ | |||
37 | #include <linux/mmc/host.h> | 38 | #include <linux/mmc/host.h> |
38 | #include <linux/mmc/sh_mobile_sdhi.h> | 39 | #include <linux/mmc/sh_mobile_sdhi.h> |
39 | #include <linux/mfd/tmio.h> | 40 | #include <linux/mfd/tmio.h> |
41 | #include <media/soc_camera.h> | ||
40 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
41 | #include <mach/r8a7779.h> | 43 | #include <mach/r8a7779.h> |
42 | #include <mach/common.h> | 44 | #include <mach/common.h> |
@@ -178,12 +180,40 @@ static struct platform_device leds_device = { | |||
178 | }, | 180 | }, |
179 | }; | 181 | }; |
180 | 182 | ||
183 | static struct rcar_vin_platform_data vin_platform_data __initdata = { | ||
184 | .flags = RCAR_VIN_BT656, | ||
185 | }; | ||
186 | |||
187 | #define MARZEN_CAMERA(idx) \ | ||
188 | static struct i2c_board_info camera##idx##_info = { \ | ||
189 | I2C_BOARD_INFO("adv7180", 0x20 + (idx)), \ | ||
190 | }; \ | ||
191 | \ | ||
192 | static struct soc_camera_link iclink##idx##_adv7180 = { \ | ||
193 | .bus_id = 1 + 2 * (idx), \ | ||
194 | .i2c_adapter_id = 0, \ | ||
195 | .board_info = &camera##idx##_info, \ | ||
196 | }; \ | ||
197 | \ | ||
198 | static struct platform_device camera##idx##_device = { \ | ||
199 | .name = "soc-camera-pdrv", \ | ||
200 | .id = idx, \ | ||
201 | .dev = { \ | ||
202 | .platform_data = &iclink##idx##_adv7180, \ | ||
203 | }, \ | ||
204 | }; | ||
205 | |||
206 | MARZEN_CAMERA(0); | ||
207 | MARZEN_CAMERA(1); | ||
208 | |||
181 | static struct platform_device *marzen_devices[] __initdata = { | 209 | static struct platform_device *marzen_devices[] __initdata = { |
182 | ð_device, | 210 | ð_device, |
183 | &sdhi0_device, | 211 | &sdhi0_device, |
184 | &thermal_device, | 212 | &thermal_device, |
185 | &hspi_device, | 213 | &hspi_device, |
186 | &leds_device, | 214 | &leds_device, |
215 | &camera0_device, | ||
216 | &camera1_device, | ||
187 | }; | 217 | }; |
188 | 218 | ||
189 | static const struct pinctrl_map marzen_pinctrl_map[] = { | 219 | static const struct pinctrl_map marzen_pinctrl_map[] = { |
@@ -219,6 +249,16 @@ static const struct pinctrl_map marzen_pinctrl_map[] = { | |||
219 | /* USB2 */ | 249 | /* USB2 */ |
220 | PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.1", "pfc-r8a7779", | 250 | PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.1", "pfc-r8a7779", |
221 | "usb2", "usb2"), | 251 | "usb2", "usb2"), |
252 | /* VIN1 */ | ||
253 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779", | ||
254 | "vin1_clk", "vin1"), | ||
255 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779", | ||
256 | "vin1_data8", "vin1"), | ||
257 | /* VIN3 */ | ||
258 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779", | ||
259 | "vin3_clk", "vin3"), | ||
260 | PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779", | ||
261 | "vin3_data8", "vin3"), | ||
222 | }; | 262 | }; |
223 | 263 | ||
224 | static void __init marzen_init(void) | 264 | static void __init marzen_init(void) |
@@ -235,6 +275,8 @@ static void __init marzen_init(void) | |||
235 | 275 | ||
236 | r8a7779_add_standard_devices(); | 276 | r8a7779_add_standard_devices(); |
237 | r8a7779_add_usb_phy_device(&usb_phy_platform_data); | 277 | r8a7779_add_usb_phy_device(&usb_phy_platform_data); |
278 | r8a7779_add_vin_device(1, &vin_platform_data); | ||
279 | r8a7779_add_vin_device(3, &vin_platform_data); | ||
238 | platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); | 280 | platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); |
239 | } | 281 | } |
240 | 282 | ||
diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index a0e9eb72e46d..c4bf2d8fb111 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c | |||
@@ -106,6 +106,7 @@ enum { | |||
106 | MSTP331, | 106 | MSTP331, |
107 | MSTP323, MSTP322, MSTP321, | 107 | MSTP323, MSTP322, MSTP321, |
108 | MSTP114, | 108 | MSTP114, |
109 | MSTP110, MSTP109, | ||
109 | MSTP100, | 110 | MSTP100, |
110 | MSTP030, | 111 | MSTP030, |
111 | MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, | 112 | MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, |
@@ -119,6 +120,8 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
119 | [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */ | 120 | [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */ |
120 | [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */ | 121 | [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */ |
121 | [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ | 122 | [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ |
123 | [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */ | ||
124 | [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 9, 0), /* VIN1 */ | ||
122 | [MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 0, 0), /* USB0/1 */ | 125 | [MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 0, 0), /* USB0/1 */ |
123 | [MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */ | 126 | [MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */ |
124 | [MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */ | 127 | [MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */ |
@@ -146,6 +149,8 @@ static struct clk_lookup lookups[] = { | |||
146 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ | 149 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ |
147 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ | 150 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ |
148 | CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */ | 151 | CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */ |
152 | CLKDEV_DEV_ID("r8a7778-vin.0", &mstp_clks[MSTP110]), /* VIN0 */ | ||
153 | CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */ | ||
149 | CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ | 154 | CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ |
150 | CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ | 155 | CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ |
151 | CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ | 156 | CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ |
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index 10340f5becbb..bd6ad922eb7e 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c | |||
@@ -112,7 +112,9 @@ static struct clk *main_clks[] = { | |||
112 | }; | 112 | }; |
113 | 113 | ||
114 | enum { MSTP323, MSTP322, MSTP321, MSTP320, | 114 | enum { MSTP323, MSTP322, MSTP321, MSTP320, |
115 | MSTP120, | ||
115 | MSTP116, MSTP115, MSTP114, | 116 | MSTP116, MSTP115, MSTP114, |
117 | MSTP110, MSTP109, MSTP108, | ||
116 | MSTP103, MSTP101, MSTP100, | 118 | MSTP103, MSTP101, MSTP100, |
117 | MSTP030, | 119 | MSTP030, |
118 | MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, | 120 | MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, |
@@ -125,9 +127,13 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
125 | [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */ | 127 | [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */ |
126 | [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */ | 128 | [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */ |
127 | [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */ | 129 | [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */ |
130 | [MSTP120] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 20, 0), /* VIN3 */ | ||
128 | [MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */ | 131 | [MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */ |
129 | [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */ | 132 | [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */ |
130 | [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */ | 133 | [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */ |
134 | [MSTP110] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 10, 0), /* VIN0 */ | ||
135 | [MSTP109] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 9, 0), /* VIN1 */ | ||
136 | [MSTP108] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 8, 0), /* VIN2 */ | ||
131 | [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */ | 137 | [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */ |
132 | [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */ | 138 | [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 1, 0), /* USB2 */ |
133 | [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */ | 139 | [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 0, 0), /* USB0/1 */ |
@@ -162,10 +168,14 @@ static struct clk_lookup lookups[] = { | |||
162 | CLKDEV_CON_ID("peripheral_clk", &clkp_clk), | 168 | CLKDEV_CON_ID("peripheral_clk", &clkp_clk), |
163 | 169 | ||
164 | /* MSTP32 clocks */ | 170 | /* MSTP32 clocks */ |
171 | CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */ | ||
165 | CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */ | 172 | CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */ |
166 | CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */ | 173 | CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */ |
167 | CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */ | 174 | CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */ |
168 | CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */ | 175 | CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */ |
176 | CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */ | ||
177 | CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */ | ||
178 | CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */ | ||
169 | CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */ | 179 | CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */ |
170 | CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */ | 180 | CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */ |
171 | CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ | 181 | CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ |
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index 851d027a2f06..a7c6d151cdd5 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/mmc/sh_mobile_sdhi.h> | 22 | #include <linux/mmc/sh_mobile_sdhi.h> |
23 | #include <linux/sh_eth.h> | 23 | #include <linux/sh_eth.h> |
24 | #include <linux/platform_data/usb-rcar-phy.h> | 24 | #include <linux/platform_data/usb-rcar-phy.h> |
25 | #include <linux/platform_data/camera-rcar.h> | ||
25 | 26 | ||
26 | extern void r8a7778_add_standard_devices(void); | 27 | extern void r8a7778_add_standard_devices(void); |
27 | extern void r8a7778_add_standard_devices_dt(void); | 28 | extern void r8a7778_add_standard_devices_dt(void); |
@@ -30,6 +31,8 @@ extern void r8a7778_add_usb_phy_device(struct rcar_phy_platform_data *pdata); | |||
30 | extern void r8a7778_add_i2c_device(int id); | 31 | extern void r8a7778_add_i2c_device(int id); |
31 | extern void r8a7778_add_hspi_device(int id); | 32 | extern void r8a7778_add_hspi_device(int id); |
32 | extern void r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info); | 33 | extern void r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info); |
34 | extern void r8a7778_add_vin_device(int id, | ||
35 | struct rcar_vin_platform_data *pdata); | ||
33 | 36 | ||
34 | extern void r8a7778_init_late(void); | 37 | extern void r8a7778_init_late(void); |
35 | extern void r8a7778_init_delay(void); | 38 | extern void r8a7778_init_delay(void); |
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index fc47073c7ba9..6d2b6417fe2a 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/pm_domain.h> | 5 | #include <linux/pm_domain.h> |
6 | #include <linux/sh_eth.h> | 6 | #include <linux/sh_eth.h> |
7 | #include <linux/platform_data/usb-rcar-phy.h> | 7 | #include <linux/platform_data/usb-rcar-phy.h> |
8 | #include <linux/platform_data/camera-rcar.h> | ||
8 | 9 | ||
9 | struct platform_device; | 10 | struct platform_device; |
10 | 11 | ||
@@ -35,6 +36,8 @@ extern void r8a7779_add_standard_devices(void); | |||
35 | extern void r8a7779_add_standard_devices_dt(void); | 36 | extern void r8a7779_add_standard_devices_dt(void); |
36 | extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata); | 37 | extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata); |
37 | extern void r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata); | 38 | extern void r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata); |
39 | extern void r8a7779_add_vin_device(int idx, | ||
40 | struct rcar_vin_platform_data *pdata); | ||
38 | extern void r8a7779_init_late(void); | 41 | extern void r8a7779_init_late(void); |
39 | extern void r8a7779_clock_init(void); | 42 | extern void r8a7779_clock_init(void); |
40 | extern void r8a7779_pinmux_init(void); | 43 | extern void r8a7779_pinmux_init(void); |
diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 80c20392ad7c..0174f059eac3 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c | |||
@@ -333,6 +333,40 @@ void __init r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info) | |||
333 | info, sizeof(*info)); | 333 | info, sizeof(*info)); |
334 | } | 334 | } |
335 | 335 | ||
336 | /* VIN */ | ||
337 | #define R8A7778_VIN(idx) \ | ||
338 | static struct resource vin##idx##_resources[] __initdata = { \ | ||
339 | DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \ | ||
340 | DEFINE_RES_IRQ(gic_iid(0x5a)), \ | ||
341 | }; \ | ||
342 | \ | ||
343 | static struct platform_device_info vin##idx##_info __initdata = { \ | ||
344 | .parent = &platform_bus, \ | ||
345 | .name = "r8a7778-vin", \ | ||
346 | .id = idx, \ | ||
347 | .res = vin##idx##_resources, \ | ||
348 | .num_res = ARRAY_SIZE(vin##idx##_resources), \ | ||
349 | .dma_mask = DMA_BIT_MASK(32), \ | ||
350 | } | ||
351 | |||
352 | R8A7778_VIN(0); | ||
353 | R8A7778_VIN(1); | ||
354 | |||
355 | static struct platform_device_info *vin_info_table[] __initdata = { | ||
356 | &vin0_info, | ||
357 | &vin1_info, | ||
358 | }; | ||
359 | |||
360 | void __init r8a7778_add_vin_device(int id, struct rcar_vin_platform_data *pdata) | ||
361 | { | ||
362 | BUG_ON(id < 0 || id > 1); | ||
363 | |||
364 | vin_info_table[id]->data = pdata; | ||
365 | vin_info_table[id]->size_data = sizeof(*pdata); | ||
366 | |||
367 | platform_device_register_full(vin_info_table[id]); | ||
368 | } | ||
369 | |||
336 | void __init r8a7778_add_standard_devices(void) | 370 | void __init r8a7778_add_standard_devices(void) |
337 | { | 371 | { |
338 | int i; | 372 | int i; |
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 398687761f50..3d8928895503 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c | |||
@@ -559,6 +559,33 @@ static struct resource ether_resources[] = { | |||
559 | }, | 559 | }, |
560 | }; | 560 | }; |
561 | 561 | ||
562 | #define R8A7779_VIN(idx) \ | ||
563 | static struct resource vin##idx##_resources[] __initdata = { \ | ||
564 | DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \ | ||
565 | DEFINE_RES_IRQ(gic_iid(0x5f + (idx))), \ | ||
566 | }; \ | ||
567 | \ | ||
568 | static struct platform_device_info vin##idx##_info __initdata = { \ | ||
569 | .parent = &platform_bus, \ | ||
570 | .name = "r8a7779-vin", \ | ||
571 | .id = idx, \ | ||
572 | .res = vin##idx##_resources, \ | ||
573 | .num_res = ARRAY_SIZE(vin##idx##_resources), \ | ||
574 | .dma_mask = DMA_BIT_MASK(32), \ | ||
575 | } | ||
576 | |||
577 | R8A7779_VIN(0); | ||
578 | R8A7779_VIN(1); | ||
579 | R8A7779_VIN(2); | ||
580 | R8A7779_VIN(3); | ||
581 | |||
582 | static struct platform_device_info *vin_info_table[] __initdata = { | ||
583 | &vin0_info, | ||
584 | &vin1_info, | ||
585 | &vin2_info, | ||
586 | &vin3_info, | ||
587 | }; | ||
588 | |||
562 | static struct platform_device *r8a7779_devices_dt[] __initdata = { | 589 | static struct platform_device *r8a7779_devices_dt[] __initdata = { |
563 | &scif0_device, | 590 | &scif0_device, |
564 | &scif1_device, | 591 | &scif1_device, |
@@ -610,6 +637,16 @@ void __init r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata) | |||
610 | pdata, sizeof(*pdata)); | 637 | pdata, sizeof(*pdata)); |
611 | } | 638 | } |
612 | 639 | ||
640 | void __init r8a7779_add_vin_device(int id, struct rcar_vin_platform_data *pdata) | ||
641 | { | ||
642 | BUG_ON(id < 0 || id > 3); | ||
643 | |||
644 | vin_info_table[id]->data = pdata; | ||
645 | vin_info_table[id]->size_data = sizeof(*pdata); | ||
646 | |||
647 | platform_device_register_full(vin_info_table[id]); | ||
648 | } | ||
649 | |||
613 | /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ | 650 | /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ |
614 | void __init __weak r8a7779_register_twd(void) { } | 651 | void __init __weak r8a7779_register_twd(void) { } |
615 | 652 | ||
diff --git a/arch/arm/mach-spear/include/mach/debug-macro.S b/arch/arm/mach-spear/include/mach/debug-macro.S deleted file mode 100644 index 75b05ad0fbad..000000000000 --- a/arch/arm/mach-spear/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/plat-spear/include/plat/debug-macro.S | ||
3 | * | ||
4 | * Debugging macro include header for spear platform | ||
5 | * | ||
6 | * Copyright (C) 2009 ST Microelectronics | ||
7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/amba/serial.h> | ||
15 | #include <mach/spear.h> | ||
16 | |||
17 | .macro addruart, rp, rv, tmp | ||
18 | mov \rp, #SPEAR_DBG_UART_BASE @ Physical base | ||
19 | mov \rv, #VA_SPEAR_DBG_UART_BASE @ Virtual base | ||
20 | .endm | ||
21 | |||
22 | .macro senduart, rd, rx | ||
23 | strb \rd, [\rx, #UART01x_DR] @ ASC_TX_BUFFER | ||
24 | .endm | ||
25 | |||
26 | .macro waituart, rd, rx | ||
27 | 1001: ldr \rd, [\rx, #UART01x_FR] @ FLAG REGISTER | ||
28 | tst \rd, #UART01x_FR_TXFF @ TX_FULL | ||
29 | bne 1001b | ||
30 | .endm | ||
31 | |||
32 | .macro busyuart, rd, rx | ||
33 | 1002: ldr \rd, [\rx, #UART01x_FR] @ FLAG REGISTER | ||
34 | tst \rd, #UART011_FR_TXFE @ TX_EMPTY | ||
35 | beq 1002b | ||
36 | .endm | ||
diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h index cf3a5369eeca..5cdc53d9b653 100644 --- a/arch/arm/mach-spear/include/mach/spear.h +++ b/arch/arm/mach-spear/include/mach/spear.h | |||
@@ -39,7 +39,6 @@ | |||
39 | 39 | ||
40 | /* Debug uart for linux, will be used for debug and uncompress messages */ | 40 | /* Debug uart for linux, will be used for debug and uncompress messages */ |
41 | #define SPEAR_DBG_UART_BASE SPEAR_ICM1_UART_BASE | 41 | #define SPEAR_DBG_UART_BASE SPEAR_ICM1_UART_BASE |
42 | #define VA_SPEAR_DBG_UART_BASE VA_SPEAR_ICM1_UART_BASE | ||
43 | 42 | ||
44 | /* Sysctl base for spear platform */ | 43 | /* Sysctl base for spear platform */ |
45 | #define SPEAR_SYS_CTRL_BASE SPEAR_ICM3_SYS_CTRL_BASE | 44 | #define SPEAR_SYS_CTRL_BASE SPEAR_ICM3_SYS_CTRL_BASE |
@@ -86,7 +85,6 @@ | |||
86 | 85 | ||
87 | /* Debug uart for linux, will be used for debug and uncompress messages */ | 86 | /* Debug uart for linux, will be used for debug and uncompress messages */ |
88 | #define SPEAR_DBG_UART_BASE UART_BASE | 87 | #define SPEAR_DBG_UART_BASE UART_BASE |
89 | #define VA_SPEAR_DBG_UART_BASE VA_UART_BASE | ||
90 | 88 | ||
91 | #endif /* SPEAR13XX */ | 89 | #endif /* SPEAR13XX */ |
92 | 90 | ||
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index 0d1e4128d460..fc97cfd52769 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/of_fdt.h> | 29 | #include <linux/of_fdt.h> |
30 | #include <linux/of_platform.h> | 30 | #include <linux/of_platform.h> |
31 | #include <linux/pda_power.h> | 31 | #include <linux/pda_power.h> |
32 | #include <linux/platform_data/tegra_usb.h> | ||
33 | #include <linux/io.h> | 32 | #include <linux/io.h> |
34 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
35 | #include <linux/sys_soc.h> | 34 | #include <linux/sys_soc.h> |
@@ -46,40 +45,6 @@ | |||
46 | #include "fuse.h" | 45 | #include "fuse.h" |
47 | #include "iomap.h" | 46 | #include "iomap.h" |
48 | 47 | ||
49 | static struct tegra_ehci_platform_data tegra_ehci1_pdata = { | ||
50 | .operating_mode = TEGRA_USB_OTG, | ||
51 | .power_down_on_bus_suspend = 1, | ||
52 | .vbus_gpio = -1, | ||
53 | }; | ||
54 | |||
55 | static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { | ||
56 | .reset_gpio = -1, | ||
57 | .clk = "cdev2", | ||
58 | }; | ||
59 | |||
60 | static struct tegra_ehci_platform_data tegra_ehci2_pdata = { | ||
61 | .phy_config = &tegra_ehci2_ulpi_phy_config, | ||
62 | .operating_mode = TEGRA_USB_HOST, | ||
63 | .power_down_on_bus_suspend = 1, | ||
64 | .vbus_gpio = -1, | ||
65 | }; | ||
66 | |||
67 | static struct tegra_ehci_platform_data tegra_ehci3_pdata = { | ||
68 | .operating_mode = TEGRA_USB_HOST, | ||
69 | .power_down_on_bus_suspend = 1, | ||
70 | .vbus_gpio = -1, | ||
71 | }; | ||
72 | |||
73 | static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { | ||
74 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0", | ||
75 | &tegra_ehci1_pdata), | ||
76 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1", | ||
77 | &tegra_ehci2_pdata), | ||
78 | OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2", | ||
79 | &tegra_ehci3_pdata), | ||
80 | {} | ||
81 | }; | ||
82 | |||
83 | static void __init tegra_dt_init(void) | 48 | static void __init tegra_dt_init(void) |
84 | { | 49 | { |
85 | struct soc_device_attribute *soc_dev_attr; | 50 | struct soc_device_attribute *soc_dev_attr; |
@@ -112,8 +77,7 @@ static void __init tegra_dt_init(void) | |||
112 | * devices | 77 | * devices |
113 | */ | 78 | */ |
114 | out: | 79 | out: |
115 | of_platform_populate(NULL, of_default_bus_match_table, | 80 | of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); |
116 | tegra20_auxdata_lookup, parent); | ||
117 | } | 81 | } |
118 | 82 | ||
119 | static void __init trimslice_init(void) | 83 | static void __init trimslice_init(void) |
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index bf9b6be5b180..fe1f3e26b88b 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -4,7 +4,6 @@ | |||
4 | 4 | ||
5 | obj-y := cpu.o devices.o devices-common.o \ | 5 | obj-y := cpu.o devices.o devices-common.o \ |
6 | id.o usb.o timer.o pm.o | 6 | id.o usb.o timer.o pm.o |
7 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | ||
8 | obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o | 7 | obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o |
9 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o | 8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o |
10 | obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \ | 9 | obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \ |
diff --git a/arch/arm/mach-ux500/cpuidle.c b/arch/arm/mach-ux500/cpuidle.c deleted file mode 100644 index a45dd09daed9..000000000000 --- a/arch/arm/mach-ux500/cpuidle.c +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Linaro : Daniel Lezcano <daniel.lezcano@linaro.org> (IBM) | ||
3 | * | ||
4 | * Based on the work of Rickard Andersson <rickard.andersson@stericsson.com> | ||
5 | * and Jonas Aaberg <jonas.aberg@stericsson.com>. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/cpuidle.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/atomic.h> | ||
16 | #include <linux/smp.h> | ||
17 | #include <linux/mfd/dbx500-prcmu.h> | ||
18 | #include <linux/platform_data/arm-ux500-pm.h> | ||
19 | |||
20 | #include <asm/cpuidle.h> | ||
21 | #include <asm/proc-fns.h> | ||
22 | |||
23 | #include "db8500-regs.h" | ||
24 | #include "id.h" | ||
25 | |||
26 | static atomic_t master = ATOMIC_INIT(0); | ||
27 | static DEFINE_SPINLOCK(master_lock); | ||
28 | |||
29 | static inline int ux500_enter_idle(struct cpuidle_device *dev, | ||
30 | struct cpuidle_driver *drv, int index) | ||
31 | { | ||
32 | int this_cpu = smp_processor_id(); | ||
33 | bool recouple = false; | ||
34 | |||
35 | if (atomic_inc_return(&master) == num_online_cpus()) { | ||
36 | |||
37 | /* With this lock, we prevent the other cpu to exit and enter | ||
38 | * this function again and become the master */ | ||
39 | if (!spin_trylock(&master_lock)) | ||
40 | goto wfi; | ||
41 | |||
42 | /* decouple the gic from the A9 cores */ | ||
43 | if (prcmu_gic_decouple()) { | ||
44 | spin_unlock(&master_lock); | ||
45 | goto out; | ||
46 | } | ||
47 | |||
48 | /* If an error occur, we will have to recouple the gic | ||
49 | * manually */ | ||
50 | recouple = true; | ||
51 | |||
52 | /* At this state, as the gic is decoupled, if the other | ||
53 | * cpu is in WFI, we have the guarantee it won't be wake | ||
54 | * up, so we can safely go to retention */ | ||
55 | if (!prcmu_is_cpu_in_wfi(this_cpu ? 0 : 1)) | ||
56 | goto out; | ||
57 | |||
58 | /* The prcmu will be in charge of watching the interrupts | ||
59 | * and wake up the cpus */ | ||
60 | if (prcmu_copy_gic_settings()) | ||
61 | goto out; | ||
62 | |||
63 | /* Check in the meantime an interrupt did | ||
64 | * not occur on the gic ... */ | ||
65 | if (prcmu_gic_pending_irq()) | ||
66 | goto out; | ||
67 | |||
68 | /* ... and the prcmu */ | ||
69 | if (prcmu_pending_irq()) | ||
70 | goto out; | ||
71 | |||
72 | /* Go to the retention state, the prcmu will wait for the | ||
73 | * cpu to go WFI and this is what happens after exiting this | ||
74 | * 'master' critical section */ | ||
75 | if (prcmu_set_power_state(PRCMU_AP_IDLE, true, true)) | ||
76 | goto out; | ||
77 | |||
78 | /* When we switch to retention, the prcmu is in charge | ||
79 | * of recoupling the gic automatically */ | ||
80 | recouple = false; | ||
81 | |||
82 | spin_unlock(&master_lock); | ||
83 | } | ||
84 | wfi: | ||
85 | cpu_do_idle(); | ||
86 | out: | ||
87 | atomic_dec(&master); | ||
88 | |||
89 | if (recouple) { | ||
90 | prcmu_gic_recouple(); | ||
91 | spin_unlock(&master_lock); | ||
92 | } | ||
93 | |||
94 | return index; | ||
95 | } | ||
96 | |||
97 | static struct cpuidle_driver ux500_idle_driver = { | ||
98 | .name = "ux500_idle", | ||
99 | .owner = THIS_MODULE, | ||
100 | .states = { | ||
101 | ARM_CPUIDLE_WFI_STATE, | ||
102 | { | ||
103 | .enter = ux500_enter_idle, | ||
104 | .exit_latency = 70, | ||
105 | .target_residency = 260, | ||
106 | .flags = CPUIDLE_FLAG_TIME_VALID | | ||
107 | CPUIDLE_FLAG_TIMER_STOP, | ||
108 | .name = "ApIdle", | ||
109 | .desc = "ARM Retention", | ||
110 | }, | ||
111 | }, | ||
112 | .safe_state_index = 0, | ||
113 | .state_count = 2, | ||
114 | }; | ||
115 | |||
116 | int __init ux500_idle_init(void) | ||
117 | { | ||
118 | if (!(cpu_is_u8500_family() || cpu_is_ux540_family())) | ||
119 | return -ENODEV; | ||
120 | |||
121 | /* Configure wake up reasons */ | ||
122 | prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | | ||
123 | PRCMU_WAKEUP(ABB)); | ||
124 | |||
125 | return cpuidle_register(&ux500_idle_driver, NULL); | ||
126 | } | ||
127 | |||
128 | device_initcall(ux500_idle_init); | ||
diff --git a/arch/arm/mach-versatile/include/mach/debug-macro.S b/arch/arm/mach-versatile/include/mach/debug-macro.S deleted file mode 100644 index d0fbd7f1cb00..000000000000 --- a/arch/arm/mach-versatile/include/mach/debug-macro.S +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* arch/arm/mach-versatile/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copyright (C) 1994-1999 Russell King | ||
6 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | .macro addruart, rp, rv, tmp | ||
15 | mov \rp, #0x001F0000 | ||
16 | orr \rp, \rp, #0x00001000 | ||
17 | orr \rv, \rp, #0xf1000000 @ virtual base | ||
18 | orr \rp, \rp, #0x10000000 @ physical base | ||
19 | .endm | ||
20 | |||
21 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index db5c2cab8fda..cd2c88e7a8f7 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -809,15 +809,18 @@ config KUSER_HELPERS | |||
809 | the CPU type fitted to the system. This permits binaries to be | 809 | the CPU type fitted to the system. This permits binaries to be |
810 | run on ARMv4 through to ARMv7 without modification. | 810 | run on ARMv4 through to ARMv7 without modification. |
811 | 811 | ||
812 | See Documentation/arm/kernel_user_helpers.txt for details. | ||
813 | |||
812 | However, the fixed address nature of these helpers can be used | 814 | However, the fixed address nature of these helpers can be used |
813 | by ROP (return orientated programming) authors when creating | 815 | by ROP (return orientated programming) authors when creating |
814 | exploits. | 816 | exploits. |
815 | 817 | ||
816 | If all of the binaries and libraries which run on your platform | 818 | If all of the binaries and libraries which run on your platform |
817 | are built specifically for your platform, and make no use of | 819 | are built specifically for your platform, and make no use of |
818 | these helpers, then you can turn this option off. However, | 820 | these helpers, then you can turn this option off to hinder |
819 | when such an binary or library is run, it will receive a SIGILL | 821 | such exploits. However, in that case, if a binary or library |
820 | signal, which will terminate the program. | 822 | relying on those helpers is run, it will receive a SIGILL signal, |
823 | which will terminate the program. | ||
821 | 824 | ||
822 | Say N here only if you are absolutely certain that you do not | 825 | Say N here only if you are absolutely certain that you do not |
823 | need these helpers; otherwise, the safe option is to say Y. | 826 | need these helpers; otherwise, the safe option is to say Y. |
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index d70e0aba0c9d..447da6ffadd5 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -290,7 +290,7 @@ static void l2x0_disable(void) | |||
290 | raw_spin_lock_irqsave(&l2x0_lock, flags); | 290 | raw_spin_lock_irqsave(&l2x0_lock, flags); |
291 | __l2x0_flush_all(); | 291 | __l2x0_flush_all(); |
292 | writel_relaxed(0, l2x0_base + L2X0_CTRL); | 292 | writel_relaxed(0, l2x0_base + L2X0_CTRL); |
293 | dsb(); | 293 | dsb(st); |
294 | raw_spin_unlock_irqrestore(&l2x0_lock, flags); | 294 | raw_spin_unlock_irqrestore(&l2x0_lock, flags); |
295 | } | 295 | } |
296 | 296 | ||
@@ -417,9 +417,9 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) | |||
417 | outer_cache.disable = l2x0_disable; | 417 | outer_cache.disable = l2x0_disable; |
418 | } | 418 | } |
419 | 419 | ||
420 | printk(KERN_INFO "%s cache controller enabled\n", type); | 420 | pr_info("%s cache controller enabled\n", type); |
421 | printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", | 421 | pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n", |
422 | ways, cache_id, aux, l2x0_size); | 422 | ways, cache_id, aux, l2x0_size >> 10); |
423 | } | 423 | } |
424 | 424 | ||
425 | #ifdef CONFIG_OF | 425 | #ifdef CONFIG_OF |
@@ -929,7 +929,9 @@ static const struct of_device_id l2x0_ids[] __initconst = { | |||
929 | .data = (void *)&aurora_no_outer_data}, | 929 | .data = (void *)&aurora_no_outer_data}, |
930 | { .compatible = "marvell,aurora-outer-cache", | 930 | { .compatible = "marvell,aurora-outer-cache", |
931 | .data = (void *)&aurora_with_outer_data}, | 931 | .data = (void *)&aurora_with_outer_data}, |
932 | { .compatible = "bcm,bcm11351-a2-pl310-cache", | 932 | { .compatible = "brcm,bcm11351-a2-pl310-cache", |
933 | .data = (void *)&bcm_l2x0_data}, | ||
934 | { .compatible = "bcm,bcm11351-a2-pl310-cache", /* deprecated name */ | ||
933 | .data = (void *)&bcm_l2x0_data}, | 935 | .data = (void *)&bcm_l2x0_data}, |
934 | {} | 936 | {} |
935 | }; | 937 | }; |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 515b00064da8..b5c467a65c27 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
@@ -282,7 +282,7 @@ ENTRY(v7_coherent_user_range) | |||
282 | add r12, r12, r2 | 282 | add r12, r12, r2 |
283 | cmp r12, r1 | 283 | cmp r12, r1 |
284 | blo 1b | 284 | blo 1b |
285 | dsb | 285 | dsb ishst |
286 | icache_line_size r2, r3 | 286 | icache_line_size r2, r3 |
287 | sub r3, r2, #1 | 287 | sub r3, r2, #1 |
288 | bic r12, r0, r3 | 288 | bic r12, r0, r3 |
@@ -294,7 +294,7 @@ ENTRY(v7_coherent_user_range) | |||
294 | mov r0, #0 | 294 | mov r0, #0 |
295 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable | 295 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable |
296 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB | 296 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB |
297 | dsb | 297 | dsb ishst |
298 | isb | 298 | isb |
299 | mov pc, lr | 299 | mov pc, lr |
300 | 300 | ||
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 4a0544492f10..84e6f772e204 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c | |||
@@ -162,10 +162,7 @@ static void flush_context(unsigned int cpu) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | /* Queue a TLB invalidate and flush the I-cache if necessary. */ | 164 | /* Queue a TLB invalidate and flush the I-cache if necessary. */ |
165 | if (!tlb_ops_need_broadcast()) | 165 | cpumask_setall(&tlb_flush_pending); |
166 | cpumask_set_cpu(cpu, &tlb_flush_pending); | ||
167 | else | ||
168 | cpumask_setall(&tlb_flush_pending); | ||
169 | 166 | ||
170 | if (icache_is_vivt_asid_tagged()) | 167 | if (icache_is_vivt_asid_tagged()) |
171 | __flush_icache_all(); | 168 | __flush_icache_all(); |
@@ -245,8 +242,6 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) | |||
245 | if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) { | 242 | if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) { |
246 | local_flush_bp_all(); | 243 | local_flush_bp_all(); |
247 | local_flush_tlb_all(); | 244 | local_flush_tlb_all(); |
248 | if (erratum_a15_798181()) | ||
249 | dummy_flush_tlb_a15_erratum(); | ||
250 | } | 245 | } |
251 | 246 | ||
252 | atomic64_set(&per_cpu(active_asids, cpu), asid); | 247 | atomic64_set(&per_cpu(active_asids, cpu), asid); |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 7f9b1798c6cf..f5e1a8471714 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -358,7 +358,7 @@ static int __init atomic_pool_init(void) | |||
358 | if (!pages) | 358 | if (!pages) |
359 | goto no_pages; | 359 | goto no_pages; |
360 | 360 | ||
361 | if (IS_ENABLED(CONFIG_CMA)) | 361 | if (IS_ENABLED(CONFIG_DMA_CMA)) |
362 | ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page, | 362 | ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page, |
363 | atomic_pool_init); | 363 | atomic_pool_init); |
364 | else | 364 | else |
@@ -455,7 +455,6 @@ static void __dma_remap(struct page *page, size_t size, pgprot_t prot) | |||
455 | unsigned end = start + size; | 455 | unsigned end = start + size; |
456 | 456 | ||
457 | apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot); | 457 | apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot); |
458 | dsb(); | ||
459 | flush_tlb_kernel_range(start, end); | 458 | flush_tlb_kernel_range(start, end); |
460 | } | 459 | } |
461 | 460 | ||
@@ -670,7 +669,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | |||
670 | addr = __alloc_simple_buffer(dev, size, gfp, &page); | 669 | addr = __alloc_simple_buffer(dev, size, gfp, &page); |
671 | else if (!(gfp & __GFP_WAIT)) | 670 | else if (!(gfp & __GFP_WAIT)) |
672 | addr = __alloc_from_pool(size, &page); | 671 | addr = __alloc_from_pool(size, &page); |
673 | else if (!IS_ENABLED(CONFIG_CMA)) | 672 | else if (!IS_ENABLED(CONFIG_DMA_CMA)) |
674 | addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); | 673 | addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); |
675 | else | 674 | else |
676 | addr = __alloc_from_contiguous(dev, size, prot, &page, caller); | 675 | addr = __alloc_from_contiguous(dev, size, prot, &page, caller); |
@@ -759,7 +758,7 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr, | |||
759 | __dma_free_buffer(page, size); | 758 | __dma_free_buffer(page, size); |
760 | } else if (__free_from_pool(cpu_addr, size)) { | 759 | } else if (__free_from_pool(cpu_addr, size)) { |
761 | return; | 760 | return; |
762 | } else if (!IS_ENABLED(CONFIG_CMA)) { | 761 | } else if (!IS_ENABLED(CONFIG_DMA_CMA)) { |
763 | __dma_free_remap(cpu_addr, size); | 762 | __dma_free_remap(cpu_addr, size); |
764 | __dma_free_buffer(page, size); | 763 | __dma_free_buffer(page, size); |
765 | } else { | 764 | } else { |
diff --git a/arch/arm/mm/hugetlbpage.c b/arch/arm/mm/hugetlbpage.c index 3d1e4a205b0b..66781bf34077 100644 --- a/arch/arm/mm/hugetlbpage.c +++ b/arch/arm/mm/hugetlbpage.c | |||
@@ -36,22 +36,6 @@ | |||
36 | * of type casting from pmd_t * to pte_t *. | 36 | * of type casting from pmd_t * to pte_t *. |
37 | */ | 37 | */ |
38 | 38 | ||
39 | pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | ||
40 | { | ||
41 | pgd_t *pgd; | ||
42 | pud_t *pud; | ||
43 | pmd_t *pmd = NULL; | ||
44 | |||
45 | pgd = pgd_offset(mm, addr); | ||
46 | if (pgd_present(*pgd)) { | ||
47 | pud = pud_offset(pgd, addr); | ||
48 | if (pud_present(*pud)) | ||
49 | pmd = pmd_offset(pud, addr); | ||
50 | } | ||
51 | |||
52 | return (pte_t *)pmd; | ||
53 | } | ||
54 | |||
55 | struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, | 39 | struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, |
56 | int write) | 40 | int write) |
57 | { | 41 | { |
@@ -68,33 +52,6 @@ int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) | |||
68 | return 0; | 52 | return 0; |
69 | } | 53 | } |
70 | 54 | ||
71 | pte_t *huge_pte_alloc(struct mm_struct *mm, | ||
72 | unsigned long addr, unsigned long sz) | ||
73 | { | ||
74 | pgd_t *pgd; | ||
75 | pud_t *pud; | ||
76 | pte_t *pte = NULL; | ||
77 | |||
78 | pgd = pgd_offset(mm, addr); | ||
79 | pud = pud_alloc(mm, pgd, addr); | ||
80 | if (pud) | ||
81 | pte = (pte_t *)pmd_alloc(mm, pud, addr); | ||
82 | |||
83 | return pte; | ||
84 | } | ||
85 | |||
86 | struct page * | ||
87 | follow_huge_pmd(struct mm_struct *mm, unsigned long address, | ||
88 | pmd_t *pmd, int write) | ||
89 | { | ||
90 | struct page *page; | ||
91 | |||
92 | page = pte_page(*(pte_t *)pmd); | ||
93 | if (page) | ||
94 | page += ((address & ~PMD_MASK) >> PAGE_SHIFT); | ||
95 | return page; | ||
96 | } | ||
97 | |||
98 | int pmd_huge(pmd_t pmd) | 55 | int pmd_huge(pmd_t pmd) |
99 | { | 56 | { |
100 | return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT); | 57 | return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT); |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 15225d829d71..2958e74fc42c 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -231,7 +231,7 @@ static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, | |||
231 | } | 231 | } |
232 | #endif | 232 | #endif |
233 | 233 | ||
234 | void __init setup_dma_zone(struct machine_desc *mdesc) | 234 | void __init setup_dma_zone(const struct machine_desc *mdesc) |
235 | { | 235 | { |
236 | #ifdef CONFIG_ZONE_DMA | 236 | #ifdef CONFIG_ZONE_DMA |
237 | if (mdesc->dma_zone_size) { | 237 | if (mdesc->dma_zone_size) { |
@@ -335,7 +335,8 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align) | |||
335 | return phys; | 335 | return phys; |
336 | } | 336 | } |
337 | 337 | ||
338 | void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) | 338 | void __init arm_memblock_init(struct meminfo *mi, |
339 | const struct machine_desc *mdesc) | ||
339 | { | 340 | { |
340 | int i; | 341 | int i; |
341 | 342 | ||
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 53cdbd39ec8e..b1d17eeb59b8 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -1186,7 +1186,7 @@ void __init arm_mm_memblock_reserve(void) | |||
1186 | * called function. This means you can't use any function or debugging | 1186 | * called function. This means you can't use any function or debugging |
1187 | * method which may touch any device, otherwise the kernel _will_ crash. | 1187 | * method which may touch any device, otherwise the kernel _will_ crash. |
1188 | */ | 1188 | */ |
1189 | static void __init devicemaps_init(struct machine_desc *mdesc) | 1189 | static void __init devicemaps_init(const struct machine_desc *mdesc) |
1190 | { | 1190 | { |
1191 | struct map_desc map; | 1191 | struct map_desc map; |
1192 | unsigned long addr; | 1192 | unsigned long addr; |
@@ -1319,7 +1319,7 @@ static void __init map_lowmem(void) | |||
1319 | * paging_init() sets up the page tables, initialises the zone memory | 1319 | * paging_init() sets up the page tables, initialises the zone memory |
1320 | * maps, and sets up the zero page, bad page and bad page tables. | 1320 | * maps, and sets up the zero page, bad page and bad page tables. |
1321 | */ | 1321 | */ |
1322 | void __init paging_init(struct machine_desc *mdesc) | 1322 | void __init paging_init(const struct machine_desc *mdesc) |
1323 | { | 1323 | { |
1324 | void *zero_page; | 1324 | void *zero_page; |
1325 | 1325 | ||
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 1fa50100ab6a..34d4ab217bab 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c | |||
@@ -299,7 +299,7 @@ void __init sanity_check_meminfo(void) | |||
299 | * paging_init() sets up the page tables, initialises the zone memory | 299 | * paging_init() sets up the page tables, initialises the zone memory |
300 | * maps, and sets up the zero page, bad page and bad page tables. | 300 | * maps, and sets up the zero page, bad page and bad page tables. |
301 | */ | 301 | */ |
302 | void __init paging_init(struct machine_desc *mdesc) | 302 | void __init paging_init(const struct machine_desc *mdesc) |
303 | { | 303 | { |
304 | early_trap_init((void *)CONFIG_VECTORS_BASE); | 304 | early_trap_init((void *)CONFIG_VECTORS_BASE); |
305 | mpu_setup(); | 305 | mpu_setup(); |
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index d5146b98c8d1..db79b62c92fb 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S | |||
@@ -514,6 +514,32 @@ ENTRY(cpu_feroceon_set_pte_ext) | |||
514 | #endif | 514 | #endif |
515 | mov pc, lr | 515 | mov pc, lr |
516 | 516 | ||
517 | /* Suspend/resume support: taken from arch/arm/mm/proc-arm926.S */ | ||
518 | .globl cpu_feroceon_suspend_size | ||
519 | .equ cpu_feroceon_suspend_size, 4 * 3 | ||
520 | #ifdef CONFIG_ARM_CPU_SUSPEND | ||
521 | ENTRY(cpu_feroceon_do_suspend) | ||
522 | stmfd sp!, {r4 - r6, lr} | ||
523 | mrc p15, 0, r4, c13, c0, 0 @ PID | ||
524 | mrc p15, 0, r5, c3, c0, 0 @ Domain ID | ||
525 | mrc p15, 0, r6, c1, c0, 0 @ Control register | ||
526 | stmia r0, {r4 - r6} | ||
527 | ldmfd sp!, {r4 - r6, pc} | ||
528 | ENDPROC(cpu_feroceon_do_suspend) | ||
529 | |||
530 | ENTRY(cpu_feroceon_do_resume) | ||
531 | mov ip, #0 | ||
532 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs | ||
533 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches | ||
534 | ldmia r0, {r4 - r6} | ||
535 | mcr p15, 0, r4, c13, c0, 0 @ PID | ||
536 | mcr p15, 0, r5, c3, c0, 0 @ Domain ID | ||
537 | mcr p15, 0, r1, c2, c0, 0 @ TTB address | ||
538 | mov r0, r6 @ control register | ||
539 | b cpu_resume_mmu | ||
540 | ENDPROC(cpu_feroceon_do_resume) | ||
541 | #endif | ||
542 | |||
517 | .type __feroceon_setup, #function | 543 | .type __feroceon_setup, #function |
518 | __feroceon_setup: | 544 | __feroceon_setup: |
519 | mov r0, #0 | 545 | mov r0, #0 |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 73398bcf9bd8..c63d9bdee51e 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -83,7 +83,7 @@ ENTRY(cpu_v7_dcache_clean_area) | |||
83 | add r0, r0, r2 | 83 | add r0, r0, r2 |
84 | subs r1, r1, r2 | 84 | subs r1, r1, r2 |
85 | bhi 2b | 85 | bhi 2b |
86 | dsb | 86 | dsb ishst |
87 | mov pc, lr | 87 | mov pc, lr |
88 | ENDPROC(cpu_v7_dcache_clean_area) | 88 | ENDPROC(cpu_v7_dcache_clean_area) |
89 | 89 | ||
@@ -330,7 +330,19 @@ __v7_setup: | |||
330 | 1: | 330 | 1: |
331 | #endif | 331 | #endif |
332 | 332 | ||
333 | 3: mov r10, #0 | 333 | /* Cortex-A15 Errata */ |
334 | 3: ldr r10, =0x00000c0f @ Cortex-A15 primary part number | ||
335 | teq r0, r10 | ||
336 | bne 4f | ||
337 | |||
338 | #ifdef CONFIG_ARM_ERRATA_773022 | ||
339 | cmp r6, #0x4 @ only present up to r0p4 | ||
340 | mrcle p15, 0, r10, c1, c0, 1 @ read aux control register | ||
341 | orrle r10, r10, #1 << 1 @ disable loop buffer | ||
342 | mcrle p15, 0, r10, c1, c0, 1 @ write aux control register | ||
343 | #endif | ||
344 | |||
345 | 4: mov r10, #0 | ||
334 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate | 346 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate |
335 | dsb | 347 | dsb |
336 | #ifdef CONFIG_MMU | 348 | #ifdef CONFIG_MMU |
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index ea94765acf9a..355308767bae 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S | |||
@@ -35,7 +35,7 @@ | |||
35 | ENTRY(v7wbi_flush_user_tlb_range) | 35 | ENTRY(v7wbi_flush_user_tlb_range) |
36 | vma_vm_mm r3, r2 @ get vma->vm_mm | 36 | vma_vm_mm r3, r2 @ get vma->vm_mm |
37 | mmid r3, r3 @ get vm_mm->context.id | 37 | mmid r3, r3 @ get vm_mm->context.id |
38 | dsb | 38 | dsb ish |
39 | mov r0, r0, lsr #PAGE_SHIFT @ align address | 39 | mov r0, r0, lsr #PAGE_SHIFT @ align address |
40 | mov r1, r1, lsr #PAGE_SHIFT | 40 | mov r1, r1, lsr #PAGE_SHIFT |
41 | asid r3, r3 @ mask ASID | 41 | asid r3, r3 @ mask ASID |
@@ -56,7 +56,7 @@ ENTRY(v7wbi_flush_user_tlb_range) | |||
56 | add r0, r0, #PAGE_SZ | 56 | add r0, r0, #PAGE_SZ |
57 | cmp r0, r1 | 57 | cmp r0, r1 |
58 | blo 1b | 58 | blo 1b |
59 | dsb | 59 | dsb ish |
60 | mov pc, lr | 60 | mov pc, lr |
61 | ENDPROC(v7wbi_flush_user_tlb_range) | 61 | ENDPROC(v7wbi_flush_user_tlb_range) |
62 | 62 | ||
@@ -69,7 +69,7 @@ ENDPROC(v7wbi_flush_user_tlb_range) | |||
69 | * - end - end address (exclusive, may not be aligned) | 69 | * - end - end address (exclusive, may not be aligned) |
70 | */ | 70 | */ |
71 | ENTRY(v7wbi_flush_kern_tlb_range) | 71 | ENTRY(v7wbi_flush_kern_tlb_range) |
72 | dsb | 72 | dsb ish |
73 | mov r0, r0, lsr #PAGE_SHIFT @ align address | 73 | mov r0, r0, lsr #PAGE_SHIFT @ align address |
74 | mov r1, r1, lsr #PAGE_SHIFT | 74 | mov r1, r1, lsr #PAGE_SHIFT |
75 | mov r0, r0, lsl #PAGE_SHIFT | 75 | mov r0, r0, lsl #PAGE_SHIFT |
@@ -84,7 +84,7 @@ ENTRY(v7wbi_flush_kern_tlb_range) | |||
84 | add r0, r0, #PAGE_SZ | 84 | add r0, r0, #PAGE_SZ |
85 | cmp r0, r1 | 85 | cmp r0, r1 |
86 | blo 1b | 86 | blo 1b |
87 | dsb | 87 | dsb ish |
88 | isb | 88 | isb |
89 | mov pc, lr | 89 | mov pc, lr |
90 | ENDPROC(v7wbi_flush_kern_tlb_range) | 90 | ENDPROC(v7wbi_flush_kern_tlb_range) |
diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index 8e11e96eab5e..c83f27b6bdda 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/spi/pxa2xx_spi.h> | 31 | #include <linux/spi/pxa2xx_spi.h> |
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/of.h> | ||
34 | #include <linux/of_device.h> | ||
33 | 35 | ||
34 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
35 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
@@ -60,6 +62,30 @@ struct ssp_device *pxa_ssp_request(int port, const char *label) | |||
60 | } | 62 | } |
61 | EXPORT_SYMBOL(pxa_ssp_request); | 63 | EXPORT_SYMBOL(pxa_ssp_request); |
62 | 64 | ||
65 | struct ssp_device *pxa_ssp_request_of(const struct device_node *of_node, | ||
66 | const char *label) | ||
67 | { | ||
68 | struct ssp_device *ssp = NULL; | ||
69 | |||
70 | mutex_lock(&ssp_lock); | ||
71 | |||
72 | list_for_each_entry(ssp, &ssp_list, node) { | ||
73 | if (ssp->of_node == of_node && ssp->use_count == 0) { | ||
74 | ssp->use_count++; | ||
75 | ssp->label = label; | ||
76 | break; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | mutex_unlock(&ssp_lock); | ||
81 | |||
82 | if (&ssp->node == &ssp_list) | ||
83 | return NULL; | ||
84 | |||
85 | return ssp; | ||
86 | } | ||
87 | EXPORT_SYMBOL(pxa_ssp_request_of); | ||
88 | |||
63 | void pxa_ssp_free(struct ssp_device *ssp) | 89 | void pxa_ssp_free(struct ssp_device *ssp) |
64 | { | 90 | { |
65 | mutex_lock(&ssp_lock); | 91 | mutex_lock(&ssp_lock); |
@@ -72,96 +98,126 @@ void pxa_ssp_free(struct ssp_device *ssp) | |||
72 | } | 98 | } |
73 | EXPORT_SYMBOL(pxa_ssp_free); | 99 | EXPORT_SYMBOL(pxa_ssp_free); |
74 | 100 | ||
101 | #ifdef CONFIG_OF | ||
102 | static const struct of_device_id pxa_ssp_of_ids[] = { | ||
103 | { .compatible = "mrvl,pxa25x-ssp", .data = (void *) PXA25x_SSP }, | ||
104 | { .compatible = "mvrl,pxa25x-nssp", .data = (void *) PXA25x_NSSP }, | ||
105 | { .compatible = "mrvl,pxa27x-ssp", .data = (void *) PXA27x_SSP }, | ||
106 | { .compatible = "mrvl,pxa3xx-ssp", .data = (void *) PXA3xx_SSP }, | ||
107 | { .compatible = "mvrl,pxa168-ssp", .data = (void *) PXA168_SSP }, | ||
108 | { .compatible = "mrvl,pxa910-ssp", .data = (void *) PXA910_SSP }, | ||
109 | { .compatible = "mrvl,ce4100-ssp", .data = (void *) CE4100_SSP }, | ||
110 | { .compatible = "mrvl,lpss-ssp", .data = (void *) LPSS_SSP }, | ||
111 | { }, | ||
112 | }; | ||
113 | MODULE_DEVICE_TABLE(of, pxa_ssp_of_ids); | ||
114 | #endif | ||
115 | |||
75 | static int pxa_ssp_probe(struct platform_device *pdev) | 116 | static int pxa_ssp_probe(struct platform_device *pdev) |
76 | { | 117 | { |
77 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
78 | struct resource *res; | 118 | struct resource *res; |
79 | struct ssp_device *ssp; | 119 | struct ssp_device *ssp; |
80 | int ret = 0; | 120 | struct device *dev = &pdev->dev; |
81 | 121 | ||
82 | ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL); | 122 | ssp = devm_kzalloc(dev, sizeof(struct ssp_device), GFP_KERNEL); |
83 | if (ssp == NULL) { | 123 | if (ssp == NULL) |
84 | dev_err(&pdev->dev, "failed to allocate memory"); | ||
85 | return -ENOMEM; | 124 | return -ENOMEM; |
86 | } | ||
87 | ssp->pdev = pdev; | ||
88 | 125 | ||
89 | ssp->clk = clk_get(&pdev->dev, NULL); | 126 | ssp->pdev = pdev; |
90 | if (IS_ERR(ssp->clk)) { | ||
91 | ret = PTR_ERR(ssp->clk); | ||
92 | goto err_free; | ||
93 | } | ||
94 | 127 | ||
95 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 128 | ssp->clk = devm_clk_get(dev, NULL); |
96 | if (res == NULL) { | 129 | if (IS_ERR(ssp->clk)) |
97 | dev_err(&pdev->dev, "no SSP RX DRCMR defined\n"); | 130 | return PTR_ERR(ssp->clk); |
98 | ret = -ENODEV; | 131 | |
99 | goto err_free_clk; | 132 | if (dev->of_node) { |
100 | } | 133 | struct of_phandle_args dma_spec; |
101 | ssp->drcmr_rx = res->start; | 134 | struct device_node *np = dev->of_node; |
135 | |||
136 | /* | ||
137 | * FIXME: we should allocate the DMA channel from this | ||
138 | * context and pass the channel down to the ssp users. | ||
139 | * For now, we lookup the rx and tx indices manually | ||
140 | */ | ||
141 | |||
142 | /* rx */ | ||
143 | of_parse_phandle_with_args(np, "dmas", "#dma-cells", | ||
144 | 0, &dma_spec); | ||
145 | ssp->drcmr_rx = dma_spec.args[0]; | ||
146 | of_node_put(dma_spec.np); | ||
147 | |||
148 | /* tx */ | ||
149 | of_parse_phandle_with_args(np, "dmas", "#dma-cells", | ||
150 | 1, &dma_spec); | ||
151 | ssp->drcmr_tx = dma_spec.args[0]; | ||
152 | of_node_put(dma_spec.np); | ||
153 | } else { | ||
154 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
155 | if (res == NULL) { | ||
156 | dev_err(dev, "no SSP RX DRCMR defined\n"); | ||
157 | return -ENODEV; | ||
158 | } | ||
159 | ssp->drcmr_rx = res->start; | ||
102 | 160 | ||
103 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); | 161 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); |
104 | if (res == NULL) { | 162 | if (res == NULL) { |
105 | dev_err(&pdev->dev, "no SSP TX DRCMR defined\n"); | 163 | dev_err(dev, "no SSP TX DRCMR defined\n"); |
106 | ret = -ENODEV; | 164 | return -ENODEV; |
107 | goto err_free_clk; | 165 | } |
166 | ssp->drcmr_tx = res->start; | ||
108 | } | 167 | } |
109 | ssp->drcmr_tx = res->start; | ||
110 | 168 | ||
111 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 169 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
112 | if (res == NULL) { | 170 | if (res == NULL) { |
113 | dev_err(&pdev->dev, "no memory resource defined\n"); | 171 | dev_err(dev, "no memory resource defined\n"); |
114 | ret = -ENODEV; | 172 | return -ENODEV; |
115 | goto err_free_clk; | ||
116 | } | 173 | } |
117 | 174 | ||
118 | res = request_mem_region(res->start, resource_size(res), | 175 | res = devm_request_mem_region(dev, res->start, resource_size(res), |
119 | pdev->name); | 176 | pdev->name); |
120 | if (res == NULL) { | 177 | if (res == NULL) { |
121 | dev_err(&pdev->dev, "failed to request memory resource\n"); | 178 | dev_err(dev, "failed to request memory resource\n"); |
122 | ret = -EBUSY; | 179 | return -EBUSY; |
123 | goto err_free_clk; | ||
124 | } | 180 | } |
125 | 181 | ||
126 | ssp->phys_base = res->start; | 182 | ssp->phys_base = res->start; |
127 | 183 | ||
128 | ssp->mmio_base = ioremap(res->start, resource_size(res)); | 184 | ssp->mmio_base = devm_ioremap(dev, res->start, resource_size(res)); |
129 | if (ssp->mmio_base == NULL) { | 185 | if (ssp->mmio_base == NULL) { |
130 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | 186 | dev_err(dev, "failed to ioremap() registers\n"); |
131 | ret = -ENODEV; | 187 | return -ENODEV; |
132 | goto err_free_mem; | ||
133 | } | 188 | } |
134 | 189 | ||
135 | ssp->irq = platform_get_irq(pdev, 0); | 190 | ssp->irq = platform_get_irq(pdev, 0); |
136 | if (ssp->irq < 0) { | 191 | if (ssp->irq < 0) { |
137 | dev_err(&pdev->dev, "no IRQ resource defined\n"); | 192 | dev_err(dev, "no IRQ resource defined\n"); |
138 | ret = -ENODEV; | 193 | return -ENODEV; |
139 | goto err_free_io; | 194 | } |
195 | |||
196 | if (dev->of_node) { | ||
197 | const struct of_device_id *id = | ||
198 | of_match_device(of_match_ptr(pxa_ssp_of_ids), dev); | ||
199 | ssp->type = (int) id->data; | ||
200 | } else { | ||
201 | const struct platform_device_id *id = | ||
202 | platform_get_device_id(pdev); | ||
203 | ssp->type = (int) id->driver_data; | ||
204 | |||
205 | /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id | ||
206 | * starts from 0, do a translation here | ||
207 | */ | ||
208 | ssp->port_id = pdev->id + 1; | ||
140 | } | 209 | } |
141 | 210 | ||
142 | /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id | ||
143 | * starts from 0, do a translation here | ||
144 | */ | ||
145 | ssp->port_id = pdev->id + 1; | ||
146 | ssp->use_count = 0; | 211 | ssp->use_count = 0; |
147 | ssp->type = (int)id->driver_data; | 212 | ssp->of_node = dev->of_node; |
148 | 213 | ||
149 | mutex_lock(&ssp_lock); | 214 | mutex_lock(&ssp_lock); |
150 | list_add(&ssp->node, &ssp_list); | 215 | list_add(&ssp->node, &ssp_list); |
151 | mutex_unlock(&ssp_lock); | 216 | mutex_unlock(&ssp_lock); |
152 | 217 | ||
153 | platform_set_drvdata(pdev, ssp); | 218 | platform_set_drvdata(pdev, ssp); |
154 | return 0; | ||
155 | 219 | ||
156 | err_free_io: | 220 | return 0; |
157 | iounmap(ssp->mmio_base); | ||
158 | err_free_mem: | ||
159 | release_mem_region(res->start, resource_size(res)); | ||
160 | err_free_clk: | ||
161 | clk_put(ssp->clk); | ||
162 | err_free: | ||
163 | kfree(ssp); | ||
164 | return ret; | ||
165 | } | 221 | } |
166 | 222 | ||
167 | static int pxa_ssp_remove(struct platform_device *pdev) | 223 | static int pxa_ssp_remove(struct platform_device *pdev) |
@@ -201,8 +257,9 @@ static struct platform_driver pxa_ssp_driver = { | |||
201 | .probe = pxa_ssp_probe, | 257 | .probe = pxa_ssp_probe, |
202 | .remove = pxa_ssp_remove, | 258 | .remove = pxa_ssp_remove, |
203 | .driver = { | 259 | .driver = { |
204 | .owner = THIS_MODULE, | 260 | .owner = THIS_MODULE, |
205 | .name = "pxa2xx-ssp", | 261 | .name = "pxa2xx-ssp", |
262 | .of_match_table = of_match_ptr(pxa_ssp_of_ids), | ||
206 | }, | 263 | }, |
207 | .id_table = ssp_id_table, | 264 | .id_table = ssp_id_table, |
208 | }; | 265 | }; |
diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c index 3e5c4619caa5..50a3ea0037db 100644 --- a/arch/arm/plat-samsung/init.c +++ b/arch/arm/plat-samsung/init.c | |||
@@ -55,12 +55,13 @@ void __init s3c_init_cpu(unsigned long idcode, | |||
55 | 55 | ||
56 | printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode); | 56 | printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode); |
57 | 57 | ||
58 | if (cpu->map_io == NULL || cpu->init == NULL) { | 58 | if (cpu->init == NULL) { |
59 | printk(KERN_ERR "CPU %s support not enabled\n", cpu->name); | 59 | printk(KERN_ERR "CPU %s support not enabled\n", cpu->name); |
60 | panic("Unsupported Samsung CPU"); | 60 | panic("Unsupported Samsung CPU"); |
61 | } | 61 | } |
62 | 62 | ||
63 | cpu->map_io(); | 63 | if (cpu->map_io) |
64 | cpu->map_io(); | ||
64 | } | 65 | } |
65 | 66 | ||
66 | /* s3c24xx_init_clocks | 67 | /* s3c24xx_init_clocks |
diff --git a/arch/arm/plat-samsung/s3c-dma-ops.c b/arch/arm/plat-samsung/s3c-dma-ops.c index 0cc40aea3f5a..98b10ba67dc7 100644 --- a/arch/arm/plat-samsung/s3c-dma-ops.c +++ b/arch/arm/plat-samsung/s3c-dma-ops.c | |||
@@ -82,7 +82,8 @@ static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param) | |||
82 | static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param) | 82 | static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param) |
83 | { | 83 | { |
84 | struct cb_data *data; | 84 | struct cb_data *data; |
85 | int len = (param->cap == DMA_CYCLIC) ? param->period : param->len; | 85 | dma_addr_t pos = param->buf; |
86 | dma_addr_t end = param->buf + param->len; | ||
86 | 87 | ||
87 | list_for_each_entry(data, &dma_list, node) | 88 | list_for_each_entry(data, &dma_list, node) |
88 | if (data->ch == ch) | 89 | if (data->ch == ch) |
@@ -94,7 +95,15 @@ static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param) | |||
94 | data->fp_param = param->fp_param; | 95 | data->fp_param = param->fp_param; |
95 | } | 96 | } |
96 | 97 | ||
97 | s3c2410_dma_enqueue(ch, (void *)data, param->buf, len); | 98 | if (param->cap != DMA_CYCLIC) { |
99 | s3c2410_dma_enqueue(ch, (void *)data, param->buf, param->len); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | while (pos < end) { | ||
104 | s3c2410_dma_enqueue(ch, (void *)data, pos, param->period); | ||
105 | pos += param->period; | ||
106 | } | ||
98 | 107 | ||
99 | return 0; | 108 | return 0; |
100 | } | 109 | } |
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 8d10dc8a1e17..3e5d3115a2a6 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
@@ -78,6 +78,11 @@ | |||
78 | ENTRY(vfp_support_entry) | 78 | ENTRY(vfp_support_entry) |
79 | DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 | 79 | DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 |
80 | 80 | ||
81 | ldr r3, [sp, #S_PSR] @ Neither lazy restore nor FP exceptions | ||
82 | and r3, r3, #MODE_MASK @ are supported in kernel mode | ||
83 | teq r3, #USR_MODE | ||
84 | bne vfp_kmode_exception @ Returns through lr | ||
85 | |||
81 | VFPFMRX r1, FPEXC @ Is the VFP enabled? | 86 | VFPFMRX r1, FPEXC @ Is the VFP enabled? |
82 | DBGSTR1 "fpexc %08x", r1 | 87 | DBGSTR1 "fpexc %08x", r1 |
83 | tst r1, #FPEXC_EN | 88 | tst r1, #FPEXC_EN |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 5dfbb0b8e7f4..52b8f40b1c73 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/user.h> | 22 | #include <linux/user.h> |
23 | #include <linux/export.h> | ||
23 | 24 | ||
24 | #include <asm/cp15.h> | 25 | #include <asm/cp15.h> |
25 | #include <asm/cputype.h> | 26 | #include <asm/cputype.h> |
@@ -648,6 +649,72 @@ static int vfp_hotplug(struct notifier_block *b, unsigned long action, | |||
648 | return NOTIFY_OK; | 649 | return NOTIFY_OK; |
649 | } | 650 | } |
650 | 651 | ||
652 | void vfp_kmode_exception(void) | ||
653 | { | ||
654 | /* | ||
655 | * If we reach this point, a floating point exception has been raised | ||
656 | * while running in kernel mode. If the NEON/VFP unit was enabled at the | ||
657 | * time, it means a VFP instruction has been issued that requires | ||
658 | * software assistance to complete, something which is not currently | ||
659 | * supported in kernel mode. | ||
660 | * If the NEON/VFP unit was disabled, and the location pointed to below | ||
661 | * is properly preceded by a call to kernel_neon_begin(), something has | ||
662 | * caused the task to be scheduled out and back in again. In this case, | ||
663 | * rebuilding and running with CONFIG_DEBUG_ATOMIC_SLEEP enabled should | ||
664 | * be helpful in localizing the problem. | ||
665 | */ | ||
666 | if (fmrx(FPEXC) & FPEXC_EN) | ||
667 | pr_crit("BUG: unsupported FP instruction in kernel mode\n"); | ||
668 | else | ||
669 | pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n"); | ||
670 | } | ||
671 | |||
672 | #ifdef CONFIG_KERNEL_MODE_NEON | ||
673 | |||
674 | /* | ||
675 | * Kernel-side NEON support functions | ||
676 | */ | ||
677 | void kernel_neon_begin(void) | ||
678 | { | ||
679 | struct thread_info *thread = current_thread_info(); | ||
680 | unsigned int cpu; | ||
681 | u32 fpexc; | ||
682 | |||
683 | /* | ||
684 | * Kernel mode NEON is only allowed outside of interrupt context | ||
685 | * with preemption disabled. This will make sure that the kernel | ||
686 | * mode NEON register contents never need to be preserved. | ||
687 | */ | ||
688 | BUG_ON(in_interrupt()); | ||
689 | cpu = get_cpu(); | ||
690 | |||
691 | fpexc = fmrx(FPEXC) | FPEXC_EN; | ||
692 | fmxr(FPEXC, fpexc); | ||
693 | |||
694 | /* | ||
695 | * Save the userland NEON/VFP state. Under UP, | ||
696 | * the owner could be a task other than 'current' | ||
697 | */ | ||
698 | if (vfp_state_in_hw(cpu, thread)) | ||
699 | vfp_save_state(&thread->vfpstate, fpexc); | ||
700 | #ifndef CONFIG_SMP | ||
701 | else if (vfp_current_hw_state[cpu] != NULL) | ||
702 | vfp_save_state(vfp_current_hw_state[cpu], fpexc); | ||
703 | #endif | ||
704 | vfp_current_hw_state[cpu] = NULL; | ||
705 | } | ||
706 | EXPORT_SYMBOL(kernel_neon_begin); | ||
707 | |||
708 | void kernel_neon_end(void) | ||
709 | { | ||
710 | /* Disable the NEON/VFP unit. */ | ||
711 | fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); | ||
712 | put_cpu(); | ||
713 | } | ||
714 | EXPORT_SYMBOL(kernel_neon_end); | ||
715 | |||
716 | #endif /* CONFIG_KERNEL_MODE_NEON */ | ||
717 | |||
651 | /* | 718 | /* |
652 | * VFP support code initialisation. | 719 | * VFP support code initialisation. |
653 | */ | 720 | */ |
@@ -731,4 +798,4 @@ static int __init vfp_init(void) | |||
731 | return 0; | 798 | return 0; |
732 | } | 799 | } |
733 | 800 | ||
734 | late_initcall(vfp_init); | 801 | core_initcall(vfp_init); |
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index c9770ba5c7df..8a6295c86209 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
@@ -170,6 +170,7 @@ static void __init xen_percpu_init(void *unused) | |||
170 | per_cpu(xen_vcpu, cpu) = vcpup; | 170 | per_cpu(xen_vcpu, cpu) = vcpup; |
171 | 171 | ||
172 | enable_percpu_irq(xen_events_irq, 0); | 172 | enable_percpu_irq(xen_events_irq, 0); |
173 | put_cpu(); | ||
173 | } | 174 | } |
174 | 175 | ||
175 | static void xen_restart(enum reboot_mode reboot_mode, const char *cmd) | 176 | static void xen_restart(enum reboot_mode reboot_mode, const char *cmd) |
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 98abd476992d..c9f1d2816c2b 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h | |||
@@ -26,7 +26,13 @@ | |||
26 | 26 | ||
27 | #include <clocksource/arm_arch_timer.h> | 27 | #include <clocksource/arm_arch_timer.h> |
28 | 28 | ||
29 | static inline void arch_timer_reg_write(int access, int reg, u32 val) | 29 | /* |
30 | * These register accessors are marked inline so the compiler can | ||
31 | * nicely work out which register we want, and chuck away the rest of | ||
32 | * the code. | ||
33 | */ | ||
34 | static __always_inline | ||
35 | void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) | ||
30 | { | 36 | { |
31 | if (access == ARCH_TIMER_PHYS_ACCESS) { | 37 | if (access == ARCH_TIMER_PHYS_ACCESS) { |
32 | switch (reg) { | 38 | switch (reg) { |
@@ -36,8 +42,6 @@ static inline void arch_timer_reg_write(int access, int reg, u32 val) | |||
36 | case ARCH_TIMER_REG_TVAL: | 42 | case ARCH_TIMER_REG_TVAL: |
37 | asm volatile("msr cntp_tval_el0, %0" : : "r" (val)); | 43 | asm volatile("msr cntp_tval_el0, %0" : : "r" (val)); |
38 | break; | 44 | break; |
39 | default: | ||
40 | BUILD_BUG(); | ||
41 | } | 45 | } |
42 | } else if (access == ARCH_TIMER_VIRT_ACCESS) { | 46 | } else if (access == ARCH_TIMER_VIRT_ACCESS) { |
43 | switch (reg) { | 47 | switch (reg) { |
@@ -47,17 +51,14 @@ static inline void arch_timer_reg_write(int access, int reg, u32 val) | |||
47 | case ARCH_TIMER_REG_TVAL: | 51 | case ARCH_TIMER_REG_TVAL: |
48 | asm volatile("msr cntv_tval_el0, %0" : : "r" (val)); | 52 | asm volatile("msr cntv_tval_el0, %0" : : "r" (val)); |
49 | break; | 53 | break; |
50 | default: | ||
51 | BUILD_BUG(); | ||
52 | } | 54 | } |
53 | } else { | ||
54 | BUILD_BUG(); | ||
55 | } | 55 | } |
56 | 56 | ||
57 | isb(); | 57 | isb(); |
58 | } | 58 | } |
59 | 59 | ||
60 | static inline u32 arch_timer_reg_read(int access, int reg) | 60 | static __always_inline |
61 | u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) | ||
61 | { | 62 | { |
62 | u32 val; | 63 | u32 val; |
63 | 64 | ||
@@ -69,8 +70,6 @@ static inline u32 arch_timer_reg_read(int access, int reg) | |||
69 | case ARCH_TIMER_REG_TVAL: | 70 | case ARCH_TIMER_REG_TVAL: |
70 | asm volatile("mrs %0, cntp_tval_el0" : "=r" (val)); | 71 | asm volatile("mrs %0, cntp_tval_el0" : "=r" (val)); |
71 | break; | 72 | break; |
72 | default: | ||
73 | BUILD_BUG(); | ||
74 | } | 73 | } |
75 | } else if (access == ARCH_TIMER_VIRT_ACCESS) { | 74 | } else if (access == ARCH_TIMER_VIRT_ACCESS) { |
76 | switch (reg) { | 75 | switch (reg) { |
@@ -80,11 +79,7 @@ static inline u32 arch_timer_reg_read(int access, int reg) | |||
80 | case ARCH_TIMER_REG_TVAL: | 79 | case ARCH_TIMER_REG_TVAL: |
81 | asm volatile("mrs %0, cntv_tval_el0" : "=r" (val)); | 80 | asm volatile("mrs %0, cntv_tval_el0" : "=r" (val)); |
82 | break; | 81 | break; |
83 | default: | ||
84 | BUILD_BUG(); | ||
85 | } | 82 | } |
86 | } else { | ||
87 | BUILD_BUG(); | ||
88 | } | 83 | } |
89 | 84 | ||
90 | return val; | 85 | return val; |
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index c92de4163eba..b25763bc0ec4 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h | |||
@@ -42,14 +42,15 @@ | |||
42 | #define TPIDR_EL1 18 /* Thread ID, Privileged */ | 42 | #define TPIDR_EL1 18 /* Thread ID, Privileged */ |
43 | #define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */ | 43 | #define AMAIR_EL1 19 /* Aux Memory Attribute Indirection Register */ |
44 | #define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */ | 44 | #define CNTKCTL_EL1 20 /* Timer Control Register (EL1) */ |
45 | #define PAR_EL1 21 /* Physical Address Register */ | ||
45 | /* 32bit specific registers. Keep them at the end of the range */ | 46 | /* 32bit specific registers. Keep them at the end of the range */ |
46 | #define DACR32_EL2 21 /* Domain Access Control Register */ | 47 | #define DACR32_EL2 22 /* Domain Access Control Register */ |
47 | #define IFSR32_EL2 22 /* Instruction Fault Status Register */ | 48 | #define IFSR32_EL2 23 /* Instruction Fault Status Register */ |
48 | #define FPEXC32_EL2 23 /* Floating-Point Exception Control Register */ | 49 | #define FPEXC32_EL2 24 /* Floating-Point Exception Control Register */ |
49 | #define DBGVCR32_EL2 24 /* Debug Vector Catch Register */ | 50 | #define DBGVCR32_EL2 25 /* Debug Vector Catch Register */ |
50 | #define TEECR32_EL1 25 /* ThumbEE Configuration Register */ | 51 | #define TEECR32_EL1 26 /* ThumbEE Configuration Register */ |
51 | #define TEEHBR32_EL1 26 /* ThumbEE Handler Base Register */ | 52 | #define TEEHBR32_EL1 27 /* ThumbEE Handler Base Register */ |
52 | #define NR_SYS_REGS 27 | 53 | #define NR_SYS_REGS 28 |
53 | 54 | ||
54 | /* 32bit mapping */ | 55 | /* 32bit mapping */ |
55 | #define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */ | 56 | #define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */ |
@@ -69,6 +70,8 @@ | |||
69 | #define c5_AIFSR (AFSR1_EL1 * 2) /* Auxiliary Instr Fault Status R */ | 70 | #define c5_AIFSR (AFSR1_EL1 * 2) /* Auxiliary Instr Fault Status R */ |
70 | #define c6_DFAR (FAR_EL1 * 2) /* Data Fault Address Register */ | 71 | #define c6_DFAR (FAR_EL1 * 2) /* Data Fault Address Register */ |
71 | #define c6_IFAR (c6_DFAR + 1) /* Instruction Fault Address Register */ | 72 | #define c6_IFAR (c6_DFAR + 1) /* Instruction Fault Address Register */ |
73 | #define c7_PAR (PAR_EL1 * 2) /* Physical Address Register */ | ||
74 | #define c7_PAR_high (c7_PAR + 1) /* PAR top 32 bits */ | ||
72 | #define c10_PRRR (MAIR_EL1 * 2) /* Primary Region Remap Register */ | 75 | #define c10_PRRR (MAIR_EL1 * 2) /* Primary Region Remap Register */ |
73 | #define c10_NMRR (c10_PRRR + 1) /* Normal Memory Remap Register */ | 76 | #define c10_NMRR (c10_PRRR + 1) /* Normal Memory Remap Register */ |
74 | #define c12_VBAR (VBAR_EL1 * 2) /* Vector Base Address Register */ | 77 | #define c12_VBAR (VBAR_EL1 * 2) /* Vector Base Address Register */ |
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 644d73956864..0859a4ddd1e7 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h | |||
@@ -129,7 +129,7 @@ struct kvm_vcpu_arch { | |||
129 | struct kvm_mmu_memory_cache mmu_page_cache; | 129 | struct kvm_mmu_memory_cache mmu_page_cache; |
130 | 130 | ||
131 | /* Target CPU and feature flags */ | 131 | /* Target CPU and feature flags */ |
132 | u32 target; | 132 | int target; |
133 | DECLARE_BITMAP(features, KVM_VCPU_MAX_FEATURES); | 133 | DECLARE_BITMAP(features, KVM_VCPU_MAX_FEATURES); |
134 | 134 | ||
135 | /* Detect first run of a vcpu */ | 135 | /* Detect first run of a vcpu */ |
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h index 46b3beb4b773..717031a762c2 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h | |||
@@ -35,6 +35,7 @@ struct mmu_gather { | |||
35 | struct mm_struct *mm; | 35 | struct mm_struct *mm; |
36 | unsigned int fullmm; | 36 | unsigned int fullmm; |
37 | struct vm_area_struct *vma; | 37 | struct vm_area_struct *vma; |
38 | unsigned long start, end; | ||
38 | unsigned long range_start; | 39 | unsigned long range_start; |
39 | unsigned long range_end; | 40 | unsigned long range_end; |
40 | unsigned int nr; | 41 | unsigned int nr; |
@@ -97,10 +98,12 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb) | |||
97 | } | 98 | } |
98 | 99 | ||
99 | static inline void | 100 | static inline void |
100 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm) | 101 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) |
101 | { | 102 | { |
102 | tlb->mm = mm; | 103 | tlb->mm = mm; |
103 | tlb->fullmm = fullmm; | 104 | tlb->fullmm = !(start | (end+1)); |
105 | tlb->start = start; | ||
106 | tlb->end = end; | ||
104 | tlb->vma = NULL; | 107 | tlb->vma = NULL; |
105 | tlb->max = ARRAY_SIZE(tlb->local); | 108 | tlb->max = ARRAY_SIZE(tlb->local); |
106 | tlb->pages = tlb->local; | 109 | tlb->pages = tlb->local; |
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 9ba33c40cdf8..12e6ccb88691 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c | |||
@@ -107,7 +107,12 @@ armpmu_map_cache_event(const unsigned (*cache_map) | |||
107 | static int | 107 | static int |
108 | armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) | 108 | armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) |
109 | { | 109 | { |
110 | int mapping = (*event_map)[config]; | 110 | int mapping; |
111 | |||
112 | if (config >= PERF_COUNT_HW_MAX) | ||
113 | return -EINVAL; | ||
114 | |||
115 | mapping = (*event_map)[config]; | ||
111 | return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; | 116 | return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; |
112 | } | 117 | } |
113 | 118 | ||
@@ -317,6 +322,9 @@ validate_event(struct pmu_hw_events *hw_events, | |||
317 | struct hw_perf_event fake_event = event->hw; | 322 | struct hw_perf_event fake_event = event->hw; |
318 | struct pmu *leader_pmu = event->group_leader->pmu; | 323 | struct pmu *leader_pmu = event->group_leader->pmu; |
319 | 324 | ||
325 | if (is_software_event(event)) | ||
326 | return 1; | ||
327 | |||
320 | if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF) | 328 | if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF) |
321 | return 1; | 329 | return 1; |
322 | 330 | ||
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index ff985e3d8b72..1ac0bbbdddb2 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S | |||
@@ -214,6 +214,7 @@ __kvm_hyp_code_start: | |||
214 | mrs x21, tpidr_el1 | 214 | mrs x21, tpidr_el1 |
215 | mrs x22, amair_el1 | 215 | mrs x22, amair_el1 |
216 | mrs x23, cntkctl_el1 | 216 | mrs x23, cntkctl_el1 |
217 | mrs x24, par_el1 | ||
217 | 218 | ||
218 | stp x4, x5, [x3] | 219 | stp x4, x5, [x3] |
219 | stp x6, x7, [x3, #16] | 220 | stp x6, x7, [x3, #16] |
@@ -225,6 +226,7 @@ __kvm_hyp_code_start: | |||
225 | stp x18, x19, [x3, #112] | 226 | stp x18, x19, [x3, #112] |
226 | stp x20, x21, [x3, #128] | 227 | stp x20, x21, [x3, #128] |
227 | stp x22, x23, [x3, #144] | 228 | stp x22, x23, [x3, #144] |
229 | str x24, [x3, #160] | ||
228 | .endm | 230 | .endm |
229 | 231 | ||
230 | .macro restore_sysregs | 232 | .macro restore_sysregs |
@@ -243,6 +245,7 @@ __kvm_hyp_code_start: | |||
243 | ldp x18, x19, [x3, #112] | 245 | ldp x18, x19, [x3, #112] |
244 | ldp x20, x21, [x3, #128] | 246 | ldp x20, x21, [x3, #128] |
245 | ldp x22, x23, [x3, #144] | 247 | ldp x22, x23, [x3, #144] |
248 | ldr x24, [x3, #160] | ||
246 | 249 | ||
247 | msr vmpidr_el2, x4 | 250 | msr vmpidr_el2, x4 |
248 | msr csselr_el1, x5 | 251 | msr csselr_el1, x5 |
@@ -264,6 +267,7 @@ __kvm_hyp_code_start: | |||
264 | msr tpidr_el1, x21 | 267 | msr tpidr_el1, x21 |
265 | msr amair_el1, x22 | 268 | msr amair_el1, x22 |
266 | msr cntkctl_el1, x23 | 269 | msr cntkctl_el1, x23 |
270 | msr par_el1, x24 | ||
267 | .endm | 271 | .endm |
268 | 272 | ||
269 | .macro skip_32bit_state tmp, target | 273 | .macro skip_32bit_state tmp, target |
@@ -600,6 +604,8 @@ END(__kvm_vcpu_run) | |||
600 | 604 | ||
601 | // void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); | 605 | // void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); |
602 | ENTRY(__kvm_tlb_flush_vmid_ipa) | 606 | ENTRY(__kvm_tlb_flush_vmid_ipa) |
607 | dsb ishst | ||
608 | |||
603 | kern_hyp_va x0 | 609 | kern_hyp_va x0 |
604 | ldr x2, [x0, #KVM_VTTBR] | 610 | ldr x2, [x0, #KVM_VTTBR] |
605 | msr vttbr_el2, x2 | 611 | msr vttbr_el2, x2 |
@@ -621,6 +627,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa) | |||
621 | ENDPROC(__kvm_tlb_flush_vmid_ipa) | 627 | ENDPROC(__kvm_tlb_flush_vmid_ipa) |
622 | 628 | ||
623 | ENTRY(__kvm_flush_vm_context) | 629 | ENTRY(__kvm_flush_vm_context) |
630 | dsb ishst | ||
624 | tlbi alle1is | 631 | tlbi alle1is |
625 | ic ialluis | 632 | ic ialluis |
626 | dsb sy | 633 | dsb sy |
@@ -753,6 +760,10 @@ el1_trap: | |||
753 | */ | 760 | */ |
754 | tbnz x1, #7, 1f // S1PTW is set | 761 | tbnz x1, #7, 1f // S1PTW is set |
755 | 762 | ||
763 | /* Preserve PAR_EL1 */ | ||
764 | mrs x3, par_el1 | ||
765 | push x3, xzr | ||
766 | |||
756 | /* | 767 | /* |
757 | * Permission fault, HPFAR_EL2 is invalid. | 768 | * Permission fault, HPFAR_EL2 is invalid. |
758 | * Resolve the IPA the hard way using the guest VA. | 769 | * Resolve the IPA the hard way using the guest VA. |
@@ -766,6 +777,8 @@ el1_trap: | |||
766 | 777 | ||
767 | /* Read result */ | 778 | /* Read result */ |
768 | mrs x3, par_el1 | 779 | mrs x3, par_el1 |
780 | pop x0, xzr // Restore PAR_EL1 from the stack | ||
781 | msr par_el1, x0 | ||
769 | tbnz x3, #0, 3f // Bail out if we failed the translation | 782 | tbnz x3, #0, 3f // Bail out if we failed the translation |
770 | ubfx x3, x3, #12, #36 // Extract IPA | 783 | ubfx x3, x3, #12, #36 // Extract IPA |
771 | lsl x3, x3, #4 // and present it like HPFAR | 784 | lsl x3, x3, #4 // and present it like HPFAR |
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 94923609753b..02e9d09e1d80 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c | |||
@@ -211,6 +211,9 @@ static const struct sys_reg_desc sys_reg_descs[] = { | |||
211 | /* FAR_EL1 */ | 211 | /* FAR_EL1 */ |
212 | { Op0(0b11), Op1(0b000), CRn(0b0110), CRm(0b0000), Op2(0b000), | 212 | { Op0(0b11), Op1(0b000), CRn(0b0110), CRm(0b0000), Op2(0b000), |
213 | NULL, reset_unknown, FAR_EL1 }, | 213 | NULL, reset_unknown, FAR_EL1 }, |
214 | /* PAR_EL1 */ | ||
215 | { Op0(0b11), Op1(0b000), CRn(0b0111), CRm(0b0100), Op2(0b000), | ||
216 | NULL, reset_unknown, PAR_EL1 }, | ||
214 | 217 | ||
215 | /* PMINTENSET_EL1 */ | 218 | /* PMINTENSET_EL1 */ |
216 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001), | 219 | { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001), |
diff --git a/arch/avr32/oprofile/op_model_avr32.c b/arch/avr32/oprofile/op_model_avr32.c index f74b7809e089..08308be2c02c 100644 --- a/arch/avr32/oprofile/op_model_avr32.c +++ b/arch/avr32/oprofile/op_model_avr32.c | |||
@@ -97,8 +97,7 @@ static irqreturn_t avr32_perf_counter_interrupt(int irq, void *dev_id) | |||
97 | return IRQ_HANDLED; | 97 | return IRQ_HANDLED; |
98 | } | 98 | } |
99 | 99 | ||
100 | static int avr32_perf_counter_create_files(struct super_block *sb, | 100 | static int avr32_perf_counter_create_files(struct dentry *root) |
101 | struct dentry *root) | ||
102 | { | 101 | { |
103 | struct dentry *dir; | 102 | struct dentry *dir; |
104 | unsigned int i; | 103 | unsigned int i; |
@@ -106,21 +105,21 @@ static int avr32_perf_counter_create_files(struct super_block *sb, | |||
106 | 105 | ||
107 | for (i = 0; i < NR_counter; i++) { | 106 | for (i = 0; i < NR_counter; i++) { |
108 | snprintf(filename, sizeof(filename), "%u", i); | 107 | snprintf(filename, sizeof(filename), "%u", i); |
109 | dir = oprofilefs_mkdir(sb, root, filename); | 108 | dir = oprofilefs_mkdir(root, filename); |
110 | 109 | ||
111 | oprofilefs_create_ulong(sb, dir, "enabled", | 110 | oprofilefs_create_ulong(dir, "enabled", |
112 | &counter[i].enabled); | 111 | &counter[i].enabled); |
113 | oprofilefs_create_ulong(sb, dir, "event", | 112 | oprofilefs_create_ulong(dir, "event", |
114 | &counter[i].event); | 113 | &counter[i].event); |
115 | oprofilefs_create_ulong(sb, dir, "count", | 114 | oprofilefs_create_ulong(dir, "count", |
116 | &counter[i].count); | 115 | &counter[i].count); |
117 | 116 | ||
118 | /* Dummy entries */ | 117 | /* Dummy entries */ |
119 | oprofilefs_create_ulong(sb, dir, "kernel", | 118 | oprofilefs_create_ulong(dir, "kernel", |
120 | &counter[i].kernel); | 119 | &counter[i].kernel); |
121 | oprofilefs_create_ulong(sb, dir, "user", | 120 | oprofilefs_create_ulong(dir, "user", |
122 | &counter[i].user); | 121 | &counter[i].user); |
123 | oprofilefs_create_ulong(sb, dir, "unit_mask", | 122 | oprofilefs_create_ulong(dir, "unit_mask", |
124 | &counter[i].unit_mask); | 123 | &counter[i].unit_mask); |
125 | } | 124 | } |
126 | 125 | ||
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index 0aa35f0eb0db..deb67843693c 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c | |||
@@ -320,7 +320,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | |||
320 | * are examined. | 320 | * are examined. |
321 | */ | 321 | */ |
322 | 322 | ||
323 | void __init pcibios_fixup_bus(struct pci_bus *bus) | 323 | void pcibios_fixup_bus(struct pci_bus *bus) |
324 | { | 324 | { |
325 | #if 0 | 325 | #if 0 |
326 | printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number); | 326 | printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number); |
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 33a97929d055..77d442ab28c8 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig | |||
@@ -158,6 +158,7 @@ source "kernel/Kconfig.hz" | |||
158 | endmenu | 158 | endmenu |
159 | 159 | ||
160 | source "init/Kconfig" | 160 | source "init/Kconfig" |
161 | source "kernel/Kconfig.freezer" | ||
161 | source "drivers/Kconfig" | 162 | source "drivers/Kconfig" |
162 | source "fs/Kconfig" | 163 | source "fs/Kconfig" |
163 | 164 | ||
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 5a768ad8e893..566642266324 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -43,6 +43,7 @@ config IA64 | |||
43 | select SYSCTL_ARCH_UNALIGN_NO_WARN | 43 | select SYSCTL_ARCH_UNALIGN_NO_WARN |
44 | select HAVE_MOD_ARCH_SPECIFIC | 44 | select HAVE_MOD_ARCH_SPECIFIC |
45 | select MODULES_USE_ELF_RELA | 45 | select MODULES_USE_ELF_RELA |
46 | select ARCH_USE_CMPXCHG_LOCKREF | ||
46 | default y | 47 | default y |
47 | help | 48 | help |
48 | The Itanium Processor Family is Intel's 64-bit successor to | 49 | The Itanium Processor Family is Intel's 64-bit successor to |
@@ -565,9 +566,9 @@ config KEXEC | |||
565 | 566 | ||
566 | It is an ongoing process to be certain the hardware in a machine | 567 | It is an ongoing process to be certain the hardware in a machine |
567 | is properly shutdown, so do not be surprised if this code does not | 568 | is properly shutdown, so do not be surprised if this code does not |
568 | initially work for you. It may help to enable device hotplugging | 569 | initially work for you. As of this writing the exact hardware |
569 | support. As of this writing the exact hardware interface is | 570 | interface is strongly in flux, so no good recommendation can be |
570 | strongly in flux, so no good recommendation can be made. | 571 | made. |
571 | 572 | ||
572 | config CRASH_DUMP | 573 | config CRASH_DUMP |
573 | bool "kernel crash dumps" | 574 | bool "kernel crash dumps" |
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index 05b03ecd7933..a3456f34f672 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild | |||
@@ -3,3 +3,4 @@ generic-y += clkdev.h | |||
3 | generic-y += exec.h | 3 | generic-y += exec.h |
4 | generic-y += kvm_para.h | 4 | generic-y += kvm_para.h |
5 | generic-y += trace_clock.h | 5 | generic-y += trace_clock.h |
6 | generic-y += vtime.h \ No newline at end of file | ||
diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h index 54ff557d474e..45698cd15b7b 100644 --- a/arch/ia64/include/asm/spinlock.h +++ b/arch/ia64/include/asm/spinlock.h | |||
@@ -102,6 +102,11 @@ static inline int __ticket_spin_is_contended(arch_spinlock_t *lock) | |||
102 | return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1; | 102 | return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1; |
103 | } | 103 | } |
104 | 104 | ||
105 | static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock) | ||
106 | { | ||
107 | return !(((lock.lock >> TICKET_SHIFT) ^ lock.lock) & TICKET_MASK); | ||
108 | } | ||
109 | |||
105 | static inline int arch_spin_is_locked(arch_spinlock_t *lock) | 110 | static inline int arch_spin_is_locked(arch_spinlock_t *lock) |
106 | { | 111 | { |
107 | return __ticket_spin_is_locked(lock); | 112 | return __ticket_spin_is_locked(lock); |
diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h index ef3a9de01954..bc5efc7c3f3f 100644 --- a/arch/ia64/include/asm/tlb.h +++ b/arch/ia64/include/asm/tlb.h | |||
@@ -22,7 +22,7 @@ | |||
22 | * unmapping a portion of the virtual address space, these hooks are called according to | 22 | * unmapping a portion of the virtual address space, these hooks are called according to |
23 | * the following template: | 23 | * the following template: |
24 | * | 24 | * |
25 | * tlb <- tlb_gather_mmu(mm, full_mm_flush); // start unmap for address space MM | 25 | * tlb <- tlb_gather_mmu(mm, start, end); // start unmap for address space MM |
26 | * { | 26 | * { |
27 | * for each vma that needs a shootdown do { | 27 | * for each vma that needs a shootdown do { |
28 | * tlb_start_vma(tlb, vma); | 28 | * tlb_start_vma(tlb, vma); |
@@ -58,6 +58,7 @@ struct mmu_gather { | |||
58 | unsigned int max; | 58 | unsigned int max; |
59 | unsigned char fullmm; /* non-zero means full mm flush */ | 59 | unsigned char fullmm; /* non-zero means full mm flush */ |
60 | unsigned char need_flush; /* really unmapped some PTEs? */ | 60 | unsigned char need_flush; /* really unmapped some PTEs? */ |
61 | unsigned long start, end; | ||
61 | unsigned long start_addr; | 62 | unsigned long start_addr; |
62 | unsigned long end_addr; | 63 | unsigned long end_addr; |
63 | struct page **pages; | 64 | struct page **pages; |
@@ -155,13 +156,15 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb) | |||
155 | 156 | ||
156 | 157 | ||
157 | static inline void | 158 | static inline void |
158 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush) | 159 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) |
159 | { | 160 | { |
160 | tlb->mm = mm; | 161 | tlb->mm = mm; |
161 | tlb->max = ARRAY_SIZE(tlb->local); | 162 | tlb->max = ARRAY_SIZE(tlb->local); |
162 | tlb->pages = tlb->local; | 163 | tlb->pages = tlb->local; |
163 | tlb->nr = 0; | 164 | tlb->nr = 0; |
164 | tlb->fullmm = full_mm_flush; | 165 | tlb->fullmm = !(start | (end+1)); |
166 | tlb->start = start; | ||
167 | tlb->end = end; | ||
165 | tlb->start_addr = ~0UL; | 168 | tlb->start_addr = ~0UL; |
166 | } | 169 | } |
167 | 170 | ||
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 5b2dc0d10c8f..bdfd8789b376 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -1560,6 +1560,10 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | |||
1560 | return 0; | 1560 | return 0; |
1561 | } | 1561 | } |
1562 | 1562 | ||
1563 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
1564 | { | ||
1565 | } | ||
1566 | |||
1563 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 1567 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
1564 | struct kvm_memory_slot *memslot, | 1568 | struct kvm_memory_slot *memslot, |
1565 | struct kvm_userspace_memory_region *mem, | 1569 | struct kvm_userspace_memory_region *mem, |
diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 6083088c0cca..dacd9f911f71 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c | |||
@@ -56,7 +56,7 @@ static int __init amiga_init_bus(void) | |||
56 | n = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2; | 56 | n = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2; |
57 | pdev = platform_device_register_simple("amiga-zorro", -1, | 57 | pdev = platform_device_register_simple("amiga-zorro", -1, |
58 | zorro_resources, n); | 58 | zorro_resources, n); |
59 | return PTR_RET(pdev); | 59 | return PTR_ERR_OR_ZERO(pdev); |
60 | } | 60 | } |
61 | 61 | ||
62 | subsys_initcall(amiga_init_bus); | 62 | subsys_initcall(amiga_init_bus); |
diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c index 2291a7d69d49..121a6660ad4e 100644 --- a/arch/m68k/emu/natfeat.c +++ b/arch/m68k/emu/natfeat.c | |||
@@ -18,9 +18,11 @@ | |||
18 | #include <asm/machdep.h> | 18 | #include <asm/machdep.h> |
19 | #include <asm/natfeat.h> | 19 | #include <asm/natfeat.h> |
20 | 20 | ||
21 | extern long nf_get_id_phys(unsigned long feature_name); | ||
22 | |||
21 | asm("\n" | 23 | asm("\n" |
22 | " .global nf_get_id,nf_call\n" | 24 | " .global nf_get_id_phys,nf_call\n" |
23 | "nf_get_id:\n" | 25 | "nf_get_id_phys:\n" |
24 | " .short 0x7300\n" | 26 | " .short 0x7300\n" |
25 | " rts\n" | 27 | " rts\n" |
26 | "nf_call:\n" | 28 | "nf_call:\n" |
@@ -29,12 +31,25 @@ asm("\n" | |||
29 | "1: moveq.l #0,%d0\n" | 31 | "1: moveq.l #0,%d0\n" |
30 | " rts\n" | 32 | " rts\n" |
31 | " .section __ex_table,\"a\"\n" | 33 | " .section __ex_table,\"a\"\n" |
32 | " .long nf_get_id,1b\n" | 34 | " .long nf_get_id_phys,1b\n" |
33 | " .long nf_call,1b\n" | 35 | " .long nf_call,1b\n" |
34 | " .previous"); | 36 | " .previous"); |
35 | EXPORT_SYMBOL_GPL(nf_get_id); | ||
36 | EXPORT_SYMBOL_GPL(nf_call); | 37 | EXPORT_SYMBOL_GPL(nf_call); |
37 | 38 | ||
39 | long nf_get_id(const char *feature_name) | ||
40 | { | ||
41 | /* feature_name may be in vmalloc()ed memory, so make a copy */ | ||
42 | char name_copy[32]; | ||
43 | size_t n; | ||
44 | |||
45 | n = strlcpy(name_copy, feature_name, sizeof(name_copy)); | ||
46 | if (n >= sizeof(name_copy)) | ||
47 | return 0; | ||
48 | |||
49 | return nf_get_id_phys(virt_to_phys(name_copy)); | ||
50 | } | ||
51 | EXPORT_SYMBOL_GPL(nf_get_id); | ||
52 | |||
38 | void nfprint(const char *fmt, ...) | 53 | void nfprint(const char *fmt, ...) |
39 | { | 54 | { |
40 | static char buf[256]; | 55 | static char buf[256]; |
@@ -43,7 +58,7 @@ void nfprint(const char *fmt, ...) | |||
43 | 58 | ||
44 | va_start(ap, fmt); | 59 | va_start(ap, fmt); |
45 | n = vsnprintf(buf, 256, fmt, ap); | 60 | n = vsnprintf(buf, 256, fmt, ap); |
46 | nf_call(nf_get_id("NF_STDERR"), buf); | 61 | nf_call(nf_get_id("NF_STDERR"), virt_to_phys(buf)); |
47 | va_end(ap); | 62 | va_end(ap); |
48 | } | 63 | } |
49 | 64 | ||
@@ -68,7 +83,7 @@ void nf_init(void) | |||
68 | id = nf_get_id("NF_NAME"); | 83 | id = nf_get_id("NF_NAME"); |
69 | if (!id) | 84 | if (!id) |
70 | return; | 85 | return; |
71 | nf_call(id, buf, 256); | 86 | nf_call(id, virt_to_phys(buf), 256); |
72 | buf[255] = 0; | 87 | buf[255] = 0; |
73 | 88 | ||
74 | pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16, | 89 | pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16, |
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c index e3011338ab40..0721858fbd1e 100644 --- a/arch/m68k/emu/nfblock.c +++ b/arch/m68k/emu/nfblock.c | |||
@@ -41,8 +41,8 @@ static inline s32 nfhd_read_write(u32 major, u32 minor, u32 rwflag, u32 recno, | |||
41 | static inline s32 nfhd_get_capacity(u32 major, u32 minor, u32 *blocks, | 41 | static inline s32 nfhd_get_capacity(u32 major, u32 minor, u32 *blocks, |
42 | u32 *blocksize) | 42 | u32 *blocksize) |
43 | { | 43 | { |
44 | return nf_call(nfhd_id + NFHD_GET_CAPACITY, major, minor, blocks, | 44 | return nf_call(nfhd_id + NFHD_GET_CAPACITY, major, minor, |
45 | blocksize); | 45 | virt_to_phys(blocks), virt_to_phys(blocksize)); |
46 | } | 46 | } |
47 | 47 | ||
48 | static LIST_HEAD(nfhd_list); | 48 | static LIST_HEAD(nfhd_list); |
diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index 6685bf45c2c3..57e8c8fb5eba 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
18 | #include <linux/io.h> | ||
18 | 19 | ||
19 | #include <asm/natfeat.h> | 20 | #include <asm/natfeat.h> |
20 | 21 | ||
@@ -25,17 +26,18 @@ static struct tty_driver *nfcon_tty_driver; | |||
25 | static void nfputs(const char *str, unsigned int count) | 26 | static void nfputs(const char *str, unsigned int count) |
26 | { | 27 | { |
27 | char buf[68]; | 28 | char buf[68]; |
29 | unsigned long phys = virt_to_phys(buf); | ||
28 | 30 | ||
29 | buf[64] = 0; | 31 | buf[64] = 0; |
30 | while (count > 64) { | 32 | while (count > 64) { |
31 | memcpy(buf, str, 64); | 33 | memcpy(buf, str, 64); |
32 | nf_call(stderr_id, buf); | 34 | nf_call(stderr_id, phys); |
33 | str += 64; | 35 | str += 64; |
34 | count -= 64; | 36 | count -= 64; |
35 | } | 37 | } |
36 | memcpy(buf, str, count); | 38 | memcpy(buf, str, count); |
37 | buf[count] = 0; | 39 | buf[count] = 0; |
38 | nf_call(stderr_id, buf); | 40 | nf_call(stderr_id, phys); |
39 | } | 41 | } |
40 | 42 | ||
41 | static void nfcon_write(struct console *con, const char *str, | 43 | static void nfcon_write(struct console *con, const char *str, |
@@ -79,7 +81,7 @@ static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch) | |||
79 | { | 81 | { |
80 | char temp[2] = { ch, 0 }; | 82 | char temp[2] = { ch, 0 }; |
81 | 83 | ||
82 | nf_call(stderr_id, temp); | 84 | nf_call(stderr_id, virt_to_phys(temp)); |
83 | return 1; | 85 | return 1; |
84 | } | 86 | } |
85 | 87 | ||
diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c index 695cd737a42e..a0985fd088d1 100644 --- a/arch/m68k/emu/nfeth.c +++ b/arch/m68k/emu/nfeth.c | |||
@@ -195,7 +195,8 @@ static struct net_device * __init nfeth_probe(int unit) | |||
195 | char mac[ETH_ALEN], host_ip[32], local_ip[32]; | 195 | char mac[ETH_ALEN], host_ip[32], local_ip[32]; |
196 | int err; | 196 | int err; |
197 | 197 | ||
198 | if (!nf_call(nfEtherID + XIF_GET_MAC, unit, mac, ETH_ALEN)) | 198 | if (!nf_call(nfEtherID + XIF_GET_MAC, unit, virt_to_phys(mac), |
199 | ETH_ALEN)) | ||
199 | return NULL; | 200 | return NULL; |
200 | 201 | ||
201 | dev = alloc_etherdev(sizeof(struct nfeth_private)); | 202 | dev = alloc_etherdev(sizeof(struct nfeth_private)); |
@@ -217,9 +218,9 @@ static struct net_device * __init nfeth_probe(int unit) | |||
217 | } | 218 | } |
218 | 219 | ||
219 | nf_call(nfEtherID + XIF_GET_IPHOST, unit, | 220 | nf_call(nfEtherID + XIF_GET_IPHOST, unit, |
220 | host_ip, sizeof(host_ip)); | 221 | virt_to_phys(host_ip), sizeof(host_ip)); |
221 | nf_call(nfEtherID + XIF_GET_IPATARI, unit, | 222 | nf_call(nfEtherID + XIF_GET_IPATARI, unit, |
222 | local_ip, sizeof(local_ip)); | 223 | virt_to_phys(local_ip), sizeof(local_ip)); |
223 | 224 | ||
224 | netdev_info(dev, KBUILD_MODNAME " addr:%s (%s) HWaddr:%pM\n", host_ip, | 225 | netdev_info(dev, KBUILD_MODNAME " addr:%s (%s) HWaddr:%pM\n", host_ip, |
225 | local_ip, mac); | 226 | local_ip, mac); |
diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h index 444ea8a09e9f..ef881cfbbca9 100644 --- a/arch/m68k/include/asm/div64.h +++ b/arch/m68k/include/asm/div64.h | |||
@@ -15,16 +15,17 @@ | |||
15 | unsigned long long n64; \ | 15 | unsigned long long n64; \ |
16 | } __n; \ | 16 | } __n; \ |
17 | unsigned long __rem, __upper; \ | 17 | unsigned long __rem, __upper; \ |
18 | unsigned long __base = (base); \ | ||
18 | \ | 19 | \ |
19 | __n.n64 = (n); \ | 20 | __n.n64 = (n); \ |
20 | if ((__upper = __n.n32[0])) { \ | 21 | if ((__upper = __n.n32[0])) { \ |
21 | asm ("divul.l %2,%1:%0" \ | 22 | asm ("divul.l %2,%1:%0" \ |
22 | : "=d" (__n.n32[0]), "=d" (__upper) \ | 23 | : "=d" (__n.n32[0]), "=d" (__upper) \ |
23 | : "d" (base), "0" (__n.n32[0])); \ | 24 | : "d" (__base), "0" (__n.n32[0])); \ |
24 | } \ | 25 | } \ |
25 | asm ("divu.l %2,%1:%0" \ | 26 | asm ("divu.l %2,%1:%0" \ |
26 | : "=d" (__n.n32[1]), "=d" (__rem) \ | 27 | : "=d" (__n.n32[1]), "=d" (__rem) \ |
27 | : "d" (base), "1" (__upper), "0" (__n.n32[1])); \ | 28 | : "d" (__base), "1" (__upper), "0" (__n.n32[1])); \ |
28 | (n) = __n.n64; \ | 29 | (n) = __n.n64; \ |
29 | __rem; \ | 30 | __rem; \ |
30 | }) | 31 | }) |
diff --git a/arch/m68k/include/asm/irqflags.h b/arch/m68k/include/asm/irqflags.h index 7ef4115b8c4a..a823cd73dc09 100644 --- a/arch/m68k/include/asm/irqflags.h +++ b/arch/m68k/include/asm/irqflags.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #ifdef CONFIG_MMU | 5 | #ifdef CONFIG_MMU |
6 | #include <linux/hardirq.h> | 6 | #include <linux/preempt_mask.h> |
7 | #endif | 7 | #endif |
8 | #include <linux/preempt.h> | 8 | #include <linux/preempt.h> |
9 | #include <asm/thread_info.h> | 9 | #include <asm/thread_info.h> |
@@ -67,6 +67,10 @@ static inline void arch_local_irq_restore(unsigned long flags) | |||
67 | 67 | ||
68 | static inline bool arch_irqs_disabled_flags(unsigned long flags) | 68 | static inline bool arch_irqs_disabled_flags(unsigned long flags) |
69 | { | 69 | { |
70 | if (MACH_IS_ATARI) { | ||
71 | /* Ignore HSYNC = ipl 2 on Atari */ | ||
72 | return (flags & ~(ALLOWINT | 0x200)) != 0; | ||
73 | } | ||
70 | return (flags & ~ALLOWINT) != 0; | 74 | return (flags & ~ALLOWINT) != 0; |
71 | } | 75 | } |
72 | 76 | ||
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index bea6bcf8f9b8..7eb9792009f8 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c | |||
@@ -90,7 +90,7 @@ static int __init rtc_init(void) | |||
90 | return -ENODEV; | 90 | return -ENODEV; |
91 | 91 | ||
92 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | 92 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); |
93 | return PTR_RET(pdev); | 93 | return PTR_ERR_OR_ZERO(pdev); |
94 | } | 94 | } |
95 | 95 | ||
96 | module_init(rtc_init); | 96 | module_init(rtc_init); |
diff --git a/arch/m68k/platform/coldfire/pci.c b/arch/m68k/platform/coldfire/pci.c index b33f97a13e6d..df9679238b6d 100644 --- a/arch/m68k/platform/coldfire/pci.c +++ b/arch/m68k/platform/coldfire/pci.c | |||
@@ -319,7 +319,6 @@ static int __init mcf_pci_init(void) | |||
319 | pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq); | 319 | pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq); |
320 | pci_bus_size_bridges(rootbus); | 320 | pci_bus_size_bridges(rootbus); |
321 | pci_bus_assign_resources(rootbus); | 321 | pci_bus_assign_resources(rootbus); |
322 | pci_enable_bridges(rootbus); | ||
323 | return 0; | 322 | return 0; |
324 | } | 323 | } |
325 | 324 | ||
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 658542b914fc..078bb744b5fe 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c | |||
@@ -338,6 +338,6 @@ static __init int q40_add_kbd_device(void) | |||
338 | return -ENODEV; | 338 | return -ENODEV; |
339 | 339 | ||
340 | pdev = platform_device_register_simple("q40kbd", -1, NULL, 0); | 340 | pdev = platform_device_register_simple("q40kbd", -1, NULL, 0); |
341 | return PTR_RET(pdev); | 341 | return PTR_ERR_OR_ZERO(pdev); |
342 | } | 342 | } |
343 | arch_initcall(q40_add_kbd_device); | 343 | arch_initcall(q40_add_kbd_device); |
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index d22a4ecffff4..4fab52294d98 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig | |||
@@ -28,7 +28,7 @@ config MICROBLAZE | |||
28 | select GENERIC_CLOCKEVENTS | 28 | select GENERIC_CLOCKEVENTS |
29 | select GENERIC_IDLE_POLL_SETUP | 29 | select GENERIC_IDLE_POLL_SETUP |
30 | select MODULES_USE_ELF_RELA | 30 | select MODULES_USE_ELF_RELA |
31 | select CLONE_BACKWARDS | 31 | select CLONE_BACKWARDS3 |
32 | 32 | ||
33 | config SWAP | 33 | config SWAP |
34 | def_bool n | 34 | def_bool n |
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 20c5e8e5121b..9977816c5ad3 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h | |||
@@ -50,9 +50,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | |||
50 | 50 | ||
51 | extern void kdump_move_device_tree(void); | 51 | extern void kdump_move_device_tree(void); |
52 | 52 | ||
53 | /* CPU OF node matching */ | ||
54 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); | ||
55 | |||
56 | #endif /* __ASSEMBLY__ */ | 53 | #endif /* __ASSEMBLY__ */ |
57 | #endif /* __KERNEL__ */ | 54 | #endif /* __KERNEL__ */ |
58 | 55 | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e12764c2a9d0..dccd7cec442d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -2305,9 +2305,9 @@ config KEXEC | |||
2305 | 2305 | ||
2306 | It is an ongoing process to be certain the hardware in a machine | 2306 | It is an ongoing process to be certain the hardware in a machine |
2307 | is properly shutdown, so do not be surprised if this code does not | 2307 | is properly shutdown, so do not be surprised if this code does not |
2308 | initially work for you. It may help to enable device hotplugging | 2308 | initially work for you. As of this writing the exact hardware |
2309 | support. As of this writing the exact hardware interface is | 2309 | interface is strongly in flux, so no good recommendation can be |
2310 | strongly in flux, so no good recommendation can be made. | 2310 | made. |
2311 | 2311 | ||
2312 | config CRASH_DUMP | 2312 | config CRASH_DUMP |
2313 | bool "Kernel crash dumps" | 2313 | bool "Kernel crash dumps" |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 1765bab000a0..faf84c5f2629 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -1335,8 +1335,9 @@ static ssize_t store_kill(struct device *dev, struct device_attribute *attr, | |||
1335 | 1335 | ||
1336 | return len; | 1336 | return len; |
1337 | } | 1337 | } |
1338 | static DEVICE_ATTR(kill, S_IWUSR, NULL, store_kill); | ||
1338 | 1339 | ||
1339 | static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr, | 1340 | static ssize_t ntcs_show(struct device *cd, struct device_attribute *attr, |
1340 | char *buf) | 1341 | char *buf) |
1341 | { | 1342 | { |
1342 | struct vpe *vpe = get_vpe(tclimit); | 1343 | struct vpe *vpe = get_vpe(tclimit); |
@@ -1344,7 +1345,7 @@ static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr, | |||
1344 | return sprintf(buf, "%d\n", vpe->ntcs); | 1345 | return sprintf(buf, "%d\n", vpe->ntcs); |
1345 | } | 1346 | } |
1346 | 1347 | ||
1347 | static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, | 1348 | static ssize_t ntcs_store(struct device *dev, struct device_attribute *attr, |
1348 | const char *buf, size_t len) | 1349 | const char *buf, size_t len) |
1349 | { | 1350 | { |
1350 | struct vpe *vpe = get_vpe(tclimit); | 1351 | struct vpe *vpe = get_vpe(tclimit); |
@@ -1365,12 +1366,14 @@ static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, | |||
1365 | out_einval: | 1366 | out_einval: |
1366 | return -EINVAL; | 1367 | return -EINVAL; |
1367 | } | 1368 | } |
1369 | static DEVICE_ATTR_RW(ntcs); | ||
1368 | 1370 | ||
1369 | static struct device_attribute vpe_class_attributes[] = { | 1371 | static struct attribute vpe_attrs[] = { |
1370 | __ATTR(kill, S_IWUSR, NULL, store_kill), | 1372 | &dev_attr_kill.attr, |
1371 | __ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs), | 1373 | &dev_attr_ntcs.attr, |
1372 | {} | 1374 | NULL, |
1373 | }; | 1375 | }; |
1376 | ATTRIBUTE_GROUPS(vpe); | ||
1374 | 1377 | ||
1375 | static void vpe_device_release(struct device *cd) | 1378 | static void vpe_device_release(struct device *cd) |
1376 | { | 1379 | { |
@@ -1381,7 +1384,7 @@ struct class vpe_class = { | |||
1381 | .name = "vpe", | 1384 | .name = "vpe", |
1382 | .owner = THIS_MODULE, | 1385 | .owner = THIS_MODULE, |
1383 | .dev_release = vpe_device_release, | 1386 | .dev_release = vpe_device_release, |
1384 | .dev_attrs = vpe_class_attributes, | 1387 | .dev_groups = vpe_groups, |
1385 | }; | 1388 | }; |
1386 | 1389 | ||
1387 | struct device vpe_device; | 1390 | struct device vpe_device; |
diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S index dca2aa665993..bbace092ad0a 100644 --- a/arch/mips/kvm/kvm_locore.S +++ b/arch/mips/kvm/kvm_locore.S | |||
@@ -1,13 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * This file is subject to the terms and conditions of the GNU General Public | 2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Main entry point for the guest, exception handling. | 6 | * Main entry point for the guest, exception handling. |
7 | * | 7 | * |
8 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | 8 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. |
9 | * Authors: Sanjay Lal <sanjayl@kymasys.com> | 9 | * Authors: Sanjay Lal <sanjayl@kymasys.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <asm/asm.h> | 12 | #include <asm/asm.h> |
13 | #include <asm/asmmacro.h> | 13 | #include <asm/asmmacro.h> |
@@ -55,195 +55,193 @@ | |||
55 | * a0: run | 55 | * a0: run |
56 | * a1: vcpu | 56 | * a1: vcpu |
57 | */ | 57 | */ |
58 | .set noreorder | ||
59 | .set noat | ||
58 | 60 | ||
59 | FEXPORT(__kvm_mips_vcpu_run) | 61 | FEXPORT(__kvm_mips_vcpu_run) |
60 | .set push | 62 | /* k0/k1 not being used in host kernel context */ |
61 | .set noreorder | 63 | INT_ADDIU k1, sp, -PT_SIZE |
62 | .set noat | 64 | LONG_S $0, PT_R0(k1) |
63 | 65 | LONG_S $1, PT_R1(k1) | |
64 | /* k0/k1 not being used in host kernel context */ | 66 | LONG_S $2, PT_R2(k1) |
65 | addiu k1,sp, -PT_SIZE | 67 | LONG_S $3, PT_R3(k1) |
66 | LONG_S $0, PT_R0(k1) | 68 | |
67 | LONG_S $1, PT_R1(k1) | 69 | LONG_S $4, PT_R4(k1) |
68 | LONG_S $2, PT_R2(k1) | 70 | LONG_S $5, PT_R5(k1) |
69 | LONG_S $3, PT_R3(k1) | 71 | LONG_S $6, PT_R6(k1) |
70 | 72 | LONG_S $7, PT_R7(k1) | |
71 | LONG_S $4, PT_R4(k1) | 73 | |
72 | LONG_S $5, PT_R5(k1) | 74 | LONG_S $8, PT_R8(k1) |
73 | LONG_S $6, PT_R6(k1) | 75 | LONG_S $9, PT_R9(k1) |
74 | LONG_S $7, PT_R7(k1) | 76 | LONG_S $10, PT_R10(k1) |
75 | 77 | LONG_S $11, PT_R11(k1) | |
76 | LONG_S $8, PT_R8(k1) | 78 | LONG_S $12, PT_R12(k1) |
77 | LONG_S $9, PT_R9(k1) | 79 | LONG_S $13, PT_R13(k1) |
78 | LONG_S $10, PT_R10(k1) | 80 | LONG_S $14, PT_R14(k1) |
79 | LONG_S $11, PT_R11(k1) | 81 | LONG_S $15, PT_R15(k1) |
80 | LONG_S $12, PT_R12(k1) | 82 | LONG_S $16, PT_R16(k1) |
81 | LONG_S $13, PT_R13(k1) | 83 | LONG_S $17, PT_R17(k1) |
82 | LONG_S $14, PT_R14(k1) | 84 | |
83 | LONG_S $15, PT_R15(k1) | 85 | LONG_S $18, PT_R18(k1) |
84 | LONG_S $16, PT_R16(k1) | 86 | LONG_S $19, PT_R19(k1) |
85 | LONG_S $17, PT_R17(k1) | 87 | LONG_S $20, PT_R20(k1) |
86 | 88 | LONG_S $21, PT_R21(k1) | |
87 | LONG_S $18, PT_R18(k1) | 89 | LONG_S $22, PT_R22(k1) |
88 | LONG_S $19, PT_R19(k1) | 90 | LONG_S $23, PT_R23(k1) |
89 | LONG_S $20, PT_R20(k1) | 91 | LONG_S $24, PT_R24(k1) |
90 | LONG_S $21, PT_R21(k1) | 92 | LONG_S $25, PT_R25(k1) |
91 | LONG_S $22, PT_R22(k1) | ||
92 | LONG_S $23, PT_R23(k1) | ||
93 | LONG_S $24, PT_R24(k1) | ||
94 | LONG_S $25, PT_R25(k1) | ||
95 | 93 | ||
96 | /* XXXKYMA k0/k1 not saved, not being used if we got here through an ioctl() */ | 94 | /* XXXKYMA k0/k1 not saved, not being used if we got here through an ioctl() */ |
97 | 95 | ||
98 | LONG_S $28, PT_R28(k1) | 96 | LONG_S $28, PT_R28(k1) |
99 | LONG_S $29, PT_R29(k1) | 97 | LONG_S $29, PT_R29(k1) |
100 | LONG_S $30, PT_R30(k1) | 98 | LONG_S $30, PT_R30(k1) |
101 | LONG_S $31, PT_R31(k1) | 99 | LONG_S $31, PT_R31(k1) |
102 | 100 | ||
103 | /* Save hi/lo */ | 101 | /* Save hi/lo */ |
104 | mflo v0 | 102 | mflo v0 |
105 | LONG_S v0, PT_LO(k1) | 103 | LONG_S v0, PT_LO(k1) |
106 | mfhi v1 | 104 | mfhi v1 |
107 | LONG_S v1, PT_HI(k1) | 105 | LONG_S v1, PT_HI(k1) |
108 | 106 | ||
109 | /* Save host status */ | 107 | /* Save host status */ |
110 | mfc0 v0, CP0_STATUS | 108 | mfc0 v0, CP0_STATUS |
111 | LONG_S v0, PT_STATUS(k1) | 109 | LONG_S v0, PT_STATUS(k1) |
112 | 110 | ||
113 | /* Save host ASID, shove it into the BVADDR location */ | 111 | /* Save host ASID, shove it into the BVADDR location */ |
114 | mfc0 v1,CP0_ENTRYHI | 112 | mfc0 v1, CP0_ENTRYHI |
115 | andi v1, 0xff | 113 | andi v1, 0xff |
116 | LONG_S v1, PT_HOST_ASID(k1) | 114 | LONG_S v1, PT_HOST_ASID(k1) |
117 | 115 | ||
118 | /* Save DDATA_LO, will be used to store pointer to vcpu */ | 116 | /* Save DDATA_LO, will be used to store pointer to vcpu */ |
119 | mfc0 v1, CP0_DDATA_LO | 117 | mfc0 v1, CP0_DDATA_LO |
120 | LONG_S v1, PT_HOST_USERLOCAL(k1) | 118 | LONG_S v1, PT_HOST_USERLOCAL(k1) |
121 | 119 | ||
122 | /* DDATA_LO has pointer to vcpu */ | 120 | /* DDATA_LO has pointer to vcpu */ |
123 | mtc0 a1,CP0_DDATA_LO | 121 | mtc0 a1, CP0_DDATA_LO |
124 | 122 | ||
125 | /* Offset into vcpu->arch */ | 123 | /* Offset into vcpu->arch */ |
126 | addiu k1, a1, VCPU_HOST_ARCH | 124 | INT_ADDIU k1, a1, VCPU_HOST_ARCH |
127 | 125 | ||
128 | /* Save the host stack to VCPU, used for exception processing when we exit from the Guest */ | 126 | /* |
129 | LONG_S sp, VCPU_HOST_STACK(k1) | 127 | * Save the host stack to VCPU, used for exception processing |
128 | * when we exit from the Guest | ||
129 | */ | ||
130 | LONG_S sp, VCPU_HOST_STACK(k1) | ||
130 | 131 | ||
131 | /* Save the kernel gp as well */ | 132 | /* Save the kernel gp as well */ |
132 | LONG_S gp, VCPU_HOST_GP(k1) | 133 | LONG_S gp, VCPU_HOST_GP(k1) |
133 | 134 | ||
134 | /* Setup status register for running the guest in UM, interrupts are disabled */ | 135 | /* Setup status register for running the guest in UM, interrupts are disabled */ |
135 | li k0,(ST0_EXL | KSU_USER| ST0_BEV) | 136 | li k0, (ST0_EXL | KSU_USER | ST0_BEV) |
136 | mtc0 k0,CP0_STATUS | 137 | mtc0 k0, CP0_STATUS |
137 | ehb | 138 | ehb |
138 | 139 | ||
139 | /* load up the new EBASE */ | 140 | /* load up the new EBASE */ |
140 | LONG_L k0, VCPU_GUEST_EBASE(k1) | 141 | LONG_L k0, VCPU_GUEST_EBASE(k1) |
141 | mtc0 k0,CP0_EBASE | 142 | mtc0 k0, CP0_EBASE |
142 | 143 | ||
143 | /* Now that the new EBASE has been loaded, unset BEV, set interrupt mask as it was | 144 | /* |
144 | * but make sure that timer interrupts are enabled | 145 | * Now that the new EBASE has been loaded, unset BEV, set |
145 | */ | 146 | * interrupt mask as it was but make sure that timer interrupts |
146 | li k0,(ST0_EXL | KSU_USER | ST0_IE) | 147 | * are enabled |
147 | andi v0, v0, ST0_IM | 148 | */ |
148 | or k0, k0, v0 | 149 | li k0, (ST0_EXL | KSU_USER | ST0_IE) |
149 | mtc0 k0,CP0_STATUS | 150 | andi v0, v0, ST0_IM |
150 | ehb | 151 | or k0, k0, v0 |
152 | mtc0 k0, CP0_STATUS | ||
153 | ehb | ||
151 | 154 | ||
152 | 155 | ||
153 | /* Set Guest EPC */ | 156 | /* Set Guest EPC */ |
154 | LONG_L t0, VCPU_PC(k1) | 157 | LONG_L t0, VCPU_PC(k1) |
155 | mtc0 t0, CP0_EPC | 158 | mtc0 t0, CP0_EPC |
156 | 159 | ||
157 | FEXPORT(__kvm_mips_load_asid) | 160 | FEXPORT(__kvm_mips_load_asid) |
158 | /* Set the ASID for the Guest Kernel */ | 161 | /* Set the ASID for the Guest Kernel */ |
159 | sll t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ | 162 | INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ |
160 | /* addresses shift to 0x80000000 */ | 163 | /* addresses shift to 0x80000000 */ |
161 | bltz t0, 1f /* If kernel */ | 164 | bltz t0, 1f /* If kernel */ |
162 | addiu t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ | 165 | INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ |
163 | addiu t1, k1, VCPU_GUEST_USER_ASID /* else user */ | 166 | INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ |
164 | 1: | 167 | 1: |
165 | /* t1: contains the base of the ASID array, need to get the cpu id */ | 168 | /* t1: contains the base of the ASID array, need to get the cpu id */ |
166 | LONG_L t2, TI_CPU($28) /* smp_processor_id */ | 169 | LONG_L t2, TI_CPU($28) /* smp_processor_id */ |
167 | sll t2, t2, 2 /* x4 */ | 170 | INT_SLL t2, t2, 2 /* x4 */ |
168 | addu t3, t1, t2 | 171 | REG_ADDU t3, t1, t2 |
169 | LONG_L k0, (t3) | 172 | LONG_L k0, (t3) |
170 | andi k0, k0, 0xff | 173 | andi k0, k0, 0xff |
171 | mtc0 k0,CP0_ENTRYHI | 174 | mtc0 k0, CP0_ENTRYHI |
172 | ehb | 175 | ehb |
173 | 176 | ||
174 | /* Disable RDHWR access */ | 177 | /* Disable RDHWR access */ |
175 | mtc0 zero, CP0_HWRENA | 178 | mtc0 zero, CP0_HWRENA |
176 | 179 | ||
177 | /* Now load up the Guest Context from VCPU */ | 180 | /* Now load up the Guest Context from VCPU */ |
178 | LONG_L $1, VCPU_R1(k1) | 181 | LONG_L $1, VCPU_R1(k1) |
179 | LONG_L $2, VCPU_R2(k1) | 182 | LONG_L $2, VCPU_R2(k1) |
180 | LONG_L $3, VCPU_R3(k1) | 183 | LONG_L $3, VCPU_R3(k1) |
181 | 184 | ||
182 | LONG_L $4, VCPU_R4(k1) | 185 | LONG_L $4, VCPU_R4(k1) |
183 | LONG_L $5, VCPU_R5(k1) | 186 | LONG_L $5, VCPU_R5(k1) |
184 | LONG_L $6, VCPU_R6(k1) | 187 | LONG_L $6, VCPU_R6(k1) |
185 | LONG_L $7, VCPU_R7(k1) | 188 | LONG_L $7, VCPU_R7(k1) |
186 | 189 | ||
187 | LONG_L $8, VCPU_R8(k1) | 190 | LONG_L $8, VCPU_R8(k1) |
188 | LONG_L $9, VCPU_R9(k1) | 191 | LONG_L $9, VCPU_R9(k1) |
189 | LONG_L $10, VCPU_R10(k1) | 192 | LONG_L $10, VCPU_R10(k1) |
190 | LONG_L $11, VCPU_R11(k1) | 193 | LONG_L $11, VCPU_R11(k1) |
191 | LONG_L $12, VCPU_R12(k1) | 194 | LONG_L $12, VCPU_R12(k1) |
192 | LONG_L $13, VCPU_R13(k1) | 195 | LONG_L $13, VCPU_R13(k1) |
193 | LONG_L $14, VCPU_R14(k1) | 196 | LONG_L $14, VCPU_R14(k1) |
194 | LONG_L $15, VCPU_R15(k1) | 197 | LONG_L $15, VCPU_R15(k1) |
195 | LONG_L $16, VCPU_R16(k1) | 198 | LONG_L $16, VCPU_R16(k1) |
196 | LONG_L $17, VCPU_R17(k1) | 199 | LONG_L $17, VCPU_R17(k1) |
197 | LONG_L $18, VCPU_R18(k1) | 200 | LONG_L $18, VCPU_R18(k1) |
198 | LONG_L $19, VCPU_R19(k1) | 201 | LONG_L $19, VCPU_R19(k1) |
199 | LONG_L $20, VCPU_R20(k1) | 202 | LONG_L $20, VCPU_R20(k1) |
200 | LONG_L $21, VCPU_R21(k1) | 203 | LONG_L $21, VCPU_R21(k1) |
201 | LONG_L $22, VCPU_R22(k1) | 204 | LONG_L $22, VCPU_R22(k1) |
202 | LONG_L $23, VCPU_R23(k1) | 205 | LONG_L $23, VCPU_R23(k1) |
203 | LONG_L $24, VCPU_R24(k1) | 206 | LONG_L $24, VCPU_R24(k1) |
204 | LONG_L $25, VCPU_R25(k1) | 207 | LONG_L $25, VCPU_R25(k1) |
205 | 208 | ||
206 | /* k0/k1 loaded up later */ | 209 | /* k0/k1 loaded up later */ |
207 | 210 | ||
208 | LONG_L $28, VCPU_R28(k1) | 211 | LONG_L $28, VCPU_R28(k1) |
209 | LONG_L $29, VCPU_R29(k1) | 212 | LONG_L $29, VCPU_R29(k1) |
210 | LONG_L $30, VCPU_R30(k1) | 213 | LONG_L $30, VCPU_R30(k1) |
211 | LONG_L $31, VCPU_R31(k1) | 214 | LONG_L $31, VCPU_R31(k1) |
212 | 215 | ||
213 | /* Restore hi/lo */ | 216 | /* Restore hi/lo */ |
214 | LONG_L k0, VCPU_LO(k1) | 217 | LONG_L k0, VCPU_LO(k1) |
215 | mtlo k0 | 218 | mtlo k0 |
216 | 219 | ||
217 | LONG_L k0, VCPU_HI(k1) | 220 | LONG_L k0, VCPU_HI(k1) |
218 | mthi k0 | 221 | mthi k0 |
219 | 222 | ||
220 | FEXPORT(__kvm_mips_load_k0k1) | 223 | FEXPORT(__kvm_mips_load_k0k1) |
221 | /* Restore the guest's k0/k1 registers */ | 224 | /* Restore the guest's k0/k1 registers */ |
222 | LONG_L k0, VCPU_R26(k1) | 225 | LONG_L k0, VCPU_R26(k1) |
223 | LONG_L k1, VCPU_R27(k1) | 226 | LONG_L k1, VCPU_R27(k1) |
224 | 227 | ||
225 | /* Jump to guest */ | 228 | /* Jump to guest */ |
226 | eret | 229 | eret |
227 | .set pop | ||
228 | 230 | ||
229 | VECTOR(MIPSX(exception), unknown) | 231 | VECTOR(MIPSX(exception), unknown) |
230 | /* | 232 | /* |
231 | * Find out what mode we came from and jump to the proper handler. | 233 | * Find out what mode we came from and jump to the proper handler. |
232 | */ | 234 | */ |
233 | .set push | 235 | mtc0 k0, CP0_ERROREPC #01: Save guest k0 |
234 | .set noat | 236 | ehb #02: |
235 | .set noreorder | 237 | |
236 | mtc0 k0, CP0_ERROREPC #01: Save guest k0 | 238 | mfc0 k0, CP0_EBASE #02: Get EBASE |
237 | ehb #02: | 239 | INT_SRL k0, k0, 10 #03: Get rid of CPUNum |
238 | 240 | INT_SLL k0, k0, 10 #04 | |
239 | mfc0 k0, CP0_EBASE #02: Get EBASE | 241 | LONG_S k1, 0x3000(k0) #05: Save k1 @ offset 0x3000 |
240 | srl k0, k0, 10 #03: Get rid of CPUNum | 242 | INT_ADDIU k0, k0, 0x2000 #06: Exception handler is installed @ offset 0x2000 |
241 | sll k0, k0, 10 #04 | 243 | j k0 #07: jump to the function |
242 | LONG_S k1, 0x3000(k0) #05: Save k1 @ offset 0x3000 | 244 | nop #08: branch delay slot |
243 | addiu k0, k0, 0x2000 #06: Exception handler is installed @ offset 0x2000 | ||
244 | j k0 #07: jump to the function | ||
245 | nop #08: branch delay slot | ||
246 | .set push | ||
247 | VECTOR_END(MIPSX(exceptionEnd)) | 245 | VECTOR_END(MIPSX(exceptionEnd)) |
248 | .end MIPSX(exception) | 246 | .end MIPSX(exception) |
249 | 247 | ||
@@ -253,329 +251,327 @@ VECTOR_END(MIPSX(exceptionEnd)) | |||
253 | * | 251 | * |
254 | */ | 252 | */ |
255 | NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) | 253 | NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) |
256 | .set push | 254 | /* Get the VCPU pointer from DDTATA_LO */ |
257 | .set noat | 255 | mfc0 k1, CP0_DDATA_LO |
258 | .set noreorder | 256 | INT_ADDIU k1, k1, VCPU_HOST_ARCH |
259 | 257 | ||
260 | /* Get the VCPU pointer from DDTATA_LO */ | 258 | /* Start saving Guest context to VCPU */ |
261 | mfc0 k1, CP0_DDATA_LO | 259 | LONG_S $0, VCPU_R0(k1) |
262 | addiu k1, k1, VCPU_HOST_ARCH | 260 | LONG_S $1, VCPU_R1(k1) |
263 | 261 | LONG_S $2, VCPU_R2(k1) | |
264 | /* Start saving Guest context to VCPU */ | 262 | LONG_S $3, VCPU_R3(k1) |
265 | LONG_S $0, VCPU_R0(k1) | 263 | LONG_S $4, VCPU_R4(k1) |
266 | LONG_S $1, VCPU_R1(k1) | 264 | LONG_S $5, VCPU_R5(k1) |
267 | LONG_S $2, VCPU_R2(k1) | 265 | LONG_S $6, VCPU_R6(k1) |
268 | LONG_S $3, VCPU_R3(k1) | 266 | LONG_S $7, VCPU_R7(k1) |
269 | LONG_S $4, VCPU_R4(k1) | 267 | LONG_S $8, VCPU_R8(k1) |
270 | LONG_S $5, VCPU_R5(k1) | 268 | LONG_S $9, VCPU_R9(k1) |
271 | LONG_S $6, VCPU_R6(k1) | 269 | LONG_S $10, VCPU_R10(k1) |
272 | LONG_S $7, VCPU_R7(k1) | 270 | LONG_S $11, VCPU_R11(k1) |
273 | LONG_S $8, VCPU_R8(k1) | 271 | LONG_S $12, VCPU_R12(k1) |
274 | LONG_S $9, VCPU_R9(k1) | 272 | LONG_S $13, VCPU_R13(k1) |
275 | LONG_S $10, VCPU_R10(k1) | 273 | LONG_S $14, VCPU_R14(k1) |
276 | LONG_S $11, VCPU_R11(k1) | 274 | LONG_S $15, VCPU_R15(k1) |
277 | LONG_S $12, VCPU_R12(k1) | 275 | LONG_S $16, VCPU_R16(k1) |
278 | LONG_S $13, VCPU_R13(k1) | 276 | LONG_S $17, VCPU_R17(k1) |
279 | LONG_S $14, VCPU_R14(k1) | 277 | LONG_S $18, VCPU_R18(k1) |
280 | LONG_S $15, VCPU_R15(k1) | 278 | LONG_S $19, VCPU_R19(k1) |
281 | LONG_S $16, VCPU_R16(k1) | 279 | LONG_S $20, VCPU_R20(k1) |
282 | LONG_S $17,VCPU_R17(k1) | 280 | LONG_S $21, VCPU_R21(k1) |
283 | LONG_S $18, VCPU_R18(k1) | 281 | LONG_S $22, VCPU_R22(k1) |
284 | LONG_S $19, VCPU_R19(k1) | 282 | LONG_S $23, VCPU_R23(k1) |
285 | LONG_S $20, VCPU_R20(k1) | 283 | LONG_S $24, VCPU_R24(k1) |
286 | LONG_S $21, VCPU_R21(k1) | 284 | LONG_S $25, VCPU_R25(k1) |
287 | LONG_S $22, VCPU_R22(k1) | 285 | |
288 | LONG_S $23, VCPU_R23(k1) | 286 | /* Guest k0/k1 saved later */ |
289 | LONG_S $24, VCPU_R24(k1) | 287 | |
290 | LONG_S $25, VCPU_R25(k1) | 288 | LONG_S $28, VCPU_R28(k1) |
291 | 289 | LONG_S $29, VCPU_R29(k1) | |
292 | /* Guest k0/k1 saved later */ | 290 | LONG_S $30, VCPU_R30(k1) |
293 | 291 | LONG_S $31, VCPU_R31(k1) | |
294 | LONG_S $28, VCPU_R28(k1) | 292 | |
295 | LONG_S $29, VCPU_R29(k1) | 293 | /* We need to save hi/lo and restore them on |
296 | LONG_S $30, VCPU_R30(k1) | 294 | * the way out |
297 | LONG_S $31, VCPU_R31(k1) | 295 | */ |
298 | 296 | mfhi t0 | |
299 | /* We need to save hi/lo and restore them on | 297 | LONG_S t0, VCPU_HI(k1) |
300 | * the way out | 298 | |
301 | */ | 299 | mflo t0 |
302 | mfhi t0 | 300 | LONG_S t0, VCPU_LO(k1) |
303 | LONG_S t0, VCPU_HI(k1) | 301 | |
304 | 302 | /* Finally save guest k0/k1 to VCPU */ | |
305 | mflo t0 | 303 | mfc0 t0, CP0_ERROREPC |
306 | LONG_S t0, VCPU_LO(k1) | 304 | LONG_S t0, VCPU_R26(k1) |
307 | 305 | ||
308 | /* Finally save guest k0/k1 to VCPU */ | 306 | /* Get GUEST k1 and save it in VCPU */ |
309 | mfc0 t0, CP0_ERROREPC | 307 | PTR_LI t1, ~0x2ff |
310 | LONG_S t0, VCPU_R26(k1) | 308 | mfc0 t0, CP0_EBASE |
311 | 309 | and t0, t0, t1 | |
312 | /* Get GUEST k1 and save it in VCPU */ | 310 | LONG_L t0, 0x3000(t0) |
313 | la t1, ~0x2ff | 311 | LONG_S t0, VCPU_R27(k1) |
314 | mfc0 t0, CP0_EBASE | 312 | |
315 | and t0, t0, t1 | 313 | /* Now that context has been saved, we can use other registers */ |
316 | LONG_L t0, 0x3000(t0) | 314 | |
317 | LONG_S t0, VCPU_R27(k1) | 315 | /* Restore vcpu */ |
318 | 316 | mfc0 a1, CP0_DDATA_LO | |
319 | /* Now that context has been saved, we can use other registers */ | 317 | move s1, a1 |
320 | 318 | ||
321 | /* Restore vcpu */ | 319 | /* Restore run (vcpu->run) */ |
322 | mfc0 a1, CP0_DDATA_LO | 320 | LONG_L a0, VCPU_RUN(a1) |
323 | move s1, a1 | 321 | /* Save pointer to run in s0, will be saved by the compiler */ |
324 | 322 | move s0, a0 | |
325 | /* Restore run (vcpu->run) */ | 323 | |
326 | LONG_L a0, VCPU_RUN(a1) | 324 | /* Save Host level EPC, BadVaddr and Cause to VCPU, useful to |
327 | /* Save pointer to run in s0, will be saved by the compiler */ | 325 | * process the exception */ |
328 | move s0, a0 | 326 | mfc0 k0,CP0_EPC |
329 | 327 | LONG_S k0, VCPU_PC(k1) | |
330 | 328 | ||
331 | /* Save Host level EPC, BadVaddr and Cause to VCPU, useful to process the exception */ | 329 | mfc0 k0, CP0_BADVADDR |
332 | mfc0 k0,CP0_EPC | 330 | LONG_S k0, VCPU_HOST_CP0_BADVADDR(k1) |
333 | LONG_S k0, VCPU_PC(k1) | 331 | |
334 | 332 | mfc0 k0, CP0_CAUSE | |
335 | mfc0 k0, CP0_BADVADDR | 333 | LONG_S k0, VCPU_HOST_CP0_CAUSE(k1) |
336 | LONG_S k0, VCPU_HOST_CP0_BADVADDR(k1) | 334 | |
337 | 335 | mfc0 k0, CP0_ENTRYHI | |
338 | mfc0 k0, CP0_CAUSE | 336 | LONG_S k0, VCPU_HOST_ENTRYHI(k1) |
339 | LONG_S k0, VCPU_HOST_CP0_CAUSE(k1) | 337 | |
340 | 338 | /* Now restore the host state just enough to run the handlers */ | |
341 | mfc0 k0, CP0_ENTRYHI | 339 | |
342 | LONG_S k0, VCPU_HOST_ENTRYHI(k1) | 340 | /* Swtich EBASE to the one used by Linux */ |
343 | 341 | /* load up the host EBASE */ | |
344 | /* Now restore the host state just enough to run the handlers */ | 342 | mfc0 v0, CP0_STATUS |
345 | 343 | ||
346 | /* Swtich EBASE to the one used by Linux */ | 344 | .set at |
347 | /* load up the host EBASE */ | 345 | or k0, v0, ST0_BEV |
348 | mfc0 v0, CP0_STATUS | 346 | .set noat |
349 | 347 | ||
350 | .set at | 348 | mtc0 k0, CP0_STATUS |
351 | or k0, v0, ST0_BEV | 349 | ehb |
352 | .set noat | 350 | |
353 | 351 | LONG_L k0, VCPU_HOST_EBASE(k1) | |
354 | mtc0 k0, CP0_STATUS | 352 | mtc0 k0,CP0_EBASE |
355 | ehb | 353 | |
356 | |||
357 | LONG_L k0, VCPU_HOST_EBASE(k1) | ||
358 | mtc0 k0,CP0_EBASE | ||
359 | |||
360 | |||
361 | /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ | ||
362 | .set at | ||
363 | and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) | ||
364 | or v0, v0, ST0_CU0 | ||
365 | .set noat | ||
366 | mtc0 v0, CP0_STATUS | ||
367 | ehb | ||
368 | |||
369 | /* Load up host GP */ | ||
370 | LONG_L gp, VCPU_HOST_GP(k1) | ||
371 | |||
372 | /* Need a stack before we can jump to "C" */ | ||
373 | LONG_L sp, VCPU_HOST_STACK(k1) | ||
374 | |||
375 | /* Saved host state */ | ||
376 | addiu sp,sp, -PT_SIZE | ||
377 | 354 | ||
378 | /* XXXKYMA do we need to load the host ASID, maybe not because the | 355 | /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ |
379 | * kernel entries are marked GLOBAL, need to verify | 356 | .set at |
380 | */ | 357 | and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) |
358 | or v0, v0, ST0_CU0 | ||
359 | .set noat | ||
360 | mtc0 v0, CP0_STATUS | ||
361 | ehb | ||
362 | |||
363 | /* Load up host GP */ | ||
364 | LONG_L gp, VCPU_HOST_GP(k1) | ||
365 | |||
366 | /* Need a stack before we can jump to "C" */ | ||
367 | LONG_L sp, VCPU_HOST_STACK(k1) | ||
368 | |||
369 | /* Saved host state */ | ||
370 | INT_ADDIU sp, sp, -PT_SIZE | ||
381 | 371 | ||
382 | /* Restore host DDATA_LO */ | 372 | /* XXXKYMA do we need to load the host ASID, maybe not because the |
383 | LONG_L k0, PT_HOST_USERLOCAL(sp) | 373 | * kernel entries are marked GLOBAL, need to verify |
384 | mtc0 k0, CP0_DDATA_LO | 374 | */ |
385 | 375 | ||
386 | /* Restore RDHWR access */ | 376 | /* Restore host DDATA_LO */ |
387 | la k0, 0x2000000F | 377 | LONG_L k0, PT_HOST_USERLOCAL(sp) |
388 | mtc0 k0, CP0_HWRENA | 378 | mtc0 k0, CP0_DDATA_LO |
389 | 379 | ||
390 | /* Jump to handler */ | 380 | /* Restore RDHWR access */ |
381 | PTR_LI k0, 0x2000000F | ||
382 | mtc0 k0, CP0_HWRENA | ||
383 | |||
384 | /* Jump to handler */ | ||
391 | FEXPORT(__kvm_mips_jump_to_handler) | 385 | FEXPORT(__kvm_mips_jump_to_handler) |
392 | /* XXXKYMA: not sure if this is safe, how large is the stack?? */ | 386 | /* XXXKYMA: not sure if this is safe, how large is the stack?? |
393 | /* Now jump to the kvm_mips_handle_exit() to see if we can deal with this in the kernel */ | 387 | * Now jump to the kvm_mips_handle_exit() to see if we can deal |
394 | la t9,kvm_mips_handle_exit | 388 | * with this in the kernel */ |
395 | jalr.hb t9 | 389 | PTR_LA t9, kvm_mips_handle_exit |
396 | addiu sp,sp, -CALLFRAME_SIZ /* BD Slot */ | 390 | jalr.hb t9 |
397 | 391 | INT_ADDIU sp, sp, -CALLFRAME_SIZ /* BD Slot */ | |
398 | /* Return from handler Make sure interrupts are disabled */ | 392 | |
399 | di | 393 | /* Return from handler Make sure interrupts are disabled */ |
400 | ehb | 394 | di |
401 | 395 | ehb | |
402 | /* XXXKYMA: k0/k1 could have been blown away if we processed an exception | 396 | |
403 | * while we were handling the exception from the guest, reload k1 | 397 | /* XXXKYMA: k0/k1 could have been blown away if we processed |
404 | */ | 398 | * an exception while we were handling the exception from the |
405 | move k1, s1 | 399 | * guest, reload k1 |
406 | addiu k1, k1, VCPU_HOST_ARCH | 400 | */ |
407 | 401 | ||
408 | /* Check return value, should tell us if we are returning to the host (handle I/O etc) | 402 | move k1, s1 |
409 | * or resuming the guest | 403 | INT_ADDIU k1, k1, VCPU_HOST_ARCH |
410 | */ | 404 | |
411 | andi t0, v0, RESUME_HOST | 405 | /* Check return value, should tell us if we are returning to the |
412 | bnez t0, __kvm_mips_return_to_host | 406 | * host (handle I/O etc)or resuming the guest |
413 | nop | 407 | */ |
408 | andi t0, v0, RESUME_HOST | ||
409 | bnez t0, __kvm_mips_return_to_host | ||
410 | nop | ||
414 | 411 | ||
415 | __kvm_mips_return_to_guest: | 412 | __kvm_mips_return_to_guest: |
416 | /* Put the saved pointer to vcpu (s1) back into the DDATA_LO Register */ | 413 | /* Put the saved pointer to vcpu (s1) back into the DDATA_LO Register */ |
417 | mtc0 s1, CP0_DDATA_LO | 414 | mtc0 s1, CP0_DDATA_LO |
418 | |||
419 | /* Load up the Guest EBASE to minimize the window where BEV is set */ | ||
420 | LONG_L t0, VCPU_GUEST_EBASE(k1) | ||
421 | |||
422 | /* Switch EBASE back to the one used by KVM */ | ||
423 | mfc0 v1, CP0_STATUS | ||
424 | .set at | ||
425 | or k0, v1, ST0_BEV | ||
426 | .set noat | ||
427 | mtc0 k0, CP0_STATUS | ||
428 | ehb | ||
429 | mtc0 t0,CP0_EBASE | ||
430 | |||
431 | /* Setup status register for running guest in UM */ | ||
432 | .set at | ||
433 | or v1, v1, (ST0_EXL | KSU_USER | ST0_IE) | ||
434 | and v1, v1, ~ST0_CU0 | ||
435 | .set noat | ||
436 | mtc0 v1, CP0_STATUS | ||
437 | ehb | ||
438 | 415 | ||
416 | /* Load up the Guest EBASE to minimize the window where BEV is set */ | ||
417 | LONG_L t0, VCPU_GUEST_EBASE(k1) | ||
418 | |||
419 | /* Switch EBASE back to the one used by KVM */ | ||
420 | mfc0 v1, CP0_STATUS | ||
421 | .set at | ||
422 | or k0, v1, ST0_BEV | ||
423 | .set noat | ||
424 | mtc0 k0, CP0_STATUS | ||
425 | ehb | ||
426 | mtc0 t0, CP0_EBASE | ||
427 | |||
428 | /* Setup status register for running guest in UM */ | ||
429 | .set at | ||
430 | or v1, v1, (ST0_EXL | KSU_USER | ST0_IE) | ||
431 | and v1, v1, ~ST0_CU0 | ||
432 | .set noat | ||
433 | mtc0 v1, CP0_STATUS | ||
434 | ehb | ||
439 | 435 | ||
440 | /* Set Guest EPC */ | 436 | /* Set Guest EPC */ |
441 | LONG_L t0, VCPU_PC(k1) | 437 | LONG_L t0, VCPU_PC(k1) |
442 | mtc0 t0, CP0_EPC | 438 | mtc0 t0, CP0_EPC |
443 | 439 | ||
444 | /* Set the ASID for the Guest Kernel */ | 440 | /* Set the ASID for the Guest Kernel */ |
445 | sll t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ | 441 | INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ |
446 | /* addresses shift to 0x80000000 */ | 442 | /* addresses shift to 0x80000000 */ |
447 | bltz t0, 1f /* If kernel */ | 443 | bltz t0, 1f /* If kernel */ |
448 | addiu t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ | 444 | INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ |
449 | addiu t1, k1, VCPU_GUEST_USER_ASID /* else user */ | 445 | INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ |
450 | 1: | 446 | 1: |
451 | /* t1: contains the base of the ASID array, need to get the cpu id */ | 447 | /* t1: contains the base of the ASID array, need to get the cpu id */ |
452 | LONG_L t2, TI_CPU($28) /* smp_processor_id */ | 448 | LONG_L t2, TI_CPU($28) /* smp_processor_id */ |
453 | sll t2, t2, 2 /* x4 */ | 449 | INT_SLL t2, t2, 2 /* x4 */ |
454 | addu t3, t1, t2 | 450 | REG_ADDU t3, t1, t2 |
455 | LONG_L k0, (t3) | 451 | LONG_L k0, (t3) |
456 | andi k0, k0, 0xff | 452 | andi k0, k0, 0xff |
457 | mtc0 k0,CP0_ENTRYHI | 453 | mtc0 k0,CP0_ENTRYHI |
458 | ehb | 454 | ehb |
459 | 455 | ||
460 | /* Disable RDHWR access */ | 456 | /* Disable RDHWR access */ |
461 | mtc0 zero, CP0_HWRENA | 457 | mtc0 zero, CP0_HWRENA |
462 | 458 | ||
463 | /* load the guest context from VCPU and return */ | 459 | /* load the guest context from VCPU and return */ |
464 | LONG_L $0, VCPU_R0(k1) | 460 | LONG_L $0, VCPU_R0(k1) |
465 | LONG_L $1, VCPU_R1(k1) | 461 | LONG_L $1, VCPU_R1(k1) |
466 | LONG_L $2, VCPU_R2(k1) | 462 | LONG_L $2, VCPU_R2(k1) |
467 | LONG_L $3, VCPU_R3(k1) | 463 | LONG_L $3, VCPU_R3(k1) |
468 | LONG_L $4, VCPU_R4(k1) | 464 | LONG_L $4, VCPU_R4(k1) |
469 | LONG_L $5, VCPU_R5(k1) | 465 | LONG_L $5, VCPU_R5(k1) |
470 | LONG_L $6, VCPU_R6(k1) | 466 | LONG_L $6, VCPU_R6(k1) |
471 | LONG_L $7, VCPU_R7(k1) | 467 | LONG_L $7, VCPU_R7(k1) |
472 | LONG_L $8, VCPU_R8(k1) | 468 | LONG_L $8, VCPU_R8(k1) |
473 | LONG_L $9, VCPU_R9(k1) | 469 | LONG_L $9, VCPU_R9(k1) |
474 | LONG_L $10, VCPU_R10(k1) | 470 | LONG_L $10, VCPU_R10(k1) |
475 | LONG_L $11, VCPU_R11(k1) | 471 | LONG_L $11, VCPU_R11(k1) |
476 | LONG_L $12, VCPU_R12(k1) | 472 | LONG_L $12, VCPU_R12(k1) |
477 | LONG_L $13, VCPU_R13(k1) | 473 | LONG_L $13, VCPU_R13(k1) |
478 | LONG_L $14, VCPU_R14(k1) | 474 | LONG_L $14, VCPU_R14(k1) |
479 | LONG_L $15, VCPU_R15(k1) | 475 | LONG_L $15, VCPU_R15(k1) |
480 | LONG_L $16, VCPU_R16(k1) | 476 | LONG_L $16, VCPU_R16(k1) |
481 | LONG_L $17, VCPU_R17(k1) | 477 | LONG_L $17, VCPU_R17(k1) |
482 | LONG_L $18, VCPU_R18(k1) | 478 | LONG_L $18, VCPU_R18(k1) |
483 | LONG_L $19, VCPU_R19(k1) | 479 | LONG_L $19, VCPU_R19(k1) |
484 | LONG_L $20, VCPU_R20(k1) | 480 | LONG_L $20, VCPU_R20(k1) |
485 | LONG_L $21, VCPU_R21(k1) | 481 | LONG_L $21, VCPU_R21(k1) |
486 | LONG_L $22, VCPU_R22(k1) | 482 | LONG_L $22, VCPU_R22(k1) |
487 | LONG_L $23, VCPU_R23(k1) | 483 | LONG_L $23, VCPU_R23(k1) |
488 | LONG_L $24, VCPU_R24(k1) | 484 | LONG_L $24, VCPU_R24(k1) |
489 | LONG_L $25, VCPU_R25(k1) | 485 | LONG_L $25, VCPU_R25(k1) |
490 | 486 | ||
491 | /* $/k1 loaded later */ | 487 | /* $/k1 loaded later */ |
492 | LONG_L $28, VCPU_R28(k1) | 488 | LONG_L $28, VCPU_R28(k1) |
493 | LONG_L $29, VCPU_R29(k1) | 489 | LONG_L $29, VCPU_R29(k1) |
494 | LONG_L $30, VCPU_R30(k1) | 490 | LONG_L $30, VCPU_R30(k1) |
495 | LONG_L $31, VCPU_R31(k1) | 491 | LONG_L $31, VCPU_R31(k1) |
496 | 492 | ||
497 | FEXPORT(__kvm_mips_skip_guest_restore) | 493 | FEXPORT(__kvm_mips_skip_guest_restore) |
498 | LONG_L k0, VCPU_HI(k1) | 494 | LONG_L k0, VCPU_HI(k1) |
499 | mthi k0 | 495 | mthi k0 |
500 | 496 | ||
501 | LONG_L k0, VCPU_LO(k1) | 497 | LONG_L k0, VCPU_LO(k1) |
502 | mtlo k0 | 498 | mtlo k0 |
503 | 499 | ||
504 | LONG_L k0, VCPU_R26(k1) | 500 | LONG_L k0, VCPU_R26(k1) |
505 | LONG_L k1, VCPU_R27(k1) | 501 | LONG_L k1, VCPU_R27(k1) |
506 | 502 | ||
507 | eret | 503 | eret |
508 | 504 | ||
509 | __kvm_mips_return_to_host: | 505 | __kvm_mips_return_to_host: |
510 | /* EBASE is already pointing to Linux */ | 506 | /* EBASE is already pointing to Linux */ |
511 | LONG_L k1, VCPU_HOST_STACK(k1) | 507 | LONG_L k1, VCPU_HOST_STACK(k1) |
512 | addiu k1,k1, -PT_SIZE | 508 | INT_ADDIU k1,k1, -PT_SIZE |
513 | 509 | ||
514 | /* Restore host DDATA_LO */ | 510 | /* Restore host DDATA_LO */ |
515 | LONG_L k0, PT_HOST_USERLOCAL(k1) | 511 | LONG_L k0, PT_HOST_USERLOCAL(k1) |
516 | mtc0 k0, CP0_DDATA_LO | 512 | mtc0 k0, CP0_DDATA_LO |
517 | 513 | ||
518 | /* Restore host ASID */ | 514 | /* Restore host ASID */ |
519 | LONG_L k0, PT_HOST_ASID(sp) | 515 | LONG_L k0, PT_HOST_ASID(sp) |
520 | andi k0, 0xff | 516 | andi k0, 0xff |
521 | mtc0 k0,CP0_ENTRYHI | 517 | mtc0 k0,CP0_ENTRYHI |
522 | ehb | 518 | ehb |
523 | 519 | ||
524 | /* Load context saved on the host stack */ | 520 | /* Load context saved on the host stack */ |
525 | LONG_L $0, PT_R0(k1) | 521 | LONG_L $0, PT_R0(k1) |
526 | LONG_L $1, PT_R1(k1) | 522 | LONG_L $1, PT_R1(k1) |
527 | 523 | ||
528 | /* r2/v0 is the return code, shift it down by 2 (arithmetic) to recover the err code */ | 524 | /* r2/v0 is the return code, shift it down by 2 (arithmetic) |
529 | sra k0, v0, 2 | 525 | * to recover the err code */ |
530 | move $2, k0 | 526 | INT_SRA k0, v0, 2 |
531 | 527 | move $2, k0 | |
532 | LONG_L $3, PT_R3(k1) | 528 | |
533 | LONG_L $4, PT_R4(k1) | 529 | LONG_L $3, PT_R3(k1) |
534 | LONG_L $5, PT_R5(k1) | 530 | LONG_L $4, PT_R4(k1) |
535 | LONG_L $6, PT_R6(k1) | 531 | LONG_L $5, PT_R5(k1) |
536 | LONG_L $7, PT_R7(k1) | 532 | LONG_L $6, PT_R6(k1) |
537 | LONG_L $8, PT_R8(k1) | 533 | LONG_L $7, PT_R7(k1) |
538 | LONG_L $9, PT_R9(k1) | 534 | LONG_L $8, PT_R8(k1) |
539 | LONG_L $10, PT_R10(k1) | 535 | LONG_L $9, PT_R9(k1) |
540 | LONG_L $11, PT_R11(k1) | 536 | LONG_L $10, PT_R10(k1) |
541 | LONG_L $12, PT_R12(k1) | 537 | LONG_L $11, PT_R11(k1) |
542 | LONG_L $13, PT_R13(k1) | 538 | LONG_L $12, PT_R12(k1) |
543 | LONG_L $14, PT_R14(k1) | 539 | LONG_L $13, PT_R13(k1) |
544 | LONG_L $15, PT_R15(k1) | 540 | LONG_L $14, PT_R14(k1) |
545 | LONG_L $16, PT_R16(k1) | 541 | LONG_L $15, PT_R15(k1) |
546 | LONG_L $17, PT_R17(k1) | 542 | LONG_L $16, PT_R16(k1) |
547 | LONG_L $18, PT_R18(k1) | 543 | LONG_L $17, PT_R17(k1) |
548 | LONG_L $19, PT_R19(k1) | 544 | LONG_L $18, PT_R18(k1) |
549 | LONG_L $20, PT_R20(k1) | 545 | LONG_L $19, PT_R19(k1) |
550 | LONG_L $21, PT_R21(k1) | 546 | LONG_L $20, PT_R20(k1) |
551 | LONG_L $22, PT_R22(k1) | 547 | LONG_L $21, PT_R21(k1) |
552 | LONG_L $23, PT_R23(k1) | 548 | LONG_L $22, PT_R22(k1) |
553 | LONG_L $24, PT_R24(k1) | 549 | LONG_L $23, PT_R23(k1) |
554 | LONG_L $25, PT_R25(k1) | 550 | LONG_L $24, PT_R24(k1) |
555 | 551 | LONG_L $25, PT_R25(k1) | |
556 | /* Host k0/k1 were not saved */ | 552 | |
557 | 553 | /* Host k0/k1 were not saved */ | |
558 | LONG_L $28, PT_R28(k1) | 554 | |
559 | LONG_L $29, PT_R29(k1) | 555 | LONG_L $28, PT_R28(k1) |
560 | LONG_L $30, PT_R30(k1) | 556 | LONG_L $29, PT_R29(k1) |
561 | 557 | LONG_L $30, PT_R30(k1) | |
562 | LONG_L k0, PT_HI(k1) | 558 | |
563 | mthi k0 | 559 | LONG_L k0, PT_HI(k1) |
564 | 560 | mthi k0 | |
565 | LONG_L k0, PT_LO(k1) | 561 | |
566 | mtlo k0 | 562 | LONG_L k0, PT_LO(k1) |
567 | 563 | mtlo k0 | |
568 | /* Restore RDHWR access */ | 564 | |
569 | la k0, 0x2000000F | 565 | /* Restore RDHWR access */ |
570 | mtc0 k0, CP0_HWRENA | 566 | PTR_LI k0, 0x2000000F |
571 | 567 | mtc0 k0, CP0_HWRENA | |
572 | 568 | ||
573 | /* Restore RA, which is the address we will return to */ | 569 | |
574 | LONG_L ra, PT_R31(k1) | 570 | /* Restore RA, which is the address we will return to */ |
575 | j ra | 571 | LONG_L ra, PT_R31(k1) |
576 | nop | 572 | j ra |
577 | 573 | nop | |
578 | .set pop | 574 | |
579 | VECTOR_END(MIPSX(GuestExceptionEnd)) | 575 | VECTOR_END(MIPSX(GuestExceptionEnd)) |
580 | .end MIPSX(GuestException) | 576 | .end MIPSX(GuestException) |
581 | 577 | ||
@@ -627,24 +623,23 @@ MIPSX(exceptions): | |||
627 | 623 | ||
628 | #define HW_SYNCI_Step $1 | 624 | #define HW_SYNCI_Step $1 |
629 | LEAF(MIPSX(SyncICache)) | 625 | LEAF(MIPSX(SyncICache)) |
630 | .set push | 626 | .set push |
631 | .set mips32r2 | 627 | .set mips32r2 |
632 | beq a1, zero, 20f | 628 | beq a1, zero, 20f |
633 | nop | 629 | nop |
634 | addu a1, a0, a1 | 630 | REG_ADDU a1, a0, a1 |
635 | rdhwr v0, HW_SYNCI_Step | 631 | rdhwr v0, HW_SYNCI_Step |
636 | beq v0, zero, 20f | 632 | beq v0, zero, 20f |
637 | nop | 633 | nop |
638 | |||
639 | 10: | 634 | 10: |
640 | synci 0(a0) | 635 | synci 0(a0) |
641 | addu a0, a0, v0 | 636 | REG_ADDU a0, a0, v0 |
642 | sltu v1, a0, a1 | 637 | sltu v1, a0, a1 |
643 | bne v1, zero, 10b | 638 | bne v1, zero, 10b |
644 | nop | 639 | nop |
645 | sync | 640 | sync |
646 | 20: | 641 | 20: |
647 | jr.hb ra | 642 | jr.hb ra |
648 | nop | 643 | nop |
649 | .set pop | 644 | .set pop |
650 | END(MIPSX(SyncICache)) | 645 | END(MIPSX(SyncICache)) |
diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index dd203e59e6fd..a7b044536de4 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c | |||
@@ -208,6 +208,10 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | |||
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
210 | 210 | ||
211 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
212 | { | ||
213 | } | ||
214 | |||
211 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 215 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
212 | struct kvm_memory_slot *memslot, | 216 | struct kvm_memory_slot *memslot, |
213 | struct kvm_userspace_memory_region *mem, | 217 | struct kvm_userspace_memory_region *mem, |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index e773659ccf9f..46048d24328c 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -803,6 +803,32 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, | |||
803 | dec_insn.next_pc_inc; | 803 | dec_insn.next_pc_inc; |
804 | return 1; | 804 | return 1; |
805 | break; | 805 | break; |
806 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | ||
807 | case lwc2_op: /* This is bbit0 on Octeon */ | ||
808 | if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) == 0) | ||
809 | *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2); | ||
810 | else | ||
811 | *contpc = regs->cp0_epc + 8; | ||
812 | return 1; | ||
813 | case ldc2_op: /* This is bbit032 on Octeon */ | ||
814 | if ((regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32))) == 0) | ||
815 | *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2); | ||
816 | else | ||
817 | *contpc = regs->cp0_epc + 8; | ||
818 | return 1; | ||
819 | case swc2_op: /* This is bbit1 on Octeon */ | ||
820 | if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) | ||
821 | *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2); | ||
822 | else | ||
823 | *contpc = regs->cp0_epc + 8; | ||
824 | return 1; | ||
825 | case sdc2_op: /* This is bbit132 on Octeon */ | ||
826 | if (regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32))) | ||
827 | *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2); | ||
828 | else | ||
829 | *contpc = regs->cp0_epc + 8; | ||
830 | return 1; | ||
831 | #endif | ||
806 | case cop0_op: | 832 | case cop0_op: |
807 | case cop1_op: | 833 | case cop1_op: |
808 | case cop2_op: | 834 | case cop2_op: |
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index af763e838fdd..5e5424753b56 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
@@ -33,7 +33,7 @@ static int op_mips_setup(void) | |||
33 | return 0; | 33 | return 0; |
34 | } | 34 | } |
35 | 35 | ||
36 | static int op_mips_create_files(struct super_block *sb, struct dentry *root) | 36 | static int op_mips_create_files(struct dentry *root) |
37 | { | 37 | { |
38 | int i; | 38 | int i; |
39 | 39 | ||
@@ -42,16 +42,16 @@ static int op_mips_create_files(struct super_block *sb, struct dentry *root) | |||
42 | char buf[4]; | 42 | char buf[4]; |
43 | 43 | ||
44 | snprintf(buf, sizeof buf, "%d", i); | 44 | snprintf(buf, sizeof buf, "%d", i); |
45 | dir = oprofilefs_mkdir(sb, root, buf); | 45 | dir = oprofilefs_mkdir(root, buf); |
46 | 46 | ||
47 | oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); | 47 | oprofilefs_create_ulong(dir, "enabled", &ctr[i].enabled); |
48 | oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); | 48 | oprofilefs_create_ulong(dir, "event", &ctr[i].event); |
49 | oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); | 49 | oprofilefs_create_ulong(dir, "count", &ctr[i].count); |
50 | oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); | 50 | oprofilefs_create_ulong(dir, "kernel", &ctr[i].kernel); |
51 | oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); | 51 | oprofilefs_create_ulong(dir, "user", &ctr[i].user); |
52 | oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl); | 52 | oprofilefs_create_ulong(dir, "exl", &ctr[i].exl); |
53 | /* Dummy. */ | 53 | /* Dummy. */ |
54 | oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); | 54 | oprofilefs_create_ulong(dir, "unit_mask", &ctr[i].unit_mask); |
55 | } | 55 | } |
56 | 56 | ||
57 | return 0; | 57 | return 0; |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 594e60d6a43b..33e7aa52d9c4 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -113,7 +113,6 @@ static void pcibios_scanbus(struct pci_controller *hose) | |||
113 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 113 | if (!pci_has_flag(PCI_PROBE_ONLY)) { |
114 | pci_bus_size_bridges(bus); | 114 | pci_bus_size_bridges(bus); |
115 | pci_bus_assign_resources(bus); | 115 | pci_bus_assign_resources(bus); |
116 | pci_enable_bridges(bus); | ||
117 | } | 116 | } |
118 | } | 117 | } |
119 | } | 118 | } |
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index dd0ab982d77e..f9407e170476 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c | |||
@@ -122,7 +122,6 @@ static struct resource sc26xx_rsrc[] = { | |||
122 | 122 | ||
123 | static struct sccnxp_pdata sccnxp_data = { | 123 | static struct sccnxp_pdata sccnxp_data = { |
124 | .reg_shift = 2, | 124 | .reg_shift = 2, |
125 | .frequency = 3686400, | ||
126 | .mctrl_cfg[0] = MCTRL_SIG(DTR_OP, LINE_OP7) | | 125 | .mctrl_cfg[0] = MCTRL_SIG(DTR_OP, LINE_OP7) | |
127 | MCTRL_SIG(RTS_OP, LINE_OP3) | | 126 | MCTRL_SIG(RTS_OP, LINE_OP3) | |
128 | MCTRL_SIG(DSR_IP, LINE_IP5) | | 127 | MCTRL_SIG(DSR_IP, LINE_IP5) | |
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 99dbab1c59ac..d60bf98fa5cf 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig | |||
@@ -55,6 +55,7 @@ config GENERIC_CSUM | |||
55 | 55 | ||
56 | source "init/Kconfig" | 56 | source "init/Kconfig" |
57 | 57 | ||
58 | source "kernel/Kconfig.freezer" | ||
58 | 59 | ||
59 | menu "Processor type and features" | 60 | menu "Processor type and features" |
60 | 61 | ||
diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h index bbb34e5343a2..eb59bfe23e85 100644 --- a/arch/openrisc/include/asm/prom.h +++ b/arch/openrisc/include/asm/prom.h | |||
@@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | |||
44 | 44 | ||
45 | extern void kdump_move_device_tree(void); | 45 | extern void kdump_move_device_tree(void); |
46 | 46 | ||
47 | /* CPU OF node matching */ | ||
48 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); | ||
49 | |||
50 | /* Get the MAC address */ | 47 | /* Get the MAC address */ |
51 | extern const void *of_get_mac_address(struct device_node *np); | 48 | extern const void *of_get_mac_address(struct device_node *np); |
52 | 49 | ||
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 07349b002687..1cba8f29bb49 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
@@ -78,7 +78,7 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) | |||
78 | err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq)); | 78 | err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq)); |
79 | err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq)); | 79 | err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq)); |
80 | err |= __get_user(regs->sar, &sc->sc_sar); | 80 | err |= __get_user(regs->sar, &sc->sc_sar); |
81 | DBG(2,"restore_sigcontext: iaoq is 0x%#lx / 0x%#lx\n", | 81 | DBG(2,"restore_sigcontext: iaoq is %#lx / %#lx\n", |
82 | regs->iaoq[0],regs->iaoq[1]); | 82 | regs->iaoq[0],regs->iaoq[1]); |
83 | DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]); | 83 | DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]); |
84 | return err; | 84 | return err; |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 04f1e94c3437..a4e3a93bf2d4 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -389,9 +389,9 @@ config KEXEC | |||
389 | 389 | ||
390 | It is an ongoing process to be certain the hardware in a machine | 390 | It is an ongoing process to be certain the hardware in a machine |
391 | is properly shutdown, so do not be surprised if this code does not | 391 | is properly shutdown, so do not be surprised if this code does not |
392 | initially work for you. It may help to enable device hotplugging | 392 | initially work for you. As of this writing the exact hardware |
393 | support. As of this writing the exact hardware interface is | 393 | interface is strongly in flux, so no good recommendation can be |
394 | strongly in flux, so no good recommendation can be made. | 394 | made. |
395 | 395 | ||
396 | config CRASH_DUMP | 396 | config CRASH_DUMP |
397 | bool "Build a kdump crash kernel" | 397 | bool "Build a kdump crash kernel" |
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 650757c300db..704e6f10ae80 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild | |||
@@ -2,3 +2,4 @@ | |||
2 | generic-y += clkdev.h | 2 | generic-y += clkdev.h |
3 | generic-y += rwsem.h | 3 | generic-y += rwsem.h |
4 | generic-y += trace_clock.h | 4 | generic-y += trace_clock.h |
5 | generic-y += vtime.h \ No newline at end of file | ||
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 08891d07aeb6..fa19e2f1a874 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -334,6 +334,27 @@ static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) | |||
334 | return r; | 334 | return r; |
335 | } | 335 | } |
336 | 336 | ||
337 | /* | ||
338 | * Like kvmppc_get_last_inst(), but for fetching a sc instruction. | ||
339 | * Because the sc instruction sets SRR0 to point to the following | ||
340 | * instruction, we have to fetch from pc - 4. | ||
341 | */ | ||
342 | static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu) | ||
343 | { | ||
344 | ulong pc = kvmppc_get_pc(vcpu) - 4; | ||
345 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); | ||
346 | u32 r; | ||
347 | |||
348 | /* Load the instruction manually if it failed to do so in the | ||
349 | * exit path */ | ||
350 | if (svcpu->last_inst == KVM_INST_FETCH_FAILED) | ||
351 | kvmppc_ld(vcpu, &pc, sizeof(u32), &svcpu->last_inst, false); | ||
352 | |||
353 | r = svcpu->last_inst; | ||
354 | svcpu_put(svcpu); | ||
355 | return r; | ||
356 | } | ||
357 | |||
337 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | 358 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) |
338 | { | 359 | { |
339 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); | 360 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); |
@@ -446,6 +467,23 @@ static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) | |||
446 | return vcpu->arch.last_inst; | 467 | return vcpu->arch.last_inst; |
447 | } | 468 | } |
448 | 469 | ||
470 | /* | ||
471 | * Like kvmppc_get_last_inst(), but for fetching a sc instruction. | ||
472 | * Because the sc instruction sets SRR0 to point to the following | ||
473 | * instruction, we have to fetch from pc - 4. | ||
474 | */ | ||
475 | static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu) | ||
476 | { | ||
477 | ulong pc = kvmppc_get_pc(vcpu) - 4; | ||
478 | |||
479 | /* Load the instruction manually if it failed to do so in the | ||
480 | * exit path */ | ||
481 | if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED) | ||
482 | kvmppc_ld(vcpu, &pc, sizeof(u32), &vcpu->arch.last_inst, false); | ||
483 | |||
484 | return vcpu->arch.last_inst; | ||
485 | } | ||
486 | |||
449 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | 487 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) |
450 | { | 488 | { |
451 | return vcpu->arch.fault_dar; | 489 | return vcpu->arch.fault_dar; |
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index a1ecb14e4442..86d638a3b359 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h | |||
@@ -37,7 +37,7 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) | |||
37 | 37 | ||
38 | #ifdef CONFIG_KVM_BOOK3S_64_HV | 38 | #ifdef CONFIG_KVM_BOOK3S_64_HV |
39 | #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ | 39 | #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ |
40 | extern int kvm_hpt_order; /* order of preallocated HPTs */ | 40 | extern unsigned long kvm_rma_pages; |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ | 43 | #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ |
@@ -100,7 +100,7 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r, | |||
100 | /* (masks depend on page size) */ | 100 | /* (masks depend on page size) */ |
101 | rb |= 0x1000; /* page encoding in LP field */ | 101 | rb |= 0x1000; /* page encoding in LP field */ |
102 | rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */ | 102 | rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */ |
103 | rb |= (va_low & 0xfe); /* AVAL field (P7 doesn't seem to care) */ | 103 | rb |= ((va_low << 4) & 0xf0); /* AVAL field (P7 doesn't seem to care) */ |
104 | } | 104 | } |
105 | } else { | 105 | } else { |
106 | /* 4kB page */ | 106 | /* 4kB page */ |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index af326cde7cb6..33283532e9d8 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -183,13 +183,9 @@ struct kvmppc_spapr_tce_table { | |||
183 | struct page *pages[0]; | 183 | struct page *pages[0]; |
184 | }; | 184 | }; |
185 | 185 | ||
186 | struct kvmppc_linear_info { | 186 | struct kvm_rma_info { |
187 | void *base_virt; | 187 | atomic_t use_count; |
188 | unsigned long base_pfn; | 188 | unsigned long base_pfn; |
189 | unsigned long npages; | ||
190 | struct list_head list; | ||
191 | atomic_t use_count; | ||
192 | int type; | ||
193 | }; | 189 | }; |
194 | 190 | ||
195 | /* XICS components, defined in book3s_xics.c */ | 191 | /* XICS components, defined in book3s_xics.c */ |
@@ -246,7 +242,7 @@ struct kvm_arch { | |||
246 | int tlbie_lock; | 242 | int tlbie_lock; |
247 | unsigned long lpcr; | 243 | unsigned long lpcr; |
248 | unsigned long rmor; | 244 | unsigned long rmor; |
249 | struct kvmppc_linear_info *rma; | 245 | struct kvm_rma_info *rma; |
250 | unsigned long vrma_slb_v; | 246 | unsigned long vrma_slb_v; |
251 | int rma_setup_done; | 247 | int rma_setup_done; |
252 | int using_mmu_notifiers; | 248 | int using_mmu_notifiers; |
@@ -259,7 +255,7 @@ struct kvm_arch { | |||
259 | spinlock_t slot_phys_lock; | 255 | spinlock_t slot_phys_lock; |
260 | cpumask_t need_tlb_flush; | 256 | cpumask_t need_tlb_flush; |
261 | struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; | 257 | struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; |
262 | struct kvmppc_linear_info *hpt_li; | 258 | int hpt_cma_alloc; |
263 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ | 259 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ |
264 | #ifdef CONFIG_PPC_BOOK3S_64 | 260 | #ifdef CONFIG_PPC_BOOK3S_64 |
265 | struct list_head spapr_tce_tables; | 261 | struct list_head spapr_tce_tables; |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index a5287fe03d77..b15554a26c20 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -137,10 +137,10 @@ extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, | |||
137 | unsigned long ioba, unsigned long tce); | 137 | unsigned long ioba, unsigned long tce); |
138 | extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, | 138 | extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, |
139 | struct kvm_allocate_rma *rma); | 139 | struct kvm_allocate_rma *rma); |
140 | extern struct kvmppc_linear_info *kvm_alloc_rma(void); | 140 | extern struct kvm_rma_info *kvm_alloc_rma(void); |
141 | extern void kvm_release_rma(struct kvmppc_linear_info *ri); | 141 | extern void kvm_release_rma(struct kvm_rma_info *ri); |
142 | extern struct kvmppc_linear_info *kvm_alloc_hpt(void); | 142 | extern struct page *kvm_alloc_hpt(unsigned long nr_pages); |
143 | extern void kvm_release_hpt(struct kvmppc_linear_info *li); | 143 | extern void kvm_release_hpt(struct page *page, unsigned long nr_pages); |
144 | extern int kvmppc_core_init_vm(struct kvm *kvm); | 144 | extern int kvmppc_core_init_vm(struct kvm *kvm); |
145 | extern void kvmppc_core_destroy_vm(struct kvm *kvm); | 145 | extern void kvmppc_core_destroy_vm(struct kvm *kvm); |
146 | extern void kvmppc_core_free_memslot(struct kvm_memory_slot *free, | 146 | extern void kvmppc_core_free_memslot(struct kvm_memory_slot *free, |
@@ -261,6 +261,7 @@ void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); | |||
261 | struct openpic; | 261 | struct openpic; |
262 | 262 | ||
263 | #ifdef CONFIG_KVM_BOOK3S_64_HV | 263 | #ifdef CONFIG_KVM_BOOK3S_64_HV |
264 | extern void kvm_cma_reserve(void) __init; | ||
264 | static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) | 265 | static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) |
265 | { | 266 | { |
266 | paca[cpu].kvm_hstate.xics_phys = addr; | 267 | paca[cpu].kvm_hstate.xics_phys = addr; |
@@ -281,13 +282,12 @@ static inline void kvmppc_set_host_ipi(int cpu, u8 host_ipi) | |||
281 | } | 282 | } |
282 | 283 | ||
283 | extern void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu); | 284 | extern void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu); |
284 | extern void kvm_linear_init(void); | ||
285 | 285 | ||
286 | #else | 286 | #else |
287 | static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) | 287 | static inline void __init kvm_cma_reserve(void) |
288 | {} | 288 | {} |
289 | 289 | ||
290 | static inline void kvm_linear_init(void) | 290 | static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) |
291 | {} | 291 | {} |
292 | 292 | ||
293 | static inline u32 kvmppc_get_xics_latch(void) | 293 | static inline u32 kvmppc_get_xics_latch(void) |
@@ -394,10 +394,15 @@ static inline void kvmppc_mmu_flush_icache(pfn_t pfn) | |||
394 | } | 394 | } |
395 | } | 395 | } |
396 | 396 | ||
397 | /* Please call after prepare_to_enter. This function puts the lazy ee state | 397 | /* |
398 | back to normal mode, without actually enabling interrupts. */ | 398 | * Please call after prepare_to_enter. This function puts the lazy ee and irq |
399 | static inline void kvmppc_lazy_ee_enable(void) | 399 | * disabled tracking state back to normal mode, without actually enabling |
400 | * interrupts. | ||
401 | */ | ||
402 | static inline void kvmppc_fix_ee_before_entry(void) | ||
400 | { | 403 | { |
404 | trace_hardirqs_on(); | ||
405 | |||
401 | #ifdef CONFIG_PPC64 | 406 | #ifdef CONFIG_PPC64 |
402 | /* Only need to enable IRQs by hard enabling them after this */ | 407 | /* Only need to enable IRQs by hard enabling them after this */ |
403 | local_paca->irq_happened = 0; | 408 | local_paca->irq_happened = 0; |
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index 8b2492644754..3fd2f1b6f906 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h | |||
@@ -138,11 +138,11 @@ extern ssize_t power_events_sysfs_show(struct device *dev, | |||
138 | #define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr | 138 | #define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr |
139 | 139 | ||
140 | #define EVENT_ATTR(_name, _id, _suffix) \ | 140 | #define EVENT_ATTR(_name, _id, _suffix) \ |
141 | PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_PM_##_id, \ | 141 | PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_##_id, \ |
142 | power_events_sysfs_show) | 142 | power_events_sysfs_show) |
143 | 143 | ||
144 | #define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g) | 144 | #define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g) |
145 | #define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g) | 145 | #define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g) |
146 | 146 | ||
147 | #define POWER_EVENT_ATTR(_name, _id) EVENT_ATTR(PM_##_name, _id, _p) | 147 | #define POWER_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _p) |
148 | #define POWER_EVENT_PTR(_id) EVENT_PTR(_id, _p) | 148 | #define POWER_EVENT_PTR(_id) EVENT_PTR(_id, _p) |
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index e6ec2cffba16..7d0c7f3a7171 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h | |||
@@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const __be32 *dma_window, | |||
44 | 44 | ||
45 | extern void kdump_move_device_tree(void); | 45 | extern void kdump_move_device_tree(void); |
46 | 46 | ||
47 | /* CPU OF node matching */ | ||
48 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); | ||
49 | |||
50 | /* cache lookup */ | 47 | /* cache lookup */ |
51 | struct device_node *of_find_next_cache_node(struct device_node *np); | 48 | struct device_node *of_find_next_cache_node(struct device_node *np); |
52 | 49 | ||
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 8207459efe56..d8958be5f31a 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -454,6 +454,7 @@ int main(void) | |||
454 | DEFINE(VCPU_SPRG2, offsetof(struct kvm_vcpu, arch.shregs.sprg2)); | 454 | DEFINE(VCPU_SPRG2, offsetof(struct kvm_vcpu, arch.shregs.sprg2)); |
455 | DEFINE(VCPU_SPRG3, offsetof(struct kvm_vcpu, arch.shregs.sprg3)); | 455 | DEFINE(VCPU_SPRG3, offsetof(struct kvm_vcpu, arch.shregs.sprg3)); |
456 | #endif | 456 | #endif |
457 | DEFINE(VCPU_SHARED_SPRG3, offsetof(struct kvm_vcpu_arch_shared, sprg3)); | ||
457 | DEFINE(VCPU_SHARED_SPRG4, offsetof(struct kvm_vcpu_arch_shared, sprg4)); | 458 | DEFINE(VCPU_SHARED_SPRG4, offsetof(struct kvm_vcpu_arch_shared, sprg4)); |
458 | DEFINE(VCPU_SHARED_SPRG5, offsetof(struct kvm_vcpu_arch_shared, sprg5)); | 459 | DEFINE(VCPU_SHARED_SPRG5, offsetof(struct kvm_vcpu_arch_shared, sprg5)); |
459 | DEFINE(VCPU_SHARED_SPRG6, offsetof(struct kvm_vcpu_arch_shared, sprg6)); | 460 | DEFINE(VCPU_SHARED_SPRG6, offsetof(struct kvm_vcpu_arch_shared, sprg6)); |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index b20ff173a671..0adab06ce5c0 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -105,7 +105,7 @@ static int __init fail_iommu_debugfs(void) | |||
105 | struct dentry *dir = fault_create_debugfs_attr("fail_iommu", | 105 | struct dentry *dir = fault_create_debugfs_attr("fail_iommu", |
106 | NULL, &fail_iommu); | 106 | NULL, &fail_iommu); |
107 | 107 | ||
108 | return PTR_RET(dir); | 108 | return PTR_ERR_OR_ZERO(dir); |
109 | } | 109 | } |
110 | late_initcall(fail_iommu_debugfs); | 110 | late_initcall(fail_iommu_debugfs); |
111 | 111 | ||
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index eae0ee00ca25..905a24bb7acc 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -1673,12 +1673,8 @@ void pcibios_scan_phb(struct pci_controller *hose) | |||
1673 | /* Configure PCI Express settings */ | 1673 | /* Configure PCI Express settings */ |
1674 | if (bus && !pci_has_flag(PCI_PROBE_ONLY)) { | 1674 | if (bus && !pci_has_flag(PCI_PROBE_ONLY)) { |
1675 | struct pci_bus *child; | 1675 | struct pci_bus *child; |
1676 | list_for_each_entry(child, &bus->children, node) { | 1676 | list_for_each_entry(child, &bus->children, node) |
1677 | struct pci_dev *self = child->self; | 1677 | pcie_bus_configure_settings(child); |
1678 | if (!self) | ||
1679 | continue; | ||
1680 | pcie_bus_configure_settings(child, self->pcie_mpss); | ||
1681 | } | ||
1682 | } | 1678 | } |
1683 | } | 1679 | } |
1684 | 1680 | ||
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index d87e03fc8cfd..6bfcab97c981 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -893,49 +893,10 @@ static int __init prom_reconfig_setup(void) | |||
893 | __initcall(prom_reconfig_setup); | 893 | __initcall(prom_reconfig_setup); |
894 | #endif | 894 | #endif |
895 | 895 | ||
896 | /* Find the device node for a given logical cpu number, also returns the cpu | 896 | bool arch_match_cpu_phys_id(int cpu, u64 phys_id) |
897 | * local thread number (index in ibm,interrupt-server#s) if relevant and | ||
898 | * asked for (non NULL) | ||
899 | */ | ||
900 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | ||
901 | { | 897 | { |
902 | int hardid; | 898 | return (int)phys_id == get_hard_smp_processor_id(cpu); |
903 | struct device_node *np; | ||
904 | |||
905 | hardid = get_hard_smp_processor_id(cpu); | ||
906 | |||
907 | for_each_node_by_type(np, "cpu") { | ||
908 | const __be32 *intserv; | ||
909 | unsigned int plen, t; | ||
910 | |||
911 | /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist | ||
912 | * fallback to "reg" property and assume no threads | ||
913 | */ | ||
914 | intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", | ||
915 | &plen); | ||
916 | if (intserv == NULL) { | ||
917 | const __be32 *reg = of_get_property(np, "reg", NULL); | ||
918 | if (reg == NULL) | ||
919 | continue; | ||
920 | if (be32_to_cpup(reg) == hardid) { | ||
921 | if (thread) | ||
922 | *thread = 0; | ||
923 | return np; | ||
924 | } | ||
925 | } else { | ||
926 | plen /= sizeof(u32); | ||
927 | for (t = 0; t < plen; t++) { | ||
928 | if (hardid == be32_to_cpu(intserv[t])) { | ||
929 | if (thread) | ||
930 | *thread = t; | ||
931 | return np; | ||
932 | } | ||
933 | } | ||
934 | } | ||
935 | } | ||
936 | return NULL; | ||
937 | } | 899 | } |
938 | EXPORT_SYMBOL(of_get_cpu_node); | ||
939 | 900 | ||
940 | #if defined(CONFIG_DEBUG_FS) && defined(DEBUG) | 901 | #if defined(CONFIG_DEBUG_FS) && defined(DEBUG) |
941 | static struct debugfs_blob_wrapper flat_dt_blob; | 902 | static struct debugfs_blob_wrapper flat_dt_blob; |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 45f2d1fac670..278ca93e1f28 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -232,6 +232,8 @@ void __init early_setup(unsigned long dt_ptr) | |||
232 | /* Initialize the hash table or TLB handling */ | 232 | /* Initialize the hash table or TLB handling */ |
233 | early_init_mmu(); | 233 | early_init_mmu(); |
234 | 234 | ||
235 | kvm_cma_reserve(); | ||
236 | |||
235 | /* | 237 | /* |
236 | * Reserve any gigantic pages requested on the command line. | 238 | * Reserve any gigantic pages requested on the command line. |
237 | * memblock needs to have been initialized by the time this is | 239 | * memblock needs to have been initialized by the time this is |
@@ -624,8 +626,6 @@ void __init setup_arch(char **cmdline_p) | |||
624 | /* Initialize the MMU context management stuff */ | 626 | /* Initialize the MMU context management stuff */ |
625 | mmu_context_init(); | 627 | mmu_context_init(); |
626 | 628 | ||
627 | kvm_linear_init(); | ||
628 | |||
629 | /* Interrupt code needs to be 64K-aligned */ | 629 | /* Interrupt code needs to be 64K-aligned */ |
630 | if ((unsigned long)_stext & 0xffff) | 630 | if ((unsigned long)_stext & 0xffff) |
631 | panic("Kernelbase not 64K-aligned (0x%lx)!\n", | 631 | panic("Kernelbase not 64K-aligned (0x%lx)!\n", |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index b2bcd34f72d2..192b051df97e 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -1049,7 +1049,7 @@ static int __init rtc_init(void) | |||
1049 | 1049 | ||
1050 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | 1050 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); |
1051 | 1051 | ||
1052 | return PTR_RET(pdev); | 1052 | return PTR_ERR_OR_ZERO(pdev); |
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | module_init(rtc_init); | 1055 | module_init(rtc_init); |
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index eb643f862579..ffaef2cb101a 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig | |||
@@ -72,6 +72,7 @@ config KVM_BOOK3S_64_HV | |||
72 | bool "KVM support for POWER7 and PPC970 using hypervisor mode in host" | 72 | bool "KVM support for POWER7 and PPC970 using hypervisor mode in host" |
73 | depends on KVM_BOOK3S_64 | 73 | depends on KVM_BOOK3S_64 |
74 | select MMU_NOTIFIER | 74 | select MMU_NOTIFIER |
75 | select CMA | ||
75 | ---help--- | 76 | ---help--- |
76 | Support running unmodified book3s_64 guest kernels in | 77 | Support running unmodified book3s_64 guest kernels in |
77 | virtual machines on POWER7 and PPC970 processors that have | 78 | virtual machines on POWER7 and PPC970 processors that have |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 008cd856c5b5..6646c952c5e3 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -81,6 +81,7 @@ kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ | |||
81 | book3s_64_vio_hv.o \ | 81 | book3s_64_vio_hv.o \ |
82 | book3s_hv_ras.o \ | 82 | book3s_hv_ras.o \ |
83 | book3s_hv_builtin.o \ | 83 | book3s_hv_builtin.o \ |
84 | book3s_hv_cma.o \ | ||
84 | $(kvm-book3s_64-builtin-xics-objs-y) | 85 | $(kvm-book3s_64-builtin-xics-objs-y) |
85 | 86 | ||
86 | kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \ | 87 | kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \ |
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 739bfbadb85e..7e345e00661a 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c | |||
@@ -182,10 +182,13 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
182 | hva_t ptegp; | 182 | hva_t ptegp; |
183 | u64 pteg[16]; | 183 | u64 pteg[16]; |
184 | u64 avpn = 0; | 184 | u64 avpn = 0; |
185 | u64 v, r; | ||
186 | u64 v_val, v_mask; | ||
187 | u64 eaddr_mask; | ||
185 | int i; | 188 | int i; |
186 | u8 key = 0; | 189 | u8 pp, key = 0; |
187 | bool found = false; | 190 | bool found = false; |
188 | int second = 0; | 191 | bool second = false; |
189 | ulong mp_ea = vcpu->arch.magic_page_ea; | 192 | ulong mp_ea = vcpu->arch.magic_page_ea; |
190 | 193 | ||
191 | /* Magic page override */ | 194 | /* Magic page override */ |
@@ -208,8 +211,16 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
208 | goto no_seg_found; | 211 | goto no_seg_found; |
209 | 212 | ||
210 | avpn = kvmppc_mmu_book3s_64_get_avpn(slbe, eaddr); | 213 | avpn = kvmppc_mmu_book3s_64_get_avpn(slbe, eaddr); |
214 | v_val = avpn & HPTE_V_AVPN; | ||
215 | |||
211 | if (slbe->tb) | 216 | if (slbe->tb) |
212 | avpn |= SLB_VSID_B_1T; | 217 | v_val |= SLB_VSID_B_1T; |
218 | if (slbe->large) | ||
219 | v_val |= HPTE_V_LARGE; | ||
220 | v_val |= HPTE_V_VALID; | ||
221 | |||
222 | v_mask = SLB_VSID_B | HPTE_V_AVPN | HPTE_V_LARGE | HPTE_V_VALID | | ||
223 | HPTE_V_SECONDARY; | ||
213 | 224 | ||
214 | do_second: | 225 | do_second: |
215 | ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu_book3s, slbe, eaddr, second); | 226 | ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu_book3s, slbe, eaddr, second); |
@@ -227,91 +238,74 @@ do_second: | |||
227 | key = 4; | 238 | key = 4; |
228 | 239 | ||
229 | for (i=0; i<16; i+=2) { | 240 | for (i=0; i<16; i+=2) { |
230 | u64 v = pteg[i]; | 241 | /* Check all relevant fields of 1st dword */ |
231 | u64 r = pteg[i+1]; | 242 | if ((pteg[i] & v_mask) == v_val) { |
232 | |||
233 | /* Valid check */ | ||
234 | if (!(v & HPTE_V_VALID)) | ||
235 | continue; | ||
236 | /* Hash check */ | ||
237 | if ((v & HPTE_V_SECONDARY) != second) | ||
238 | continue; | ||
239 | |||
240 | /* AVPN compare */ | ||
241 | if (HPTE_V_COMPARE(avpn, v)) { | ||
242 | u8 pp = (r & HPTE_R_PP) | key; | ||
243 | int eaddr_mask = 0xFFF; | ||
244 | |||
245 | gpte->eaddr = eaddr; | ||
246 | gpte->vpage = kvmppc_mmu_book3s_64_ea_to_vp(vcpu, | ||
247 | eaddr, | ||
248 | data); | ||
249 | if (slbe->large) | ||
250 | eaddr_mask = 0xFFFFFF; | ||
251 | gpte->raddr = (r & HPTE_R_RPN) | (eaddr & eaddr_mask); | ||
252 | gpte->may_execute = ((r & HPTE_R_N) ? false : true); | ||
253 | gpte->may_read = false; | ||
254 | gpte->may_write = false; | ||
255 | |||
256 | switch (pp) { | ||
257 | case 0: | ||
258 | case 1: | ||
259 | case 2: | ||
260 | case 6: | ||
261 | gpte->may_write = true; | ||
262 | /* fall through */ | ||
263 | case 3: | ||
264 | case 5: | ||
265 | case 7: | ||
266 | gpte->may_read = true; | ||
267 | break; | ||
268 | } | ||
269 | |||
270 | dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx " | ||
271 | "-> 0x%lx\n", | ||
272 | eaddr, avpn, gpte->vpage, gpte->raddr); | ||
273 | found = true; | 243 | found = true; |
274 | break; | 244 | break; |
275 | } | 245 | } |
276 | } | 246 | } |
277 | 247 | ||
278 | /* Update PTE R and C bits, so the guest's swapper knows we used the | 248 | if (!found) { |
279 | * page */ | 249 | if (second) |
280 | if (found) { | 250 | goto no_page_found; |
281 | u32 oldr = pteg[i+1]; | 251 | v_val |= HPTE_V_SECONDARY; |
252 | second = true; | ||
253 | goto do_second; | ||
254 | } | ||
282 | 255 | ||
283 | if (gpte->may_read) { | 256 | v = pteg[i]; |
284 | /* Set the accessed flag */ | 257 | r = pteg[i+1]; |
285 | pteg[i+1] |= HPTE_R_R; | 258 | pp = (r & HPTE_R_PP) | key; |
286 | } | 259 | eaddr_mask = 0xFFF; |
287 | if (gpte->may_write) { | 260 | |
288 | /* Set the dirty flag */ | 261 | gpte->eaddr = eaddr; |
289 | pteg[i+1] |= HPTE_R_C; | 262 | gpte->vpage = kvmppc_mmu_book3s_64_ea_to_vp(vcpu, eaddr, data); |
290 | } else { | 263 | if (slbe->large) |
291 | dprintk("KVM: Mapping read-only page!\n"); | 264 | eaddr_mask = 0xFFFFFF; |
292 | } | 265 | gpte->raddr = (r & HPTE_R_RPN & ~eaddr_mask) | (eaddr & eaddr_mask); |
266 | gpte->may_execute = ((r & HPTE_R_N) ? false : true); | ||
267 | gpte->may_read = false; | ||
268 | gpte->may_write = false; | ||
269 | |||
270 | switch (pp) { | ||
271 | case 0: | ||
272 | case 1: | ||
273 | case 2: | ||
274 | case 6: | ||
275 | gpte->may_write = true; | ||
276 | /* fall through */ | ||
277 | case 3: | ||
278 | case 5: | ||
279 | case 7: | ||
280 | gpte->may_read = true; | ||
281 | break; | ||
282 | } | ||
293 | 283 | ||
294 | /* Write back into the PTEG */ | 284 | dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx " |
295 | if (pteg[i+1] != oldr) | 285 | "-> 0x%lx\n", |
296 | copy_to_user((void __user *)ptegp, pteg, sizeof(pteg)); | 286 | eaddr, avpn, gpte->vpage, gpte->raddr); |
297 | 287 | ||
298 | if (!gpte->may_read) | 288 | /* Update PTE R and C bits, so the guest's swapper knows we used the |
299 | return -EPERM; | 289 | * page */ |
300 | return 0; | 290 | if (gpte->may_read) { |
301 | } else { | 291 | /* Set the accessed flag */ |
302 | dprintk("KVM MMU: No PTE found (ea=0x%lx sdr1=0x%llx " | 292 | r |= HPTE_R_R; |
303 | "ptegp=0x%lx)\n", | 293 | } |
304 | eaddr, to_book3s(vcpu)->sdr1, ptegp); | 294 | if (data && gpte->may_write) { |
305 | for (i = 0; i < 16; i += 2) | 295 | /* Set the dirty flag -- XXX even if not writing */ |
306 | dprintk(" %02d: 0x%llx - 0x%llx (0x%llx)\n", | 296 | r |= HPTE_R_C; |
307 | i, pteg[i], pteg[i+1], avpn); | 297 | } |
308 | 298 | ||
309 | if (!second) { | 299 | /* Write back into the PTEG */ |
310 | second = HPTE_V_SECONDARY; | 300 | if (pteg[i+1] != r) { |
311 | goto do_second; | 301 | pteg[i+1] = r; |
312 | } | 302 | copy_to_user((void __user *)ptegp, pteg, sizeof(pteg)); |
313 | } | 303 | } |
314 | 304 | ||
305 | if (!gpte->may_read) | ||
306 | return -EPERM; | ||
307 | return 0; | ||
308 | |||
315 | no_page_found: | 309 | no_page_found: |
316 | return -ENOENT; | 310 | return -ENOENT; |
317 | 311 | ||
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 710d31317d81..043eec8461e7 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <asm/ppc-opcode.h> | 37 | #include <asm/ppc-opcode.h> |
38 | #include <asm/cputable.h> | 38 | #include <asm/cputable.h> |
39 | 39 | ||
40 | #include "book3s_hv_cma.h" | ||
41 | |||
40 | /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ | 42 | /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ |
41 | #define MAX_LPID_970 63 | 43 | #define MAX_LPID_970 63 |
42 | 44 | ||
@@ -52,8 +54,8 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) | |||
52 | { | 54 | { |
53 | unsigned long hpt; | 55 | unsigned long hpt; |
54 | struct revmap_entry *rev; | 56 | struct revmap_entry *rev; |
55 | struct kvmppc_linear_info *li; | 57 | struct page *page = NULL; |
56 | long order = kvm_hpt_order; | 58 | long order = KVM_DEFAULT_HPT_ORDER; |
57 | 59 | ||
58 | if (htab_orderp) { | 60 | if (htab_orderp) { |
59 | order = *htab_orderp; | 61 | order = *htab_orderp; |
@@ -61,26 +63,23 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) | |||
61 | order = PPC_MIN_HPT_ORDER; | 63 | order = PPC_MIN_HPT_ORDER; |
62 | } | 64 | } |
63 | 65 | ||
66 | kvm->arch.hpt_cma_alloc = 0; | ||
64 | /* | 67 | /* |
65 | * If the user wants a different size from default, | ||
66 | * try first to allocate it from the kernel page allocator. | 68 | * try first to allocate it from the kernel page allocator. |
69 | * We keep the CMA reserved for failed allocation. | ||
67 | */ | 70 | */ |
68 | hpt = 0; | 71 | hpt = __get_free_pages(GFP_KERNEL | __GFP_ZERO | __GFP_REPEAT | |
69 | if (order != kvm_hpt_order) { | 72 | __GFP_NOWARN, order - PAGE_SHIFT); |
70 | hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| | ||
71 | __GFP_NOWARN, order - PAGE_SHIFT); | ||
72 | if (!hpt) | ||
73 | --order; | ||
74 | } | ||
75 | 73 | ||
76 | /* Next try to allocate from the preallocated pool */ | 74 | /* Next try to allocate from the preallocated pool */ |
77 | if (!hpt) { | 75 | if (!hpt) { |
78 | li = kvm_alloc_hpt(); | 76 | VM_BUG_ON(order < KVM_CMA_CHUNK_ORDER); |
79 | if (li) { | 77 | page = kvm_alloc_hpt(1 << (order - PAGE_SHIFT)); |
80 | hpt = (ulong)li->base_virt; | 78 | if (page) { |
81 | kvm->arch.hpt_li = li; | 79 | hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); |
82 | order = kvm_hpt_order; | 80 | kvm->arch.hpt_cma_alloc = 1; |
83 | } | 81 | } else |
82 | --order; | ||
84 | } | 83 | } |
85 | 84 | ||
86 | /* Lastly try successively smaller sizes from the page allocator */ | 85 | /* Lastly try successively smaller sizes from the page allocator */ |
@@ -118,8 +117,8 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) | |||
118 | return 0; | 117 | return 0; |
119 | 118 | ||
120 | out_freehpt: | 119 | out_freehpt: |
121 | if (kvm->arch.hpt_li) | 120 | if (kvm->arch.hpt_cma_alloc) |
122 | kvm_release_hpt(kvm->arch.hpt_li); | 121 | kvm_release_hpt(page, 1 << (order - PAGE_SHIFT)); |
123 | else | 122 | else |
124 | free_pages(hpt, order - PAGE_SHIFT); | 123 | free_pages(hpt, order - PAGE_SHIFT); |
125 | return -ENOMEM; | 124 | return -ENOMEM; |
@@ -165,8 +164,9 @@ void kvmppc_free_hpt(struct kvm *kvm) | |||
165 | { | 164 | { |
166 | kvmppc_free_lpid(kvm->arch.lpid); | 165 | kvmppc_free_lpid(kvm->arch.lpid); |
167 | vfree(kvm->arch.revmap); | 166 | vfree(kvm->arch.revmap); |
168 | if (kvm->arch.hpt_li) | 167 | if (kvm->arch.hpt_cma_alloc) |
169 | kvm_release_hpt(kvm->arch.hpt_li); | 168 | kvm_release_hpt(virt_to_page(kvm->arch.hpt_virt), |
169 | 1 << (kvm->arch.hpt_order - PAGE_SHIFT)); | ||
170 | else | 170 | else |
171 | free_pages(kvm->arch.hpt_virt, | 171 | free_pages(kvm->arch.hpt_virt, |
172 | kvm->arch.hpt_order - PAGE_SHIFT); | 172 | kvm->arch.hpt_order - PAGE_SHIFT); |
@@ -1579,7 +1579,7 @@ int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *ghf) | |||
1579 | ctx->first_pass = 1; | 1579 | ctx->first_pass = 1; |
1580 | 1580 | ||
1581 | rwflag = (ghf->flags & KVM_GET_HTAB_WRITE) ? O_WRONLY : O_RDONLY; | 1581 | rwflag = (ghf->flags & KVM_GET_HTAB_WRITE) ? O_WRONLY : O_RDONLY; |
1582 | ret = anon_inode_getfd("kvm-htab", &kvm_htab_fops, ctx, rwflag); | 1582 | ret = anon_inode_getfd("kvm-htab", &kvm_htab_fops, ctx, rwflag | O_CLOEXEC); |
1583 | if (ret < 0) { | 1583 | if (ret < 0) { |
1584 | kvm_put_kvm(kvm); | 1584 | kvm_put_kvm(kvm); |
1585 | return ret; | 1585 | return ret; |
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index b2d3f3b2de72..54cf9bc94dad 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c | |||
@@ -136,7 +136,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, | |||
136 | mutex_unlock(&kvm->lock); | 136 | mutex_unlock(&kvm->lock); |
137 | 137 | ||
138 | return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, | 138 | return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, |
139 | stt, O_RDWR); | 139 | stt, O_RDWR | O_CLOEXEC); |
140 | 140 | ||
141 | fail: | 141 | fail: |
142 | if (stt) { | 142 | if (stt) { |
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 1f6344c4408d..360ce68c9809 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c | |||
@@ -458,6 +458,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
458 | case SPRN_PMC4_GEKKO: | 458 | case SPRN_PMC4_GEKKO: |
459 | case SPRN_WPAR_GEKKO: | 459 | case SPRN_WPAR_GEKKO: |
460 | case SPRN_MSSSR0: | 460 | case SPRN_MSSSR0: |
461 | case SPRN_DABR: | ||
461 | break; | 462 | break; |
462 | unprivileged: | 463 | unprivileged: |
463 | default: | 464 | default: |
@@ -555,6 +556,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) | |||
555 | case SPRN_PMC4_GEKKO: | 556 | case SPRN_PMC4_GEKKO: |
556 | case SPRN_WPAR_GEKKO: | 557 | case SPRN_WPAR_GEKKO: |
557 | case SPRN_MSSSR0: | 558 | case SPRN_MSSSR0: |
559 | case SPRN_DABR: | ||
558 | *spr_val = 0; | 560 | *spr_val = 0; |
559 | break; | 561 | break; |
560 | default: | 562 | default: |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index e8d51cb76752..62a2b5ab08ed 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -680,13 +680,12 @@ static int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
680 | } | 680 | } |
681 | 681 | ||
682 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | 682 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, |
683 | struct kvm_sregs *sregs) | 683 | struct kvm_sregs *sregs) |
684 | { | 684 | { |
685 | int i; | 685 | int i; |
686 | 686 | ||
687 | sregs->pvr = vcpu->arch.pvr; | ||
688 | |||
689 | memset(sregs, 0, sizeof(struct kvm_sregs)); | 687 | memset(sregs, 0, sizeof(struct kvm_sregs)); |
688 | sregs->pvr = vcpu->arch.pvr; | ||
690 | for (i = 0; i < vcpu->arch.slb_max; i++) { | 689 | for (i = 0; i < vcpu->arch.slb_max; i++) { |
691 | sregs->u.s.ppc64.slb[i].slbe = vcpu->arch.slb[i].orige; | 690 | sregs->u.s.ppc64.slb[i].slbe = vcpu->arch.slb[i].orige; |
692 | sregs->u.s.ppc64.slb[i].slbv = vcpu->arch.slb[i].origv; | 691 | sregs->u.s.ppc64.slb[i].slbv = vcpu->arch.slb[i].origv; |
@@ -696,7 +695,7 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | |||
696 | } | 695 | } |
697 | 696 | ||
698 | int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | 697 | int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, |
699 | struct kvm_sregs *sregs) | 698 | struct kvm_sregs *sregs) |
700 | { | 699 | { |
701 | int i, j; | 700 | int i, j; |
702 | 701 | ||
@@ -1511,10 +1510,10 @@ static inline int lpcr_rmls(unsigned long rma_size) | |||
1511 | 1510 | ||
1512 | static int kvm_rma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 1511 | static int kvm_rma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
1513 | { | 1512 | { |
1514 | struct kvmppc_linear_info *ri = vma->vm_file->private_data; | ||
1515 | struct page *page; | 1513 | struct page *page; |
1514 | struct kvm_rma_info *ri = vma->vm_file->private_data; | ||
1516 | 1515 | ||
1517 | if (vmf->pgoff >= ri->npages) | 1516 | if (vmf->pgoff >= kvm_rma_pages) |
1518 | return VM_FAULT_SIGBUS; | 1517 | return VM_FAULT_SIGBUS; |
1519 | 1518 | ||
1520 | page = pfn_to_page(ri->base_pfn + vmf->pgoff); | 1519 | page = pfn_to_page(ri->base_pfn + vmf->pgoff); |
@@ -1536,7 +1535,7 @@ static int kvm_rma_mmap(struct file *file, struct vm_area_struct *vma) | |||
1536 | 1535 | ||
1537 | static int kvm_rma_release(struct inode *inode, struct file *filp) | 1536 | static int kvm_rma_release(struct inode *inode, struct file *filp) |
1538 | { | 1537 | { |
1539 | struct kvmppc_linear_info *ri = filp->private_data; | 1538 | struct kvm_rma_info *ri = filp->private_data; |
1540 | 1539 | ||
1541 | kvm_release_rma(ri); | 1540 | kvm_release_rma(ri); |
1542 | return 0; | 1541 | return 0; |
@@ -1549,18 +1548,27 @@ static const struct file_operations kvm_rma_fops = { | |||
1549 | 1548 | ||
1550 | long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret) | 1549 | long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret) |
1551 | { | 1550 | { |
1552 | struct kvmppc_linear_info *ri; | ||
1553 | long fd; | 1551 | long fd; |
1552 | struct kvm_rma_info *ri; | ||
1553 | /* | ||
1554 | * Only do this on PPC970 in HV mode | ||
1555 | */ | ||
1556 | if (!cpu_has_feature(CPU_FTR_HVMODE) || | ||
1557 | !cpu_has_feature(CPU_FTR_ARCH_201)) | ||
1558 | return -EINVAL; | ||
1559 | |||
1560 | if (!kvm_rma_pages) | ||
1561 | return -EINVAL; | ||
1554 | 1562 | ||
1555 | ri = kvm_alloc_rma(); | 1563 | ri = kvm_alloc_rma(); |
1556 | if (!ri) | 1564 | if (!ri) |
1557 | return -ENOMEM; | 1565 | return -ENOMEM; |
1558 | 1566 | ||
1559 | fd = anon_inode_getfd("kvm-rma", &kvm_rma_fops, ri, O_RDWR); | 1567 | fd = anon_inode_getfd("kvm-rma", &kvm_rma_fops, ri, O_RDWR | O_CLOEXEC); |
1560 | if (fd < 0) | 1568 | if (fd < 0) |
1561 | kvm_release_rma(ri); | 1569 | kvm_release_rma(ri); |
1562 | 1570 | ||
1563 | ret->rma_size = ri->npages << PAGE_SHIFT; | 1571 | ret->rma_size = kvm_rma_pages << PAGE_SHIFT; |
1564 | return fd; | 1572 | return fd; |
1565 | } | 1573 | } |
1566 | 1574 | ||
@@ -1725,7 +1733,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) | |||
1725 | { | 1733 | { |
1726 | int err = 0; | 1734 | int err = 0; |
1727 | struct kvm *kvm = vcpu->kvm; | 1735 | struct kvm *kvm = vcpu->kvm; |
1728 | struct kvmppc_linear_info *ri = NULL; | 1736 | struct kvm_rma_info *ri = NULL; |
1729 | unsigned long hva; | 1737 | unsigned long hva; |
1730 | struct kvm_memory_slot *memslot; | 1738 | struct kvm_memory_slot *memslot; |
1731 | struct vm_area_struct *vma; | 1739 | struct vm_area_struct *vma; |
@@ -1803,7 +1811,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) | |||
1803 | 1811 | ||
1804 | } else { | 1812 | } else { |
1805 | /* Set up to use an RMO region */ | 1813 | /* Set up to use an RMO region */ |
1806 | rma_size = ri->npages; | 1814 | rma_size = kvm_rma_pages; |
1807 | if (rma_size > memslot->npages) | 1815 | if (rma_size > memslot->npages) |
1808 | rma_size = memslot->npages; | 1816 | rma_size = memslot->npages; |
1809 | rma_size <<= PAGE_SHIFT; | 1817 | rma_size <<= PAGE_SHIFT; |
@@ -1831,14 +1839,14 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) | |||
1831 | /* POWER7 */ | 1839 | /* POWER7 */ |
1832 | lpcr &= ~(LPCR_VPM0 | LPCR_VRMA_L); | 1840 | lpcr &= ~(LPCR_VPM0 | LPCR_VRMA_L); |
1833 | lpcr |= rmls << LPCR_RMLS_SH; | 1841 | lpcr |= rmls << LPCR_RMLS_SH; |
1834 | kvm->arch.rmor = kvm->arch.rma->base_pfn << PAGE_SHIFT; | 1842 | kvm->arch.rmor = ri->base_pfn << PAGE_SHIFT; |
1835 | } | 1843 | } |
1836 | kvm->arch.lpcr = lpcr; | 1844 | kvm->arch.lpcr = lpcr; |
1837 | pr_info("KVM: Using RMO at %lx size %lx (LPCR = %lx)\n", | 1845 | pr_info("KVM: Using RMO at %lx size %lx (LPCR = %lx)\n", |
1838 | ri->base_pfn << PAGE_SHIFT, rma_size, lpcr); | 1846 | ri->base_pfn << PAGE_SHIFT, rma_size, lpcr); |
1839 | 1847 | ||
1840 | /* Initialize phys addrs of pages in RMO */ | 1848 | /* Initialize phys addrs of pages in RMO */ |
1841 | npages = ri->npages; | 1849 | npages = kvm_rma_pages; |
1842 | porder = __ilog2(npages); | 1850 | porder = __ilog2(npages); |
1843 | physp = memslot->arch.slot_phys; | 1851 | physp = memslot->arch.slot_phys; |
1844 | if (physp) { | 1852 | if (physp) { |
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index ec0a9e5de100..8cd0daebb82d 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -13,33 +13,34 @@ | |||
13 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
14 | #include <linux/bootmem.h> | 14 | #include <linux/bootmem.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/memblock.h> | ||
17 | #include <linux/sizes.h> | ||
16 | 18 | ||
17 | #include <asm/cputable.h> | 19 | #include <asm/cputable.h> |
18 | #include <asm/kvm_ppc.h> | 20 | #include <asm/kvm_ppc.h> |
19 | #include <asm/kvm_book3s.h> | 21 | #include <asm/kvm_book3s.h> |
20 | 22 | ||
21 | #define KVM_LINEAR_RMA 0 | 23 | #include "book3s_hv_cma.h" |
22 | #define KVM_LINEAR_HPT 1 | 24 | /* |
23 | 25 | * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206) | |
24 | static void __init kvm_linear_init_one(ulong size, int count, int type); | 26 | * should be power of 2. |
25 | static struct kvmppc_linear_info *kvm_alloc_linear(int type); | 27 | */ |
26 | static void kvm_release_linear(struct kvmppc_linear_info *ri); | 28 | #define HPT_ALIGN_PAGES ((1 << 18) >> PAGE_SHIFT) /* 256k */ |
27 | 29 | /* | |
28 | int kvm_hpt_order = KVM_DEFAULT_HPT_ORDER; | 30 | * By default we reserve 5% of memory for hash pagetable allocation. |
29 | EXPORT_SYMBOL_GPL(kvm_hpt_order); | 31 | */ |
30 | 32 | static unsigned long kvm_cma_resv_ratio = 5; | |
31 | /*************** RMA *************/ | ||
32 | |||
33 | /* | 33 | /* |
34 | * This maintains a list of RMAs (real mode areas) for KVM guests to use. | 34 | * We allocate RMAs (real mode areas) for KVM guests from the KVM CMA area. |
35 | * Each RMA has to be physically contiguous and of a size that the | 35 | * Each RMA has to be physically contiguous and of a size that the |
36 | * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB, | 36 | * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB, |
37 | * and other larger sizes. Since we are unlikely to be allocate that | 37 | * and other larger sizes. Since we are unlikely to be allocate that |
38 | * much physically contiguous memory after the system is up and running, | 38 | * much physically contiguous memory after the system is up and running, |
39 | * we preallocate a set of RMAs in early boot for KVM to use. | 39 | * we preallocate a set of RMAs in early boot using CMA. |
40 | * should be power of 2. | ||
40 | */ | 41 | */ |
41 | static unsigned long kvm_rma_size = 64 << 20; /* 64MB */ | 42 | unsigned long kvm_rma_pages = (1 << 27) >> PAGE_SHIFT; /* 128MB */ |
42 | static unsigned long kvm_rma_count; | 43 | EXPORT_SYMBOL_GPL(kvm_rma_pages); |
43 | 44 | ||
44 | /* Work out RMLS (real mode limit selector) field value for a given RMA size. | 45 | /* Work out RMLS (real mode limit selector) field value for a given RMA size. |
45 | Assumes POWER7 or PPC970. */ | 46 | Assumes POWER7 or PPC970. */ |
@@ -69,165 +70,114 @@ static inline int lpcr_rmls(unsigned long rma_size) | |||
69 | 70 | ||
70 | static int __init early_parse_rma_size(char *p) | 71 | static int __init early_parse_rma_size(char *p) |
71 | { | 72 | { |
72 | if (!p) | 73 | unsigned long kvm_rma_size; |
73 | return 1; | ||
74 | 74 | ||
75 | pr_debug("%s(%s)\n", __func__, p); | ||
76 | if (!p) | ||
77 | return -EINVAL; | ||
75 | kvm_rma_size = memparse(p, &p); | 78 | kvm_rma_size = memparse(p, &p); |
76 | 79 | /* | |
80 | * Check that the requested size is one supported in hardware | ||
81 | */ | ||
82 | if (lpcr_rmls(kvm_rma_size) < 0) { | ||
83 | pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | kvm_rma_pages = kvm_rma_size >> PAGE_SHIFT; | ||
77 | return 0; | 87 | return 0; |
78 | } | 88 | } |
79 | early_param("kvm_rma_size", early_parse_rma_size); | 89 | early_param("kvm_rma_size", early_parse_rma_size); |
80 | 90 | ||
81 | static int __init early_parse_rma_count(char *p) | 91 | struct kvm_rma_info *kvm_alloc_rma() |
82 | { | 92 | { |
83 | if (!p) | 93 | struct page *page; |
84 | return 1; | 94 | struct kvm_rma_info *ri; |
85 | 95 | ||
86 | kvm_rma_count = simple_strtoul(p, NULL, 0); | 96 | ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL); |
87 | 97 | if (!ri) | |
88 | return 0; | 98 | return NULL; |
89 | } | 99 | page = kvm_alloc_cma(kvm_rma_pages, kvm_rma_pages); |
90 | early_param("kvm_rma_count", early_parse_rma_count); | 100 | if (!page) |
91 | 101 | goto err_out; | |
92 | struct kvmppc_linear_info *kvm_alloc_rma(void) | 102 | atomic_set(&ri->use_count, 1); |
93 | { | 103 | ri->base_pfn = page_to_pfn(page); |
94 | return kvm_alloc_linear(KVM_LINEAR_RMA); | 104 | return ri; |
105 | err_out: | ||
106 | kfree(ri); | ||
107 | return NULL; | ||
95 | } | 108 | } |
96 | EXPORT_SYMBOL_GPL(kvm_alloc_rma); | 109 | EXPORT_SYMBOL_GPL(kvm_alloc_rma); |
97 | 110 | ||
98 | void kvm_release_rma(struct kvmppc_linear_info *ri) | 111 | void kvm_release_rma(struct kvm_rma_info *ri) |
99 | { | 112 | { |
100 | kvm_release_linear(ri); | 113 | if (atomic_dec_and_test(&ri->use_count)) { |
114 | kvm_release_cma(pfn_to_page(ri->base_pfn), kvm_rma_pages); | ||
115 | kfree(ri); | ||
116 | } | ||
101 | } | 117 | } |
102 | EXPORT_SYMBOL_GPL(kvm_release_rma); | 118 | EXPORT_SYMBOL_GPL(kvm_release_rma); |
103 | 119 | ||
104 | /*************** HPT *************/ | 120 | static int __init early_parse_kvm_cma_resv(char *p) |
105 | |||
106 | /* | ||
107 | * This maintains a list of big linear HPT tables that contain the GVA->HPA | ||
108 | * memory mappings. If we don't reserve those early on, we might not be able | ||
109 | * to get a big (usually 16MB) linear memory region from the kernel anymore. | ||
110 | */ | ||
111 | |||
112 | static unsigned long kvm_hpt_count; | ||
113 | |||
114 | static int __init early_parse_hpt_count(char *p) | ||
115 | { | 121 | { |
122 | pr_debug("%s(%s)\n", __func__, p); | ||
116 | if (!p) | 123 | if (!p) |
117 | return 1; | 124 | return -EINVAL; |
118 | 125 | return kstrtoul(p, 0, &kvm_cma_resv_ratio); | |
119 | kvm_hpt_count = simple_strtoul(p, NULL, 0); | ||
120 | |||
121 | return 0; | ||
122 | } | 126 | } |
123 | early_param("kvm_hpt_count", early_parse_hpt_count); | 127 | early_param("kvm_cma_resv_ratio", early_parse_kvm_cma_resv); |
124 | 128 | ||
125 | struct kvmppc_linear_info *kvm_alloc_hpt(void) | 129 | struct page *kvm_alloc_hpt(unsigned long nr_pages) |
126 | { | 130 | { |
127 | return kvm_alloc_linear(KVM_LINEAR_HPT); | 131 | unsigned long align_pages = HPT_ALIGN_PAGES; |
132 | |||
133 | /* Old CPUs require HPT aligned on a multiple of its size */ | ||
134 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | ||
135 | align_pages = nr_pages; | ||
136 | return kvm_alloc_cma(nr_pages, align_pages); | ||
128 | } | 137 | } |
129 | EXPORT_SYMBOL_GPL(kvm_alloc_hpt); | 138 | EXPORT_SYMBOL_GPL(kvm_alloc_hpt); |
130 | 139 | ||
131 | void kvm_release_hpt(struct kvmppc_linear_info *li) | 140 | void kvm_release_hpt(struct page *page, unsigned long nr_pages) |
132 | { | 141 | { |
133 | kvm_release_linear(li); | 142 | kvm_release_cma(page, nr_pages); |
134 | } | 143 | } |
135 | EXPORT_SYMBOL_GPL(kvm_release_hpt); | 144 | EXPORT_SYMBOL_GPL(kvm_release_hpt); |
136 | 145 | ||
137 | /*************** generic *************/ | 146 | /** |
138 | 147 | * kvm_cma_reserve() - reserve area for kvm hash pagetable | |
139 | static LIST_HEAD(free_linears); | 148 | * |
140 | static DEFINE_SPINLOCK(linear_lock); | 149 | * This function reserves memory from early allocator. It should be |
141 | 150 | * called by arch specific code once the early allocator (memblock or bootmem) | |
142 | static void __init kvm_linear_init_one(ulong size, int count, int type) | 151 | * has been activated and all other subsystems have already allocated/reserved |
143 | { | 152 | * memory. |
144 | unsigned long i; | ||
145 | unsigned long j, npages; | ||
146 | void *linear; | ||
147 | struct page *pg; | ||
148 | const char *typestr; | ||
149 | struct kvmppc_linear_info *linear_info; | ||
150 | |||
151 | if (!count) | ||
152 | return; | ||
153 | |||
154 | typestr = (type == KVM_LINEAR_RMA) ? "RMA" : "HPT"; | ||
155 | |||
156 | npages = size >> PAGE_SHIFT; | ||
157 | linear_info = alloc_bootmem(count * sizeof(struct kvmppc_linear_info)); | ||
158 | for (i = 0; i < count; ++i) { | ||
159 | linear = alloc_bootmem_align(size, size); | ||
160 | pr_debug("Allocated KVM %s at %p (%ld MB)\n", typestr, linear, | ||
161 | size >> 20); | ||
162 | linear_info[i].base_virt = linear; | ||
163 | linear_info[i].base_pfn = __pa(linear) >> PAGE_SHIFT; | ||
164 | linear_info[i].npages = npages; | ||
165 | linear_info[i].type = type; | ||
166 | list_add_tail(&linear_info[i].list, &free_linears); | ||
167 | atomic_set(&linear_info[i].use_count, 0); | ||
168 | |||
169 | pg = pfn_to_page(linear_info[i].base_pfn); | ||
170 | for (j = 0; j < npages; ++j) { | ||
171 | atomic_inc(&pg->_count); | ||
172 | ++pg; | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static struct kvmppc_linear_info *kvm_alloc_linear(int type) | ||
178 | { | ||
179 | struct kvmppc_linear_info *ri, *ret; | ||
180 | |||
181 | ret = NULL; | ||
182 | spin_lock(&linear_lock); | ||
183 | list_for_each_entry(ri, &free_linears, list) { | ||
184 | if (ri->type != type) | ||
185 | continue; | ||
186 | |||
187 | list_del(&ri->list); | ||
188 | atomic_inc(&ri->use_count); | ||
189 | memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT); | ||
190 | ret = ri; | ||
191 | break; | ||
192 | } | ||
193 | spin_unlock(&linear_lock); | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static void kvm_release_linear(struct kvmppc_linear_info *ri) | ||
198 | { | ||
199 | if (atomic_dec_and_test(&ri->use_count)) { | ||
200 | spin_lock(&linear_lock); | ||
201 | list_add_tail(&ri->list, &free_linears); | ||
202 | spin_unlock(&linear_lock); | ||
203 | |||
204 | } | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * Called at boot time while the bootmem allocator is active, | ||
209 | * to allocate contiguous physical memory for the hash page | ||
210 | * tables for guests. | ||
211 | */ | 153 | */ |
212 | void __init kvm_linear_init(void) | 154 | void __init kvm_cma_reserve(void) |
213 | { | 155 | { |
214 | /* HPT */ | 156 | unsigned long align_size; |
215 | kvm_linear_init_one(1 << kvm_hpt_order, kvm_hpt_count, KVM_LINEAR_HPT); | 157 | struct memblock_region *reg; |
216 | 158 | phys_addr_t selected_size = 0; | |
217 | /* RMA */ | 159 | /* |
218 | /* Only do this on PPC970 in HV mode */ | 160 | * We cannot use memblock_phys_mem_size() here, because |
219 | if (!cpu_has_feature(CPU_FTR_HVMODE) || | 161 | * memblock_analyze() has not been called yet. |
220 | !cpu_has_feature(CPU_FTR_ARCH_201)) | 162 | */ |
221 | return; | 163 | for_each_memblock(memory, reg) |
222 | 164 | selected_size += memblock_region_memory_end_pfn(reg) - | |
223 | if (!kvm_rma_size || !kvm_rma_count) | 165 | memblock_region_memory_base_pfn(reg); |
224 | return; | 166 | |
225 | 167 | selected_size = (selected_size * kvm_cma_resv_ratio / 100) << PAGE_SHIFT; | |
226 | /* Check that the requested size is one supported in hardware */ | 168 | if (selected_size) { |
227 | if (lpcr_rmls(kvm_rma_size) < 0) { | 169 | pr_debug("%s: reserving %ld MiB for global area\n", __func__, |
228 | pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size); | 170 | (unsigned long)selected_size / SZ_1M); |
229 | return; | 171 | /* |
172 | * Old CPUs require HPT aligned on a multiple of its size. So for them | ||
173 | * make the alignment as max size we could request. | ||
174 | */ | ||
175 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | ||
176 | align_size = __rounddown_pow_of_two(selected_size); | ||
177 | else | ||
178 | align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; | ||
179 | |||
180 | align_size = max(kvm_rma_pages << PAGE_SHIFT, align_size); | ||
181 | kvm_cma_declare_contiguous(selected_size, align_size); | ||
230 | } | 182 | } |
231 | |||
232 | kvm_linear_init_one(kvm_rma_size, kvm_rma_count, KVM_LINEAR_RMA); | ||
233 | } | 183 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_cma.c b/arch/powerpc/kvm/book3s_hv_cma.c new file mode 100644 index 000000000000..d9d3d8553d51 --- /dev/null +++ b/arch/powerpc/kvm/book3s_hv_cma.c | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | * Contiguous Memory Allocator for ppc KVM hash pagetable based on CMA | ||
3 | * for DMA mapping framework | ||
4 | * | ||
5 | * Copyright IBM Corporation, 2013 | ||
6 | * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License or (at your optional) any later version of the license. | ||
12 | * | ||
13 | */ | ||
14 | #define pr_fmt(fmt) "kvm_cma: " fmt | ||
15 | |||
16 | #ifdef CONFIG_CMA_DEBUG | ||
17 | #ifndef DEBUG | ||
18 | # define DEBUG | ||
19 | #endif | ||
20 | #endif | ||
21 | |||
22 | #include <linux/memblock.h> | ||
23 | #include <linux/mutex.h> | ||
24 | #include <linux/sizes.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | #include "book3s_hv_cma.h" | ||
28 | |||
29 | struct kvm_cma { | ||
30 | unsigned long base_pfn; | ||
31 | unsigned long count; | ||
32 | unsigned long *bitmap; | ||
33 | }; | ||
34 | |||
35 | static DEFINE_MUTEX(kvm_cma_mutex); | ||
36 | static struct kvm_cma kvm_cma_area; | ||
37 | |||
38 | /** | ||
39 | * kvm_cma_declare_contiguous() - reserve area for contiguous memory handling | ||
40 | * for kvm hash pagetable | ||
41 | * @size: Size of the reserved memory. | ||
42 | * @alignment: Alignment for the contiguous memory area | ||
43 | * | ||
44 | * This function reserves memory for kvm cma area. It should be | ||
45 | * called by arch code when early allocator (memblock or bootmem) | ||
46 | * is still activate. | ||
47 | */ | ||
48 | long __init kvm_cma_declare_contiguous(phys_addr_t size, phys_addr_t alignment) | ||
49 | { | ||
50 | long base_pfn; | ||
51 | phys_addr_t addr; | ||
52 | struct kvm_cma *cma = &kvm_cma_area; | ||
53 | |||
54 | pr_debug("%s(size %lx)\n", __func__, (unsigned long)size); | ||
55 | |||
56 | if (!size) | ||
57 | return -EINVAL; | ||
58 | /* | ||
59 | * Sanitise input arguments. | ||
60 | * We should be pageblock aligned for CMA. | ||
61 | */ | ||
62 | alignment = max(alignment, (phys_addr_t)(PAGE_SIZE << pageblock_order)); | ||
63 | size = ALIGN(size, alignment); | ||
64 | /* | ||
65 | * Reserve memory | ||
66 | * Use __memblock_alloc_base() since | ||
67 | * memblock_alloc_base() panic()s. | ||
68 | */ | ||
69 | addr = __memblock_alloc_base(size, alignment, 0); | ||
70 | if (!addr) { | ||
71 | base_pfn = -ENOMEM; | ||
72 | goto err; | ||
73 | } else | ||
74 | base_pfn = PFN_DOWN(addr); | ||
75 | |||
76 | /* | ||
77 | * Each reserved area must be initialised later, when more kernel | ||
78 | * subsystems (like slab allocator) are available. | ||
79 | */ | ||
80 | cma->base_pfn = base_pfn; | ||
81 | cma->count = size >> PAGE_SHIFT; | ||
82 | pr_info("CMA: reserved %ld MiB\n", (unsigned long)size / SZ_1M); | ||
83 | return 0; | ||
84 | err: | ||
85 | pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M); | ||
86 | return base_pfn; | ||
87 | } | ||
88 | |||
89 | /** | ||
90 | * kvm_alloc_cma() - allocate pages from contiguous area | ||
91 | * @nr_pages: Requested number of pages. | ||
92 | * @align_pages: Requested alignment in number of pages | ||
93 | * | ||
94 | * This function allocates memory buffer for hash pagetable. | ||
95 | */ | ||
96 | struct page *kvm_alloc_cma(unsigned long nr_pages, unsigned long align_pages) | ||
97 | { | ||
98 | int ret; | ||
99 | struct page *page = NULL; | ||
100 | struct kvm_cma *cma = &kvm_cma_area; | ||
101 | unsigned long chunk_count, nr_chunk; | ||
102 | unsigned long mask, pfn, pageno, start = 0; | ||
103 | |||
104 | |||
105 | if (!cma || !cma->count) | ||
106 | return NULL; | ||
107 | |||
108 | pr_debug("%s(cma %p, count %lu, align pages %lu)\n", __func__, | ||
109 | (void *)cma, nr_pages, align_pages); | ||
110 | |||
111 | if (!nr_pages) | ||
112 | return NULL; | ||
113 | /* | ||
114 | * align mask with chunk size. The bit tracks pages in chunk size | ||
115 | */ | ||
116 | VM_BUG_ON(!is_power_of_2(align_pages)); | ||
117 | mask = (align_pages >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT)) - 1; | ||
118 | BUILD_BUG_ON(PAGE_SHIFT > KVM_CMA_CHUNK_ORDER); | ||
119 | |||
120 | chunk_count = cma->count >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); | ||
121 | nr_chunk = nr_pages >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); | ||
122 | |||
123 | mutex_lock(&kvm_cma_mutex); | ||
124 | for (;;) { | ||
125 | pageno = bitmap_find_next_zero_area(cma->bitmap, chunk_count, | ||
126 | start, nr_chunk, mask); | ||
127 | if (pageno >= chunk_count) | ||
128 | break; | ||
129 | |||
130 | pfn = cma->base_pfn + (pageno << (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT)); | ||
131 | ret = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_CMA); | ||
132 | if (ret == 0) { | ||
133 | bitmap_set(cma->bitmap, pageno, nr_chunk); | ||
134 | page = pfn_to_page(pfn); | ||
135 | memset(pfn_to_kaddr(pfn), 0, nr_pages << PAGE_SHIFT); | ||
136 | break; | ||
137 | } else if (ret != -EBUSY) { | ||
138 | break; | ||
139 | } | ||
140 | pr_debug("%s(): memory range at %p is busy, retrying\n", | ||
141 | __func__, pfn_to_page(pfn)); | ||
142 | /* try again with a bit different memory target */ | ||
143 | start = pageno + mask + 1; | ||
144 | } | ||
145 | mutex_unlock(&kvm_cma_mutex); | ||
146 | pr_debug("%s(): returned %p\n", __func__, page); | ||
147 | return page; | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * kvm_release_cma() - release allocated pages for hash pagetable | ||
152 | * @pages: Allocated pages. | ||
153 | * @nr_pages: Number of allocated pages. | ||
154 | * | ||
155 | * This function releases memory allocated by kvm_alloc_cma(). | ||
156 | * It returns false when provided pages do not belong to contiguous area and | ||
157 | * true otherwise. | ||
158 | */ | ||
159 | bool kvm_release_cma(struct page *pages, unsigned long nr_pages) | ||
160 | { | ||
161 | unsigned long pfn; | ||
162 | unsigned long nr_chunk; | ||
163 | struct kvm_cma *cma = &kvm_cma_area; | ||
164 | |||
165 | if (!cma || !pages) | ||
166 | return false; | ||
167 | |||
168 | pr_debug("%s(page %p count %lu)\n", __func__, (void *)pages, nr_pages); | ||
169 | |||
170 | pfn = page_to_pfn(pages); | ||
171 | |||
172 | if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count) | ||
173 | return false; | ||
174 | |||
175 | VM_BUG_ON(pfn + nr_pages > cma->base_pfn + cma->count); | ||
176 | nr_chunk = nr_pages >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); | ||
177 | |||
178 | mutex_lock(&kvm_cma_mutex); | ||
179 | bitmap_clear(cma->bitmap, | ||
180 | (pfn - cma->base_pfn) >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT), | ||
181 | nr_chunk); | ||
182 | free_contig_range(pfn, nr_pages); | ||
183 | mutex_unlock(&kvm_cma_mutex); | ||
184 | |||
185 | return true; | ||
186 | } | ||
187 | |||
188 | static int __init kvm_cma_activate_area(unsigned long base_pfn, | ||
189 | unsigned long count) | ||
190 | { | ||
191 | unsigned long pfn = base_pfn; | ||
192 | unsigned i = count >> pageblock_order; | ||
193 | struct zone *zone; | ||
194 | |||
195 | WARN_ON_ONCE(!pfn_valid(pfn)); | ||
196 | zone = page_zone(pfn_to_page(pfn)); | ||
197 | do { | ||
198 | unsigned j; | ||
199 | base_pfn = pfn; | ||
200 | for (j = pageblock_nr_pages; j; --j, pfn++) { | ||
201 | WARN_ON_ONCE(!pfn_valid(pfn)); | ||
202 | /* | ||
203 | * alloc_contig_range requires the pfn range | ||
204 | * specified to be in the same zone. Make this | ||
205 | * simple by forcing the entire CMA resv range | ||
206 | * to be in the same zone. | ||
207 | */ | ||
208 | if (page_zone(pfn_to_page(pfn)) != zone) | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | init_cma_reserved_pageblock(pfn_to_page(base_pfn)); | ||
212 | } while (--i); | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int __init kvm_cma_init_reserved_areas(void) | ||
217 | { | ||
218 | int bitmap_size, ret; | ||
219 | unsigned long chunk_count; | ||
220 | struct kvm_cma *cma = &kvm_cma_area; | ||
221 | |||
222 | pr_debug("%s()\n", __func__); | ||
223 | if (!cma->count) | ||
224 | return 0; | ||
225 | chunk_count = cma->count >> (KVM_CMA_CHUNK_ORDER - PAGE_SHIFT); | ||
226 | bitmap_size = BITS_TO_LONGS(chunk_count) * sizeof(long); | ||
227 | cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
228 | if (!cma->bitmap) | ||
229 | return -ENOMEM; | ||
230 | |||
231 | ret = kvm_cma_activate_area(cma->base_pfn, cma->count); | ||
232 | if (ret) | ||
233 | goto error; | ||
234 | return 0; | ||
235 | |||
236 | error: | ||
237 | kfree(cma->bitmap); | ||
238 | return ret; | ||
239 | } | ||
240 | core_initcall(kvm_cma_init_reserved_areas); | ||
diff --git a/arch/powerpc/kvm/book3s_hv_cma.h b/arch/powerpc/kvm/book3s_hv_cma.h new file mode 100644 index 000000000000..655144f75fa5 --- /dev/null +++ b/arch/powerpc/kvm/book3s_hv_cma.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * Contiguous Memory Allocator for ppc KVM hash pagetable based on CMA | ||
3 | * for DMA mapping framework | ||
4 | * | ||
5 | * Copyright IBM Corporation, 2013 | ||
6 | * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License or (at your optional) any later version of the license. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #ifndef __POWERPC_KVM_CMA_ALLOC_H__ | ||
16 | #define __POWERPC_KVM_CMA_ALLOC_H__ | ||
17 | /* | ||
18 | * Both RMA and Hash page allocation will be multiple of 256K. | ||
19 | */ | ||
20 | #define KVM_CMA_CHUNK_ORDER 18 | ||
21 | |||
22 | extern struct page *kvm_alloc_cma(unsigned long nr_pages, | ||
23 | unsigned long align_pages); | ||
24 | extern bool kvm_release_cma(struct page *pages, unsigned long nr_pages); | ||
25 | extern long kvm_cma_declare_contiguous(phys_addr_t size, | ||
26 | phys_addr_t alignment) __init; | ||
27 | #endif | ||
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index c3785d4aeed7..9c515440ad1a 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -387,6 +387,80 @@ static inline int try_lock_tlbie(unsigned int *lock) | |||
387 | return old == 0; | 387 | return old == 0; |
388 | } | 388 | } |
389 | 389 | ||
390 | /* | ||
391 | * tlbie/tlbiel is a bit different on the PPC970 compared to later | ||
392 | * processors such as POWER7; the large page bit is in the instruction | ||
393 | * not RB, and the top 16 bits and the bottom 12 bits of the VA | ||
394 | * in RB must be 0. | ||
395 | */ | ||
396 | static void do_tlbies_970(struct kvm *kvm, unsigned long *rbvalues, | ||
397 | long npages, int global, bool need_sync) | ||
398 | { | ||
399 | long i; | ||
400 | |||
401 | if (global) { | ||
402 | while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) | ||
403 | cpu_relax(); | ||
404 | if (need_sync) | ||
405 | asm volatile("ptesync" : : : "memory"); | ||
406 | for (i = 0; i < npages; ++i) { | ||
407 | unsigned long rb = rbvalues[i]; | ||
408 | |||
409 | if (rb & 1) /* large page */ | ||
410 | asm volatile("tlbie %0,1" : : | ||
411 | "r" (rb & 0x0000fffffffff000ul)); | ||
412 | else | ||
413 | asm volatile("tlbie %0,0" : : | ||
414 | "r" (rb & 0x0000fffffffff000ul)); | ||
415 | } | ||
416 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); | ||
417 | kvm->arch.tlbie_lock = 0; | ||
418 | } else { | ||
419 | if (need_sync) | ||
420 | asm volatile("ptesync" : : : "memory"); | ||
421 | for (i = 0; i < npages; ++i) { | ||
422 | unsigned long rb = rbvalues[i]; | ||
423 | |||
424 | if (rb & 1) /* large page */ | ||
425 | asm volatile("tlbiel %0,1" : : | ||
426 | "r" (rb & 0x0000fffffffff000ul)); | ||
427 | else | ||
428 | asm volatile("tlbiel %0,0" : : | ||
429 | "r" (rb & 0x0000fffffffff000ul)); | ||
430 | } | ||
431 | asm volatile("ptesync" : : : "memory"); | ||
432 | } | ||
433 | } | ||
434 | |||
435 | static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues, | ||
436 | long npages, int global, bool need_sync) | ||
437 | { | ||
438 | long i; | ||
439 | |||
440 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { | ||
441 | /* PPC970 tlbie instruction is a bit different */ | ||
442 | do_tlbies_970(kvm, rbvalues, npages, global, need_sync); | ||
443 | return; | ||
444 | } | ||
445 | if (global) { | ||
446 | while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) | ||
447 | cpu_relax(); | ||
448 | if (need_sync) | ||
449 | asm volatile("ptesync" : : : "memory"); | ||
450 | for (i = 0; i < npages; ++i) | ||
451 | asm volatile(PPC_TLBIE(%1,%0) : : | ||
452 | "r" (rbvalues[i]), "r" (kvm->arch.lpid)); | ||
453 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); | ||
454 | kvm->arch.tlbie_lock = 0; | ||
455 | } else { | ||
456 | if (need_sync) | ||
457 | asm volatile("ptesync" : : : "memory"); | ||
458 | for (i = 0; i < npages; ++i) | ||
459 | asm volatile("tlbiel %0" : : "r" (rbvalues[i])); | ||
460 | asm volatile("ptesync" : : : "memory"); | ||
461 | } | ||
462 | } | ||
463 | |||
390 | long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, | 464 | long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, |
391 | unsigned long pte_index, unsigned long avpn, | 465 | unsigned long pte_index, unsigned long avpn, |
392 | unsigned long *hpret) | 466 | unsigned long *hpret) |
@@ -412,19 +486,7 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags, | |||
412 | if (v & HPTE_V_VALID) { | 486 | if (v & HPTE_V_VALID) { |
413 | hpte[0] &= ~HPTE_V_VALID; | 487 | hpte[0] &= ~HPTE_V_VALID; |
414 | rb = compute_tlbie_rb(v, hpte[1], pte_index); | 488 | rb = compute_tlbie_rb(v, hpte[1], pte_index); |
415 | if (global_invalidates(kvm, flags)) { | 489 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); |
416 | while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) | ||
417 | cpu_relax(); | ||
418 | asm volatile("ptesync" : : : "memory"); | ||
419 | asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync" | ||
420 | : : "r" (rb), "r" (kvm->arch.lpid)); | ||
421 | asm volatile("ptesync" : : : "memory"); | ||
422 | kvm->arch.tlbie_lock = 0; | ||
423 | } else { | ||
424 | asm volatile("ptesync" : : : "memory"); | ||
425 | asm volatile("tlbiel %0" : : "r" (rb)); | ||
426 | asm volatile("ptesync" : : : "memory"); | ||
427 | } | ||
428 | /* Read PTE low word after tlbie to get final R/C values */ | 490 | /* Read PTE low word after tlbie to get final R/C values */ |
429 | remove_revmap_chain(kvm, pte_index, rev, v, hpte[1]); | 491 | remove_revmap_chain(kvm, pte_index, rev, v, hpte[1]); |
430 | } | 492 | } |
@@ -452,12 +514,11 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
452 | unsigned long *hp, *hptes[4], tlbrb[4]; | 514 | unsigned long *hp, *hptes[4], tlbrb[4]; |
453 | long int i, j, k, n, found, indexes[4]; | 515 | long int i, j, k, n, found, indexes[4]; |
454 | unsigned long flags, req, pte_index, rcbits; | 516 | unsigned long flags, req, pte_index, rcbits; |
455 | long int local = 0; | 517 | int global; |
456 | long int ret = H_SUCCESS; | 518 | long int ret = H_SUCCESS; |
457 | struct revmap_entry *rev, *revs[4]; | 519 | struct revmap_entry *rev, *revs[4]; |
458 | 520 | ||
459 | if (atomic_read(&kvm->online_vcpus) == 1) | 521 | global = global_invalidates(kvm, 0); |
460 | local = 1; | ||
461 | for (i = 0; i < 4 && ret == H_SUCCESS; ) { | 522 | for (i = 0; i < 4 && ret == H_SUCCESS; ) { |
462 | n = 0; | 523 | n = 0; |
463 | for (; i < 4; ++i) { | 524 | for (; i < 4; ++i) { |
@@ -533,22 +594,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
533 | break; | 594 | break; |
534 | 595 | ||
535 | /* Now that we've collected a batch, do the tlbies */ | 596 | /* Now that we've collected a batch, do the tlbies */ |
536 | if (!local) { | 597 | do_tlbies(kvm, tlbrb, n, global, true); |
537 | while(!try_lock_tlbie(&kvm->arch.tlbie_lock)) | ||
538 | cpu_relax(); | ||
539 | asm volatile("ptesync" : : : "memory"); | ||
540 | for (k = 0; k < n; ++k) | ||
541 | asm volatile(PPC_TLBIE(%1,%0) : : | ||
542 | "r" (tlbrb[k]), | ||
543 | "r" (kvm->arch.lpid)); | ||
544 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); | ||
545 | kvm->arch.tlbie_lock = 0; | ||
546 | } else { | ||
547 | asm volatile("ptesync" : : : "memory"); | ||
548 | for (k = 0; k < n; ++k) | ||
549 | asm volatile("tlbiel %0" : : "r" (tlbrb[k])); | ||
550 | asm volatile("ptesync" : : : "memory"); | ||
551 | } | ||
552 | 598 | ||
553 | /* Read PTE low words after tlbie to get final R/C values */ | 599 | /* Read PTE low words after tlbie to get final R/C values */ |
554 | for (k = 0; k < n; ++k) { | 600 | for (k = 0; k < n; ++k) { |
@@ -607,19 +653,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
607 | if (v & HPTE_V_VALID) { | 653 | if (v & HPTE_V_VALID) { |
608 | rb = compute_tlbie_rb(v, r, pte_index); | 654 | rb = compute_tlbie_rb(v, r, pte_index); |
609 | hpte[0] = v & ~HPTE_V_VALID; | 655 | hpte[0] = v & ~HPTE_V_VALID; |
610 | if (global_invalidates(kvm, flags)) { | 656 | do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); |
611 | while(!try_lock_tlbie(&kvm->arch.tlbie_lock)) | ||
612 | cpu_relax(); | ||
613 | asm volatile("ptesync" : : : "memory"); | ||
614 | asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync" | ||
615 | : : "r" (rb), "r" (kvm->arch.lpid)); | ||
616 | asm volatile("ptesync" : : : "memory"); | ||
617 | kvm->arch.tlbie_lock = 0; | ||
618 | } else { | ||
619 | asm volatile("ptesync" : : : "memory"); | ||
620 | asm volatile("tlbiel %0" : : "r" (rb)); | ||
621 | asm volatile("ptesync" : : : "memory"); | ||
622 | } | ||
623 | /* | 657 | /* |
624 | * If the host has this page as readonly but the guest | 658 | * If the host has this page as readonly but the guest |
625 | * wants to make it read/write, reduce the permissions. | 659 | * wants to make it read/write, reduce the permissions. |
@@ -690,13 +724,7 @@ void kvmppc_invalidate_hpte(struct kvm *kvm, unsigned long *hptep, | |||
690 | 724 | ||
691 | hptep[0] &= ~HPTE_V_VALID; | 725 | hptep[0] &= ~HPTE_V_VALID; |
692 | rb = compute_tlbie_rb(hptep[0], hptep[1], pte_index); | 726 | rb = compute_tlbie_rb(hptep[0], hptep[1], pte_index); |
693 | while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) | 727 | do_tlbies(kvm, &rb, 1, 1, true); |
694 | cpu_relax(); | ||
695 | asm volatile("ptesync" : : : "memory"); | ||
696 | asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync" | ||
697 | : : "r" (rb), "r" (kvm->arch.lpid)); | ||
698 | asm volatile("ptesync" : : : "memory"); | ||
699 | kvm->arch.tlbie_lock = 0; | ||
700 | } | 728 | } |
701 | EXPORT_SYMBOL_GPL(kvmppc_invalidate_hpte); | 729 | EXPORT_SYMBOL_GPL(kvmppc_invalidate_hpte); |
702 | 730 | ||
@@ -710,12 +738,7 @@ void kvmppc_clear_ref_hpte(struct kvm *kvm, unsigned long *hptep, | |||
710 | rbyte = (hptep[1] & ~HPTE_R_R) >> 8; | 738 | rbyte = (hptep[1] & ~HPTE_R_R) >> 8; |
711 | /* modify only the second-last byte, which contains the ref bit */ | 739 | /* modify only the second-last byte, which contains the ref bit */ |
712 | *((char *)hptep + 14) = rbyte; | 740 | *((char *)hptep + 14) = rbyte; |
713 | while (!try_lock_tlbie(&kvm->arch.tlbie_lock)) | 741 | do_tlbies(kvm, &rb, 1, 1, false); |
714 | cpu_relax(); | ||
715 | asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync" | ||
716 | : : "r" (rb), "r" (kvm->arch.lpid)); | ||
717 | asm volatile("ptesync" : : : "memory"); | ||
718 | kvm->arch.tlbie_lock = 0; | ||
719 | } | 742 | } |
720 | EXPORT_SYMBOL_GPL(kvmppc_clear_ref_hpte); | 743 | EXPORT_SYMBOL_GPL(kvmppc_clear_ref_hpte); |
721 | 744 | ||
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index b93e3cd8bf2b..294b7af28cdd 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -1393,7 +1393,7 @@ hcall_try_real_mode: | |||
1393 | cmpldi r3,hcall_real_table_end - hcall_real_table | 1393 | cmpldi r3,hcall_real_table_end - hcall_real_table |
1394 | bge guest_exit_cont | 1394 | bge guest_exit_cont |
1395 | LOAD_REG_ADDR(r4, hcall_real_table) | 1395 | LOAD_REG_ADDR(r4, hcall_real_table) |
1396 | lwzx r3,r3,r4 | 1396 | lwax r3,r3,r4 |
1397 | cmpwi r3,0 | 1397 | cmpwi r3,0 |
1398 | beq guest_exit_cont | 1398 | beq guest_exit_cont |
1399 | add r3,r3,r4 | 1399 | add r3,r3,r4 |
diff --git a/arch/powerpc/kvm/book3s_interrupts.S b/arch/powerpc/kvm/book3s_interrupts.S index 48cbbf862958..17cfae5497a3 100644 --- a/arch/powerpc/kvm/book3s_interrupts.S +++ b/arch/powerpc/kvm/book3s_interrupts.S | |||
@@ -92,6 +92,11 @@ kvm_start_lightweight: | |||
92 | PPC_LL r3, VCPU_HFLAGS(r4) | 92 | PPC_LL r3, VCPU_HFLAGS(r4) |
93 | rldicl r3, r3, 0, 63 /* r3 &= 1 */ | 93 | rldicl r3, r3, 0, 63 /* r3 &= 1 */ |
94 | stb r3, HSTATE_RESTORE_HID5(r13) | 94 | stb r3, HSTATE_RESTORE_HID5(r13) |
95 | |||
96 | /* Load up guest SPRG3 value, since it's user readable */ | ||
97 | ld r3, VCPU_SHARED(r4) | ||
98 | ld r3, VCPU_SHARED_SPRG3(r3) | ||
99 | mtspr SPRN_SPRG3, r3 | ||
95 | #endif /* CONFIG_PPC_BOOK3S_64 */ | 100 | #endif /* CONFIG_PPC_BOOK3S_64 */ |
96 | 101 | ||
97 | PPC_LL r4, VCPU_SHADOW_MSR(r4) /* get shadow_msr */ | 102 | PPC_LL r4, VCPU_SHADOW_MSR(r4) /* get shadow_msr */ |
@@ -123,6 +128,15 @@ kvmppc_handler_highmem: | |||
123 | /* R7 = vcpu */ | 128 | /* R7 = vcpu */ |
124 | PPC_LL r7, GPR4(r1) | 129 | PPC_LL r7, GPR4(r1) |
125 | 130 | ||
131 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
132 | /* | ||
133 | * Reload kernel SPRG3 value. | ||
134 | * No need to save guest value as usermode can't modify SPRG3. | ||
135 | */ | ||
136 | ld r3, PACA_SPRG3(r13) | ||
137 | mtspr SPRN_SPRG3, r3 | ||
138 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
139 | |||
126 | PPC_STL r14, VCPU_GPR(R14)(r7) | 140 | PPC_STL r14, VCPU_GPR(R14)(r7) |
127 | PPC_STL r15, VCPU_GPR(R15)(r7) | 141 | PPC_STL r15, VCPU_GPR(R15)(r7) |
128 | PPC_STL r16, VCPU_GPR(R16)(r7) | 142 | PPC_STL r16, VCPU_GPR(R16)(r7) |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index c6e13d9a9e15..27db1e665959 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -468,7 +468,8 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) | |||
468 | * both the traditional FP registers and the added VSX | 468 | * both the traditional FP registers and the added VSX |
469 | * registers into thread.fpr[]. | 469 | * registers into thread.fpr[]. |
470 | */ | 470 | */ |
471 | giveup_fpu(current); | 471 | if (current->thread.regs->msr & MSR_FP) |
472 | giveup_fpu(current); | ||
472 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) | 473 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) |
473 | vcpu_fpr[i] = thread_fpr[get_fpr_index(i)]; | 474 | vcpu_fpr[i] = thread_fpr[get_fpr_index(i)]; |
474 | 475 | ||
@@ -483,7 +484,8 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) | |||
483 | 484 | ||
484 | #ifdef CONFIG_ALTIVEC | 485 | #ifdef CONFIG_ALTIVEC |
485 | if (msr & MSR_VEC) { | 486 | if (msr & MSR_VEC) { |
486 | giveup_altivec(current); | 487 | if (current->thread.regs->msr & MSR_VEC) |
488 | giveup_altivec(current); | ||
487 | memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr)); | 489 | memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr)); |
488 | vcpu->arch.vscr = t->vscr; | 490 | vcpu->arch.vscr = t->vscr; |
489 | } | 491 | } |
@@ -575,8 +577,6 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, | |||
575 | printk(KERN_INFO "Loading up ext 0x%lx\n", msr); | 577 | printk(KERN_INFO "Loading up ext 0x%lx\n", msr); |
576 | #endif | 578 | #endif |
577 | 579 | ||
578 | current->thread.regs->msr |= msr; | ||
579 | |||
580 | if (msr & MSR_FP) { | 580 | if (msr & MSR_FP) { |
581 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) | 581 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) |
582 | thread_fpr[get_fpr_index(i)] = vcpu_fpr[i]; | 582 | thread_fpr[get_fpr_index(i)] = vcpu_fpr[i]; |
@@ -598,12 +598,32 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, | |||
598 | #endif | 598 | #endif |
599 | } | 599 | } |
600 | 600 | ||
601 | current->thread.regs->msr |= msr; | ||
601 | vcpu->arch.guest_owned_ext |= msr; | 602 | vcpu->arch.guest_owned_ext |= msr; |
602 | kvmppc_recalc_shadow_msr(vcpu); | 603 | kvmppc_recalc_shadow_msr(vcpu); |
603 | 604 | ||
604 | return RESUME_GUEST; | 605 | return RESUME_GUEST; |
605 | } | 606 | } |
606 | 607 | ||
608 | /* | ||
609 | * Kernel code using FP or VMX could have flushed guest state to | ||
610 | * the thread_struct; if so, get it back now. | ||
611 | */ | ||
612 | static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu) | ||
613 | { | ||
614 | unsigned long lost_ext; | ||
615 | |||
616 | lost_ext = vcpu->arch.guest_owned_ext & ~current->thread.regs->msr; | ||
617 | if (!lost_ext) | ||
618 | return; | ||
619 | |||
620 | if (lost_ext & MSR_FP) | ||
621 | kvmppc_load_up_fpu(); | ||
622 | if (lost_ext & MSR_VEC) | ||
623 | kvmppc_load_up_altivec(); | ||
624 | current->thread.regs->msr |= lost_ext; | ||
625 | } | ||
626 | |||
607 | int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | 627 | int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, |
608 | unsigned int exit_nr) | 628 | unsigned int exit_nr) |
609 | { | 629 | { |
@@ -772,7 +792,7 @@ program_interrupt: | |||
772 | } | 792 | } |
773 | case BOOK3S_INTERRUPT_SYSCALL: | 793 | case BOOK3S_INTERRUPT_SYSCALL: |
774 | if (vcpu->arch.papr_enabled && | 794 | if (vcpu->arch.papr_enabled && |
775 | (kvmppc_get_last_inst(vcpu) == 0x44000022) && | 795 | (kvmppc_get_last_sc(vcpu) == 0x44000022) && |
776 | !(vcpu->arch.shared->msr & MSR_PR)) { | 796 | !(vcpu->arch.shared->msr & MSR_PR)) { |
777 | /* SC 1 papr hypercalls */ | 797 | /* SC 1 papr hypercalls */ |
778 | ulong cmd = kvmppc_get_gpr(vcpu, 3); | 798 | ulong cmd = kvmppc_get_gpr(vcpu, 3); |
@@ -890,8 +910,9 @@ program_interrupt: | |||
890 | local_irq_enable(); | 910 | local_irq_enable(); |
891 | r = s; | 911 | r = s; |
892 | } else { | 912 | } else { |
893 | kvmppc_lazy_ee_enable(); | 913 | kvmppc_fix_ee_before_entry(); |
894 | } | 914 | } |
915 | kvmppc_handle_lost_ext(vcpu); | ||
895 | } | 916 | } |
896 | 917 | ||
897 | trace_kvm_book3s_reenter(r, vcpu); | 918 | trace_kvm_book3s_reenter(r, vcpu); |
@@ -1162,7 +1183,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1162 | if (vcpu->arch.shared->msr & MSR_FP) | 1183 | if (vcpu->arch.shared->msr & MSR_FP) |
1163 | kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); | 1184 | kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); |
1164 | 1185 | ||
1165 | kvmppc_lazy_ee_enable(); | 1186 | kvmppc_fix_ee_before_entry(); |
1166 | 1187 | ||
1167 | ret = __kvmppc_vcpu_run(kvm_run, vcpu); | 1188 | ret = __kvmppc_vcpu_run(kvm_run, vcpu); |
1168 | 1189 | ||
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index 94c1dd46b83d..a3a5cb8ee7ea 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/hvcall.h> | 19 | #include <asm/hvcall.h> |
20 | #include <asm/xics.h> | 20 | #include <asm/xics.h> |
21 | #include <asm/debug.h> | 21 | #include <asm/debug.h> |
22 | #include <asm/time.h> | ||
22 | 23 | ||
23 | #include <linux/debugfs.h> | 24 | #include <linux/debugfs.h> |
24 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index dcc94f016007..17722d82f1d1 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -674,8 +674,6 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
674 | goto out; | 674 | goto out; |
675 | } | 675 | } |
676 | 676 | ||
677 | kvm_guest_enter(); | ||
678 | |||
679 | #ifdef CONFIG_PPC_FPU | 677 | #ifdef CONFIG_PPC_FPU |
680 | /* Save userspace FPU state in stack */ | 678 | /* Save userspace FPU state in stack */ |
681 | enable_kernel_fp(); | 679 | enable_kernel_fp(); |
@@ -698,7 +696,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
698 | kvmppc_load_guest_fp(vcpu); | 696 | kvmppc_load_guest_fp(vcpu); |
699 | #endif | 697 | #endif |
700 | 698 | ||
701 | kvmppc_lazy_ee_enable(); | 699 | kvmppc_fix_ee_before_entry(); |
702 | 700 | ||
703 | ret = __kvmppc_vcpu_run(kvm_run, vcpu); | 701 | ret = __kvmppc_vcpu_run(kvm_run, vcpu); |
704 | 702 | ||
@@ -1168,7 +1166,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
1168 | local_irq_enable(); | 1166 | local_irq_enable(); |
1169 | r = (s << 2) | RESUME_HOST | (r & RESUME_FLAG_NV); | 1167 | r = (s << 2) | RESUME_HOST | (r & RESUME_FLAG_NV); |
1170 | } else { | 1168 | } else { |
1171 | kvmppc_lazy_ee_enable(); | 1169 | kvmppc_fix_ee_before_entry(); |
1172 | } | 1170 | } |
1173 | } | 1171 | } |
1174 | 1172 | ||
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 6316ee336e88..07c0106fab76 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -117,8 +117,6 @@ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu) | |||
117 | kvm_guest_exit(); | 117 | kvm_guest_exit(); |
118 | continue; | 118 | continue; |
119 | } | 119 | } |
120 | |||
121 | trace_hardirqs_on(); | ||
122 | #endif | 120 | #endif |
123 | 121 | ||
124 | kvm_guest_enter(); | 122 | kvm_guest_enter(); |
@@ -420,6 +418,10 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | |||
420 | return kvmppc_core_create_memslot(slot, npages); | 418 | return kvmppc_core_create_memslot(slot, npages); |
421 | } | 419 | } |
422 | 420 | ||
421 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
422 | { | ||
423 | } | ||
424 | |||
423 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 425 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
424 | struct kvm_memory_slot *memslot, | 426 | struct kvm_memory_slot *memslot, |
425 | struct kvm_userspace_memory_region *mem, | 427 | struct kvm_userspace_memory_region *mem, |
@@ -823,39 +825,39 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, | |||
823 | #endif | 825 | #endif |
824 | #ifdef CONFIG_KVM_MPIC | 826 | #ifdef CONFIG_KVM_MPIC |
825 | case KVM_CAP_IRQ_MPIC: { | 827 | case KVM_CAP_IRQ_MPIC: { |
826 | struct file *filp; | 828 | struct fd f; |
827 | struct kvm_device *dev; | 829 | struct kvm_device *dev; |
828 | 830 | ||
829 | r = -EBADF; | 831 | r = -EBADF; |
830 | filp = fget(cap->args[0]); | 832 | f = fdget(cap->args[0]); |
831 | if (!filp) | 833 | if (!f.file) |
832 | break; | 834 | break; |
833 | 835 | ||
834 | r = -EPERM; | 836 | r = -EPERM; |
835 | dev = kvm_device_from_filp(filp); | 837 | dev = kvm_device_from_filp(f.file); |
836 | if (dev) | 838 | if (dev) |
837 | r = kvmppc_mpic_connect_vcpu(dev, vcpu, cap->args[1]); | 839 | r = kvmppc_mpic_connect_vcpu(dev, vcpu, cap->args[1]); |
838 | 840 | ||
839 | fput(filp); | 841 | fdput(f); |
840 | break; | 842 | break; |
841 | } | 843 | } |
842 | #endif | 844 | #endif |
843 | #ifdef CONFIG_KVM_XICS | 845 | #ifdef CONFIG_KVM_XICS |
844 | case KVM_CAP_IRQ_XICS: { | 846 | case KVM_CAP_IRQ_XICS: { |
845 | struct file *filp; | 847 | struct fd f; |
846 | struct kvm_device *dev; | 848 | struct kvm_device *dev; |
847 | 849 | ||
848 | r = -EBADF; | 850 | r = -EBADF; |
849 | filp = fget(cap->args[0]); | 851 | f = fdget(cap->args[0]); |
850 | if (!filp) | 852 | if (!f.file) |
851 | break; | 853 | break; |
852 | 854 | ||
853 | r = -EPERM; | 855 | r = -EPERM; |
854 | dev = kvm_device_from_filp(filp); | 856 | dev = kvm_device_from_filp(f.file); |
855 | if (dev) | 857 | if (dev) |
856 | r = kvmppc_xics_connect_vcpu(dev, vcpu, cap->args[1]); | 858 | r = kvmppc_xics_connect_vcpu(dev, vcpu, cap->args[1]); |
857 | 859 | ||
858 | fput(filp); | 860 | fdput(f); |
859 | break; | 861 | break; |
860 | } | 862 | } |
861 | #endif /* CONFIG_KVM_XICS */ | 863 | #endif /* CONFIG_KVM_XICS */ |
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 01e2db97a210..d47d3dab4870 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c | |||
@@ -52,7 +52,7 @@ | |||
52 | #if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL) | 52 | #if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL) |
53 | /* The amount of lowmem must be within 0xF0000000 - KERNELBASE. */ | 53 | /* The amount of lowmem must be within 0xF0000000 - KERNELBASE. */ |
54 | #if (CONFIG_LOWMEM_SIZE > (0xF0000000 - PAGE_OFFSET)) | 54 | #if (CONFIG_LOWMEM_SIZE > (0xF0000000 - PAGE_OFFSET)) |
55 | #error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL" | 55 | #error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_KERNEL_START" |
56 | #endif | 56 | #endif |
57 | #endif | 57 | #endif |
58 | #define MAX_LOW_MEM CONFIG_LOWMEM_SIZE | 58 | #define MAX_LOW_MEM CONFIG_LOWMEM_SIZE |
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 4f51025f5b00..c77348c5d463 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c | |||
@@ -119,7 +119,7 @@ static void op_powerpc_stop(void) | |||
119 | model->global_stop(); | 119 | model->global_stop(); |
120 | } | 120 | } |
121 | 121 | ||
122 | static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) | 122 | static int op_powerpc_create_files(struct dentry *root) |
123 | { | 123 | { |
124 | int i; | 124 | int i; |
125 | 125 | ||
@@ -128,9 +128,9 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) | |||
128 | * There is one mmcr0, mmcr1 and mmcra for setting the events for | 128 | * There is one mmcr0, mmcr1 and mmcra for setting the events for |
129 | * all of the counters. | 129 | * all of the counters. |
130 | */ | 130 | */ |
131 | oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0); | 131 | oprofilefs_create_ulong(root, "mmcr0", &sys.mmcr0); |
132 | oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1); | 132 | oprofilefs_create_ulong(root, "mmcr1", &sys.mmcr1); |
133 | oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra); | 133 | oprofilefs_create_ulong(root, "mmcra", &sys.mmcra); |
134 | #ifdef CONFIG_OPROFILE_CELL | 134 | #ifdef CONFIG_OPROFILE_CELL |
135 | /* create a file the user tool can check to see what level of profiling | 135 | /* create a file the user tool can check to see what level of profiling |
136 | * support exits with this kernel. Initialize bit mask to indicate | 136 | * support exits with this kernel. Initialize bit mask to indicate |
@@ -142,7 +142,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) | |||
142 | * If the file does not exist, then the kernel only supports SPU | 142 | * If the file does not exist, then the kernel only supports SPU |
143 | * cycle profiling, PPU event and cycle profiling. | 143 | * cycle profiling, PPU event and cycle profiling. |
144 | */ | 144 | */ |
145 | oprofilefs_create_ulong(sb, root, "cell_support", &sys.cell_support); | 145 | oprofilefs_create_ulong(root, "cell_support", &sys.cell_support); |
146 | sys.cell_support = 0x1; /* Note, the user OProfile tool must check | 146 | sys.cell_support = 0x1; /* Note, the user OProfile tool must check |
147 | * that this bit is set before attempting to | 147 | * that this bit is set before attempting to |
148 | * user SPU event profiling. Older kernels | 148 | * user SPU event profiling. Older kernels |
@@ -160,11 +160,11 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) | |||
160 | char buf[4]; | 160 | char buf[4]; |
161 | 161 | ||
162 | snprintf(buf, sizeof buf, "%d", i); | 162 | snprintf(buf, sizeof buf, "%d", i); |
163 | dir = oprofilefs_mkdir(sb, root, buf); | 163 | dir = oprofilefs_mkdir(root, buf); |
164 | 164 | ||
165 | oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); | 165 | oprofilefs_create_ulong(dir, "enabled", &ctr[i].enabled); |
166 | oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); | 166 | oprofilefs_create_ulong(dir, "event", &ctr[i].event); |
167 | oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); | 167 | oprofilefs_create_ulong(dir, "count", &ctr[i].count); |
168 | 168 | ||
169 | /* | 169 | /* |
170 | * Classic PowerPC doesn't support per-counter | 170 | * Classic PowerPC doesn't support per-counter |
@@ -173,14 +173,14 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) | |||
173 | * Book-E style performance monitors, we do | 173 | * Book-E style performance monitors, we do |
174 | * support them. | 174 | * support them. |
175 | */ | 175 | */ |
176 | oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); | 176 | oprofilefs_create_ulong(dir, "kernel", &ctr[i].kernel); |
177 | oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); | 177 | oprofilefs_create_ulong(dir, "user", &ctr[i].user); |
178 | 178 | ||
179 | oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); | 179 | oprofilefs_create_ulong(dir, "unit_mask", &ctr[i].unit_mask); |
180 | } | 180 | } |
181 | 181 | ||
182 | oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); | 182 | oprofilefs_create_ulong(root, "enable_kernel", &sys.enable_kernel); |
183 | oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); | 183 | oprofilefs_create_ulong(root, "enable_user", &sys.enable_user); |
184 | 184 | ||
185 | /* Default to tracing both kernel and user */ | 185 | /* Default to tracing both kernel and user */ |
186 | sys.enable_kernel = 1; | 186 | sys.enable_kernel = 1; |
diff --git a/arch/powerpc/perf/power7-events-list.h b/arch/powerpc/perf/power7-events-list.h new file mode 100644 index 000000000000..687790a2c0b8 --- /dev/null +++ b/arch/powerpc/perf/power7-events-list.h | |||
@@ -0,0 +1,548 @@ | |||
1 | /* | ||
2 | * Performance counter support for POWER7 processors. | ||
3 | * | ||
4 | * Copyright 2013 Runzhen Wang, IBM Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | EVENT(PM_IC_DEMAND_L2_BR_ALL, 0x04898) | ||
13 | EVENT(PM_GCT_UTIL_7_TO_10_SLOTS, 0x020a0) | ||
14 | EVENT(PM_PMC2_SAVED, 0x10022) | ||
15 | EVENT(PM_CMPLU_STALL_DFU, 0x2003c) | ||
16 | EVENT(PM_VSU0_16FLOP, 0x0a0a4) | ||
17 | EVENT(PM_MRK_LSU_DERAT_MISS, 0x3d05a) | ||
18 | EVENT(PM_MRK_ST_CMPL, 0x10034) | ||
19 | EVENT(PM_NEST_PAIR3_ADD, 0x40881) | ||
20 | EVENT(PM_L2_ST_DISP, 0x46180) | ||
21 | EVENT(PM_L2_CASTOUT_MOD, 0x16180) | ||
22 | EVENT(PM_ISEG, 0x020a4) | ||
23 | EVENT(PM_MRK_INST_TIMEO, 0x40034) | ||
24 | EVENT(PM_L2_RCST_DISP_FAIL_ADDR, 0x36282) | ||
25 | EVENT(PM_LSU1_DC_PREF_STREAM_CONFIRM, 0x0d0b6) | ||
26 | EVENT(PM_IERAT_WR_64K, 0x040be) | ||
27 | EVENT(PM_MRK_DTLB_MISS_16M, 0x4d05e) | ||
28 | EVENT(PM_IERAT_MISS, 0x100f6) | ||
29 | EVENT(PM_MRK_PTEG_FROM_LMEM, 0x4d052) | ||
30 | EVENT(PM_FLOP, 0x100f4) | ||
31 | EVENT(PM_THRD_PRIO_4_5_CYC, 0x040b4) | ||
32 | EVENT(PM_BR_PRED_TA, 0x040aa) | ||
33 | EVENT(PM_CMPLU_STALL_FXU, 0x20014) | ||
34 | EVENT(PM_EXT_INT, 0x200f8) | ||
35 | EVENT(PM_VSU_FSQRT_FDIV, 0x0a888) | ||
36 | EVENT(PM_MRK_LD_MISS_EXPOSED_CYC, 0x1003e) | ||
37 | EVENT(PM_LSU1_LDF, 0x0c086) | ||
38 | EVENT(PM_IC_WRITE_ALL, 0x0488c) | ||
39 | EVENT(PM_LSU0_SRQ_STFWD, 0x0c0a0) | ||
40 | EVENT(PM_PTEG_FROM_RL2L3_MOD, 0x1c052) | ||
41 | EVENT(PM_MRK_DATA_FROM_L31_SHR, 0x1d04e) | ||
42 | EVENT(PM_DATA_FROM_L21_MOD, 0x3c046) | ||
43 | EVENT(PM_VSU1_SCAL_DOUBLE_ISSUED, 0x0b08a) | ||
44 | EVENT(PM_VSU0_8FLOP, 0x0a0a0) | ||
45 | EVENT(PM_POWER_EVENT1, 0x1006e) | ||
46 | EVENT(PM_DISP_CLB_HELD_BAL, 0x02092) | ||
47 | EVENT(PM_VSU1_2FLOP, 0x0a09a) | ||
48 | EVENT(PM_LWSYNC_HELD, 0x0209a) | ||
49 | EVENT(PM_PTEG_FROM_DL2L3_SHR, 0x3c054) | ||
50 | EVENT(PM_INST_FROM_L21_MOD, 0x34046) | ||
51 | EVENT(PM_IERAT_XLATE_WR_16MPLUS, 0x040bc) | ||
52 | EVENT(PM_IC_REQ_ALL, 0x04888) | ||
53 | EVENT(PM_DSLB_MISS, 0x0d090) | ||
54 | EVENT(PM_L3_MISS, 0x1f082) | ||
55 | EVENT(PM_LSU0_L1_PREF, 0x0d0b8) | ||
56 | EVENT(PM_VSU_SCALAR_SINGLE_ISSUED, 0x0b884) | ||
57 | EVENT(PM_LSU1_DC_PREF_STREAM_CONFIRM_STRIDE, 0x0d0be) | ||
58 | EVENT(PM_L2_INST, 0x36080) | ||
59 | EVENT(PM_VSU0_FRSP, 0x0a0b4) | ||
60 | EVENT(PM_FLUSH_DISP, 0x02082) | ||
61 | EVENT(PM_PTEG_FROM_L2MISS, 0x4c058) | ||
62 | EVENT(PM_VSU1_DQ_ISSUED, 0x0b09a) | ||
63 | EVENT(PM_CMPLU_STALL_LSU, 0x20012) | ||
64 | EVENT(PM_MRK_DATA_FROM_DMEM, 0x1d04a) | ||
65 | EVENT(PM_LSU_FLUSH_ULD, 0x0c8b0) | ||
66 | EVENT(PM_PTEG_FROM_LMEM, 0x4c052) | ||
67 | EVENT(PM_MRK_DERAT_MISS_16M, 0x3d05c) | ||
68 | EVENT(PM_THRD_ALL_RUN_CYC, 0x2000c) | ||
69 | EVENT(PM_MEM0_PREFETCH_DISP, 0x20083) | ||
70 | EVENT(PM_MRK_STALL_CMPLU_CYC_COUNT, 0x3003f) | ||
71 | EVENT(PM_DATA_FROM_DL2L3_MOD, 0x3c04c) | ||
72 | EVENT(PM_VSU_FRSP, 0x0a8b4) | ||
73 | EVENT(PM_MRK_DATA_FROM_L21_MOD, 0x3d046) | ||
74 | EVENT(PM_PMC1_OVERFLOW, 0x20010) | ||
75 | EVENT(PM_VSU0_SINGLE, 0x0a0a8) | ||
76 | EVENT(PM_MRK_PTEG_FROM_L3MISS, 0x2d058) | ||
77 | EVENT(PM_MRK_PTEG_FROM_L31_SHR, 0x2d056) | ||
78 | EVENT(PM_VSU0_VECTOR_SP_ISSUED, 0x0b090) | ||
79 | EVENT(PM_VSU1_FEST, 0x0a0ba) | ||
80 | EVENT(PM_MRK_INST_DISP, 0x20030) | ||
81 | EVENT(PM_VSU0_COMPLEX_ISSUED, 0x0b096) | ||
82 | EVENT(PM_LSU1_FLUSH_UST, 0x0c0b6) | ||
83 | EVENT(PM_INST_CMPL, 0x00002) | ||
84 | EVENT(PM_FXU_IDLE, 0x1000e) | ||
85 | EVENT(PM_LSU0_FLUSH_ULD, 0x0c0b0) | ||
86 | EVENT(PM_MRK_DATA_FROM_DL2L3_MOD, 0x3d04c) | ||
87 | EVENT(PM_LSU_LMQ_SRQ_EMPTY_ALL_CYC, 0x3001c) | ||
88 | EVENT(PM_LSU1_REJECT_LMQ_FULL, 0x0c0a6) | ||
89 | EVENT(PM_INST_PTEG_FROM_L21_MOD, 0x3e056) | ||
90 | EVENT(PM_INST_FROM_RL2L3_MOD, 0x14042) | ||
91 | EVENT(PM_SHL_CREATED, 0x05082) | ||
92 | EVENT(PM_L2_ST_HIT, 0x46182) | ||
93 | EVENT(PM_DATA_FROM_DMEM, 0x1c04a) | ||
94 | EVENT(PM_L3_LD_MISS, 0x2f082) | ||
95 | EVENT(PM_FXU1_BUSY_FXU0_IDLE, 0x4000e) | ||
96 | EVENT(PM_DISP_CLB_HELD_RES, 0x02094) | ||
97 | EVENT(PM_L2_SN_SX_I_DONE, 0x36382) | ||
98 | EVENT(PM_GRP_CMPL, 0x30004) | ||
99 | EVENT(PM_STCX_CMPL, 0x0c098) | ||
100 | EVENT(PM_VSU0_2FLOP, 0x0a098) | ||
101 | EVENT(PM_L3_PREF_MISS, 0x3f082) | ||
102 | EVENT(PM_LSU_SRQ_SYNC_CYC, 0x0d096) | ||
103 | EVENT(PM_LSU_REJECT_ERAT_MISS, 0x20064) | ||
104 | EVENT(PM_L1_ICACHE_MISS, 0x200fc) | ||
105 | EVENT(PM_LSU1_FLUSH_SRQ, 0x0c0be) | ||
106 | EVENT(PM_LD_REF_L1_LSU0, 0x0c080) | ||
107 | EVENT(PM_VSU0_FEST, 0x0a0b8) | ||
108 | EVENT(PM_VSU_VECTOR_SINGLE_ISSUED, 0x0b890) | ||
109 | EVENT(PM_FREQ_UP, 0x4000c) | ||
110 | EVENT(PM_DATA_FROM_LMEM, 0x3c04a) | ||
111 | EVENT(PM_LSU1_LDX, 0x0c08a) | ||
112 | EVENT(PM_PMC3_OVERFLOW, 0x40010) | ||
113 | EVENT(PM_MRK_BR_MPRED, 0x30036) | ||
114 | EVENT(PM_SHL_MATCH, 0x05086) | ||
115 | EVENT(PM_MRK_BR_TAKEN, 0x10036) | ||
116 | EVENT(PM_CMPLU_STALL_BRU, 0x4004e) | ||
117 | EVENT(PM_ISLB_MISS, 0x0d092) | ||
118 | EVENT(PM_CYC, 0x0001e) | ||
119 | EVENT(PM_DISP_HELD_THERMAL, 0x30006) | ||
120 | EVENT(PM_INST_PTEG_FROM_RL2L3_SHR, 0x2e054) | ||
121 | EVENT(PM_LSU1_SRQ_STFWD, 0x0c0a2) | ||
122 | EVENT(PM_GCT_NOSLOT_BR_MPRED, 0x4001a) | ||
123 | EVENT(PM_1PLUS_PPC_CMPL, 0x100f2) | ||
124 | EVENT(PM_PTEG_FROM_DMEM, 0x2c052) | ||
125 | EVENT(PM_VSU_2FLOP, 0x0a898) | ||
126 | EVENT(PM_GCT_FULL_CYC, 0x04086) | ||
127 | EVENT(PM_MRK_DATA_FROM_L3_CYC, 0x40020) | ||
128 | EVENT(PM_LSU_SRQ_S0_ALLOC, 0x0d09d) | ||
129 | EVENT(PM_MRK_DERAT_MISS_4K, 0x1d05c) | ||
130 | EVENT(PM_BR_MPRED_TA, 0x040ae) | ||
131 | EVENT(PM_INST_PTEG_FROM_L2MISS, 0x4e058) | ||
132 | EVENT(PM_DPU_HELD_POWER, 0x20006) | ||
133 | EVENT(PM_RUN_INST_CMPL, 0x400fa) | ||
134 | EVENT(PM_MRK_VSU_FIN, 0x30032) | ||
135 | EVENT(PM_LSU_SRQ_S0_VALID, 0x0d09c) | ||
136 | EVENT(PM_GCT_EMPTY_CYC, 0x20008) | ||
137 | EVENT(PM_IOPS_DISP, 0x30014) | ||
138 | EVENT(PM_RUN_SPURR, 0x10008) | ||
139 | EVENT(PM_PTEG_FROM_L21_MOD, 0x3c056) | ||
140 | EVENT(PM_VSU0_1FLOP, 0x0a080) | ||
141 | EVENT(PM_SNOOP_TLBIE, 0x0d0b2) | ||
142 | EVENT(PM_DATA_FROM_L3MISS, 0x2c048) | ||
143 | EVENT(PM_VSU_SINGLE, 0x0a8a8) | ||
144 | EVENT(PM_DTLB_MISS_16G, 0x1c05e) | ||
145 | EVENT(PM_CMPLU_STALL_VECTOR, 0x2001c) | ||
146 | EVENT(PM_FLUSH, 0x400f8) | ||
147 | EVENT(PM_L2_LD_HIT, 0x36182) | ||
148 | EVENT(PM_NEST_PAIR2_AND, 0x30883) | ||
149 | EVENT(PM_VSU1_1FLOP, 0x0a082) | ||
150 | EVENT(PM_IC_PREF_REQ, 0x0408a) | ||
151 | EVENT(PM_L3_LD_HIT, 0x2f080) | ||
152 | EVENT(PM_GCT_NOSLOT_IC_MISS, 0x2001a) | ||
153 | EVENT(PM_DISP_HELD, 0x10006) | ||
154 | EVENT(PM_L2_LD, 0x16080) | ||
155 | EVENT(PM_LSU_FLUSH_SRQ, 0x0c8bc) | ||
156 | EVENT(PM_BC_PLUS_8_CONV, 0x040b8) | ||
157 | EVENT(PM_MRK_DATA_FROM_L31_MOD_CYC, 0x40026) | ||
158 | EVENT(PM_CMPLU_STALL_VECTOR_LONG, 0x4004a) | ||
159 | EVENT(PM_L2_RCST_BUSY_RC_FULL, 0x26282) | ||
160 | EVENT(PM_TB_BIT_TRANS, 0x300f8) | ||
161 | EVENT(PM_THERMAL_MAX, 0x40006) | ||
162 | EVENT(PM_LSU1_FLUSH_ULD, 0x0c0b2) | ||
163 | EVENT(PM_LSU1_REJECT_LHS, 0x0c0ae) | ||
164 | EVENT(PM_LSU_LRQ_S0_ALLOC, 0x0d09f) | ||
165 | EVENT(PM_L3_CO_L31, 0x4f080) | ||
166 | EVENT(PM_POWER_EVENT4, 0x4006e) | ||
167 | EVENT(PM_DATA_FROM_L31_SHR, 0x1c04e) | ||
168 | EVENT(PM_BR_UNCOND, 0x0409e) | ||
169 | EVENT(PM_LSU1_DC_PREF_STREAM_ALLOC, 0x0d0aa) | ||
170 | EVENT(PM_PMC4_REWIND, 0x10020) | ||
171 | EVENT(PM_L2_RCLD_DISP, 0x16280) | ||
172 | EVENT(PM_THRD_PRIO_2_3_CYC, 0x040b2) | ||
173 | EVENT(PM_MRK_PTEG_FROM_L2MISS, 0x4d058) | ||
174 | EVENT(PM_IC_DEMAND_L2_BHT_REDIRECT, 0x04098) | ||
175 | EVENT(PM_LSU_DERAT_MISS, 0x200f6) | ||
176 | EVENT(PM_IC_PREF_CANCEL_L2, 0x04094) | ||
177 | EVENT(PM_MRK_FIN_STALL_CYC_COUNT, 0x1003d) | ||
178 | EVENT(PM_BR_PRED_CCACHE, 0x040a0) | ||
179 | EVENT(PM_GCT_UTIL_1_TO_2_SLOTS, 0x0209c) | ||
180 | EVENT(PM_MRK_ST_CMPL_INT, 0x30034) | ||
181 | EVENT(PM_LSU_TWO_TABLEWALK_CYC, 0x0d0a6) | ||
182 | EVENT(PM_MRK_DATA_FROM_L3MISS, 0x2d048) | ||
183 | EVENT(PM_GCT_NOSLOT_CYC, 0x100f8) | ||
184 | EVENT(PM_LSU_SET_MPRED, 0x0c0a8) | ||
185 | EVENT(PM_FLUSH_DISP_TLBIE, 0x0208a) | ||
186 | EVENT(PM_VSU1_FCONV, 0x0a0b2) | ||
187 | EVENT(PM_DERAT_MISS_16G, 0x4c05c) | ||
188 | EVENT(PM_INST_FROM_LMEM, 0x3404a) | ||
189 | EVENT(PM_IC_DEMAND_L2_BR_REDIRECT, 0x0409a) | ||
190 | EVENT(PM_CMPLU_STALL_SCALAR_LONG, 0x20018) | ||
191 | EVENT(PM_INST_PTEG_FROM_L2, 0x1e050) | ||
192 | EVENT(PM_PTEG_FROM_L2, 0x1c050) | ||
193 | EVENT(PM_MRK_DATA_FROM_L21_SHR_CYC, 0x20024) | ||
194 | EVENT(PM_MRK_DTLB_MISS_4K, 0x2d05a) | ||
195 | EVENT(PM_VSU0_FPSCR, 0x0b09c) | ||
196 | EVENT(PM_VSU1_VECT_DOUBLE_ISSUED, 0x0b082) | ||
197 | EVENT(PM_MRK_PTEG_FROM_RL2L3_MOD, 0x1d052) | ||
198 | EVENT(PM_MEM0_RQ_DISP, 0x10083) | ||
199 | EVENT(PM_L2_LD_MISS, 0x26080) | ||
200 | EVENT(PM_VMX_RESULT_SAT_1, 0x0b0a0) | ||
201 | EVENT(PM_L1_PREF, 0x0d8b8) | ||
202 | EVENT(PM_MRK_DATA_FROM_LMEM_CYC, 0x2002c) | ||
203 | EVENT(PM_GRP_IC_MISS_NONSPEC, 0x1000c) | ||
204 | EVENT(PM_PB_NODE_PUMP, 0x10081) | ||
205 | EVENT(PM_SHL_MERGED, 0x05084) | ||
206 | EVENT(PM_NEST_PAIR1_ADD, 0x20881) | ||
207 | EVENT(PM_DATA_FROM_L3, 0x1c048) | ||
208 | EVENT(PM_LSU_FLUSH, 0x0208e) | ||
209 | EVENT(PM_LSU_SRQ_SYNC_COUNT, 0x0d097) | ||
210 | EVENT(PM_PMC2_OVERFLOW, 0x30010) | ||
211 | EVENT(PM_LSU_LDF, 0x0c884) | ||
212 | EVENT(PM_POWER_EVENT3, 0x3006e) | ||
213 | EVENT(PM_DISP_WT, 0x30008) | ||
214 | EVENT(PM_CMPLU_STALL_REJECT, 0x40016) | ||
215 | EVENT(PM_IC_BANK_CONFLICT, 0x04082) | ||
216 | EVENT(PM_BR_MPRED_CR_TA, 0x048ae) | ||
217 | EVENT(PM_L2_INST_MISS, 0x36082) | ||
218 | EVENT(PM_CMPLU_STALL_ERAT_MISS, 0x40018) | ||
219 | EVENT(PM_NEST_PAIR2_ADD, 0x30881) | ||
220 | EVENT(PM_MRK_LSU_FLUSH, 0x0d08c) | ||
221 | EVENT(PM_L2_LDST, 0x16880) | ||
222 | EVENT(PM_INST_FROM_L31_SHR, 0x1404e) | ||
223 | EVENT(PM_VSU0_FIN, 0x0a0bc) | ||
224 | EVENT(PM_LARX_LSU, 0x0c894) | ||
225 | EVENT(PM_INST_FROM_RMEM, 0x34042) | ||
226 | EVENT(PM_DISP_CLB_HELD_TLBIE, 0x02096) | ||
227 | EVENT(PM_MRK_DATA_FROM_DMEM_CYC, 0x2002e) | ||
228 | EVENT(PM_BR_PRED_CR, 0x040a8) | ||
229 | EVENT(PM_LSU_REJECT, 0x10064) | ||
230 | EVENT(PM_GCT_UTIL_3_TO_6_SLOTS, 0x0209e) | ||
231 | EVENT(PM_CMPLU_STALL_END_GCT_NOSLOT, 0x10028) | ||
232 | EVENT(PM_LSU0_REJECT_LMQ_FULL, 0x0c0a4) | ||
233 | EVENT(PM_VSU_FEST, 0x0a8b8) | ||
234 | EVENT(PM_NEST_PAIR0_AND, 0x10883) | ||
235 | EVENT(PM_PTEG_FROM_L3, 0x2c050) | ||
236 | EVENT(PM_POWER_EVENT2, 0x2006e) | ||
237 | EVENT(PM_IC_PREF_CANCEL_PAGE, 0x04090) | ||
238 | EVENT(PM_VSU0_FSQRT_FDIV, 0x0a088) | ||
239 | EVENT(PM_MRK_GRP_CMPL, 0x40030) | ||
240 | EVENT(PM_VSU0_SCAL_DOUBLE_ISSUED, 0x0b088) | ||
241 | EVENT(PM_GRP_DISP, 0x3000a) | ||
242 | EVENT(PM_LSU0_LDX, 0x0c088) | ||
243 | EVENT(PM_DATA_FROM_L2, 0x1c040) | ||
244 | EVENT(PM_MRK_DATA_FROM_RL2L3_MOD, 0x1d042) | ||
245 | EVENT(PM_LD_REF_L1, 0x0c880) | ||
246 | EVENT(PM_VSU0_VECT_DOUBLE_ISSUED, 0x0b080) | ||
247 | EVENT(PM_VSU1_2FLOP_DOUBLE, 0x0a08e) | ||
248 | EVENT(PM_THRD_PRIO_6_7_CYC, 0x040b6) | ||
249 | EVENT(PM_BC_PLUS_8_RSLV_TAKEN, 0x040ba) | ||
250 | EVENT(PM_BR_MPRED_CR, 0x040ac) | ||
251 | EVENT(PM_L3_CO_MEM, 0x4f082) | ||
252 | EVENT(PM_LD_MISS_L1, 0x400f0) | ||
253 | EVENT(PM_DATA_FROM_RL2L3_MOD, 0x1c042) | ||
254 | EVENT(PM_LSU_SRQ_FULL_CYC, 0x1001a) | ||
255 | EVENT(PM_TABLEWALK_CYC, 0x10026) | ||
256 | EVENT(PM_MRK_PTEG_FROM_RMEM, 0x3d052) | ||
257 | EVENT(PM_LSU_SRQ_STFWD, 0x0c8a0) | ||
258 | EVENT(PM_INST_PTEG_FROM_RMEM, 0x3e052) | ||
259 | EVENT(PM_FXU0_FIN, 0x10004) | ||
260 | EVENT(PM_LSU1_L1_SW_PREF, 0x0c09e) | ||
261 | EVENT(PM_PTEG_FROM_L31_MOD, 0x1c054) | ||
262 | EVENT(PM_PMC5_OVERFLOW, 0x10024) | ||
263 | EVENT(PM_LD_REF_L1_LSU1, 0x0c082) | ||
264 | EVENT(PM_INST_PTEG_FROM_L21_SHR, 0x4e056) | ||
265 | EVENT(PM_CMPLU_STALL_THRD, 0x1001c) | ||
266 | EVENT(PM_DATA_FROM_RMEM, 0x3c042) | ||
267 | EVENT(PM_VSU0_SCAL_SINGLE_ISSUED, 0x0b084) | ||
268 | EVENT(PM_BR_MPRED_LSTACK, 0x040a6) | ||
269 | EVENT(PM_MRK_DATA_FROM_RL2L3_MOD_CYC, 0x40028) | ||
270 | EVENT(PM_LSU0_FLUSH_UST, 0x0c0b4) | ||
271 | EVENT(PM_LSU_NCST, 0x0c090) | ||
272 | EVENT(PM_BR_TAKEN, 0x20004) | ||
273 | EVENT(PM_INST_PTEG_FROM_LMEM, 0x4e052) | ||
274 | EVENT(PM_GCT_NOSLOT_BR_MPRED_IC_MISS, 0x4001c) | ||
275 | EVENT(PM_DTLB_MISS_4K, 0x2c05a) | ||
276 | EVENT(PM_PMC4_SAVED, 0x30022) | ||
277 | EVENT(PM_VSU1_PERMUTE_ISSUED, 0x0b092) | ||
278 | EVENT(PM_SLB_MISS, 0x0d890) | ||
279 | EVENT(PM_LSU1_FLUSH_LRQ, 0x0c0ba) | ||
280 | EVENT(PM_DTLB_MISS, 0x300fc) | ||
281 | EVENT(PM_VSU1_FRSP, 0x0a0b6) | ||
282 | EVENT(PM_VSU_VECTOR_DOUBLE_ISSUED, 0x0b880) | ||
283 | EVENT(PM_L2_CASTOUT_SHR, 0x16182) | ||
284 | EVENT(PM_DATA_FROM_DL2L3_SHR, 0x3c044) | ||
285 | EVENT(PM_VSU1_STF, 0x0b08e) | ||
286 | EVENT(PM_ST_FIN, 0x200f0) | ||
287 | EVENT(PM_PTEG_FROM_L21_SHR, 0x4c056) | ||
288 | EVENT(PM_L2_LOC_GUESS_WRONG, 0x26480) | ||
289 | EVENT(PM_MRK_STCX_FAIL, 0x0d08e) | ||
290 | EVENT(PM_LSU0_REJECT_LHS, 0x0c0ac) | ||
291 | EVENT(PM_IC_PREF_CANCEL_HIT, 0x04092) | ||
292 | EVENT(PM_L3_PREF_BUSY, 0x4f080) | ||
293 | EVENT(PM_MRK_BRU_FIN, 0x2003a) | ||
294 | EVENT(PM_LSU1_NCLD, 0x0c08e) | ||
295 | EVENT(PM_INST_PTEG_FROM_L31_MOD, 0x1e054) | ||
296 | EVENT(PM_LSU_NCLD, 0x0c88c) | ||
297 | EVENT(PM_LSU_LDX, 0x0c888) | ||
298 | EVENT(PM_L2_LOC_GUESS_CORRECT, 0x16480) | ||
299 | EVENT(PM_THRESH_TIMEO, 0x10038) | ||
300 | EVENT(PM_L3_PREF_ST, 0x0d0ae) | ||
301 | EVENT(PM_DISP_CLB_HELD_SYNC, 0x02098) | ||
302 | EVENT(PM_VSU_SIMPLE_ISSUED, 0x0b894) | ||
303 | EVENT(PM_VSU1_SINGLE, 0x0a0aa) | ||
304 | EVENT(PM_DATA_TABLEWALK_CYC, 0x3001a) | ||
305 | EVENT(PM_L2_RC_ST_DONE, 0x36380) | ||
306 | EVENT(PM_MRK_PTEG_FROM_L21_MOD, 0x3d056) | ||
307 | EVENT(PM_LARX_LSU1, 0x0c096) | ||
308 | EVENT(PM_MRK_DATA_FROM_RMEM, 0x3d042) | ||
309 | EVENT(PM_DISP_CLB_HELD, 0x02090) | ||
310 | EVENT(PM_DERAT_MISS_4K, 0x1c05c) | ||
311 | EVENT(PM_L2_RCLD_DISP_FAIL_ADDR, 0x16282) | ||
312 | EVENT(PM_SEG_EXCEPTION, 0x028a4) | ||
313 | EVENT(PM_FLUSH_DISP_SB, 0x0208c) | ||
314 | EVENT(PM_L2_DC_INV, 0x26182) | ||
315 | EVENT(PM_PTEG_FROM_DL2L3_MOD, 0x4c054) | ||
316 | EVENT(PM_DSEG, 0x020a6) | ||
317 | EVENT(PM_BR_PRED_LSTACK, 0x040a2) | ||
318 | EVENT(PM_VSU0_STF, 0x0b08c) | ||
319 | EVENT(PM_LSU_FX_FIN, 0x10066) | ||
320 | EVENT(PM_DERAT_MISS_16M, 0x3c05c) | ||
321 | EVENT(PM_MRK_PTEG_FROM_DL2L3_MOD, 0x4d054) | ||
322 | EVENT(PM_GCT_UTIL_11_PLUS_SLOTS, 0x020a2) | ||
323 | EVENT(PM_INST_FROM_L3, 0x14048) | ||
324 | EVENT(PM_MRK_IFU_FIN, 0x3003a) | ||
325 | EVENT(PM_ITLB_MISS, 0x400fc) | ||
326 | EVENT(PM_VSU_STF, 0x0b88c) | ||
327 | EVENT(PM_LSU_FLUSH_UST, 0x0c8b4) | ||
328 | EVENT(PM_L2_LDST_MISS, 0x26880) | ||
329 | EVENT(PM_FXU1_FIN, 0x40004) | ||
330 | EVENT(PM_SHL_DEALLOCATED, 0x05080) | ||
331 | EVENT(PM_L2_SN_M_WR_DONE, 0x46382) | ||
332 | EVENT(PM_LSU_REJECT_SET_MPRED, 0x0c8a8) | ||
333 | EVENT(PM_L3_PREF_LD, 0x0d0ac) | ||
334 | EVENT(PM_L2_SN_M_RD_DONE, 0x46380) | ||
335 | EVENT(PM_MRK_DERAT_MISS_16G, 0x4d05c) | ||
336 | EVENT(PM_VSU_FCONV, 0x0a8b0) | ||
337 | EVENT(PM_ANY_THRD_RUN_CYC, 0x100fa) | ||
338 | EVENT(PM_LSU_LMQ_FULL_CYC, 0x0d0a4) | ||
339 | EVENT(PM_MRK_LSU_REJECT_LHS, 0x0d082) | ||
340 | EVENT(PM_MRK_LD_MISS_L1_CYC, 0x4003e) | ||
341 | EVENT(PM_MRK_DATA_FROM_L2_CYC, 0x20020) | ||
342 | EVENT(PM_INST_IMC_MATCH_DISP, 0x30016) | ||
343 | EVENT(PM_MRK_DATA_FROM_RMEM_CYC, 0x4002c) | ||
344 | EVENT(PM_VSU0_SIMPLE_ISSUED, 0x0b094) | ||
345 | EVENT(PM_CMPLU_STALL_DIV, 0x40014) | ||
346 | EVENT(PM_MRK_PTEG_FROM_RL2L3_SHR, 0x2d054) | ||
347 | EVENT(PM_VSU_FMA_DOUBLE, 0x0a890) | ||
348 | EVENT(PM_VSU_4FLOP, 0x0a89c) | ||
349 | EVENT(PM_VSU1_FIN, 0x0a0be) | ||
350 | EVENT(PM_NEST_PAIR1_AND, 0x20883) | ||
351 | EVENT(PM_INST_PTEG_FROM_RL2L3_MOD, 0x1e052) | ||
352 | EVENT(PM_RUN_CYC, 0x200f4) | ||
353 | EVENT(PM_PTEG_FROM_RMEM, 0x3c052) | ||
354 | EVENT(PM_LSU_LRQ_S0_VALID, 0x0d09e) | ||
355 | EVENT(PM_LSU0_LDF, 0x0c084) | ||
356 | EVENT(PM_FLUSH_COMPLETION, 0x30012) | ||
357 | EVENT(PM_ST_MISS_L1, 0x300f0) | ||
358 | EVENT(PM_L2_NODE_PUMP, 0x36480) | ||
359 | EVENT(PM_INST_FROM_DL2L3_SHR, 0x34044) | ||
360 | EVENT(PM_MRK_STALL_CMPLU_CYC, 0x3003e) | ||
361 | EVENT(PM_VSU1_DENORM, 0x0a0ae) | ||
362 | EVENT(PM_MRK_DATA_FROM_L31_SHR_CYC, 0x20026) | ||
363 | EVENT(PM_NEST_PAIR0_ADD, 0x10881) | ||
364 | EVENT(PM_INST_FROM_L3MISS, 0x24048) | ||
365 | EVENT(PM_EE_OFF_EXT_INT, 0x02080) | ||
366 | EVENT(PM_INST_PTEG_FROM_DMEM, 0x2e052) | ||
367 | EVENT(PM_INST_FROM_DL2L3_MOD, 0x3404c) | ||
368 | EVENT(PM_PMC6_OVERFLOW, 0x30024) | ||
369 | EVENT(PM_VSU_2FLOP_DOUBLE, 0x0a88c) | ||
370 | EVENT(PM_TLB_MISS, 0x20066) | ||
371 | EVENT(PM_FXU_BUSY, 0x2000e) | ||
372 | EVENT(PM_L2_RCLD_DISP_FAIL_OTHER, 0x26280) | ||
373 | EVENT(PM_LSU_REJECT_LMQ_FULL, 0x0c8a4) | ||
374 | EVENT(PM_IC_RELOAD_SHR, 0x04096) | ||
375 | EVENT(PM_GRP_MRK, 0x10031) | ||
376 | EVENT(PM_MRK_ST_NEST, 0x20034) | ||
377 | EVENT(PM_VSU1_FSQRT_FDIV, 0x0a08a) | ||
378 | EVENT(PM_LSU0_FLUSH_LRQ, 0x0c0b8) | ||
379 | EVENT(PM_LARX_LSU0, 0x0c094) | ||
380 | EVENT(PM_IBUF_FULL_CYC, 0x04084) | ||
381 | EVENT(PM_MRK_DATA_FROM_DL2L3_SHR_CYC, 0x2002a) | ||
382 | EVENT(PM_LSU_DC_PREF_STREAM_ALLOC, 0x0d8a8) | ||
383 | EVENT(PM_GRP_MRK_CYC, 0x10030) | ||
384 | EVENT(PM_MRK_DATA_FROM_RL2L3_SHR_CYC, 0x20028) | ||
385 | EVENT(PM_L2_GLOB_GUESS_CORRECT, 0x16482) | ||
386 | EVENT(PM_LSU_REJECT_LHS, 0x0c8ac) | ||
387 | EVENT(PM_MRK_DATA_FROM_LMEM, 0x3d04a) | ||
388 | EVENT(PM_INST_PTEG_FROM_L3, 0x2e050) | ||
389 | EVENT(PM_FREQ_DOWN, 0x3000c) | ||
390 | EVENT(PM_PB_RETRY_NODE_PUMP, 0x30081) | ||
391 | EVENT(PM_INST_FROM_RL2L3_SHR, 0x1404c) | ||
392 | EVENT(PM_MRK_INST_ISSUED, 0x10032) | ||
393 | EVENT(PM_PTEG_FROM_L3MISS, 0x2c058) | ||
394 | EVENT(PM_RUN_PURR, 0x400f4) | ||
395 | EVENT(PM_MRK_GRP_IC_MISS, 0x40038) | ||
396 | EVENT(PM_MRK_DATA_FROM_L3, 0x1d048) | ||
397 | EVENT(PM_CMPLU_STALL_DCACHE_MISS, 0x20016) | ||
398 | EVENT(PM_PTEG_FROM_RL2L3_SHR, 0x2c054) | ||
399 | EVENT(PM_LSU_FLUSH_LRQ, 0x0c8b8) | ||
400 | EVENT(PM_MRK_DERAT_MISS_64K, 0x2d05c) | ||
401 | EVENT(PM_INST_PTEG_FROM_DL2L3_MOD, 0x4e054) | ||
402 | EVENT(PM_L2_ST_MISS, 0x26082) | ||
403 | EVENT(PM_MRK_PTEG_FROM_L21_SHR, 0x4d056) | ||
404 | EVENT(PM_LWSYNC, 0x0d094) | ||
405 | EVENT(PM_LSU0_DC_PREF_STREAM_CONFIRM_STRIDE, 0x0d0bc) | ||
406 | EVENT(PM_MRK_LSU_FLUSH_LRQ, 0x0d088) | ||
407 | EVENT(PM_INST_IMC_MATCH_CMPL, 0x100f0) | ||
408 | EVENT(PM_NEST_PAIR3_AND, 0x40883) | ||
409 | EVENT(PM_PB_RETRY_SYS_PUMP, 0x40081) | ||
410 | EVENT(PM_MRK_INST_FIN, 0x30030) | ||
411 | EVENT(PM_MRK_PTEG_FROM_DL2L3_SHR, 0x3d054) | ||
412 | EVENT(PM_INST_FROM_L31_MOD, 0x14044) | ||
413 | EVENT(PM_MRK_DTLB_MISS_64K, 0x3d05e) | ||
414 | EVENT(PM_LSU_FIN, 0x30066) | ||
415 | EVENT(PM_MRK_LSU_REJECT, 0x40064) | ||
416 | EVENT(PM_L2_CO_FAIL_BUSY, 0x16382) | ||
417 | EVENT(PM_MEM0_WQ_DISP, 0x40083) | ||
418 | EVENT(PM_DATA_FROM_L31_MOD, 0x1c044) | ||
419 | EVENT(PM_THERMAL_WARN, 0x10016) | ||
420 | EVENT(PM_VSU0_4FLOP, 0x0a09c) | ||
421 | EVENT(PM_BR_MPRED_CCACHE, 0x040a4) | ||
422 | EVENT(PM_CMPLU_STALL_IFU, 0x4004c) | ||
423 | EVENT(PM_L1_DEMAND_WRITE, 0x0408c) | ||
424 | EVENT(PM_FLUSH_BR_MPRED, 0x02084) | ||
425 | EVENT(PM_MRK_DTLB_MISS_16G, 0x1d05e) | ||
426 | EVENT(PM_MRK_PTEG_FROM_DMEM, 0x2d052) | ||
427 | EVENT(PM_L2_RCST_DISP, 0x36280) | ||
428 | EVENT(PM_CMPLU_STALL, 0x4000a) | ||
429 | EVENT(PM_LSU_PARTIAL_CDF, 0x0c0aa) | ||
430 | EVENT(PM_DISP_CLB_HELD_SB, 0x020a8) | ||
431 | EVENT(PM_VSU0_FMA_DOUBLE, 0x0a090) | ||
432 | EVENT(PM_FXU0_BUSY_FXU1_IDLE, 0x3000e) | ||
433 | EVENT(PM_IC_DEMAND_CYC, 0x10018) | ||
434 | EVENT(PM_MRK_DATA_FROM_L21_SHR, 0x3d04e) | ||
435 | EVENT(PM_MRK_LSU_FLUSH_UST, 0x0d086) | ||
436 | EVENT(PM_INST_PTEG_FROM_L3MISS, 0x2e058) | ||
437 | EVENT(PM_VSU_DENORM, 0x0a8ac) | ||
438 | EVENT(PM_MRK_LSU_PARTIAL_CDF, 0x0d080) | ||
439 | EVENT(PM_INST_FROM_L21_SHR, 0x3404e) | ||
440 | EVENT(PM_IC_PREF_WRITE, 0x0408e) | ||
441 | EVENT(PM_BR_PRED, 0x0409c) | ||
442 | EVENT(PM_INST_FROM_DMEM, 0x1404a) | ||
443 | EVENT(PM_IC_PREF_CANCEL_ALL, 0x04890) | ||
444 | EVENT(PM_LSU_DC_PREF_STREAM_CONFIRM, 0x0d8b4) | ||
445 | EVENT(PM_MRK_LSU_FLUSH_SRQ, 0x0d08a) | ||
446 | EVENT(PM_MRK_FIN_STALL_CYC, 0x1003c) | ||
447 | EVENT(PM_L2_RCST_DISP_FAIL_OTHER, 0x46280) | ||
448 | EVENT(PM_VSU1_DD_ISSUED, 0x0b098) | ||
449 | EVENT(PM_PTEG_FROM_L31_SHR, 0x2c056) | ||
450 | EVENT(PM_DATA_FROM_L21_SHR, 0x3c04e) | ||
451 | EVENT(PM_LSU0_NCLD, 0x0c08c) | ||
452 | EVENT(PM_VSU1_4FLOP, 0x0a09e) | ||
453 | EVENT(PM_VSU1_8FLOP, 0x0a0a2) | ||
454 | EVENT(PM_VSU_8FLOP, 0x0a8a0) | ||
455 | EVENT(PM_LSU_LMQ_SRQ_EMPTY_CYC, 0x2003e) | ||
456 | EVENT(PM_DTLB_MISS_64K, 0x3c05e) | ||
457 | EVENT(PM_THRD_CONC_RUN_INST, 0x300f4) | ||
458 | EVENT(PM_MRK_PTEG_FROM_L2, 0x1d050) | ||
459 | EVENT(PM_PB_SYS_PUMP, 0x20081) | ||
460 | EVENT(PM_VSU_FIN, 0x0a8bc) | ||
461 | EVENT(PM_MRK_DATA_FROM_L31_MOD, 0x1d044) | ||
462 | EVENT(PM_THRD_PRIO_0_1_CYC, 0x040b0) | ||
463 | EVENT(PM_DERAT_MISS_64K, 0x2c05c) | ||
464 | EVENT(PM_PMC2_REWIND, 0x30020) | ||
465 | EVENT(PM_INST_FROM_L2, 0x14040) | ||
466 | EVENT(PM_GRP_BR_MPRED_NONSPEC, 0x1000a) | ||
467 | EVENT(PM_INST_DISP, 0x200f2) | ||
468 | EVENT(PM_MEM0_RD_CANCEL_TOTAL, 0x30083) | ||
469 | EVENT(PM_LSU0_DC_PREF_STREAM_CONFIRM, 0x0d0b4) | ||
470 | EVENT(PM_L1_DCACHE_RELOAD_VALID, 0x300f6) | ||
471 | EVENT(PM_VSU_SCALAR_DOUBLE_ISSUED, 0x0b888) | ||
472 | EVENT(PM_L3_PREF_HIT, 0x3f080) | ||
473 | EVENT(PM_MRK_PTEG_FROM_L31_MOD, 0x1d054) | ||
474 | EVENT(PM_CMPLU_STALL_STORE, 0x2004a) | ||
475 | EVENT(PM_MRK_FXU_FIN, 0x20038) | ||
476 | EVENT(PM_PMC4_OVERFLOW, 0x10010) | ||
477 | EVENT(PM_MRK_PTEG_FROM_L3, 0x2d050) | ||
478 | EVENT(PM_LSU0_LMQ_LHR_MERGE, 0x0d098) | ||
479 | EVENT(PM_BTAC_HIT, 0x0508a) | ||
480 | EVENT(PM_L3_RD_BUSY, 0x4f082) | ||
481 | EVENT(PM_LSU0_L1_SW_PREF, 0x0c09c) | ||
482 | EVENT(PM_INST_FROM_L2MISS, 0x44048) | ||
483 | EVENT(PM_LSU0_DC_PREF_STREAM_ALLOC, 0x0d0a8) | ||
484 | EVENT(PM_L2_ST, 0x16082) | ||
485 | EVENT(PM_VSU0_DENORM, 0x0a0ac) | ||
486 | EVENT(PM_MRK_DATA_FROM_DL2L3_SHR, 0x3d044) | ||
487 | EVENT(PM_BR_PRED_CR_TA, 0x048aa) | ||
488 | EVENT(PM_VSU0_FCONV, 0x0a0b0) | ||
489 | EVENT(PM_MRK_LSU_FLUSH_ULD, 0x0d084) | ||
490 | EVENT(PM_BTAC_MISS, 0x05088) | ||
491 | EVENT(PM_MRK_LD_MISS_EXPOSED_CYC_COUNT, 0x1003f) | ||
492 | EVENT(PM_MRK_DATA_FROM_L2, 0x1d040) | ||
493 | EVENT(PM_LSU_DCACHE_RELOAD_VALID, 0x0d0a2) | ||
494 | EVENT(PM_VSU_FMA, 0x0a884) | ||
495 | EVENT(PM_LSU0_FLUSH_SRQ, 0x0c0bc) | ||
496 | EVENT(PM_LSU1_L1_PREF, 0x0d0ba) | ||
497 | EVENT(PM_IOPS_CMPL, 0x10014) | ||
498 | EVENT(PM_L2_SYS_PUMP, 0x36482) | ||
499 | EVENT(PM_L2_RCLD_BUSY_RC_FULL, 0x46282) | ||
500 | EVENT(PM_LSU_LMQ_S0_ALLOC, 0x0d0a1) | ||
501 | EVENT(PM_FLUSH_DISP_SYNC, 0x02088) | ||
502 | EVENT(PM_MRK_DATA_FROM_DL2L3_MOD_CYC, 0x4002a) | ||
503 | EVENT(PM_L2_IC_INV, 0x26180) | ||
504 | EVENT(PM_MRK_DATA_FROM_L21_MOD_CYC, 0x40024) | ||
505 | EVENT(PM_L3_PREF_LDST, 0x0d8ac) | ||
506 | EVENT(PM_LSU_SRQ_EMPTY_CYC, 0x40008) | ||
507 | EVENT(PM_LSU_LMQ_S0_VALID, 0x0d0a0) | ||
508 | EVENT(PM_FLUSH_PARTIAL, 0x02086) | ||
509 | EVENT(PM_VSU1_FMA_DOUBLE, 0x0a092) | ||
510 | EVENT(PM_1PLUS_PPC_DISP, 0x400f2) | ||
511 | EVENT(PM_DATA_FROM_L2MISS, 0x200fe) | ||
512 | EVENT(PM_SUSPENDED, 0x00000) | ||
513 | EVENT(PM_VSU0_FMA, 0x0a084) | ||
514 | EVENT(PM_CMPLU_STALL_SCALAR, 0x40012) | ||
515 | EVENT(PM_STCX_FAIL, 0x0c09a) | ||
516 | EVENT(PM_VSU0_FSQRT_FDIV_DOUBLE, 0x0a094) | ||
517 | EVENT(PM_DC_PREF_DST, 0x0d0b0) | ||
518 | EVENT(PM_VSU1_SCAL_SINGLE_ISSUED, 0x0b086) | ||
519 | EVENT(PM_L3_HIT, 0x1f080) | ||
520 | EVENT(PM_L2_GLOB_GUESS_WRONG, 0x26482) | ||
521 | EVENT(PM_MRK_DFU_FIN, 0x20032) | ||
522 | EVENT(PM_INST_FROM_L1, 0x04080) | ||
523 | EVENT(PM_BRU_FIN, 0x10068) | ||
524 | EVENT(PM_IC_DEMAND_REQ, 0x04088) | ||
525 | EVENT(PM_VSU1_FSQRT_FDIV_DOUBLE, 0x0a096) | ||
526 | EVENT(PM_VSU1_FMA, 0x0a086) | ||
527 | EVENT(PM_MRK_LD_MISS_L1, 0x20036) | ||
528 | EVENT(PM_VSU0_2FLOP_DOUBLE, 0x0a08c) | ||
529 | EVENT(PM_LSU_DC_PREF_STRIDED_STREAM_CONFIRM, 0x0d8bc) | ||
530 | EVENT(PM_INST_PTEG_FROM_L31_SHR, 0x2e056) | ||
531 | EVENT(PM_MRK_LSU_REJECT_ERAT_MISS, 0x30064) | ||
532 | EVENT(PM_MRK_DATA_FROM_L2MISS, 0x4d048) | ||
533 | EVENT(PM_DATA_FROM_RL2L3_SHR, 0x1c04c) | ||
534 | EVENT(PM_INST_FROM_PREF, 0x14046) | ||
535 | EVENT(PM_VSU1_SQ, 0x0b09e) | ||
536 | EVENT(PM_L2_LD_DISP, 0x36180) | ||
537 | EVENT(PM_L2_DISP_ALL, 0x46080) | ||
538 | EVENT(PM_THRD_GRP_CMPL_BOTH_CYC, 0x10012) | ||
539 | EVENT(PM_VSU_FSQRT_FDIV_DOUBLE, 0x0a894) | ||
540 | EVENT(PM_BR_MPRED, 0x400f6) | ||
541 | EVENT(PM_INST_PTEG_FROM_DL2L3_SHR, 0x3e054) | ||
542 | EVENT(PM_VSU_1FLOP, 0x0a880) | ||
543 | EVENT(PM_HV_CYC, 0x2000a) | ||
544 | EVENT(PM_MRK_LSU_FIN, 0x40032) | ||
545 | EVENT(PM_MRK_DATA_FROM_RL2L3_SHR, 0x1d04c) | ||
546 | EVENT(PM_DTLB_MISS_16M, 0x4c05e) | ||
547 | EVENT(PM_LSU1_LMQ_LHR_MERGE, 0x0d09a) | ||
548 | EVENT(PM_IFU_FIN, 0x40066) | ||
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c index d1821b8bbc4c..56c67bca2f75 100644 --- a/arch/powerpc/perf/power7-pmu.c +++ b/arch/powerpc/perf/power7-pmu.c | |||
@@ -53,37 +53,13 @@ | |||
53 | /* | 53 | /* |
54 | * Power7 event codes. | 54 | * Power7 event codes. |
55 | */ | 55 | */ |
56 | #define PME_PM_CYC 0x1e | 56 | #define EVENT(_name, _code) \ |
57 | #define PME_PM_GCT_NOSLOT_CYC 0x100f8 | 57 | PME_##_name = _code, |
58 | #define PME_PM_CMPLU_STALL 0x4000a | 58 | |
59 | #define PME_PM_INST_CMPL 0x2 | 59 | enum { |
60 | #define PME_PM_LD_REF_L1 0xc880 | 60 | #include "power7-events-list.h" |
61 | #define PME_PM_LD_MISS_L1 0x400f0 | 61 | }; |
62 | #define PME_PM_BRU_FIN 0x10068 | 62 | #undef EVENT |
63 | #define PME_PM_BR_MPRED 0x400f6 | ||
64 | |||
65 | #define PME_PM_CMPLU_STALL_FXU 0x20014 | ||
66 | #define PME_PM_CMPLU_STALL_DIV 0x40014 | ||
67 | #define PME_PM_CMPLU_STALL_SCALAR 0x40012 | ||
68 | #define PME_PM_CMPLU_STALL_SCALAR_LONG 0x20018 | ||
69 | #define PME_PM_CMPLU_STALL_VECTOR 0x2001c | ||
70 | #define PME_PM_CMPLU_STALL_VECTOR_LONG 0x4004a | ||
71 | #define PME_PM_CMPLU_STALL_LSU 0x20012 | ||
72 | #define PME_PM_CMPLU_STALL_REJECT 0x40016 | ||
73 | #define PME_PM_CMPLU_STALL_ERAT_MISS 0x40018 | ||
74 | #define PME_PM_CMPLU_STALL_DCACHE_MISS 0x20016 | ||
75 | #define PME_PM_CMPLU_STALL_STORE 0x2004a | ||
76 | #define PME_PM_CMPLU_STALL_THRD 0x1001c | ||
77 | #define PME_PM_CMPLU_STALL_IFU 0x4004c | ||
78 | #define PME_PM_CMPLU_STALL_BRU 0x4004e | ||
79 | #define PME_PM_GCT_NOSLOT_IC_MISS 0x2001a | ||
80 | #define PME_PM_GCT_NOSLOT_BR_MPRED 0x4001a | ||
81 | #define PME_PM_GCT_NOSLOT_BR_MPRED_IC_MISS 0x4001c | ||
82 | #define PME_PM_GRP_CMPL 0x30004 | ||
83 | #define PME_PM_1PLUS_PPC_CMPL 0x100f2 | ||
84 | #define PME_PM_CMPLU_STALL_DFU 0x2003c | ||
85 | #define PME_PM_RUN_CYC 0x200f4 | ||
86 | #define PME_PM_RUN_INST_CMPL 0x400fa | ||
87 | 63 | ||
88 | /* | 64 | /* |
89 | * Layout of constraint bits: | 65 | * Layout of constraint bits: |
@@ -398,96 +374,36 @@ static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | |||
398 | }; | 374 | }; |
399 | 375 | ||
400 | 376 | ||
401 | GENERIC_EVENT_ATTR(cpu-cycles, CYC); | 377 | GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC); |
402 | GENERIC_EVENT_ATTR(stalled-cycles-frontend, GCT_NOSLOT_CYC); | 378 | GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_GCT_NOSLOT_CYC); |
403 | GENERIC_EVENT_ATTR(stalled-cycles-backend, CMPLU_STALL); | 379 | GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL); |
404 | GENERIC_EVENT_ATTR(instructions, INST_CMPL); | 380 | GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL); |
405 | GENERIC_EVENT_ATTR(cache-references, LD_REF_L1); | 381 | GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1); |
406 | GENERIC_EVENT_ATTR(cache-misses, LD_MISS_L1); | 382 | GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1); |
407 | GENERIC_EVENT_ATTR(branch-instructions, BRU_FIN); | 383 | GENERIC_EVENT_ATTR(branch-instructions, PM_BRU_FIN); |
408 | GENERIC_EVENT_ATTR(branch-misses, BR_MPRED); | 384 | GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED); |
409 | 385 | ||
410 | POWER_EVENT_ATTR(CYC, CYC); | 386 | #define EVENT(_name, _code) POWER_EVENT_ATTR(_name, _name); |
411 | POWER_EVENT_ATTR(GCT_NOSLOT_CYC, GCT_NOSLOT_CYC); | 387 | #include "power7-events-list.h" |
412 | POWER_EVENT_ATTR(CMPLU_STALL, CMPLU_STALL); | 388 | #undef EVENT |
413 | POWER_EVENT_ATTR(INST_CMPL, INST_CMPL); | 389 | |
414 | POWER_EVENT_ATTR(LD_REF_L1, LD_REF_L1); | 390 | #define EVENT(_name, _code) POWER_EVENT_PTR(_name), |
415 | POWER_EVENT_ATTR(LD_MISS_L1, LD_MISS_L1); | ||
416 | POWER_EVENT_ATTR(BRU_FIN, BRU_FIN) | ||
417 | POWER_EVENT_ATTR(BR_MPRED, BR_MPRED); | ||
418 | |||
419 | POWER_EVENT_ATTR(CMPLU_STALL_FXU, CMPLU_STALL_FXU); | ||
420 | POWER_EVENT_ATTR(CMPLU_STALL_DIV, CMPLU_STALL_DIV); | ||
421 | POWER_EVENT_ATTR(CMPLU_STALL_SCALAR, CMPLU_STALL_SCALAR); | ||
422 | POWER_EVENT_ATTR(CMPLU_STALL_SCALAR_LONG, CMPLU_STALL_SCALAR_LONG); | ||
423 | POWER_EVENT_ATTR(CMPLU_STALL_VECTOR, CMPLU_STALL_VECTOR); | ||
424 | POWER_EVENT_ATTR(CMPLU_STALL_VECTOR_LONG, CMPLU_STALL_VECTOR_LONG); | ||
425 | POWER_EVENT_ATTR(CMPLU_STALL_LSU, CMPLU_STALL_LSU); | ||
426 | POWER_EVENT_ATTR(CMPLU_STALL_REJECT, CMPLU_STALL_REJECT); | ||
427 | |||
428 | POWER_EVENT_ATTR(CMPLU_STALL_ERAT_MISS, CMPLU_STALL_ERAT_MISS); | ||
429 | POWER_EVENT_ATTR(CMPLU_STALL_DCACHE_MISS, CMPLU_STALL_DCACHE_MISS); | ||
430 | POWER_EVENT_ATTR(CMPLU_STALL_STORE, CMPLU_STALL_STORE); | ||
431 | POWER_EVENT_ATTR(CMPLU_STALL_THRD, CMPLU_STALL_THRD); | ||
432 | POWER_EVENT_ATTR(CMPLU_STALL_IFU, CMPLU_STALL_IFU); | ||
433 | POWER_EVENT_ATTR(CMPLU_STALL_BRU, CMPLU_STALL_BRU); | ||
434 | POWER_EVENT_ATTR(GCT_NOSLOT_IC_MISS, GCT_NOSLOT_IC_MISS); | ||
435 | |||
436 | POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED, GCT_NOSLOT_BR_MPRED); | ||
437 | POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED_IC_MISS, GCT_NOSLOT_BR_MPRED_IC_MISS); | ||
438 | POWER_EVENT_ATTR(GRP_CMPL, GRP_CMPL); | ||
439 | POWER_EVENT_ATTR(1PLUS_PPC_CMPL, 1PLUS_PPC_CMPL); | ||
440 | POWER_EVENT_ATTR(CMPLU_STALL_DFU, CMPLU_STALL_DFU); | ||
441 | POWER_EVENT_ATTR(RUN_CYC, RUN_CYC); | ||
442 | POWER_EVENT_ATTR(RUN_INST_CMPL, RUN_INST_CMPL); | ||
443 | 391 | ||
444 | static struct attribute *power7_events_attr[] = { | 392 | static struct attribute *power7_events_attr[] = { |
445 | GENERIC_EVENT_PTR(CYC), | 393 | GENERIC_EVENT_PTR(PM_CYC), |
446 | GENERIC_EVENT_PTR(GCT_NOSLOT_CYC), | 394 | GENERIC_EVENT_PTR(PM_GCT_NOSLOT_CYC), |
447 | GENERIC_EVENT_PTR(CMPLU_STALL), | 395 | GENERIC_EVENT_PTR(PM_CMPLU_STALL), |
448 | GENERIC_EVENT_PTR(INST_CMPL), | 396 | GENERIC_EVENT_PTR(PM_INST_CMPL), |
449 | GENERIC_EVENT_PTR(LD_REF_L1), | 397 | GENERIC_EVENT_PTR(PM_LD_REF_L1), |
450 | GENERIC_EVENT_PTR(LD_MISS_L1), | 398 | GENERIC_EVENT_PTR(PM_LD_MISS_L1), |
451 | GENERIC_EVENT_PTR(BRU_FIN), | 399 | GENERIC_EVENT_PTR(PM_BRU_FIN), |
452 | GENERIC_EVENT_PTR(BR_MPRED), | 400 | GENERIC_EVENT_PTR(PM_BR_MPRED), |
453 | 401 | ||
454 | POWER_EVENT_PTR(CYC), | 402 | #include "power7-events-list.h" |
455 | POWER_EVENT_PTR(GCT_NOSLOT_CYC), | 403 | #undef EVENT |
456 | POWER_EVENT_PTR(CMPLU_STALL), | ||
457 | POWER_EVENT_PTR(INST_CMPL), | ||
458 | POWER_EVENT_PTR(LD_REF_L1), | ||
459 | POWER_EVENT_PTR(LD_MISS_L1), | ||
460 | POWER_EVENT_PTR(BRU_FIN), | ||
461 | POWER_EVENT_PTR(BR_MPRED), | ||
462 | |||
463 | POWER_EVENT_PTR(CMPLU_STALL_FXU), | ||
464 | POWER_EVENT_PTR(CMPLU_STALL_DIV), | ||
465 | POWER_EVENT_PTR(CMPLU_STALL_SCALAR), | ||
466 | POWER_EVENT_PTR(CMPLU_STALL_SCALAR_LONG), | ||
467 | POWER_EVENT_PTR(CMPLU_STALL_VECTOR), | ||
468 | POWER_EVENT_PTR(CMPLU_STALL_VECTOR_LONG), | ||
469 | POWER_EVENT_PTR(CMPLU_STALL_LSU), | ||
470 | POWER_EVENT_PTR(CMPLU_STALL_REJECT), | ||
471 | |||
472 | POWER_EVENT_PTR(CMPLU_STALL_ERAT_MISS), | ||
473 | POWER_EVENT_PTR(CMPLU_STALL_DCACHE_MISS), | ||
474 | POWER_EVENT_PTR(CMPLU_STALL_STORE), | ||
475 | POWER_EVENT_PTR(CMPLU_STALL_THRD), | ||
476 | POWER_EVENT_PTR(CMPLU_STALL_IFU), | ||
477 | POWER_EVENT_PTR(CMPLU_STALL_BRU), | ||
478 | POWER_EVENT_PTR(GCT_NOSLOT_IC_MISS), | ||
479 | POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED), | ||
480 | |||
481 | POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED_IC_MISS), | ||
482 | POWER_EVENT_PTR(GRP_CMPL), | ||
483 | POWER_EVENT_PTR(1PLUS_PPC_CMPL), | ||
484 | POWER_EVENT_PTR(CMPLU_STALL_DFU), | ||
485 | POWER_EVENT_PTR(RUN_CYC), | ||
486 | POWER_EVENT_PTR(RUN_INST_CMPL), | ||
487 | NULL | 404 | NULL |
488 | }; | 405 | }; |
489 | 406 | ||
490 | |||
491 | static struct attribute_group power7_pmu_events_group = { | 407 | static struct attribute_group power7_pmu_events_group = { |
492 | .name = "events", | 408 | .name = "events", |
493 | .attrs = power7_events_attr, | 409 | .attrs = power7_events_attr, |
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c index 4cfa49901c02..534574a97ec9 100644 --- a/arch/powerpc/platforms/44x/warp.c +++ b/arch/powerpc/platforms/44x/warp.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/of_gpio.h> | 18 | #include <linux/of_gpio.h> |
19 | #include <linux/of_i2c.h> | ||
20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
21 | #include <linux/export.h> | 20 | #include <linux/export.h> |
22 | 21 | ||
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c index cba1e6be68e5..ce73ce865613 100644 --- a/arch/powerpc/platforms/ps3/time.c +++ b/arch/powerpc/platforms/ps3/time.c | |||
@@ -90,7 +90,7 @@ static int __init ps3_rtc_init(void) | |||
90 | 90 | ||
91 | pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0); | 91 | pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0); |
92 | 92 | ||
93 | return PTR_RET(pdev); | 93 | return PTR_ERR_OR_ZERO(pdev); |
94 | } | 94 | } |
95 | 95 | ||
96 | module_init(ps3_rtc_init); | 96 | module_init(ps3_rtc_init); |
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 6a5f2b1f32ca..d276cd3edd8f 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c | |||
@@ -539,36 +539,6 @@ static int zip_oops(size_t text_len) | |||
539 | } | 539 | } |
540 | 540 | ||
541 | #ifdef CONFIG_PSTORE | 541 | #ifdef CONFIG_PSTORE |
542 | /* Derived from logfs_uncompress */ | ||
543 | int nvram_decompress(void *in, void *out, size_t inlen, size_t outlen) | ||
544 | { | ||
545 | int err, ret; | ||
546 | |||
547 | ret = -EIO; | ||
548 | err = zlib_inflateInit(&stream); | ||
549 | if (err != Z_OK) | ||
550 | goto error; | ||
551 | |||
552 | stream.next_in = in; | ||
553 | stream.avail_in = inlen; | ||
554 | stream.total_in = 0; | ||
555 | stream.next_out = out; | ||
556 | stream.avail_out = outlen; | ||
557 | stream.total_out = 0; | ||
558 | |||
559 | err = zlib_inflate(&stream, Z_FINISH); | ||
560 | if (err != Z_STREAM_END) | ||
561 | goto error; | ||
562 | |||
563 | err = zlib_inflateEnd(&stream); | ||
564 | if (err != Z_OK) | ||
565 | goto error; | ||
566 | |||
567 | ret = stream.total_out; | ||
568 | error: | ||
569 | return ret; | ||
570 | } | ||
571 | |||
572 | static int nvram_pstore_open(struct pstore_info *psi) | 542 | static int nvram_pstore_open(struct pstore_info *psi) |
573 | { | 543 | { |
574 | /* Reset the iterator to start reading partitions again */ | 544 | /* Reset the iterator to start reading partitions again */ |
@@ -584,7 +554,7 @@ static int nvram_pstore_open(struct pstore_info *psi) | |||
584 | * @part: pstore writes data to registered buffer in parts, | 554 | * @part: pstore writes data to registered buffer in parts, |
585 | * part number will indicate the same. | 555 | * part number will indicate the same. |
586 | * @count: Indicates oops count | 556 | * @count: Indicates oops count |
587 | * @hsize: Size of header added by pstore | 557 | * @compressed: Flag to indicate the log is compressed |
588 | * @size: number of bytes written to the registered buffer | 558 | * @size: number of bytes written to the registered buffer |
589 | * @psi: registered pstore_info structure | 559 | * @psi: registered pstore_info structure |
590 | * | 560 | * |
@@ -595,7 +565,7 @@ static int nvram_pstore_open(struct pstore_info *psi) | |||
595 | static int nvram_pstore_write(enum pstore_type_id type, | 565 | static int nvram_pstore_write(enum pstore_type_id type, |
596 | enum kmsg_dump_reason reason, | 566 | enum kmsg_dump_reason reason, |
597 | u64 *id, unsigned int part, int count, | 567 | u64 *id, unsigned int part, int count, |
598 | size_t hsize, size_t size, | 568 | bool compressed, size_t size, |
599 | struct pstore_info *psi) | 569 | struct pstore_info *psi) |
600 | { | 570 | { |
601 | int rc; | 571 | int rc; |
@@ -611,30 +581,11 @@ static int nvram_pstore_write(enum pstore_type_id type, | |||
611 | oops_hdr->report_length = (u16) size; | 581 | oops_hdr->report_length = (u16) size; |
612 | oops_hdr->timestamp = get_seconds(); | 582 | oops_hdr->timestamp = get_seconds(); |
613 | 583 | ||
614 | if (big_oops_buf) { | 584 | if (compressed) |
615 | rc = zip_oops(size); | 585 | err_type = ERR_TYPE_KERNEL_PANIC_GZ; |
616 | /* | ||
617 | * If compression fails copy recent log messages from | ||
618 | * big_oops_buf to oops_data. | ||
619 | */ | ||
620 | if (rc != 0) { | ||
621 | size_t diff = size - oops_data_sz + hsize; | ||
622 | |||
623 | if (size > oops_data_sz) { | ||
624 | memcpy(oops_data, big_oops_buf, hsize); | ||
625 | memcpy(oops_data + hsize, big_oops_buf + diff, | ||
626 | oops_data_sz - hsize); | ||
627 | |||
628 | oops_hdr->report_length = (u16) oops_data_sz; | ||
629 | } else | ||
630 | memcpy(oops_data, big_oops_buf, size); | ||
631 | } else | ||
632 | err_type = ERR_TYPE_KERNEL_PANIC_GZ; | ||
633 | } | ||
634 | 586 | ||
635 | rc = nvram_write_os_partition(&oops_log_partition, oops_buf, | 587 | rc = nvram_write_os_partition(&oops_log_partition, oops_buf, |
636 | (int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type, | 588 | (int) (sizeof(*oops_hdr) + size), err_type, count); |
637 | count); | ||
638 | 589 | ||
639 | if (rc != 0) | 590 | if (rc != 0) |
640 | return rc; | 591 | return rc; |
@@ -650,12 +601,12 @@ static int nvram_pstore_write(enum pstore_type_id type, | |||
650 | */ | 601 | */ |
651 | static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, | 602 | static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, |
652 | int *count, struct timespec *time, char **buf, | 603 | int *count, struct timespec *time, char **buf, |
653 | struct pstore_info *psi) | 604 | bool *compressed, struct pstore_info *psi) |
654 | { | 605 | { |
655 | struct oops_log_info *oops_hdr; | 606 | struct oops_log_info *oops_hdr; |
656 | unsigned int err_type, id_no, size = 0; | 607 | unsigned int err_type, id_no, size = 0; |
657 | struct nvram_os_partition *part = NULL; | 608 | struct nvram_os_partition *part = NULL; |
658 | char *buff = NULL, *big_buff = NULL; | 609 | char *buff = NULL; |
659 | int sig = 0; | 610 | int sig = 0; |
660 | loff_t p; | 611 | loff_t p; |
661 | 612 | ||
@@ -719,8 +670,7 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, | |||
719 | *id = id_no; | 670 | *id = id_no; |
720 | 671 | ||
721 | if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) { | 672 | if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) { |
722 | int length, unzipped_len; | 673 | size_t length, hdr_size; |
723 | size_t hdr_size; | ||
724 | 674 | ||
725 | oops_hdr = (struct oops_log_info *)buff; | 675 | oops_hdr = (struct oops_log_info *)buff; |
726 | if (oops_hdr->version < OOPS_HDR_VERSION) { | 676 | if (oops_hdr->version < OOPS_HDR_VERSION) { |
@@ -741,23 +691,10 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, | |||
741 | memcpy(*buf, buff + hdr_size, length); | 691 | memcpy(*buf, buff + hdr_size, length); |
742 | kfree(buff); | 692 | kfree(buff); |
743 | 693 | ||
744 | if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) { | 694 | if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) |
745 | big_buff = kmalloc(big_oops_buf_sz, GFP_KERNEL); | 695 | *compressed = true; |
746 | if (!big_buff) | 696 | else |
747 | return -ENOMEM; | 697 | *compressed = false; |
748 | |||
749 | unzipped_len = nvram_decompress(*buf, big_buff, | ||
750 | length, big_oops_buf_sz); | ||
751 | |||
752 | if (unzipped_len < 0) { | ||
753 | pr_err("nvram: decompression failed, returned " | ||
754 | "rc %d\n", unzipped_len); | ||
755 | kfree(big_buff); | ||
756 | } else { | ||
757 | *buf = big_buff; | ||
758 | length = unzipped_len; | ||
759 | } | ||
760 | } | ||
761 | return length; | 698 | return length; |
762 | } | 699 | } |
763 | 700 | ||
@@ -777,13 +714,8 @@ static int nvram_pstore_init(void) | |||
777 | { | 714 | { |
778 | int rc = 0; | 715 | int rc = 0; |
779 | 716 | ||
780 | if (big_oops_buf) { | 717 | nvram_pstore_info.buf = oops_data; |
781 | nvram_pstore_info.buf = big_oops_buf; | 718 | nvram_pstore_info.bufsize = oops_data_sz; |
782 | nvram_pstore_info.bufsize = big_oops_buf_sz; | ||
783 | } else { | ||
784 | nvram_pstore_info.buf = oops_data; | ||
785 | nvram_pstore_info.bufsize = oops_data_sz; | ||
786 | } | ||
787 | 719 | ||
788 | rc = pstore_register(&nvram_pstore_info); | 720 | rc = pstore_register(&nvram_pstore_info); |
789 | if (rc != 0) | 721 | if (rc != 0) |
@@ -802,7 +734,6 @@ static int nvram_pstore_init(void) | |||
802 | static void __init nvram_init_oops_partition(int rtas_partition_exists) | 734 | static void __init nvram_init_oops_partition(int rtas_partition_exists) |
803 | { | 735 | { |
804 | int rc; | 736 | int rc; |
805 | size_t size; | ||
806 | 737 | ||
807 | rc = pseries_nvram_init_os_partition(&oops_log_partition); | 738 | rc = pseries_nvram_init_os_partition(&oops_log_partition); |
808 | if (rc != 0) { | 739 | if (rc != 0) { |
@@ -823,6 +754,11 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists) | |||
823 | oops_data = oops_buf + sizeof(struct oops_log_info); | 754 | oops_data = oops_buf + sizeof(struct oops_log_info); |
824 | oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info); | 755 | oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info); |
825 | 756 | ||
757 | rc = nvram_pstore_init(); | ||
758 | |||
759 | if (!rc) | ||
760 | return; | ||
761 | |||
826 | /* | 762 | /* |
827 | * Figure compression (preceded by elimination of each line's <n> | 763 | * Figure compression (preceded by elimination of each line's <n> |
828 | * severity prefix) will reduce the oops/panic report to at most | 764 | * severity prefix) will reduce the oops/panic report to at most |
@@ -831,9 +767,8 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists) | |||
831 | big_oops_buf_sz = (oops_data_sz * 100) / 45; | 767 | big_oops_buf_sz = (oops_data_sz * 100) / 45; |
832 | big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); | 768 | big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); |
833 | if (big_oops_buf) { | 769 | if (big_oops_buf) { |
834 | size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL), | 770 | stream.workspace = kmalloc(zlib_deflate_workspacesize( |
835 | zlib_inflate_workspacesize()); | 771 | WINDOW_BITS, MEM_LEVEL), GFP_KERNEL); |
836 | stream.workspace = kmalloc(size, GFP_KERNEL); | ||
837 | if (!stream.workspace) { | 772 | if (!stream.workspace) { |
838 | pr_err("nvram: No memory for compression workspace; " | 773 | pr_err("nvram: No memory for compression workspace; " |
839 | "skipping compression of %s partition data\n", | 774 | "skipping compression of %s partition data\n", |
@@ -847,11 +782,6 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists) | |||
847 | stream.workspace = NULL; | 782 | stream.workspace = NULL; |
848 | } | 783 | } |
849 | 784 | ||
850 | rc = nvram_pstore_init(); | ||
851 | |||
852 | if (!rc) | ||
853 | return; | ||
854 | |||
855 | rc = kmsg_dump_register(&nvram_kmsg_dumper); | 785 | rc = kmsg_dump_register(&nvram_kmsg_dumper); |
856 | if (rc != 0) { | 786 | if (rc != 0) { |
857 | pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc); | 787 | pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc); |
diff --git a/arch/powerpc/sysdev/rtc_cmos_setup.c b/arch/powerpc/sysdev/rtc_cmos_setup.c index af79e1ea74b6..af0f9beddca9 100644 --- a/arch/powerpc/sysdev/rtc_cmos_setup.c +++ b/arch/powerpc/sysdev/rtc_cmos_setup.c | |||
@@ -62,7 +62,7 @@ static int __init add_rtc(void) | |||
62 | pd = platform_device_register_simple("rtc_cmos", -1, | 62 | pd = platform_device_register_simple("rtc_cmos", -1, |
63 | &res[0], num_res); | 63 | &res[0], num_res); |
64 | 64 | ||
65 | return PTR_RET(pd); | 65 | return PTR_ERR_OR_ZERO(pd); |
66 | } | 66 | } |
67 | fs_initcall(add_rtc); | 67 | fs_initcall(add_rtc); |
68 | 68 | ||
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 8a4cae78f03c..8b7892bf6d8b 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -116,6 +116,7 @@ config S390 | |||
116 | select HAVE_FUNCTION_GRAPH_TRACER | 116 | select HAVE_FUNCTION_GRAPH_TRACER |
117 | select HAVE_FUNCTION_TRACER | 117 | select HAVE_FUNCTION_TRACER |
118 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST | 118 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST |
119 | select HAVE_GENERIC_HARDIRQS | ||
119 | select HAVE_KERNEL_BZIP2 | 120 | select HAVE_KERNEL_BZIP2 |
120 | select HAVE_KERNEL_GZIP | 121 | select HAVE_KERNEL_GZIP |
121 | select HAVE_KERNEL_LZ4 | 122 | select HAVE_KERNEL_LZ4 |
@@ -445,6 +446,16 @@ config PCI_NR_FUNCTIONS | |||
445 | This allows you to specify the maximum number of PCI functions which | 446 | This allows you to specify the maximum number of PCI functions which |
446 | this kernel will support. | 447 | this kernel will support. |
447 | 448 | ||
449 | config PCI_NR_MSI | ||
450 | int "Maximum number of MSI interrupts (64-32768)" | ||
451 | range 64 32768 | ||
452 | default "256" | ||
453 | help | ||
454 | This defines the number of virtual interrupts the kernel will | ||
455 | provide for MSI interrupts. If you configure your system to have | ||
456 | too few drivers will fail to allocate MSI interrupts for all | ||
457 | PCI devices. | ||
458 | |||
448 | source "drivers/pci/Kconfig" | 459 | source "drivers/pci/Kconfig" |
449 | source "drivers/pci/pcie/Kconfig" | 460 | source "drivers/pci/pcie/Kconfig" |
450 | source "drivers/pci/hotplug/Kconfig" | 461 | source "drivers/pci/hotplug/Kconfig" |
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h index f41e0ef7fdf9..79f2ac55253f 100644 --- a/arch/s390/hypfs/hypfs.h +++ b/arch/s390/hypfs/hypfs.h | |||
@@ -18,26 +18,23 @@ | |||
18 | #define UPDATE_FILE_MODE 0220 | 18 | #define UPDATE_FILE_MODE 0220 |
19 | #define DIR_MODE 0550 | 19 | #define DIR_MODE 0550 |
20 | 20 | ||
21 | extern struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent, | 21 | extern struct dentry *hypfs_mkdir(struct dentry *parent, const char *name); |
22 | const char *name); | ||
23 | 22 | ||
24 | extern struct dentry *hypfs_create_u64(struct super_block *sb, | 23 | extern struct dentry *hypfs_create_u64(struct dentry *dir, const char *name, |
25 | struct dentry *dir, const char *name, | ||
26 | __u64 value); | 24 | __u64 value); |
27 | 25 | ||
28 | extern struct dentry *hypfs_create_str(struct super_block *sb, | 26 | extern struct dentry *hypfs_create_str(struct dentry *dir, const char *name, |
29 | struct dentry *dir, const char *name, | ||
30 | char *string); | 27 | char *string); |
31 | 28 | ||
32 | /* LPAR Hypervisor */ | 29 | /* LPAR Hypervisor */ |
33 | extern int hypfs_diag_init(void); | 30 | extern int hypfs_diag_init(void); |
34 | extern void hypfs_diag_exit(void); | 31 | extern void hypfs_diag_exit(void); |
35 | extern int hypfs_diag_create_files(struct super_block *sb, struct dentry *root); | 32 | extern int hypfs_diag_create_files(struct dentry *root); |
36 | 33 | ||
37 | /* VM Hypervisor */ | 34 | /* VM Hypervisor */ |
38 | extern int hypfs_vm_init(void); | 35 | extern int hypfs_vm_init(void); |
39 | extern void hypfs_vm_exit(void); | 36 | extern void hypfs_vm_exit(void); |
40 | extern int hypfs_vm_create_files(struct super_block *sb, struct dentry *root); | 37 | extern int hypfs_vm_create_files(struct dentry *root); |
41 | 38 | ||
42 | /* debugfs interface */ | 39 | /* debugfs interface */ |
43 | struct hypfs_dbfs_file; | 40 | struct hypfs_dbfs_file; |
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index bb5dd496614f..17ab8b7b53cc 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c | |||
@@ -105,7 +105,7 @@ void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df) | |||
105 | int hypfs_dbfs_init(void) | 105 | int hypfs_dbfs_init(void) |
106 | { | 106 | { |
107 | dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); | 107 | dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); |
108 | return PTR_RET(dbfs_dir); | 108 | return PTR_ERR_OR_ZERO(dbfs_dir); |
109 | } | 109 | } |
110 | 110 | ||
111 | void hypfs_dbfs_exit(void) | 111 | void hypfs_dbfs_exit(void) |
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 138893e5f736..5eeffeefae06 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c | |||
@@ -623,8 +623,7 @@ void hypfs_diag_exit(void) | |||
623 | * ******************************************* | 623 | * ******************************************* |
624 | */ | 624 | */ |
625 | 625 | ||
626 | static int hypfs_create_cpu_files(struct super_block *sb, | 626 | static int hypfs_create_cpu_files(struct dentry *cpus_dir, void *cpu_info) |
627 | struct dentry *cpus_dir, void *cpu_info) | ||
628 | { | 627 | { |
629 | struct dentry *cpu_dir; | 628 | struct dentry *cpu_dir; |
630 | char buffer[TMP_SIZE]; | 629 | char buffer[TMP_SIZE]; |
@@ -632,30 +631,29 @@ static int hypfs_create_cpu_files(struct super_block *sb, | |||
632 | 631 | ||
633 | snprintf(buffer, TMP_SIZE, "%d", cpu_info__cpu_addr(diag204_info_type, | 632 | snprintf(buffer, TMP_SIZE, "%d", cpu_info__cpu_addr(diag204_info_type, |
634 | cpu_info)); | 633 | cpu_info)); |
635 | cpu_dir = hypfs_mkdir(sb, cpus_dir, buffer); | 634 | cpu_dir = hypfs_mkdir(cpus_dir, buffer); |
636 | rc = hypfs_create_u64(sb, cpu_dir, "mgmtime", | 635 | rc = hypfs_create_u64(cpu_dir, "mgmtime", |
637 | cpu_info__acc_time(diag204_info_type, cpu_info) - | 636 | cpu_info__acc_time(diag204_info_type, cpu_info) - |
638 | cpu_info__lp_time(diag204_info_type, cpu_info)); | 637 | cpu_info__lp_time(diag204_info_type, cpu_info)); |
639 | if (IS_ERR(rc)) | 638 | if (IS_ERR(rc)) |
640 | return PTR_ERR(rc); | 639 | return PTR_ERR(rc); |
641 | rc = hypfs_create_u64(sb, cpu_dir, "cputime", | 640 | rc = hypfs_create_u64(cpu_dir, "cputime", |
642 | cpu_info__lp_time(diag204_info_type, cpu_info)); | 641 | cpu_info__lp_time(diag204_info_type, cpu_info)); |
643 | if (IS_ERR(rc)) | 642 | if (IS_ERR(rc)) |
644 | return PTR_ERR(rc); | 643 | return PTR_ERR(rc); |
645 | if (diag204_info_type == INFO_EXT) { | 644 | if (diag204_info_type == INFO_EXT) { |
646 | rc = hypfs_create_u64(sb, cpu_dir, "onlinetime", | 645 | rc = hypfs_create_u64(cpu_dir, "onlinetime", |
647 | cpu_info__online_time(diag204_info_type, | 646 | cpu_info__online_time(diag204_info_type, |
648 | cpu_info)); | 647 | cpu_info)); |
649 | if (IS_ERR(rc)) | 648 | if (IS_ERR(rc)) |
650 | return PTR_ERR(rc); | 649 | return PTR_ERR(rc); |
651 | } | 650 | } |
652 | diag224_idx2name(cpu_info__ctidx(diag204_info_type, cpu_info), buffer); | 651 | diag224_idx2name(cpu_info__ctidx(diag204_info_type, cpu_info), buffer); |
653 | rc = hypfs_create_str(sb, cpu_dir, "type", buffer); | 652 | rc = hypfs_create_str(cpu_dir, "type", buffer); |
654 | return PTR_RET(rc); | 653 | return PTR_RET(rc); |
655 | } | 654 | } |
656 | 655 | ||
657 | static void *hypfs_create_lpar_files(struct super_block *sb, | 656 | static void *hypfs_create_lpar_files(struct dentry *systems_dir, void *part_hdr) |
658 | struct dentry *systems_dir, void *part_hdr) | ||
659 | { | 657 | { |
660 | struct dentry *cpus_dir; | 658 | struct dentry *cpus_dir; |
661 | struct dentry *lpar_dir; | 659 | struct dentry *lpar_dir; |
@@ -665,16 +663,16 @@ static void *hypfs_create_lpar_files(struct super_block *sb, | |||
665 | 663 | ||
666 | part_hdr__part_name(diag204_info_type, part_hdr, lpar_name); | 664 | part_hdr__part_name(diag204_info_type, part_hdr, lpar_name); |
667 | lpar_name[LPAR_NAME_LEN] = 0; | 665 | lpar_name[LPAR_NAME_LEN] = 0; |
668 | lpar_dir = hypfs_mkdir(sb, systems_dir, lpar_name); | 666 | lpar_dir = hypfs_mkdir(systems_dir, lpar_name); |
669 | if (IS_ERR(lpar_dir)) | 667 | if (IS_ERR(lpar_dir)) |
670 | return lpar_dir; | 668 | return lpar_dir; |
671 | cpus_dir = hypfs_mkdir(sb, lpar_dir, "cpus"); | 669 | cpus_dir = hypfs_mkdir(lpar_dir, "cpus"); |
672 | if (IS_ERR(cpus_dir)) | 670 | if (IS_ERR(cpus_dir)) |
673 | return cpus_dir; | 671 | return cpus_dir; |
674 | cpu_info = part_hdr + part_hdr__size(diag204_info_type); | 672 | cpu_info = part_hdr + part_hdr__size(diag204_info_type); |
675 | for (i = 0; i < part_hdr__rcpus(diag204_info_type, part_hdr); i++) { | 673 | for (i = 0; i < part_hdr__rcpus(diag204_info_type, part_hdr); i++) { |
676 | int rc; | 674 | int rc; |
677 | rc = hypfs_create_cpu_files(sb, cpus_dir, cpu_info); | 675 | rc = hypfs_create_cpu_files(cpus_dir, cpu_info); |
678 | if (rc) | 676 | if (rc) |
679 | return ERR_PTR(rc); | 677 | return ERR_PTR(rc); |
680 | cpu_info += cpu_info__size(diag204_info_type); | 678 | cpu_info += cpu_info__size(diag204_info_type); |
@@ -682,8 +680,7 @@ static void *hypfs_create_lpar_files(struct super_block *sb, | |||
682 | return cpu_info; | 680 | return cpu_info; |
683 | } | 681 | } |
684 | 682 | ||
685 | static int hypfs_create_phys_cpu_files(struct super_block *sb, | 683 | static int hypfs_create_phys_cpu_files(struct dentry *cpus_dir, void *cpu_info) |
686 | struct dentry *cpus_dir, void *cpu_info) | ||
687 | { | 684 | { |
688 | struct dentry *cpu_dir; | 685 | struct dentry *cpu_dir; |
689 | char buffer[TMP_SIZE]; | 686 | char buffer[TMP_SIZE]; |
@@ -691,32 +688,31 @@ static int hypfs_create_phys_cpu_files(struct super_block *sb, | |||
691 | 688 | ||
692 | snprintf(buffer, TMP_SIZE, "%i", phys_cpu__cpu_addr(diag204_info_type, | 689 | snprintf(buffer, TMP_SIZE, "%i", phys_cpu__cpu_addr(diag204_info_type, |
693 | cpu_info)); | 690 | cpu_info)); |
694 | cpu_dir = hypfs_mkdir(sb, cpus_dir, buffer); | 691 | cpu_dir = hypfs_mkdir(cpus_dir, buffer); |
695 | if (IS_ERR(cpu_dir)) | 692 | if (IS_ERR(cpu_dir)) |
696 | return PTR_ERR(cpu_dir); | 693 | return PTR_ERR(cpu_dir); |
697 | rc = hypfs_create_u64(sb, cpu_dir, "mgmtime", | 694 | rc = hypfs_create_u64(cpu_dir, "mgmtime", |
698 | phys_cpu__mgm_time(diag204_info_type, cpu_info)); | 695 | phys_cpu__mgm_time(diag204_info_type, cpu_info)); |
699 | if (IS_ERR(rc)) | 696 | if (IS_ERR(rc)) |
700 | return PTR_ERR(rc); | 697 | return PTR_ERR(rc); |
701 | diag224_idx2name(phys_cpu__ctidx(diag204_info_type, cpu_info), buffer); | 698 | diag224_idx2name(phys_cpu__ctidx(diag204_info_type, cpu_info), buffer); |
702 | rc = hypfs_create_str(sb, cpu_dir, "type", buffer); | 699 | rc = hypfs_create_str(cpu_dir, "type", buffer); |
703 | return PTR_RET(rc); | 700 | return PTR_RET(rc); |
704 | } | 701 | } |
705 | 702 | ||
706 | static void *hypfs_create_phys_files(struct super_block *sb, | 703 | static void *hypfs_create_phys_files(struct dentry *parent_dir, void *phys_hdr) |
707 | struct dentry *parent_dir, void *phys_hdr) | ||
708 | { | 704 | { |
709 | int i; | 705 | int i; |
710 | void *cpu_info; | 706 | void *cpu_info; |
711 | struct dentry *cpus_dir; | 707 | struct dentry *cpus_dir; |
712 | 708 | ||
713 | cpus_dir = hypfs_mkdir(sb, parent_dir, "cpus"); | 709 | cpus_dir = hypfs_mkdir(parent_dir, "cpus"); |
714 | if (IS_ERR(cpus_dir)) | 710 | if (IS_ERR(cpus_dir)) |
715 | return cpus_dir; | 711 | return cpus_dir; |
716 | cpu_info = phys_hdr + phys_hdr__size(diag204_info_type); | 712 | cpu_info = phys_hdr + phys_hdr__size(diag204_info_type); |
717 | for (i = 0; i < phys_hdr__cpus(diag204_info_type, phys_hdr); i++) { | 713 | for (i = 0; i < phys_hdr__cpus(diag204_info_type, phys_hdr); i++) { |
718 | int rc; | 714 | int rc; |
719 | rc = hypfs_create_phys_cpu_files(sb, cpus_dir, cpu_info); | 715 | rc = hypfs_create_phys_cpu_files(cpus_dir, cpu_info); |
720 | if (rc) | 716 | if (rc) |
721 | return ERR_PTR(rc); | 717 | return ERR_PTR(rc); |
722 | cpu_info += phys_cpu__size(diag204_info_type); | 718 | cpu_info += phys_cpu__size(diag204_info_type); |
@@ -724,7 +720,7 @@ static void *hypfs_create_phys_files(struct super_block *sb, | |||
724 | return cpu_info; | 720 | return cpu_info; |
725 | } | 721 | } |
726 | 722 | ||
727 | int hypfs_diag_create_files(struct super_block *sb, struct dentry *root) | 723 | int hypfs_diag_create_files(struct dentry *root) |
728 | { | 724 | { |
729 | struct dentry *systems_dir, *hyp_dir; | 725 | struct dentry *systems_dir, *hyp_dir; |
730 | void *time_hdr, *part_hdr; | 726 | void *time_hdr, *part_hdr; |
@@ -735,7 +731,7 @@ int hypfs_diag_create_files(struct super_block *sb, struct dentry *root) | |||
735 | if (IS_ERR(buffer)) | 731 | if (IS_ERR(buffer)) |
736 | return PTR_ERR(buffer); | 732 | return PTR_ERR(buffer); |
737 | 733 | ||
738 | systems_dir = hypfs_mkdir(sb, root, "systems"); | 734 | systems_dir = hypfs_mkdir(root, "systems"); |
739 | if (IS_ERR(systems_dir)) { | 735 | if (IS_ERR(systems_dir)) { |
740 | rc = PTR_ERR(systems_dir); | 736 | rc = PTR_ERR(systems_dir); |
741 | goto err_out; | 737 | goto err_out; |
@@ -743,25 +739,25 @@ int hypfs_diag_create_files(struct super_block *sb, struct dentry *root) | |||
743 | time_hdr = (struct x_info_blk_hdr *)buffer; | 739 | time_hdr = (struct x_info_blk_hdr *)buffer; |
744 | part_hdr = time_hdr + info_blk_hdr__size(diag204_info_type); | 740 | part_hdr = time_hdr + info_blk_hdr__size(diag204_info_type); |
745 | for (i = 0; i < info_blk_hdr__npar(diag204_info_type, time_hdr); i++) { | 741 | for (i = 0; i < info_blk_hdr__npar(diag204_info_type, time_hdr); i++) { |
746 | part_hdr = hypfs_create_lpar_files(sb, systems_dir, part_hdr); | 742 | part_hdr = hypfs_create_lpar_files(systems_dir, part_hdr); |
747 | if (IS_ERR(part_hdr)) { | 743 | if (IS_ERR(part_hdr)) { |
748 | rc = PTR_ERR(part_hdr); | 744 | rc = PTR_ERR(part_hdr); |
749 | goto err_out; | 745 | goto err_out; |
750 | } | 746 | } |
751 | } | 747 | } |
752 | if (info_blk_hdr__flags(diag204_info_type, time_hdr) & LPAR_PHYS_FLG) { | 748 | if (info_blk_hdr__flags(diag204_info_type, time_hdr) & LPAR_PHYS_FLG) { |
753 | ptr = hypfs_create_phys_files(sb, root, part_hdr); | 749 | ptr = hypfs_create_phys_files(root, part_hdr); |
754 | if (IS_ERR(ptr)) { | 750 | if (IS_ERR(ptr)) { |
755 | rc = PTR_ERR(ptr); | 751 | rc = PTR_ERR(ptr); |
756 | goto err_out; | 752 | goto err_out; |
757 | } | 753 | } |
758 | } | 754 | } |
759 | hyp_dir = hypfs_mkdir(sb, root, "hyp"); | 755 | hyp_dir = hypfs_mkdir(root, "hyp"); |
760 | if (IS_ERR(hyp_dir)) { | 756 | if (IS_ERR(hyp_dir)) { |
761 | rc = PTR_ERR(hyp_dir); | 757 | rc = PTR_ERR(hyp_dir); |
762 | goto err_out; | 758 | goto err_out; |
763 | } | 759 | } |
764 | ptr = hypfs_create_str(sb, hyp_dir, "type", "LPAR Hypervisor"); | 760 | ptr = hypfs_create_str(hyp_dir, "type", "LPAR Hypervisor"); |
765 | if (IS_ERR(ptr)) { | 761 | if (IS_ERR(ptr)) { |
766 | rc = PTR_ERR(ptr); | 762 | rc = PTR_ERR(ptr); |
767 | goto err_out; | 763 | goto err_out; |
diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c index f364dcf77e8e..24908ce149f1 100644 --- a/arch/s390/hypfs/hypfs_vm.c +++ b/arch/s390/hypfs/hypfs_vm.c | |||
@@ -107,16 +107,15 @@ static void diag2fc_free(const void *data) | |||
107 | vfree(data); | 107 | vfree(data); |
108 | } | 108 | } |
109 | 109 | ||
110 | #define ATTRIBUTE(sb, dir, name, member) \ | 110 | #define ATTRIBUTE(dir, name, member) \ |
111 | do { \ | 111 | do { \ |
112 | void *rc; \ | 112 | void *rc; \ |
113 | rc = hypfs_create_u64(sb, dir, name, member); \ | 113 | rc = hypfs_create_u64(dir, name, member); \ |
114 | if (IS_ERR(rc)) \ | 114 | if (IS_ERR(rc)) \ |
115 | return PTR_ERR(rc); \ | 115 | return PTR_ERR(rc); \ |
116 | } while(0) | 116 | } while(0) |
117 | 117 | ||
118 | static int hpyfs_vm_create_guest(struct super_block *sb, | 118 | static int hpyfs_vm_create_guest(struct dentry *systems_dir, |
119 | struct dentry *systems_dir, | ||
120 | struct diag2fc_data *data) | 119 | struct diag2fc_data *data) |
121 | { | 120 | { |
122 | char guest_name[NAME_LEN + 1] = {}; | 121 | char guest_name[NAME_LEN + 1] = {}; |
@@ -130,46 +129,46 @@ static int hpyfs_vm_create_guest(struct super_block *sb, | |||
130 | memcpy(guest_name, data->guest_name, NAME_LEN); | 129 | memcpy(guest_name, data->guest_name, NAME_LEN); |
131 | EBCASC(guest_name, NAME_LEN); | 130 | EBCASC(guest_name, NAME_LEN); |
132 | strim(guest_name); | 131 | strim(guest_name); |
133 | guest_dir = hypfs_mkdir(sb, systems_dir, guest_name); | 132 | guest_dir = hypfs_mkdir(systems_dir, guest_name); |
134 | if (IS_ERR(guest_dir)) | 133 | if (IS_ERR(guest_dir)) |
135 | return PTR_ERR(guest_dir); | 134 | return PTR_ERR(guest_dir); |
136 | ATTRIBUTE(sb, guest_dir, "onlinetime_us", data->el_time); | 135 | ATTRIBUTE(guest_dir, "onlinetime_us", data->el_time); |
137 | 136 | ||
138 | /* logical cpu information */ | 137 | /* logical cpu information */ |
139 | cpus_dir = hypfs_mkdir(sb, guest_dir, "cpus"); | 138 | cpus_dir = hypfs_mkdir(guest_dir, "cpus"); |
140 | if (IS_ERR(cpus_dir)) | 139 | if (IS_ERR(cpus_dir)) |
141 | return PTR_ERR(cpus_dir); | 140 | return PTR_ERR(cpus_dir); |
142 | ATTRIBUTE(sb, cpus_dir, "cputime_us", data->used_cpu); | 141 | ATTRIBUTE(cpus_dir, "cputime_us", data->used_cpu); |
143 | ATTRIBUTE(sb, cpus_dir, "capped", capped_value); | 142 | ATTRIBUTE(cpus_dir, "capped", capped_value); |
144 | ATTRIBUTE(sb, cpus_dir, "dedicated", dedicated_flag); | 143 | ATTRIBUTE(cpus_dir, "dedicated", dedicated_flag); |
145 | ATTRIBUTE(sb, cpus_dir, "count", data->vcpus); | 144 | ATTRIBUTE(cpus_dir, "count", data->vcpus); |
146 | ATTRIBUTE(sb, cpus_dir, "weight_min", data->cpu_min); | 145 | ATTRIBUTE(cpus_dir, "weight_min", data->cpu_min); |
147 | ATTRIBUTE(sb, cpus_dir, "weight_max", data->cpu_max); | 146 | ATTRIBUTE(cpus_dir, "weight_max", data->cpu_max); |
148 | ATTRIBUTE(sb, cpus_dir, "weight_cur", data->cpu_shares); | 147 | ATTRIBUTE(cpus_dir, "weight_cur", data->cpu_shares); |
149 | 148 | ||
150 | /* memory information */ | 149 | /* memory information */ |
151 | mem_dir = hypfs_mkdir(sb, guest_dir, "mem"); | 150 | mem_dir = hypfs_mkdir(guest_dir, "mem"); |
152 | if (IS_ERR(mem_dir)) | 151 | if (IS_ERR(mem_dir)) |
153 | return PTR_ERR(mem_dir); | 152 | return PTR_ERR(mem_dir); |
154 | ATTRIBUTE(sb, mem_dir, "min_KiB", data->mem_min_kb); | 153 | ATTRIBUTE(mem_dir, "min_KiB", data->mem_min_kb); |
155 | ATTRIBUTE(sb, mem_dir, "max_KiB", data->mem_max_kb); | 154 | ATTRIBUTE(mem_dir, "max_KiB", data->mem_max_kb); |
156 | ATTRIBUTE(sb, mem_dir, "used_KiB", data->mem_used_kb); | 155 | ATTRIBUTE(mem_dir, "used_KiB", data->mem_used_kb); |
157 | ATTRIBUTE(sb, mem_dir, "share_KiB", data->mem_share_kb); | 156 | ATTRIBUTE(mem_dir, "share_KiB", data->mem_share_kb); |
158 | 157 | ||
159 | /* samples */ | 158 | /* samples */ |
160 | samples_dir = hypfs_mkdir(sb, guest_dir, "samples"); | 159 | samples_dir = hypfs_mkdir(guest_dir, "samples"); |
161 | if (IS_ERR(samples_dir)) | 160 | if (IS_ERR(samples_dir)) |
162 | return PTR_ERR(samples_dir); | 161 | return PTR_ERR(samples_dir); |
163 | ATTRIBUTE(sb, samples_dir, "cpu_using", data->cpu_use_samp); | 162 | ATTRIBUTE(samples_dir, "cpu_using", data->cpu_use_samp); |
164 | ATTRIBUTE(sb, samples_dir, "cpu_delay", data->cpu_delay_samp); | 163 | ATTRIBUTE(samples_dir, "cpu_delay", data->cpu_delay_samp); |
165 | ATTRIBUTE(sb, samples_dir, "mem_delay", data->page_wait_samp); | 164 | ATTRIBUTE(samples_dir, "mem_delay", data->page_wait_samp); |
166 | ATTRIBUTE(sb, samples_dir, "idle", data->idle_samp); | 165 | ATTRIBUTE(samples_dir, "idle", data->idle_samp); |
167 | ATTRIBUTE(sb, samples_dir, "other", data->other_samp); | 166 | ATTRIBUTE(samples_dir, "other", data->other_samp); |
168 | ATTRIBUTE(sb, samples_dir, "total", data->total_samp); | 167 | ATTRIBUTE(samples_dir, "total", data->total_samp); |
169 | return 0; | 168 | return 0; |
170 | } | 169 | } |
171 | 170 | ||
172 | int hypfs_vm_create_files(struct super_block *sb, struct dentry *root) | 171 | int hypfs_vm_create_files(struct dentry *root) |
173 | { | 172 | { |
174 | struct dentry *dir, *file; | 173 | struct dentry *dir, *file; |
175 | struct diag2fc_data *data; | 174 | struct diag2fc_data *data; |
@@ -181,38 +180,38 @@ int hypfs_vm_create_files(struct super_block *sb, struct dentry *root) | |||
181 | return PTR_ERR(data); | 180 | return PTR_ERR(data); |
182 | 181 | ||
183 | /* Hpervisor Info */ | 182 | /* Hpervisor Info */ |
184 | dir = hypfs_mkdir(sb, root, "hyp"); | 183 | dir = hypfs_mkdir(root, "hyp"); |
185 | if (IS_ERR(dir)) { | 184 | if (IS_ERR(dir)) { |
186 | rc = PTR_ERR(dir); | 185 | rc = PTR_ERR(dir); |
187 | goto failed; | 186 | goto failed; |
188 | } | 187 | } |
189 | file = hypfs_create_str(sb, dir, "type", "z/VM Hypervisor"); | 188 | file = hypfs_create_str(dir, "type", "z/VM Hypervisor"); |
190 | if (IS_ERR(file)) { | 189 | if (IS_ERR(file)) { |
191 | rc = PTR_ERR(file); | 190 | rc = PTR_ERR(file); |
192 | goto failed; | 191 | goto failed; |
193 | } | 192 | } |
194 | 193 | ||
195 | /* physical cpus */ | 194 | /* physical cpus */ |
196 | dir = hypfs_mkdir(sb, root, "cpus"); | 195 | dir = hypfs_mkdir(root, "cpus"); |
197 | if (IS_ERR(dir)) { | 196 | if (IS_ERR(dir)) { |
198 | rc = PTR_ERR(dir); | 197 | rc = PTR_ERR(dir); |
199 | goto failed; | 198 | goto failed; |
200 | } | 199 | } |
201 | file = hypfs_create_u64(sb, dir, "count", data->lcpus); | 200 | file = hypfs_create_u64(dir, "count", data->lcpus); |
202 | if (IS_ERR(file)) { | 201 | if (IS_ERR(file)) { |
203 | rc = PTR_ERR(file); | 202 | rc = PTR_ERR(file); |
204 | goto failed; | 203 | goto failed; |
205 | } | 204 | } |
206 | 205 | ||
207 | /* guests */ | 206 | /* guests */ |
208 | dir = hypfs_mkdir(sb, root, "systems"); | 207 | dir = hypfs_mkdir(root, "systems"); |
209 | if (IS_ERR(dir)) { | 208 | if (IS_ERR(dir)) { |
210 | rc = PTR_ERR(dir); | 209 | rc = PTR_ERR(dir); |
211 | goto failed; | 210 | goto failed; |
212 | } | 211 | } |
213 | 212 | ||
214 | for (i = 0; i < count; i++) { | 213 | for (i = 0; i < count; i++) { |
215 | rc = hpyfs_vm_create_guest(sb, dir, &(data[i])); | 214 | rc = hpyfs_vm_create_guest(dir, &(data[i])); |
216 | if (rc) | 215 | if (rc) |
217 | goto failed; | 216 | goto failed; |
218 | } | 217 | } |
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 7a539f4f5e30..ddfe09b45134 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
@@ -28,8 +28,7 @@ | |||
28 | #define HYPFS_MAGIC 0x687970 /* ASCII 'hyp' */ | 28 | #define HYPFS_MAGIC 0x687970 /* ASCII 'hyp' */ |
29 | #define TMP_SIZE 64 /* size of temporary buffers */ | 29 | #define TMP_SIZE 64 /* size of temporary buffers */ |
30 | 30 | ||
31 | static struct dentry *hypfs_create_update_file(struct super_block *sb, | 31 | static struct dentry *hypfs_create_update_file(struct dentry *dir); |
32 | struct dentry *dir); | ||
33 | 32 | ||
34 | struct hypfs_sb_info { | 33 | struct hypfs_sb_info { |
35 | kuid_t uid; /* uid used for files and dirs */ | 34 | kuid_t uid; /* uid used for files and dirs */ |
@@ -193,9 +192,9 @@ static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
193 | } | 192 | } |
194 | hypfs_delete_tree(sb->s_root); | 193 | hypfs_delete_tree(sb->s_root); |
195 | if (MACHINE_IS_VM) | 194 | if (MACHINE_IS_VM) |
196 | rc = hypfs_vm_create_files(sb, sb->s_root); | 195 | rc = hypfs_vm_create_files(sb->s_root); |
197 | else | 196 | else |
198 | rc = hypfs_diag_create_files(sb, sb->s_root); | 197 | rc = hypfs_diag_create_files(sb->s_root); |
199 | if (rc) { | 198 | if (rc) { |
200 | pr_err("Updating the hypfs tree failed\n"); | 199 | pr_err("Updating the hypfs tree failed\n"); |
201 | hypfs_delete_tree(sb->s_root); | 200 | hypfs_delete_tree(sb->s_root); |
@@ -302,12 +301,12 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) | |||
302 | if (!root_dentry) | 301 | if (!root_dentry) |
303 | return -ENOMEM; | 302 | return -ENOMEM; |
304 | if (MACHINE_IS_VM) | 303 | if (MACHINE_IS_VM) |
305 | rc = hypfs_vm_create_files(sb, root_dentry); | 304 | rc = hypfs_vm_create_files(root_dentry); |
306 | else | 305 | else |
307 | rc = hypfs_diag_create_files(sb, root_dentry); | 306 | rc = hypfs_diag_create_files(root_dentry); |
308 | if (rc) | 307 | if (rc) |
309 | return rc; | 308 | return rc; |
310 | sbi->update_file = hypfs_create_update_file(sb, root_dentry); | 309 | sbi->update_file = hypfs_create_update_file(root_dentry); |
311 | if (IS_ERR(sbi->update_file)) | 310 | if (IS_ERR(sbi->update_file)) |
312 | return PTR_ERR(sbi->update_file); | 311 | return PTR_ERR(sbi->update_file); |
313 | hypfs_update_update(sb); | 312 | hypfs_update_update(sb); |
@@ -334,8 +333,7 @@ static void hypfs_kill_super(struct super_block *sb) | |||
334 | kill_litter_super(sb); | 333 | kill_litter_super(sb); |
335 | } | 334 | } |
336 | 335 | ||
337 | static struct dentry *hypfs_create_file(struct super_block *sb, | 336 | static struct dentry *hypfs_create_file(struct dentry *parent, const char *name, |
338 | struct dentry *parent, const char *name, | ||
339 | char *data, umode_t mode) | 337 | char *data, umode_t mode) |
340 | { | 338 | { |
341 | struct dentry *dentry; | 339 | struct dentry *dentry; |
@@ -347,7 +345,7 @@ static struct dentry *hypfs_create_file(struct super_block *sb, | |||
347 | dentry = ERR_PTR(-ENOMEM); | 345 | dentry = ERR_PTR(-ENOMEM); |
348 | goto fail; | 346 | goto fail; |
349 | } | 347 | } |
350 | inode = hypfs_make_inode(sb, mode); | 348 | inode = hypfs_make_inode(parent->d_sb, mode); |
351 | if (!inode) { | 349 | if (!inode) { |
352 | dput(dentry); | 350 | dput(dentry); |
353 | dentry = ERR_PTR(-ENOMEM); | 351 | dentry = ERR_PTR(-ENOMEM); |
@@ -373,24 +371,22 @@ fail: | |||
373 | return dentry; | 371 | return dentry; |
374 | } | 372 | } |
375 | 373 | ||
376 | struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent, | 374 | struct dentry *hypfs_mkdir(struct dentry *parent, const char *name) |
377 | const char *name) | ||
378 | { | 375 | { |
379 | struct dentry *dentry; | 376 | struct dentry *dentry; |
380 | 377 | ||
381 | dentry = hypfs_create_file(sb, parent, name, NULL, S_IFDIR | DIR_MODE); | 378 | dentry = hypfs_create_file(parent, name, NULL, S_IFDIR | DIR_MODE); |
382 | if (IS_ERR(dentry)) | 379 | if (IS_ERR(dentry)) |
383 | return dentry; | 380 | return dentry; |
384 | hypfs_add_dentry(dentry); | 381 | hypfs_add_dentry(dentry); |
385 | return dentry; | 382 | return dentry; |
386 | } | 383 | } |
387 | 384 | ||
388 | static struct dentry *hypfs_create_update_file(struct super_block *sb, | 385 | static struct dentry *hypfs_create_update_file(struct dentry *dir) |
389 | struct dentry *dir) | ||
390 | { | 386 | { |
391 | struct dentry *dentry; | 387 | struct dentry *dentry; |
392 | 388 | ||
393 | dentry = hypfs_create_file(sb, dir, "update", NULL, | 389 | dentry = hypfs_create_file(dir, "update", NULL, |
394 | S_IFREG | UPDATE_FILE_MODE); | 390 | S_IFREG | UPDATE_FILE_MODE); |
395 | /* | 391 | /* |
396 | * We do not put the update file on the 'delete' list with | 392 | * We do not put the update file on the 'delete' list with |
@@ -400,7 +396,7 @@ static struct dentry *hypfs_create_update_file(struct super_block *sb, | |||
400 | return dentry; | 396 | return dentry; |
401 | } | 397 | } |
402 | 398 | ||
403 | struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir, | 399 | struct dentry *hypfs_create_u64(struct dentry *dir, |
404 | const char *name, __u64 value) | 400 | const char *name, __u64 value) |
405 | { | 401 | { |
406 | char *buffer; | 402 | char *buffer; |
@@ -412,7 +408,7 @@ struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir, | |||
412 | if (!buffer) | 408 | if (!buffer) |
413 | return ERR_PTR(-ENOMEM); | 409 | return ERR_PTR(-ENOMEM); |
414 | dentry = | 410 | dentry = |
415 | hypfs_create_file(sb, dir, name, buffer, S_IFREG | REG_FILE_MODE); | 411 | hypfs_create_file(dir, name, buffer, S_IFREG | REG_FILE_MODE); |
416 | if (IS_ERR(dentry)) { | 412 | if (IS_ERR(dentry)) { |
417 | kfree(buffer); | 413 | kfree(buffer); |
418 | return ERR_PTR(-ENOMEM); | 414 | return ERR_PTR(-ENOMEM); |
@@ -421,7 +417,7 @@ struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir, | |||
421 | return dentry; | 417 | return dentry; |
422 | } | 418 | } |
423 | 419 | ||
424 | struct dentry *hypfs_create_str(struct super_block *sb, struct dentry *dir, | 420 | struct dentry *hypfs_create_str(struct dentry *dir, |
425 | const char *name, char *string) | 421 | const char *name, char *string) |
426 | { | 422 | { |
427 | char *buffer; | 423 | char *buffer; |
@@ -432,7 +428,7 @@ struct dentry *hypfs_create_str(struct super_block *sb, struct dentry *dir, | |||
432 | return ERR_PTR(-ENOMEM); | 428 | return ERR_PTR(-ENOMEM); |
433 | sprintf(buffer, "%s\n", string); | 429 | sprintf(buffer, "%s\n", string); |
434 | dentry = | 430 | dentry = |
435 | hypfs_create_file(sb, dir, name, buffer, S_IFREG | REG_FILE_MODE); | 431 | hypfs_create_file(dir, name, buffer, S_IFREG | REG_FILE_MODE); |
436 | if (IS_ERR(dentry)) { | 432 | if (IS_ERR(dentry)) { |
437 | kfree(buffer); | 433 | kfree(buffer); |
438 | return ERR_PTR(-ENOMEM); | 434 | return ERR_PTR(-ENOMEM); |
diff --git a/arch/s390/include/asm/airq.h b/arch/s390/include/asm/airq.h index 4066cee0c2d2..4bbb5957ed1b 100644 --- a/arch/s390/include/asm/airq.h +++ b/arch/s390/include/asm/airq.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef _ASM_S390_AIRQ_H | 9 | #ifndef _ASM_S390_AIRQ_H |
10 | #define _ASM_S390_AIRQ_H | 10 | #define _ASM_S390_AIRQ_H |
11 | 11 | ||
12 | #include <linux/bit_spinlock.h> | ||
13 | |||
12 | struct airq_struct { | 14 | struct airq_struct { |
13 | struct hlist_node list; /* Handler queueing. */ | 15 | struct hlist_node list; /* Handler queueing. */ |
14 | void (*handler)(struct airq_struct *); /* Thin-interrupt handler */ | 16 | void (*handler)(struct airq_struct *); /* Thin-interrupt handler */ |
@@ -23,4 +25,69 @@ struct airq_struct { | |||
23 | int register_adapter_interrupt(struct airq_struct *airq); | 25 | int register_adapter_interrupt(struct airq_struct *airq); |
24 | void unregister_adapter_interrupt(struct airq_struct *airq); | 26 | void unregister_adapter_interrupt(struct airq_struct *airq); |
25 | 27 | ||
28 | /* Adapter interrupt bit vector */ | ||
29 | struct airq_iv { | ||
30 | unsigned long *vector; /* Adapter interrupt bit vector */ | ||
31 | unsigned long *avail; /* Allocation bit mask for the bit vector */ | ||
32 | unsigned long *bitlock; /* Lock bit mask for the bit vector */ | ||
33 | unsigned long *ptr; /* Pointer associated with each bit */ | ||
34 | unsigned int *data; /* 32 bit value associated with each bit */ | ||
35 | unsigned long bits; /* Number of bits in the vector */ | ||
36 | unsigned long end; /* Number of highest allocated bit + 1 */ | ||
37 | spinlock_t lock; /* Lock to protect alloc & free */ | ||
38 | }; | ||
39 | |||
40 | #define AIRQ_IV_ALLOC 1 /* Use an allocation bit mask */ | ||
41 | #define AIRQ_IV_BITLOCK 2 /* Allocate the lock bit mask */ | ||
42 | #define AIRQ_IV_PTR 4 /* Allocate the ptr array */ | ||
43 | #define AIRQ_IV_DATA 8 /* Allocate the data array */ | ||
44 | |||
45 | struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags); | ||
46 | void airq_iv_release(struct airq_iv *iv); | ||
47 | unsigned long airq_iv_alloc_bit(struct airq_iv *iv); | ||
48 | void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit); | ||
49 | unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start, | ||
50 | unsigned long end); | ||
51 | |||
52 | static inline unsigned long airq_iv_end(struct airq_iv *iv) | ||
53 | { | ||
54 | return iv->end; | ||
55 | } | ||
56 | |||
57 | static inline void airq_iv_lock(struct airq_iv *iv, unsigned long bit) | ||
58 | { | ||
59 | const unsigned long be_to_le = BITS_PER_LONG - 1; | ||
60 | bit_spin_lock(bit ^ be_to_le, iv->bitlock); | ||
61 | } | ||
62 | |||
63 | static inline void airq_iv_unlock(struct airq_iv *iv, unsigned long bit) | ||
64 | { | ||
65 | const unsigned long be_to_le = BITS_PER_LONG - 1; | ||
66 | bit_spin_unlock(bit ^ be_to_le, iv->bitlock); | ||
67 | } | ||
68 | |||
69 | static inline void airq_iv_set_data(struct airq_iv *iv, unsigned long bit, | ||
70 | unsigned int data) | ||
71 | { | ||
72 | iv->data[bit] = data; | ||
73 | } | ||
74 | |||
75 | static inline unsigned int airq_iv_get_data(struct airq_iv *iv, | ||
76 | unsigned long bit) | ||
77 | { | ||
78 | return iv->data[bit]; | ||
79 | } | ||
80 | |||
81 | static inline void airq_iv_set_ptr(struct airq_iv *iv, unsigned long bit, | ||
82 | unsigned long ptr) | ||
83 | { | ||
84 | iv->ptr[bit] = ptr; | ||
85 | } | ||
86 | |||
87 | static inline unsigned long airq_iv_get_ptr(struct airq_iv *iv, | ||
88 | unsigned long bit) | ||
89 | { | ||
90 | return iv->ptr[bit]; | ||
91 | } | ||
92 | |||
26 | #endif /* _ASM_S390_AIRQ_H */ | 93 | #endif /* _ASM_S390_AIRQ_H */ |
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index 7d4676758733..10135a38673c 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h | |||
@@ -216,7 +216,7 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) | |||
216 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); | 216 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
217 | asm volatile( | 217 | asm volatile( |
218 | " oc %O0(1,%R0),%1" | 218 | " oc %O0(1,%R0),%1" |
219 | : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); | 219 | : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc"); |
220 | } | 220 | } |
221 | 221 | ||
222 | static inline void | 222 | static inline void |
@@ -244,7 +244,7 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr) | |||
244 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); | 244 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
245 | asm volatile( | 245 | asm volatile( |
246 | " nc %O0(1,%R0),%1" | 246 | " nc %O0(1,%R0),%1" |
247 | : "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc" ); | 247 | : "+Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc"); |
248 | } | 248 | } |
249 | 249 | ||
250 | static inline void | 250 | static inline void |
@@ -271,7 +271,7 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) | |||
271 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); | 271 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
272 | asm volatile( | 272 | asm volatile( |
273 | " xc %O0(1,%R0),%1" | 273 | " xc %O0(1,%R0),%1" |
274 | : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); | 274 | : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc"); |
275 | } | 275 | } |
276 | 276 | ||
277 | static inline void | 277 | static inline void |
@@ -301,7 +301,7 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
301 | ch = *(unsigned char *) addr; | 301 | ch = *(unsigned char *) addr; |
302 | asm volatile( | 302 | asm volatile( |
303 | " oc %O0(1,%R0),%1" | 303 | " oc %O0(1,%R0),%1" |
304 | : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) | 304 | : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) |
305 | : "cc", "memory"); | 305 | : "cc", "memory"); |
306 | return (ch >> (nr & 7)) & 1; | 306 | return (ch >> (nr & 7)) & 1; |
307 | } | 307 | } |
@@ -320,7 +320,7 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
320 | ch = *(unsigned char *) addr; | 320 | ch = *(unsigned char *) addr; |
321 | asm volatile( | 321 | asm volatile( |
322 | " nc %O0(1,%R0),%1" | 322 | " nc %O0(1,%R0),%1" |
323 | : "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) | 323 | : "+Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) |
324 | : "cc", "memory"); | 324 | : "cc", "memory"); |
325 | return (ch >> (nr & 7)) & 1; | 325 | return (ch >> (nr & 7)) & 1; |
326 | } | 326 | } |
@@ -339,7 +339,7 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
339 | ch = *(unsigned char *) addr; | 339 | ch = *(unsigned char *) addr; |
340 | asm volatile( | 340 | asm volatile( |
341 | " xc %O0(1,%R0),%1" | 341 | " xc %O0(1,%R0),%1" |
342 | : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) | 342 | : "+Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) |
343 | : "cc", "memory"); | 343 | : "cc", "memory"); |
344 | return (ch >> (nr & 7)) & 1; | 344 | return (ch >> (nr & 7)) & 1; |
345 | } | 345 | } |
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index ffb898961c8d..d42625053c37 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h | |||
@@ -296,6 +296,7 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, | |||
296 | return 0; | 296 | return 0; |
297 | } | 297 | } |
298 | 298 | ||
299 | void channel_subsystem_reinit(void); | ||
299 | extern void css_schedule_reprobe(void); | 300 | extern void css_schedule_reprobe(void); |
300 | 301 | ||
301 | extern void reipl_ccw_dev(struct ccw_dev_id *id); | 302 | extern void reipl_ccw_dev(struct ccw_dev_id *id); |
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index d2ff41370c0c..f65bd3634519 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h | |||
@@ -13,9 +13,6 @@ | |||
13 | #include <asm/div64.h> | 13 | #include <asm/div64.h> |
14 | 14 | ||
15 | 15 | ||
16 | #define __ARCH_HAS_VTIME_ACCOUNT | ||
17 | #define __ARCH_HAS_VTIME_TASK_SWITCH | ||
18 | |||
19 | /* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */ | 16 | /* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */ |
20 | 17 | ||
21 | typedef unsigned long long __nocast cputime_t; | 18 | typedef unsigned long long __nocast cputime_t; |
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h index 0c82ba86e997..a908d2941c5d 100644 --- a/arch/s390/include/asm/hardirq.h +++ b/arch/s390/include/asm/hardirq.h | |||
@@ -20,4 +20,9 @@ | |||
20 | 20 | ||
21 | #define HARDIRQ_BITS 8 | 21 | #define HARDIRQ_BITS 8 |
22 | 22 | ||
23 | static inline void ack_bad_irq(unsigned int irq) | ||
24 | { | ||
25 | printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq); | ||
26 | } | ||
27 | |||
23 | #endif /* __ASM_HARDIRQ_H */ | 28 | #endif /* __ASM_HARDIRQ_H */ |
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index bd90359d6d22..11eae5f55b70 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h | |||
@@ -17,6 +17,9 @@ | |||
17 | 17 | ||
18 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 18 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
19 | pte_t *ptep, pte_t pte); | 19 | pte_t *ptep, pte_t pte); |
20 | pte_t huge_ptep_get(pte_t *ptep); | ||
21 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | ||
22 | unsigned long addr, pte_t *ptep); | ||
20 | 23 | ||
21 | /* | 24 | /* |
22 | * If the arch doesn't supply something else, assume that hugepage | 25 | * If the arch doesn't supply something else, assume that hugepage |
@@ -38,147 +41,75 @@ static inline int prepare_hugepage_range(struct file *file, | |||
38 | int arch_prepare_hugepage(struct page *page); | 41 | int arch_prepare_hugepage(struct page *page); |
39 | void arch_release_hugepage(struct page *page); | 42 | void arch_release_hugepage(struct page *page); |
40 | 43 | ||
41 | static inline pte_t huge_pte_wrprotect(pte_t pte) | 44 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, |
45 | pte_t *ptep) | ||
42 | { | 46 | { |
43 | pte_val(pte) |= _PAGE_RO; | 47 | pte_val(*ptep) = _SEGMENT_ENTRY_EMPTY; |
44 | return pte; | ||
45 | } | 48 | } |
46 | 49 | ||
47 | static inline int huge_pte_none(pte_t pte) | 50 | static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, |
51 | unsigned long address, pte_t *ptep) | ||
48 | { | 52 | { |
49 | return (pte_val(pte) & _SEGMENT_ENTRY_INV) && | 53 | huge_ptep_get_and_clear(vma->vm_mm, address, ptep); |
50 | !(pte_val(pte) & _SEGMENT_ENTRY_RO); | ||
51 | } | 54 | } |
52 | 55 | ||
53 | static inline pte_t huge_ptep_get(pte_t *ptep) | 56 | static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, |
57 | unsigned long addr, pte_t *ptep, | ||
58 | pte_t pte, int dirty) | ||
54 | { | 59 | { |
55 | pte_t pte = *ptep; | 60 | int changed = !pte_same(huge_ptep_get(ptep), pte); |
56 | unsigned long mask; | 61 | if (changed) { |
57 | 62 | huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); | |
58 | if (!MACHINE_HAS_HPAGE) { | 63 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); |
59 | ptep = (pte_t *) (pte_val(pte) & _SEGMENT_ENTRY_ORIGIN); | ||
60 | if (ptep) { | ||
61 | mask = pte_val(pte) & | ||
62 | (_SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO); | ||
63 | pte = pte_mkhuge(*ptep); | ||
64 | pte_val(pte) |= mask; | ||
65 | } | ||
66 | } | 64 | } |
67 | return pte; | 65 | return changed; |
68 | } | 66 | } |
69 | 67 | ||
70 | static inline void __pmd_csp(pmd_t *pmdp) | 68 | static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, |
69 | unsigned long addr, pte_t *ptep) | ||
71 | { | 70 | { |
72 | register unsigned long reg2 asm("2") = pmd_val(*pmdp); | 71 | pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep); |
73 | register unsigned long reg3 asm("3") = pmd_val(*pmdp) | | 72 | set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte)); |
74 | _SEGMENT_ENTRY_INV; | ||
75 | register unsigned long reg4 asm("4") = ((unsigned long) pmdp) + 5; | ||
76 | |||
77 | asm volatile( | ||
78 | " csp %1,%3" | ||
79 | : "=m" (*pmdp) | ||
80 | : "d" (reg2), "d" (reg3), "d" (reg4), "m" (*pmdp) : "cc"); | ||
81 | } | 73 | } |
82 | 74 | ||
83 | static inline void huge_ptep_invalidate(struct mm_struct *mm, | 75 | static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot) |
84 | unsigned long address, pte_t *ptep) | ||
85 | { | ||
86 | pmd_t *pmdp = (pmd_t *) ptep; | ||
87 | |||
88 | if (MACHINE_HAS_IDTE) | ||
89 | __pmd_idte(address, pmdp); | ||
90 | else | ||
91 | __pmd_csp(pmdp); | ||
92 | pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY; | ||
93 | } | ||
94 | |||
95 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | ||
96 | unsigned long addr, pte_t *ptep) | ||
97 | { | ||
98 | pte_t pte = huge_ptep_get(ptep); | ||
99 | |||
100 | huge_ptep_invalidate(mm, addr, ptep); | ||
101 | return pte; | ||
102 | } | ||
103 | |||
104 | #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \ | ||
105 | ({ \ | ||
106 | int __changed = !pte_same(huge_ptep_get(__ptep), __entry); \ | ||
107 | if (__changed) { \ | ||
108 | huge_ptep_invalidate((__vma)->vm_mm, __addr, __ptep); \ | ||
109 | set_huge_pte_at((__vma)->vm_mm, __addr, __ptep, __entry); \ | ||
110 | } \ | ||
111 | __changed; \ | ||
112 | }) | ||
113 | |||
114 | #define huge_ptep_set_wrprotect(__mm, __addr, __ptep) \ | ||
115 | ({ \ | ||
116 | pte_t __pte = huge_ptep_get(__ptep); \ | ||
117 | if (huge_pte_write(__pte)) { \ | ||
118 | huge_ptep_invalidate(__mm, __addr, __ptep); \ | ||
119 | set_huge_pte_at(__mm, __addr, __ptep, \ | ||
120 | huge_pte_wrprotect(__pte)); \ | ||
121 | } \ | ||
122 | }) | ||
123 | |||
124 | static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, | ||
125 | unsigned long address, pte_t *ptep) | ||
126 | { | 76 | { |
127 | huge_ptep_invalidate(vma->vm_mm, address, ptep); | 77 | return mk_pte(page, pgprot); |
128 | } | 78 | } |
129 | 79 | ||
130 | static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot) | 80 | static inline int huge_pte_none(pte_t pte) |
131 | { | 81 | { |
132 | pte_t pte; | 82 | return pte_none(pte); |
133 | pmd_t pmd; | ||
134 | |||
135 | pmd = mk_pmd_phys(page_to_phys(page), pgprot); | ||
136 | pte_val(pte) = pmd_val(pmd); | ||
137 | return pte; | ||
138 | } | 83 | } |
139 | 84 | ||
140 | static inline int huge_pte_write(pte_t pte) | 85 | static inline int huge_pte_write(pte_t pte) |
141 | { | 86 | { |
142 | pmd_t pmd; | 87 | return pte_write(pte); |
143 | |||
144 | pmd_val(pmd) = pte_val(pte); | ||
145 | return pmd_write(pmd); | ||
146 | } | 88 | } |
147 | 89 | ||
148 | static inline int huge_pte_dirty(pte_t pte) | 90 | static inline int huge_pte_dirty(pte_t pte) |
149 | { | 91 | { |
150 | /* No dirty bit in the segment table entry. */ | 92 | return pte_dirty(pte); |
151 | return 0; | ||
152 | } | 93 | } |
153 | 94 | ||
154 | static inline pte_t huge_pte_mkwrite(pte_t pte) | 95 | static inline pte_t huge_pte_mkwrite(pte_t pte) |
155 | { | 96 | { |
156 | pmd_t pmd; | 97 | return pte_mkwrite(pte); |
157 | |||
158 | pmd_val(pmd) = pte_val(pte); | ||
159 | pte_val(pte) = pmd_val(pmd_mkwrite(pmd)); | ||
160 | return pte; | ||
161 | } | 98 | } |
162 | 99 | ||
163 | static inline pte_t huge_pte_mkdirty(pte_t pte) | 100 | static inline pte_t huge_pte_mkdirty(pte_t pte) |
164 | { | 101 | { |
165 | /* No dirty bit in the segment table entry. */ | 102 | return pte_mkdirty(pte); |
166 | return pte; | ||
167 | } | 103 | } |
168 | 104 | ||
169 | static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot) | 105 | static inline pte_t huge_pte_wrprotect(pte_t pte) |
170 | { | 106 | { |
171 | pmd_t pmd; | 107 | return pte_wrprotect(pte); |
172 | |||
173 | pmd_val(pmd) = pte_val(pte); | ||
174 | pte_val(pte) = pmd_val(pmd_modify(pmd, newprot)); | ||
175 | return pte; | ||
176 | } | 108 | } |
177 | 109 | ||
178 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, | 110 | static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot) |
179 | pte_t *ptep) | ||
180 | { | 111 | { |
181 | pmd_clear((pmd_t *) ptep); | 112 | return pte_modify(pte, newprot); |
182 | } | 113 | } |
183 | 114 | ||
184 | #endif /* _ASM_S390_HUGETLB_H */ | 115 | #endif /* _ASM_S390_HUGETLB_H */ |
diff --git a/arch/s390/include/asm/hw_irq.h b/arch/s390/include/asm/hw_irq.h index 7e3d2586c1ff..ee96a8b697f9 100644 --- a/arch/s390/include/asm/hw_irq.h +++ b/arch/s390/include/asm/hw_irq.h | |||
@@ -4,19 +4,8 @@ | |||
4 | #include <linux/msi.h> | 4 | #include <linux/msi.h> |
5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
6 | 6 | ||
7 | static inline struct msi_desc *irq_get_msi_desc(unsigned int irq) | 7 | void __init init_airq_interrupts(void); |
8 | { | 8 | void __init init_cio_interrupts(void); |
9 | return __irq_get_msi_desc(irq); | 9 | void __init init_ext_interrupts(void); |
10 | } | ||
11 | |||
12 | /* Must be called with msi map lock held */ | ||
13 | static inline int irq_set_msi_desc(unsigned int irq, struct msi_desc *msi) | ||
14 | { | ||
15 | if (!msi) | ||
16 | return -EINVAL; | ||
17 | |||
18 | msi->irq = irq; | ||
19 | return 0; | ||
20 | } | ||
21 | 10 | ||
22 | #endif | 11 | #endif |
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index 87c17bfb2968..1eaa3625803c 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h | |||
@@ -1,17 +1,28 @@ | |||
1 | #ifndef _ASM_IRQ_H | 1 | #ifndef _ASM_IRQ_H |
2 | #define _ASM_IRQ_H | 2 | #define _ASM_IRQ_H |
3 | 3 | ||
4 | #define EXT_INTERRUPT 1 | ||
5 | #define IO_INTERRUPT 2 | ||
6 | #define THIN_INTERRUPT 3 | ||
7 | |||
8 | #define NR_IRQS_BASE 4 | ||
9 | |||
10 | #ifdef CONFIG_PCI_NR_MSI | ||
11 | # define NR_IRQS (NR_IRQS_BASE + CONFIG_PCI_NR_MSI) | ||
12 | #else | ||
13 | # define NR_IRQS NR_IRQS_BASE | ||
14 | #endif | ||
15 | |||
16 | /* This number is used when no interrupt has been assigned */ | ||
17 | #define NO_IRQ 0 | ||
18 | |||
19 | #ifndef __ASSEMBLY__ | ||
20 | |||
4 | #include <linux/hardirq.h> | 21 | #include <linux/hardirq.h> |
5 | #include <linux/percpu.h> | 22 | #include <linux/percpu.h> |
6 | #include <linux/cache.h> | 23 | #include <linux/cache.h> |
7 | #include <linux/types.h> | 24 | #include <linux/types.h> |
8 | 25 | ||
9 | enum interruption_main_class { | ||
10 | EXTERNAL_INTERRUPT, | ||
11 | IO_INTERRUPT, | ||
12 | NR_IRQS | ||
13 | }; | ||
14 | |||
15 | enum interruption_class { | 26 | enum interruption_class { |
16 | IRQEXT_CLK, | 27 | IRQEXT_CLK, |
17 | IRQEXT_EXC, | 28 | IRQEXT_EXC, |
@@ -72,14 +83,8 @@ void service_subclass_irq_unregister(void); | |||
72 | void measurement_alert_subclass_register(void); | 83 | void measurement_alert_subclass_register(void); |
73 | void measurement_alert_subclass_unregister(void); | 84 | void measurement_alert_subclass_unregister(void); |
74 | 85 | ||
75 | #ifdef CONFIG_LOCKDEP | 86 | #define irq_canonicalize(irq) (irq) |
76 | # define disable_irq_nosync_lockdep(irq) disable_irq_nosync(irq) | 87 | |
77 | # define disable_irq_nosync_lockdep_irqsave(irq, flags) \ | 88 | #endif /* __ASSEMBLY__ */ |
78 | disable_irq_nosync(irq) | ||
79 | # define disable_irq_lockdep(irq) disable_irq(irq) | ||
80 | # define enable_irq_lockdep(irq) enable_irq(irq) | ||
81 | # define enable_irq_lockdep_irqrestore(irq, flags) \ | ||
82 | enable_irq(irq) | ||
83 | #endif | ||
84 | 89 | ||
85 | #endif /* _ASM_IRQ_H */ | 90 | #endif /* _ASM_IRQ_H */ |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 3238d4004e84..e87ecaa2c569 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -274,6 +274,14 @@ struct kvm_arch{ | |||
274 | int css_support; | 274 | int css_support; |
275 | }; | 275 | }; |
276 | 276 | ||
277 | #define KVM_HVA_ERR_BAD (-1UL) | ||
278 | #define KVM_HVA_ERR_RO_BAD (-2UL) | ||
279 | |||
280 | static inline bool kvm_is_error_hva(unsigned long addr) | ||
281 | { | ||
282 | return IS_ERR_VALUE(addr); | ||
283 | } | ||
284 | |||
277 | extern int sie64a(struct kvm_s390_sie_block *, u64 *); | 285 | extern int sie64a(struct kvm_s390_sie_block *, u64 *); |
278 | extern char sie_exit; | 286 | extern char sie_exit; |
279 | #endif | 287 | #endif |
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index 6340178748bf..ff132ac64ddd 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h | |||
@@ -12,8 +12,6 @@ typedef struct { | |||
12 | unsigned long asce_bits; | 12 | unsigned long asce_bits; |
13 | unsigned long asce_limit; | 13 | unsigned long asce_limit; |
14 | unsigned long vdso_base; | 14 | unsigned long vdso_base; |
15 | /* Cloned contexts will be created with extended page tables. */ | ||
16 | unsigned int alloc_pgste:1; | ||
17 | /* The mmu context has extended page tables. */ | 15 | /* The mmu context has extended page tables. */ |
18 | unsigned int has_pgste:1; | 16 | unsigned int has_pgste:1; |
19 | } mm_context_t; | 17 | } mm_context_t; |
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 084e7755ed9b..9f973d8de90e 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h | |||
@@ -21,24 +21,7 @@ static inline int init_new_context(struct task_struct *tsk, | |||
21 | #ifdef CONFIG_64BIT | 21 | #ifdef CONFIG_64BIT |
22 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; | 22 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; |
23 | #endif | 23 | #endif |
24 | if (current->mm && current->mm->context.alloc_pgste) { | 24 | mm->context.has_pgste = 0; |
25 | /* | ||
26 | * alloc_pgste indicates, that any NEW context will be created | ||
27 | * with extended page tables. The old context is unchanged. The | ||
28 | * page table allocation and the page table operations will | ||
29 | * look at has_pgste to distinguish normal and extended page | ||
30 | * tables. The only way to create extended page tables is to | ||
31 | * set alloc_pgste and then create a new context (e.g. dup_mm). | ||
32 | * The page table allocation is called after init_new_context | ||
33 | * and if has_pgste is set, it will create extended page | ||
34 | * tables. | ||
35 | */ | ||
36 | mm->context.has_pgste = 1; | ||
37 | mm->context.alloc_pgste = 1; | ||
38 | } else { | ||
39 | mm->context.has_pgste = 0; | ||
40 | mm->context.alloc_pgste = 0; | ||
41 | } | ||
42 | mm->context.asce_limit = STACK_TOP_MAX; | 25 | mm->context.asce_limit = STACK_TOP_MAX; |
43 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); | 26 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); |
44 | return 0; | 27 | return 0; |
@@ -77,8 +60,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
77 | WARN_ON(atomic_read(&prev->context.attach_count) < 0); | 60 | WARN_ON(atomic_read(&prev->context.attach_count) < 0); |
78 | atomic_inc(&next->context.attach_count); | 61 | atomic_inc(&next->context.attach_count); |
79 | /* Check for TLBs not flushed yet */ | 62 | /* Check for TLBs not flushed yet */ |
80 | if (next->context.flush_mm) | 63 | __tlb_flush_mm_lazy(next); |
81 | __tlb_flush_mm(next); | ||
82 | } | 64 | } |
83 | 65 | ||
84 | #define enter_lazy_tlb(mm,tsk) do { } while (0) | 66 | #define enter_lazy_tlb(mm,tsk) do { } while (0) |
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 5d64fb7619cc..1e51f2915b2e 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h | |||
@@ -32,16 +32,6 @@ | |||
32 | 32 | ||
33 | void storage_key_init_range(unsigned long start, unsigned long end); | 33 | void storage_key_init_range(unsigned long start, unsigned long end); |
34 | 34 | ||
35 | static inline unsigned long pfmf(unsigned long function, unsigned long address) | ||
36 | { | ||
37 | asm volatile( | ||
38 | " .insn rre,0xb9af0000,%[function],%[address]" | ||
39 | : [address] "+a" (address) | ||
40 | : [function] "d" (function) | ||
41 | : "memory"); | ||
42 | return address; | ||
43 | } | ||
44 | |||
45 | static inline void clear_page(void *page) | 35 | static inline void clear_page(void *page) |
46 | { | 36 | { |
47 | register unsigned long reg1 asm ("1") = 0; | 37 | register unsigned long reg1 asm ("1") = 0; |
@@ -150,15 +140,6 @@ static inline int page_reset_referenced(unsigned long addr) | |||
150 | #define _PAGE_FP_BIT 0x08 /* HW fetch protection bit */ | 140 | #define _PAGE_FP_BIT 0x08 /* HW fetch protection bit */ |
151 | #define _PAGE_ACC_BITS 0xf0 /* HW access control bits */ | 141 | #define _PAGE_ACC_BITS 0xf0 /* HW access control bits */ |
152 | 142 | ||
153 | /* | ||
154 | * Test and clear referenced bit in storage key. | ||
155 | */ | ||
156 | #define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG | ||
157 | static inline int page_test_and_clear_young(unsigned long pfn) | ||
158 | { | ||
159 | return page_reset_referenced(pfn << PAGE_SHIFT); | ||
160 | } | ||
161 | |||
162 | struct page; | 143 | struct page; |
163 | void arch_free_page(struct page *page, int order); | 144 | void arch_free_page(struct page *page, int order); |
164 | void arch_alloc_page(struct page *page, int order); | 145 | void arch_alloc_page(struct page *page, int order); |
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 6e577ba0e5da..c290f13d1c47 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h | |||
@@ -6,6 +6,7 @@ | |||
6 | /* must be set before including pci_clp.h */ | 6 | /* must be set before including pci_clp.h */ |
7 | #define PCI_BAR_COUNT 6 | 7 | #define PCI_BAR_COUNT 6 |
8 | 8 | ||
9 | #include <linux/pci.h> | ||
9 | #include <asm-generic/pci.h> | 10 | #include <asm-generic/pci.h> |
10 | #include <asm-generic/pci-dma-compat.h> | 11 | #include <asm-generic/pci-dma-compat.h> |
11 | #include <asm/pci_clp.h> | 12 | #include <asm/pci_clp.h> |
@@ -53,14 +54,9 @@ struct zpci_fmb { | |||
53 | atomic64_t unmapped_pages; | 54 | atomic64_t unmapped_pages; |
54 | } __packed __aligned(16); | 55 | } __packed __aligned(16); |
55 | 56 | ||
56 | struct msi_map { | 57 | #define ZPCI_MSI_VEC_BITS 11 |
57 | unsigned long irq; | 58 | #define ZPCI_MSI_VEC_MAX (1 << ZPCI_MSI_VEC_BITS) |
58 | struct msi_desc *msi; | 59 | #define ZPCI_MSI_VEC_MASK (ZPCI_MSI_VEC_MAX - 1) |
59 | struct hlist_node msi_chain; | ||
60 | }; | ||
61 | |||
62 | #define ZPCI_NR_MSI_VECS 64 | ||
63 | #define ZPCI_MSI_MASK (ZPCI_NR_MSI_VECS - 1) | ||
64 | 60 | ||
65 | enum zpci_state { | 61 | enum zpci_state { |
66 | ZPCI_FN_STATE_RESERVED, | 62 | ZPCI_FN_STATE_RESERVED, |
@@ -91,8 +87,7 @@ struct zpci_dev { | |||
91 | 87 | ||
92 | /* IRQ stuff */ | 88 | /* IRQ stuff */ |
93 | u64 msi_addr; /* MSI address */ | 89 | u64 msi_addr; /* MSI address */ |
94 | struct zdev_irq_map *irq_map; | 90 | struct airq_iv *aibv; /* adapter interrupt bit vector */ |
95 | struct msi_map *msi_map[ZPCI_NR_MSI_VECS]; | ||
96 | unsigned int aisb; /* number of the summary bit */ | 91 | unsigned int aisb; /* number of the summary bit */ |
97 | 92 | ||
98 | /* DMA stuff */ | 93 | /* DMA stuff */ |
@@ -122,11 +117,6 @@ struct zpci_dev { | |||
122 | struct dentry *debugfs_perf; | 117 | struct dentry *debugfs_perf; |
123 | }; | 118 | }; |
124 | 119 | ||
125 | struct pci_hp_callback_ops { | ||
126 | int (*create_slot) (struct zpci_dev *zdev); | ||
127 | void (*remove_slot) (struct zpci_dev *zdev); | ||
128 | }; | ||
129 | |||
130 | static inline bool zdev_enabled(struct zpci_dev *zdev) | 120 | static inline bool zdev_enabled(struct zpci_dev *zdev) |
131 | { | 121 | { |
132 | return (zdev->fh & (1UL << 31)) ? true : false; | 122 | return (zdev->fh & (1UL << 31)) ? true : false; |
@@ -146,32 +136,38 @@ int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64); | |||
146 | int zpci_unregister_ioat(struct zpci_dev *, u8); | 136 | int zpci_unregister_ioat(struct zpci_dev *, u8); |
147 | 137 | ||
148 | /* CLP */ | 138 | /* CLP */ |
149 | int clp_find_pci_devices(void); | 139 | int clp_scan_pci_devices(void); |
140 | int clp_rescan_pci_devices(void); | ||
141 | int clp_rescan_pci_devices_simple(void); | ||
150 | int clp_add_pci_device(u32, u32, int); | 142 | int clp_add_pci_device(u32, u32, int); |
151 | int clp_enable_fh(struct zpci_dev *, u8); | 143 | int clp_enable_fh(struct zpci_dev *, u8); |
152 | int clp_disable_fh(struct zpci_dev *); | 144 | int clp_disable_fh(struct zpci_dev *); |
153 | 145 | ||
154 | /* MSI */ | ||
155 | struct msi_desc *__irq_get_msi_desc(unsigned int); | ||
156 | int zpci_msi_set_mask_bits(struct msi_desc *, u32, u32); | ||
157 | int zpci_setup_msi_irq(struct zpci_dev *, struct msi_desc *, unsigned int, int); | ||
158 | void zpci_teardown_msi_irq(struct zpci_dev *, struct msi_desc *); | ||
159 | int zpci_msihash_init(void); | ||
160 | void zpci_msihash_exit(void); | ||
161 | |||
162 | #ifdef CONFIG_PCI | 146 | #ifdef CONFIG_PCI |
163 | /* Error handling and recovery */ | 147 | /* Error handling and recovery */ |
164 | void zpci_event_error(void *); | 148 | void zpci_event_error(void *); |
165 | void zpci_event_availability(void *); | 149 | void zpci_event_availability(void *); |
150 | void zpci_rescan(void); | ||
166 | #else /* CONFIG_PCI */ | 151 | #else /* CONFIG_PCI */ |
167 | static inline void zpci_event_error(void *e) {} | 152 | static inline void zpci_event_error(void *e) {} |
168 | static inline void zpci_event_availability(void *e) {} | 153 | static inline void zpci_event_availability(void *e) {} |
154 | static inline void zpci_rescan(void) {} | ||
169 | #endif /* CONFIG_PCI */ | 155 | #endif /* CONFIG_PCI */ |
170 | 156 | ||
157 | #ifdef CONFIG_HOTPLUG_PCI_S390 | ||
158 | int zpci_init_slot(struct zpci_dev *); | ||
159 | void zpci_exit_slot(struct zpci_dev *); | ||
160 | #else /* CONFIG_HOTPLUG_PCI_S390 */ | ||
161 | static inline int zpci_init_slot(struct zpci_dev *zdev) | ||
162 | { | ||
163 | return 0; | ||
164 | } | ||
165 | static inline void zpci_exit_slot(struct zpci_dev *zdev) {} | ||
166 | #endif /* CONFIG_HOTPLUG_PCI_S390 */ | ||
167 | |||
171 | /* Helpers */ | 168 | /* Helpers */ |
172 | struct zpci_dev *get_zdev(struct pci_dev *); | 169 | struct zpci_dev *get_zdev(struct pci_dev *); |
173 | struct zpci_dev *get_zdev_by_fid(u32); | 170 | struct zpci_dev *get_zdev_by_fid(u32); |
174 | bool zpci_fid_present(u32); | ||
175 | 171 | ||
176 | /* sysfs */ | 172 | /* sysfs */ |
177 | int zpci_sysfs_add_device(struct device *); | 173 | int zpci_sysfs_add_device(struct device *); |
@@ -181,14 +177,6 @@ void zpci_sysfs_remove_device(struct device *); | |||
181 | int zpci_dma_init(void); | 177 | int zpci_dma_init(void); |
182 | void zpci_dma_exit(void); | 178 | void zpci_dma_exit(void); |
183 | 179 | ||
184 | /* Hotplug */ | ||
185 | extern struct mutex zpci_list_lock; | ||
186 | extern struct list_head zpci_list; | ||
187 | extern unsigned int s390_pci_probe; | ||
188 | |||
189 | void zpci_register_hp_ops(struct pci_hp_callback_ops *); | ||
190 | void zpci_deregister_hp_ops(void); | ||
191 | |||
192 | /* FMB */ | 180 | /* FMB */ |
193 | int zpci_fmb_enable_device(struct zpci_dev *); | 181 | int zpci_fmb_enable_device(struct zpci_dev *); |
194 | int zpci_fmb_disable_device(struct zpci_dev *); | 182 | int zpci_fmb_disable_device(struct zpci_dev *); |
diff --git a/arch/s390/include/asm/pci_insn.h b/arch/s390/include/asm/pci_insn.h index e6a2bdd4d705..df6eac9f0cb4 100644 --- a/arch/s390/include/asm/pci_insn.h +++ b/arch/s390/include/asm/pci_insn.h | |||
@@ -79,11 +79,11 @@ struct zpci_fib { | |||
79 | } __packed; | 79 | } __packed; |
80 | 80 | ||
81 | 81 | ||
82 | int s390pci_mod_fc(u64 req, struct zpci_fib *fib); | 82 | int zpci_mod_fc(u64 req, struct zpci_fib *fib); |
83 | int s390pci_refresh_trans(u64 fn, u64 addr, u64 range); | 83 | int zpci_refresh_trans(u64 fn, u64 addr, u64 range); |
84 | int s390pci_load(u64 *data, u64 req, u64 offset); | 84 | int zpci_load(u64 *data, u64 req, u64 offset); |
85 | int s390pci_store(u64 data, u64 req, u64 offset); | 85 | int zpci_store(u64 data, u64 req, u64 offset); |
86 | int s390pci_store_block(const u64 *data, u64 req, u64 offset); | 86 | int zpci_store_block(const u64 *data, u64 req, u64 offset); |
87 | void set_irq_ctrl(u16 ctl, char *unused, u8 isc); | 87 | void zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc); |
88 | 88 | ||
89 | #endif | 89 | #endif |
diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h index 83a9caa6ae53..d194d544d694 100644 --- a/arch/s390/include/asm/pci_io.h +++ b/arch/s390/include/asm/pci_io.h | |||
@@ -36,7 +36,7 @@ static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr) \ | |||
36 | u64 data; \ | 36 | u64 data; \ |
37 | int rc; \ | 37 | int rc; \ |
38 | \ | 38 | \ |
39 | rc = s390pci_load(&data, req, ZPCI_OFFSET(addr)); \ | 39 | rc = zpci_load(&data, req, ZPCI_OFFSET(addr)); \ |
40 | if (rc) \ | 40 | if (rc) \ |
41 | data = -1ULL; \ | 41 | data = -1ULL; \ |
42 | return (RETTYPE) data; \ | 42 | return (RETTYPE) data; \ |
@@ -50,7 +50,7 @@ static inline void zpci_write_##VALTYPE(VALTYPE val, \ | |||
50 | u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ | 50 | u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ |
51 | u64 data = (VALTYPE) val; \ | 51 | u64 data = (VALTYPE) val; \ |
52 | \ | 52 | \ |
53 | s390pci_store(data, req, ZPCI_OFFSET(addr)); \ | 53 | zpci_store(data, req, ZPCI_OFFSET(addr)); \ |
54 | } | 54 | } |
55 | 55 | ||
56 | zpci_read(8, u64) | 56 | zpci_read(8, u64) |
@@ -83,7 +83,7 @@ static inline int zpci_write_single(u64 req, const u64 *data, u64 offset, u8 len | |||
83 | val = 0; /* let FW report error */ | 83 | val = 0; /* let FW report error */ |
84 | break; | 84 | break; |
85 | } | 85 | } |
86 | return s390pci_store(val, req, offset); | 86 | return zpci_store(val, req, offset); |
87 | } | 87 | } |
88 | 88 | ||
89 | static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) | 89 | static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) |
@@ -91,7 +91,7 @@ static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) | |||
91 | u64 data; | 91 | u64 data; |
92 | int cc; | 92 | int cc; |
93 | 93 | ||
94 | cc = s390pci_load(&data, req, offset); | 94 | cc = zpci_load(&data, req, offset); |
95 | if (cc) | 95 | if (cc) |
96 | goto out; | 96 | goto out; |
97 | 97 | ||
@@ -115,7 +115,7 @@ out: | |||
115 | 115 | ||
116 | static inline int zpci_write_block(u64 req, const u64 *data, u64 offset) | 116 | static inline int zpci_write_block(u64 req, const u64 *data, u64 offset) |
117 | { | 117 | { |
118 | return s390pci_store_block(data, req, offset); | 118 | return zpci_store_block(data, req, offset); |
119 | } | 119 | } |
120 | 120 | ||
121 | static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) | 121 | static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 75fb726de91f..9b60a36c348d 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -217,63 +217,57 @@ extern unsigned long MODULES_END; | |||
217 | 217 | ||
218 | /* Hardware bits in the page table entry */ | 218 | /* Hardware bits in the page table entry */ |
219 | #define _PAGE_CO 0x100 /* HW Change-bit override */ | 219 | #define _PAGE_CO 0x100 /* HW Change-bit override */ |
220 | #define _PAGE_RO 0x200 /* HW read-only bit */ | 220 | #define _PAGE_PROTECT 0x200 /* HW read-only bit */ |
221 | #define _PAGE_INVALID 0x400 /* HW invalid bit */ | 221 | #define _PAGE_INVALID 0x400 /* HW invalid bit */ |
222 | #define _PAGE_LARGE 0x800 /* Bit to mark a large pte */ | ||
222 | 223 | ||
223 | /* Software bits in the page table entry */ | 224 | /* Software bits in the page table entry */ |
224 | #define _PAGE_SWT 0x001 /* SW pte type bit t */ | 225 | #define _PAGE_PRESENT 0x001 /* SW pte present bit */ |
225 | #define _PAGE_SWX 0x002 /* SW pte type bit x */ | 226 | #define _PAGE_TYPE 0x002 /* SW pte type bit */ |
226 | #define _PAGE_SWC 0x004 /* SW pte changed bit */ | 227 | #define _PAGE_YOUNG 0x004 /* SW pte young bit */ |
227 | #define _PAGE_SWR 0x008 /* SW pte referenced bit */ | 228 | #define _PAGE_DIRTY 0x008 /* SW pte dirty bit */ |
228 | #define _PAGE_SWW 0x010 /* SW pte write bit */ | 229 | #define _PAGE_READ 0x010 /* SW pte read bit */ |
229 | #define _PAGE_SPECIAL 0x020 /* SW associated with special page */ | 230 | #define _PAGE_WRITE 0x020 /* SW pte write bit */ |
231 | #define _PAGE_SPECIAL 0x040 /* SW associated with special page */ | ||
230 | #define __HAVE_ARCH_PTE_SPECIAL | 232 | #define __HAVE_ARCH_PTE_SPECIAL |
231 | 233 | ||
232 | /* Set of bits not changed in pte_modify */ | 234 | /* Set of bits not changed in pte_modify */ |
233 | #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL | _PAGE_CO | \ | 235 | #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL | _PAGE_CO | \ |
234 | _PAGE_SWC | _PAGE_SWR) | 236 | _PAGE_DIRTY | _PAGE_YOUNG) |
235 | |||
236 | /* Six different types of pages. */ | ||
237 | #define _PAGE_TYPE_EMPTY 0x400 | ||
238 | #define _PAGE_TYPE_NONE 0x401 | ||
239 | #define _PAGE_TYPE_SWAP 0x403 | ||
240 | #define _PAGE_TYPE_FILE 0x601 /* bit 0x002 is used for offset !! */ | ||
241 | #define _PAGE_TYPE_RO 0x200 | ||
242 | #define _PAGE_TYPE_RW 0x000 | ||
243 | |||
244 | /* | ||
245 | * Only four types for huge pages, using the invalid bit and protection bit | ||
246 | * of a segment table entry. | ||
247 | */ | ||
248 | #define _HPAGE_TYPE_EMPTY 0x020 /* _SEGMENT_ENTRY_INV */ | ||
249 | #define _HPAGE_TYPE_NONE 0x220 | ||
250 | #define _HPAGE_TYPE_RO 0x200 /* _SEGMENT_ENTRY_RO */ | ||
251 | #define _HPAGE_TYPE_RW 0x000 | ||
252 | 237 | ||
253 | /* | 238 | /* |
254 | * PTE type bits are rather complicated. handle_pte_fault uses pte_present, | 239 | * handle_pte_fault uses pte_present, pte_none and pte_file to find out the |
255 | * pte_none and pte_file to find out the pte type WITHOUT holding the page | 240 | * pte type WITHOUT holding the page table lock. The _PAGE_PRESENT bit |
256 | * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to | 241 | * is used to distinguish present from not-present ptes. It is changed only |
257 | * invalidate a given pte. ipte sets the hw invalid bit and clears all tlbs | 242 | * with the page table lock held. |
258 | * for the page. The page table entry is set to _PAGE_TYPE_EMPTY afterwards. | 243 | * |
259 | * This change is done while holding the lock, but the intermediate step | 244 | * The following table gives the different possible bit combinations for |
260 | * of a previously valid pte with the hw invalid bit set can be observed by | 245 | * the pte hardware and software bits in the last 12 bits of a pte: |
261 | * handle_pte_fault. That makes it necessary that all valid pte types with | ||
262 | * the hw invalid bit set must be distinguishable from the four pte types | ||
263 | * empty, none, swap and file. | ||
264 | * | 246 | * |
265 | * irxt ipte irxt | 247 | * 842100000000 |
266 | * _PAGE_TYPE_EMPTY 1000 -> 1000 | 248 | * 000084210000 |
267 | * _PAGE_TYPE_NONE 1001 -> 1001 | 249 | * 000000008421 |
268 | * _PAGE_TYPE_SWAP 1011 -> 1011 | 250 | * .IR...wrdytp |
269 | * _PAGE_TYPE_FILE 11?1 -> 11?1 | 251 | * empty .10...000000 |
270 | * _PAGE_TYPE_RO 0100 -> 1100 | 252 | * swap .10...xxxx10 |
271 | * _PAGE_TYPE_RW 0000 -> 1000 | 253 | * file .11...xxxxx0 |
254 | * prot-none, clean, old .11...000001 | ||
255 | * prot-none, clean, young .11...000101 | ||
256 | * prot-none, dirty, old .10...001001 | ||
257 | * prot-none, dirty, young .10...001101 | ||
258 | * read-only, clean, old .11...010001 | ||
259 | * read-only, clean, young .01...010101 | ||
260 | * read-only, dirty, old .11...011001 | ||
261 | * read-only, dirty, young .01...011101 | ||
262 | * read-write, clean, old .11...110001 | ||
263 | * read-write, clean, young .01...110101 | ||
264 | * read-write, dirty, old .10...111001 | ||
265 | * read-write, dirty, young .00...111101 | ||
272 | * | 266 | * |
273 | * pte_none is true for bits combinations 1000, 1010, 1100, 1110 | 267 | * pte_present is true for the bit pattern .xx...xxxxx1, (pte & 0x001) == 0x001 |
274 | * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001 | 268 | * pte_none is true for the bit pattern .10...xxxx00, (pte & 0x603) == 0x400 |
275 | * pte_file is true for bits combinations 1101, 1111 | 269 | * pte_file is true for the bit pattern .11...xxxxx0, (pte & 0x601) == 0x600 |
276 | * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid. | 270 | * pte_swap is true for the bit pattern .10...xxxx10, (pte & 0x603) == 0x402 |
277 | */ | 271 | */ |
278 | 272 | ||
279 | #ifndef CONFIG_64BIT | 273 | #ifndef CONFIG_64BIT |
@@ -286,14 +280,25 @@ extern unsigned long MODULES_END; | |||
286 | #define _ASCE_TABLE_LENGTH 0x7f /* 128 x 64 entries = 8k */ | 280 | #define _ASCE_TABLE_LENGTH 0x7f /* 128 x 64 entries = 8k */ |
287 | 281 | ||
288 | /* Bits in the segment table entry */ | 282 | /* Bits in the segment table entry */ |
283 | #define _SEGMENT_ENTRY_BITS 0x7fffffffUL /* Valid segment table bits */ | ||
289 | #define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */ | 284 | #define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */ |
290 | #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ | 285 | #define _SEGMENT_ENTRY_PROTECT 0x200 /* page protection bit */ |
291 | #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ | 286 | #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ |
292 | #define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ | 287 | #define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ |
293 | #define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ | 288 | #define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ |
289 | #define _SEGMENT_ENTRY_NONE _SEGMENT_ENTRY_PROTECT | ||
294 | 290 | ||
295 | #define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PTL) | 291 | #define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PTL) |
296 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV) | 292 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) |
293 | |||
294 | /* | ||
295 | * Segment table entry encoding (I = invalid, R = read-only bit): | ||
296 | * ..R...I..... | ||
297 | * prot-none ..1...1..... | ||
298 | * read-only ..1...0..... | ||
299 | * read-write ..0...0..... | ||
300 | * empty ..0...1..... | ||
301 | */ | ||
297 | 302 | ||
298 | /* Page status table bits for virtualization */ | 303 | /* Page status table bits for virtualization */ |
299 | #define PGSTE_ACC_BITS 0xf0000000UL | 304 | #define PGSTE_ACC_BITS 0xf0000000UL |
@@ -303,9 +308,7 @@ extern unsigned long MODULES_END; | |||
303 | #define PGSTE_HC_BIT 0x00200000UL | 308 | #define PGSTE_HC_BIT 0x00200000UL |
304 | #define PGSTE_GR_BIT 0x00040000UL | 309 | #define PGSTE_GR_BIT 0x00040000UL |
305 | #define PGSTE_GC_BIT 0x00020000UL | 310 | #define PGSTE_GC_BIT 0x00020000UL |
306 | #define PGSTE_UR_BIT 0x00008000UL | 311 | #define PGSTE_IN_BIT 0x00008000UL /* IPTE notify bit */ |
307 | #define PGSTE_UC_BIT 0x00004000UL /* user dirty (migration) */ | ||
308 | #define PGSTE_IN_BIT 0x00002000UL /* IPTE notify bit */ | ||
309 | 312 | ||
310 | #else /* CONFIG_64BIT */ | 313 | #else /* CONFIG_64BIT */ |
311 | 314 | ||
@@ -324,8 +327,8 @@ extern unsigned long MODULES_END; | |||
324 | 327 | ||
325 | /* Bits in the region table entry */ | 328 | /* Bits in the region table entry */ |
326 | #define _REGION_ENTRY_ORIGIN ~0xfffUL/* region/segment table origin */ | 329 | #define _REGION_ENTRY_ORIGIN ~0xfffUL/* region/segment table origin */ |
327 | #define _REGION_ENTRY_RO 0x200 /* region protection bit */ | 330 | #define _REGION_ENTRY_PROTECT 0x200 /* region protection bit */ |
328 | #define _REGION_ENTRY_INV 0x20 /* invalid region table entry */ | 331 | #define _REGION_ENTRY_INVALID 0x20 /* invalid region table entry */ |
329 | #define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ | 332 | #define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ |
330 | #define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ | 333 | #define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ |
331 | #define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ | 334 | #define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ |
@@ -333,29 +336,47 @@ extern unsigned long MODULES_END; | |||
333 | #define _REGION_ENTRY_LENGTH 0x03 /* region third length */ | 336 | #define _REGION_ENTRY_LENGTH 0x03 /* region third length */ |
334 | 337 | ||
335 | #define _REGION1_ENTRY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_LENGTH) | 338 | #define _REGION1_ENTRY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_LENGTH) |
336 | #define _REGION1_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INV) | 339 | #define _REGION1_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INVALID) |
337 | #define _REGION2_ENTRY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH) | 340 | #define _REGION2_ENTRY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH) |
338 | #define _REGION2_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INV) | 341 | #define _REGION2_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INVALID) |
339 | #define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH) | 342 | #define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH) |
340 | #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV) | 343 | #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INVALID) |
341 | 344 | ||
342 | #define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */ | 345 | #define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */ |
343 | #define _REGION3_ENTRY_RO 0x200 /* page protection bit */ | 346 | #define _REGION3_ENTRY_RO 0x200 /* page protection bit */ |
344 | #define _REGION3_ENTRY_CO 0x100 /* change-recording override */ | 347 | #define _REGION3_ENTRY_CO 0x100 /* change-recording override */ |
345 | 348 | ||
346 | /* Bits in the segment table entry */ | 349 | /* Bits in the segment table entry */ |
350 | #define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL | ||
351 | #define _SEGMENT_ENTRY_BITS_LARGE 0xfffffffffff1ff33UL | ||
347 | #define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ | 352 | #define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ |
348 | #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ | 353 | #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ |
349 | #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ | 354 | #define _SEGMENT_ENTRY_PROTECT 0x200 /* page protection bit */ |
350 | #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ | 355 | #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ |
351 | 356 | ||
352 | #define _SEGMENT_ENTRY (0) | 357 | #define _SEGMENT_ENTRY (0) |
353 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV) | 358 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) |
354 | 359 | ||
355 | #define _SEGMENT_ENTRY_LARGE 0x400 /* STE-format control, large page */ | 360 | #define _SEGMENT_ENTRY_LARGE 0x400 /* STE-format control, large page */ |
356 | #define _SEGMENT_ENTRY_CO 0x100 /* change-recording override */ | 361 | #define _SEGMENT_ENTRY_CO 0x100 /* change-recording override */ |
362 | #define _SEGMENT_ENTRY_SPLIT 0x001 /* THP splitting bit */ | ||
363 | #define _SEGMENT_ENTRY_YOUNG 0x002 /* SW segment young bit */ | ||
364 | #define _SEGMENT_ENTRY_NONE _SEGMENT_ENTRY_YOUNG | ||
365 | |||
366 | /* | ||
367 | * Segment table entry encoding (R = read-only, I = invalid, y = young bit): | ||
368 | * ..R...I...y. | ||
369 | * prot-none, old ..0...1...1. | ||
370 | * prot-none, young ..1...1...1. | ||
371 | * read-only, old ..1...1...0. | ||
372 | * read-only, young ..1...0...1. | ||
373 | * read-write, old ..0...1...0. | ||
374 | * read-write, young ..0...0...1. | ||
375 | * The segment table origin is used to distinguish empty (origin==0) from | ||
376 | * read-write, old segment table entries (origin!=0) | ||
377 | */ | ||
378 | |||
357 | #define _SEGMENT_ENTRY_SPLIT_BIT 0 /* THP splitting bit number */ | 379 | #define _SEGMENT_ENTRY_SPLIT_BIT 0 /* THP splitting bit number */ |
358 | #define _SEGMENT_ENTRY_SPLIT (1UL << _SEGMENT_ENTRY_SPLIT_BIT) | ||
359 | 380 | ||
360 | /* Set of bits not changed in pmd_modify */ | 381 | /* Set of bits not changed in pmd_modify */ |
361 | #define _SEGMENT_CHG_MASK (_SEGMENT_ENTRY_ORIGIN | _SEGMENT_ENTRY_LARGE \ | 382 | #define _SEGMENT_CHG_MASK (_SEGMENT_ENTRY_ORIGIN | _SEGMENT_ENTRY_LARGE \ |
@@ -369,9 +390,7 @@ extern unsigned long MODULES_END; | |||
369 | #define PGSTE_HC_BIT 0x0020000000000000UL | 390 | #define PGSTE_HC_BIT 0x0020000000000000UL |
370 | #define PGSTE_GR_BIT 0x0004000000000000UL | 391 | #define PGSTE_GR_BIT 0x0004000000000000UL |
371 | #define PGSTE_GC_BIT 0x0002000000000000UL | 392 | #define PGSTE_GC_BIT 0x0002000000000000UL |
372 | #define PGSTE_UR_BIT 0x0000800000000000UL | 393 | #define PGSTE_IN_BIT 0x0000800000000000UL /* IPTE notify bit */ |
373 | #define PGSTE_UC_BIT 0x0000400000000000UL /* user dirty (migration) */ | ||
374 | #define PGSTE_IN_BIT 0x0000200000000000UL /* IPTE notify bit */ | ||
375 | 394 | ||
376 | #endif /* CONFIG_64BIT */ | 395 | #endif /* CONFIG_64BIT */ |
377 | 396 | ||
@@ -386,14 +405,18 @@ extern unsigned long MODULES_END; | |||
386 | /* | 405 | /* |
387 | * Page protection definitions. | 406 | * Page protection definitions. |
388 | */ | 407 | */ |
389 | #define PAGE_NONE __pgprot(_PAGE_TYPE_NONE) | 408 | #define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_INVALID) |
390 | #define PAGE_RO __pgprot(_PAGE_TYPE_RO) | 409 | #define PAGE_READ __pgprot(_PAGE_PRESENT | _PAGE_READ | \ |
391 | #define PAGE_RW __pgprot(_PAGE_TYPE_RO | _PAGE_SWW) | 410 | _PAGE_INVALID | _PAGE_PROTECT) |
392 | #define PAGE_RWC __pgprot(_PAGE_TYPE_RW | _PAGE_SWW | _PAGE_SWC) | 411 | #define PAGE_WRITE __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ |
393 | 412 | _PAGE_INVALID | _PAGE_PROTECT) | |
394 | #define PAGE_KERNEL PAGE_RWC | 413 | |
395 | #define PAGE_SHARED PAGE_KERNEL | 414 | #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ |
396 | #define PAGE_COPY PAGE_RO | 415 | _PAGE_YOUNG | _PAGE_DIRTY) |
416 | #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ | ||
417 | _PAGE_YOUNG | _PAGE_DIRTY) | ||
418 | #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_YOUNG | \ | ||
419 | _PAGE_PROTECT) | ||
397 | 420 | ||
398 | /* | 421 | /* |
399 | * On s390 the page table entry has an invalid bit and a read-only bit. | 422 | * On s390 the page table entry has an invalid bit and a read-only bit. |
@@ -402,35 +425,31 @@ extern unsigned long MODULES_END; | |||
402 | */ | 425 | */ |
403 | /*xwr*/ | 426 | /*xwr*/ |
404 | #define __P000 PAGE_NONE | 427 | #define __P000 PAGE_NONE |
405 | #define __P001 PAGE_RO | 428 | #define __P001 PAGE_READ |
406 | #define __P010 PAGE_RO | 429 | #define __P010 PAGE_READ |
407 | #define __P011 PAGE_RO | 430 | #define __P011 PAGE_READ |
408 | #define __P100 PAGE_RO | 431 | #define __P100 PAGE_READ |
409 | #define __P101 PAGE_RO | 432 | #define __P101 PAGE_READ |
410 | #define __P110 PAGE_RO | 433 | #define __P110 PAGE_READ |
411 | #define __P111 PAGE_RO | 434 | #define __P111 PAGE_READ |
412 | 435 | ||
413 | #define __S000 PAGE_NONE | 436 | #define __S000 PAGE_NONE |
414 | #define __S001 PAGE_RO | 437 | #define __S001 PAGE_READ |
415 | #define __S010 PAGE_RW | 438 | #define __S010 PAGE_WRITE |
416 | #define __S011 PAGE_RW | 439 | #define __S011 PAGE_WRITE |
417 | #define __S100 PAGE_RO | 440 | #define __S100 PAGE_READ |
418 | #define __S101 PAGE_RO | 441 | #define __S101 PAGE_READ |
419 | #define __S110 PAGE_RW | 442 | #define __S110 PAGE_WRITE |
420 | #define __S111 PAGE_RW | 443 | #define __S111 PAGE_WRITE |
421 | 444 | ||
422 | /* | 445 | /* |
423 | * Segment entry (large page) protection definitions. | 446 | * Segment entry (large page) protection definitions. |
424 | */ | 447 | */ |
425 | #define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) | 448 | #define SEGMENT_NONE __pgprot(_SEGMENT_ENTRY_INVALID | \ |
426 | #define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) | 449 | _SEGMENT_ENTRY_NONE) |
427 | #define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) | 450 | #define SEGMENT_READ __pgprot(_SEGMENT_ENTRY_INVALID | \ |
428 | 451 | _SEGMENT_ENTRY_PROTECT) | |
429 | static inline int mm_exclusive(struct mm_struct *mm) | 452 | #define SEGMENT_WRITE __pgprot(_SEGMENT_ENTRY_INVALID) |
430 | { | ||
431 | return likely(mm == current->active_mm && | ||
432 | atomic_read(&mm->context.attach_count) <= 1); | ||
433 | } | ||
434 | 453 | ||
435 | static inline int mm_has_pgste(struct mm_struct *mm) | 454 | static inline int mm_has_pgste(struct mm_struct *mm) |
436 | { | 455 | { |
@@ -467,7 +486,7 @@ static inline int pgd_none(pgd_t pgd) | |||
467 | { | 486 | { |
468 | if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) | 487 | if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) |
469 | return 0; | 488 | return 0; |
470 | return (pgd_val(pgd) & _REGION_ENTRY_INV) != 0UL; | 489 | return (pgd_val(pgd) & _REGION_ENTRY_INVALID) != 0UL; |
471 | } | 490 | } |
472 | 491 | ||
473 | static inline int pgd_bad(pgd_t pgd) | 492 | static inline int pgd_bad(pgd_t pgd) |
@@ -478,7 +497,7 @@ static inline int pgd_bad(pgd_t pgd) | |||
478 | * invalid for either table entry. | 497 | * invalid for either table entry. |
479 | */ | 498 | */ |
480 | unsigned long mask = | 499 | unsigned long mask = |
481 | ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV & | 500 | ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INVALID & |
482 | ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; | 501 | ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; |
483 | return (pgd_val(pgd) & mask) != 0; | 502 | return (pgd_val(pgd) & mask) != 0; |
484 | } | 503 | } |
@@ -494,7 +513,7 @@ static inline int pud_none(pud_t pud) | |||
494 | { | 513 | { |
495 | if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) | 514 | if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) |
496 | return 0; | 515 | return 0; |
497 | return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; | 516 | return (pud_val(pud) & _REGION_ENTRY_INVALID) != 0UL; |
498 | } | 517 | } |
499 | 518 | ||
500 | static inline int pud_large(pud_t pud) | 519 | static inline int pud_large(pud_t pud) |
@@ -512,7 +531,7 @@ static inline int pud_bad(pud_t pud) | |||
512 | * invalid for either table entry. | 531 | * invalid for either table entry. |
513 | */ | 532 | */ |
514 | unsigned long mask = | 533 | unsigned long mask = |
515 | ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV & | 534 | ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INVALID & |
516 | ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; | 535 | ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; |
517 | return (pud_val(pud) & mask) != 0; | 536 | return (pud_val(pud) & mask) != 0; |
518 | } | 537 | } |
@@ -521,30 +540,36 @@ static inline int pud_bad(pud_t pud) | |||
521 | 540 | ||
522 | static inline int pmd_present(pmd_t pmd) | 541 | static inline int pmd_present(pmd_t pmd) |
523 | { | 542 | { |
524 | unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; | 543 | return pmd_val(pmd) != _SEGMENT_ENTRY_INVALID; |
525 | return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || | ||
526 | !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); | ||
527 | } | 544 | } |
528 | 545 | ||
529 | static inline int pmd_none(pmd_t pmd) | 546 | static inline int pmd_none(pmd_t pmd) |
530 | { | 547 | { |
531 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && | 548 | return pmd_val(pmd) == _SEGMENT_ENTRY_INVALID; |
532 | !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); | ||
533 | } | 549 | } |
534 | 550 | ||
535 | static inline int pmd_large(pmd_t pmd) | 551 | static inline int pmd_large(pmd_t pmd) |
536 | { | 552 | { |
537 | #ifdef CONFIG_64BIT | 553 | #ifdef CONFIG_64BIT |
538 | return !!(pmd_val(pmd) & _SEGMENT_ENTRY_LARGE); | 554 | return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0; |
539 | #else | 555 | #else |
540 | return 0; | 556 | return 0; |
541 | #endif | 557 | #endif |
542 | } | 558 | } |
543 | 559 | ||
560 | static inline int pmd_prot_none(pmd_t pmd) | ||
561 | { | ||
562 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INVALID) && | ||
563 | (pmd_val(pmd) & _SEGMENT_ENTRY_NONE); | ||
564 | } | ||
565 | |||
544 | static inline int pmd_bad(pmd_t pmd) | 566 | static inline int pmd_bad(pmd_t pmd) |
545 | { | 567 | { |
546 | unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV; | 568 | #ifdef CONFIG_64BIT |
547 | return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY; | 569 | if (pmd_large(pmd)) |
570 | return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS_LARGE) != 0; | ||
571 | #endif | ||
572 | return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS) != 0; | ||
548 | } | 573 | } |
549 | 574 | ||
550 | #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH | 575 | #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH |
@@ -563,31 +588,40 @@ extern int pmdp_clear_flush_young(struct vm_area_struct *vma, | |||
563 | #define __HAVE_ARCH_PMD_WRITE | 588 | #define __HAVE_ARCH_PMD_WRITE |
564 | static inline int pmd_write(pmd_t pmd) | 589 | static inline int pmd_write(pmd_t pmd) |
565 | { | 590 | { |
566 | return (pmd_val(pmd) & _SEGMENT_ENTRY_RO) == 0; | 591 | if (pmd_prot_none(pmd)) |
592 | return 0; | ||
593 | return (pmd_val(pmd) & _SEGMENT_ENTRY_PROTECT) == 0; | ||
567 | } | 594 | } |
568 | 595 | ||
569 | static inline int pmd_young(pmd_t pmd) | 596 | static inline int pmd_young(pmd_t pmd) |
570 | { | 597 | { |
571 | return 0; | 598 | int young = 0; |
599 | #ifdef CONFIG_64BIT | ||
600 | if (pmd_prot_none(pmd)) | ||
601 | young = (pmd_val(pmd) & _SEGMENT_ENTRY_PROTECT) != 0; | ||
602 | else | ||
603 | young = (pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG) != 0; | ||
604 | #endif | ||
605 | return young; | ||
572 | } | 606 | } |
573 | 607 | ||
574 | static inline int pte_none(pte_t pte) | 608 | static inline int pte_present(pte_t pte) |
575 | { | 609 | { |
576 | return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT); | 610 | /* Bit pattern: (pte & 0x001) == 0x001 */ |
611 | return (pte_val(pte) & _PAGE_PRESENT) != 0; | ||
577 | } | 612 | } |
578 | 613 | ||
579 | static inline int pte_present(pte_t pte) | 614 | static inline int pte_none(pte_t pte) |
580 | { | 615 | { |
581 | unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT | _PAGE_SWX; | 616 | /* Bit pattern: pte == 0x400 */ |
582 | return (pte_val(pte) & mask) == _PAGE_TYPE_NONE || | 617 | return pte_val(pte) == _PAGE_INVALID; |
583 | (!(pte_val(pte) & _PAGE_INVALID) && | ||
584 | !(pte_val(pte) & _PAGE_SWT)); | ||
585 | } | 618 | } |
586 | 619 | ||
587 | static inline int pte_file(pte_t pte) | 620 | static inline int pte_file(pte_t pte) |
588 | { | 621 | { |
589 | unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT; | 622 | /* Bit pattern: (pte & 0x601) == 0x600 */ |
590 | return (pte_val(pte) & mask) == _PAGE_TYPE_FILE; | 623 | return (pte_val(pte) & (_PAGE_INVALID | _PAGE_PROTECT | _PAGE_PRESENT)) |
624 | == (_PAGE_INVALID | _PAGE_PROTECT); | ||
591 | } | 625 | } |
592 | 626 | ||
593 | static inline int pte_special(pte_t pte) | 627 | static inline int pte_special(pte_t pte) |
@@ -634,6 +668,15 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) | |||
634 | #endif | 668 | #endif |
635 | } | 669 | } |
636 | 670 | ||
671 | static inline pgste_t pgste_get(pte_t *ptep) | ||
672 | { | ||
673 | unsigned long pgste = 0; | ||
674 | #ifdef CONFIG_PGSTE | ||
675 | pgste = *(unsigned long *)(ptep + PTRS_PER_PTE); | ||
676 | #endif | ||
677 | return __pgste(pgste); | ||
678 | } | ||
679 | |||
637 | static inline void pgste_set(pte_t *ptep, pgste_t pgste) | 680 | static inline void pgste_set(pte_t *ptep, pgste_t pgste) |
638 | { | 681 | { |
639 | #ifdef CONFIG_PGSTE | 682 | #ifdef CONFIG_PGSTE |
@@ -644,33 +687,28 @@ static inline void pgste_set(pte_t *ptep, pgste_t pgste) | |||
644 | static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) | 687 | static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) |
645 | { | 688 | { |
646 | #ifdef CONFIG_PGSTE | 689 | #ifdef CONFIG_PGSTE |
647 | unsigned long address, bits; | 690 | unsigned long address, bits, skey; |
648 | unsigned char skey; | ||
649 | 691 | ||
650 | if (pte_val(*ptep) & _PAGE_INVALID) | 692 | if (pte_val(*ptep) & _PAGE_INVALID) |
651 | return pgste; | 693 | return pgste; |
652 | address = pte_val(*ptep) & PAGE_MASK; | 694 | address = pte_val(*ptep) & PAGE_MASK; |
653 | skey = page_get_storage_key(address); | 695 | skey = (unsigned long) page_get_storage_key(address); |
654 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); | 696 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); |
655 | /* Clear page changed & referenced bit in the storage key */ | 697 | if (!(pgste_val(pgste) & PGSTE_HC_BIT) && (bits & _PAGE_CHANGED)) { |
656 | if (bits & _PAGE_CHANGED) | 698 | /* Transfer dirty + referenced bit to host bits in pgste */ |
699 | pgste_val(pgste) |= bits << 52; | ||
657 | page_set_storage_key(address, skey ^ bits, 0); | 700 | page_set_storage_key(address, skey ^ bits, 0); |
658 | else if (bits) | 701 | } else if (!(pgste_val(pgste) & PGSTE_HR_BIT) && |
702 | (bits & _PAGE_REFERENCED)) { | ||
703 | /* Transfer referenced bit to host bit in pgste */ | ||
704 | pgste_val(pgste) |= PGSTE_HR_BIT; | ||
659 | page_reset_referenced(address); | 705 | page_reset_referenced(address); |
706 | } | ||
660 | /* Transfer page changed & referenced bit to guest bits in pgste */ | 707 | /* Transfer page changed & referenced bit to guest bits in pgste */ |
661 | pgste_val(pgste) |= bits << 48; /* GR bit & GC bit */ | 708 | pgste_val(pgste) |= bits << 48; /* GR bit & GC bit */ |
662 | /* Get host changed & referenced bits from pgste */ | ||
663 | bits |= (pgste_val(pgste) & (PGSTE_HR_BIT | PGSTE_HC_BIT)) >> 52; | ||
664 | /* Transfer page changed & referenced bit to kvm user bits */ | ||
665 | pgste_val(pgste) |= bits << 45; /* PGSTE_UR_BIT & PGSTE_UC_BIT */ | ||
666 | /* Clear relevant host bits in pgste. */ | ||
667 | pgste_val(pgste) &= ~(PGSTE_HR_BIT | PGSTE_HC_BIT); | ||
668 | pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT); | ||
669 | /* Copy page access key and fetch protection bit to pgste */ | 709 | /* Copy page access key and fetch protection bit to pgste */ |
670 | pgste_val(pgste) |= | 710 | pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT); |
671 | (unsigned long) (skey & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56; | 711 | pgste_val(pgste) |= (skey & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56; |
672 | /* Transfer referenced bit to pte */ | ||
673 | pte_val(*ptep) |= (bits & _PAGE_REFERENCED) << 1; | ||
674 | #endif | 712 | #endif |
675 | return pgste; | 713 | return pgste; |
676 | 714 | ||
@@ -679,24 +717,11 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) | |||
679 | static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste) | 717 | static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste) |
680 | { | 718 | { |
681 | #ifdef CONFIG_PGSTE | 719 | #ifdef CONFIG_PGSTE |
682 | int young; | ||
683 | |||
684 | if (pte_val(*ptep) & _PAGE_INVALID) | 720 | if (pte_val(*ptep) & _PAGE_INVALID) |
685 | return pgste; | 721 | return pgste; |
686 | /* Get referenced bit from storage key */ | 722 | /* Get referenced bit from storage key */ |
687 | young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK); | 723 | if (page_reset_referenced(pte_val(*ptep) & PAGE_MASK)) |
688 | if (young) | 724 | pgste_val(pgste) |= PGSTE_HR_BIT | PGSTE_GR_BIT; |
689 | pgste_val(pgste) |= PGSTE_GR_BIT; | ||
690 | /* Get host referenced bit from pgste */ | ||
691 | if (pgste_val(pgste) & PGSTE_HR_BIT) { | ||
692 | pgste_val(pgste) &= ~PGSTE_HR_BIT; | ||
693 | young = 1; | ||
694 | } | ||
695 | /* Transfer referenced bit to kvm user bits and pte */ | ||
696 | if (young) { | ||
697 | pgste_val(pgste) |= PGSTE_UR_BIT; | ||
698 | pte_val(*ptep) |= _PAGE_SWR; | ||
699 | } | ||
700 | #endif | 725 | #endif |
701 | return pgste; | 726 | return pgste; |
702 | } | 727 | } |
@@ -723,13 +748,13 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry) | |||
723 | 748 | ||
724 | static inline void pgste_set_pte(pte_t *ptep, pte_t entry) | 749 | static inline void pgste_set_pte(pte_t *ptep, pte_t entry) |
725 | { | 750 | { |
726 | if (!MACHINE_HAS_ESOP && (pte_val(entry) & _PAGE_SWW)) { | 751 | if (!MACHINE_HAS_ESOP && (pte_val(entry) & _PAGE_WRITE)) { |
727 | /* | 752 | /* |
728 | * Without enhanced suppression-on-protection force | 753 | * Without enhanced suppression-on-protection force |
729 | * the dirty bit on for all writable ptes. | 754 | * the dirty bit on for all writable ptes. |
730 | */ | 755 | */ |
731 | pte_val(entry) |= _PAGE_SWC; | 756 | pte_val(entry) |= _PAGE_DIRTY; |
732 | pte_val(entry) &= ~_PAGE_RO; | 757 | pte_val(entry) &= ~_PAGE_PROTECT; |
733 | } | 758 | } |
734 | *ptep = entry; | 759 | *ptep = entry; |
735 | } | 760 | } |
@@ -841,21 +866,17 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
841 | */ | 866 | */ |
842 | static inline int pte_write(pte_t pte) | 867 | static inline int pte_write(pte_t pte) |
843 | { | 868 | { |
844 | return (pte_val(pte) & _PAGE_SWW) != 0; | 869 | return (pte_val(pte) & _PAGE_WRITE) != 0; |
845 | } | 870 | } |
846 | 871 | ||
847 | static inline int pte_dirty(pte_t pte) | 872 | static inline int pte_dirty(pte_t pte) |
848 | { | 873 | { |
849 | return (pte_val(pte) & _PAGE_SWC) != 0; | 874 | return (pte_val(pte) & _PAGE_DIRTY) != 0; |
850 | } | 875 | } |
851 | 876 | ||
852 | static inline int pte_young(pte_t pte) | 877 | static inline int pte_young(pte_t pte) |
853 | { | 878 | { |
854 | #ifdef CONFIG_PGSTE | 879 | return (pte_val(pte) & _PAGE_YOUNG) != 0; |
855 | if (pte_val(pte) & _PAGE_SWR) | ||
856 | return 1; | ||
857 | #endif | ||
858 | return 0; | ||
859 | } | 880 | } |
860 | 881 | ||
861 | /* | 882 | /* |
@@ -880,12 +901,12 @@ static inline void pud_clear(pud_t *pud) | |||
880 | 901 | ||
881 | static inline void pmd_clear(pmd_t *pmdp) | 902 | static inline void pmd_clear(pmd_t *pmdp) |
882 | { | 903 | { |
883 | pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY; | 904 | pmd_val(*pmdp) = _SEGMENT_ENTRY_INVALID; |
884 | } | 905 | } |
885 | 906 | ||
886 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 907 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
887 | { | 908 | { |
888 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | 909 | pte_val(*ptep) = _PAGE_INVALID; |
889 | } | 910 | } |
890 | 911 | ||
891 | /* | 912 | /* |
@@ -896,55 +917,63 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
896 | { | 917 | { |
897 | pte_val(pte) &= _PAGE_CHG_MASK; | 918 | pte_val(pte) &= _PAGE_CHG_MASK; |
898 | pte_val(pte) |= pgprot_val(newprot); | 919 | pte_val(pte) |= pgprot_val(newprot); |
899 | if ((pte_val(pte) & _PAGE_SWC) && (pte_val(pte) & _PAGE_SWW)) | 920 | /* |
900 | pte_val(pte) &= ~_PAGE_RO; | 921 | * newprot for PAGE_NONE, PAGE_READ and PAGE_WRITE has the |
922 | * invalid bit set, clear it again for readable, young pages | ||
923 | */ | ||
924 | if ((pte_val(pte) & _PAGE_YOUNG) && (pte_val(pte) & _PAGE_READ)) | ||
925 | pte_val(pte) &= ~_PAGE_INVALID; | ||
926 | /* | ||
927 | * newprot for PAGE_READ and PAGE_WRITE has the page protection | ||
928 | * bit set, clear it again for writable, dirty pages | ||
929 | */ | ||
930 | if ((pte_val(pte) & _PAGE_DIRTY) && (pte_val(pte) & _PAGE_WRITE)) | ||
931 | pte_val(pte) &= ~_PAGE_PROTECT; | ||
901 | return pte; | 932 | return pte; |
902 | } | 933 | } |
903 | 934 | ||
904 | static inline pte_t pte_wrprotect(pte_t pte) | 935 | static inline pte_t pte_wrprotect(pte_t pte) |
905 | { | 936 | { |
906 | pte_val(pte) &= ~_PAGE_SWW; | 937 | pte_val(pte) &= ~_PAGE_WRITE; |
907 | /* Do not clobber _PAGE_TYPE_NONE pages! */ | 938 | pte_val(pte) |= _PAGE_PROTECT; |
908 | if (!(pte_val(pte) & _PAGE_INVALID)) | ||
909 | pte_val(pte) |= _PAGE_RO; | ||
910 | return pte; | 939 | return pte; |
911 | } | 940 | } |
912 | 941 | ||
913 | static inline pte_t pte_mkwrite(pte_t pte) | 942 | static inline pte_t pte_mkwrite(pte_t pte) |
914 | { | 943 | { |
915 | pte_val(pte) |= _PAGE_SWW; | 944 | pte_val(pte) |= _PAGE_WRITE; |
916 | if (pte_val(pte) & _PAGE_SWC) | 945 | if (pte_val(pte) & _PAGE_DIRTY) |
917 | pte_val(pte) &= ~_PAGE_RO; | 946 | pte_val(pte) &= ~_PAGE_PROTECT; |
918 | return pte; | 947 | return pte; |
919 | } | 948 | } |
920 | 949 | ||
921 | static inline pte_t pte_mkclean(pte_t pte) | 950 | static inline pte_t pte_mkclean(pte_t pte) |
922 | { | 951 | { |
923 | pte_val(pte) &= ~_PAGE_SWC; | 952 | pte_val(pte) &= ~_PAGE_DIRTY; |
924 | /* Do not clobber _PAGE_TYPE_NONE pages! */ | 953 | pte_val(pte) |= _PAGE_PROTECT; |
925 | if (!(pte_val(pte) & _PAGE_INVALID)) | ||
926 | pte_val(pte) |= _PAGE_RO; | ||
927 | return pte; | 954 | return pte; |
928 | } | 955 | } |
929 | 956 | ||
930 | static inline pte_t pte_mkdirty(pte_t pte) | 957 | static inline pte_t pte_mkdirty(pte_t pte) |
931 | { | 958 | { |
932 | pte_val(pte) |= _PAGE_SWC; | 959 | pte_val(pte) |= _PAGE_DIRTY; |
933 | if (pte_val(pte) & _PAGE_SWW) | 960 | if (pte_val(pte) & _PAGE_WRITE) |
934 | pte_val(pte) &= ~_PAGE_RO; | 961 | pte_val(pte) &= ~_PAGE_PROTECT; |
935 | return pte; | 962 | return pte; |
936 | } | 963 | } |
937 | 964 | ||
938 | static inline pte_t pte_mkold(pte_t pte) | 965 | static inline pte_t pte_mkold(pte_t pte) |
939 | { | 966 | { |
940 | #ifdef CONFIG_PGSTE | 967 | pte_val(pte) &= ~_PAGE_YOUNG; |
941 | pte_val(pte) &= ~_PAGE_SWR; | 968 | pte_val(pte) |= _PAGE_INVALID; |
942 | #endif | ||
943 | return pte; | 969 | return pte; |
944 | } | 970 | } |
945 | 971 | ||
946 | static inline pte_t pte_mkyoung(pte_t pte) | 972 | static inline pte_t pte_mkyoung(pte_t pte) |
947 | { | 973 | { |
974 | pte_val(pte) |= _PAGE_YOUNG; | ||
975 | if (pte_val(pte) & _PAGE_READ) | ||
976 | pte_val(pte) &= ~_PAGE_INVALID; | ||
948 | return pte; | 977 | return pte; |
949 | } | 978 | } |
950 | 979 | ||
@@ -957,7 +986,7 @@ static inline pte_t pte_mkspecial(pte_t pte) | |||
957 | #ifdef CONFIG_HUGETLB_PAGE | 986 | #ifdef CONFIG_HUGETLB_PAGE |
958 | static inline pte_t pte_mkhuge(pte_t pte) | 987 | static inline pte_t pte_mkhuge(pte_t pte) |
959 | { | 988 | { |
960 | pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO); | 989 | pte_val(pte) |= _PAGE_LARGE; |
961 | return pte; | 990 | return pte; |
962 | } | 991 | } |
963 | #endif | 992 | #endif |
@@ -974,8 +1003,8 @@ static inline int ptep_test_and_clear_user_dirty(struct mm_struct *mm, | |||
974 | if (mm_has_pgste(mm)) { | 1003 | if (mm_has_pgste(mm)) { |
975 | pgste = pgste_get_lock(ptep); | 1004 | pgste = pgste_get_lock(ptep); |
976 | pgste = pgste_update_all(ptep, pgste); | 1005 | pgste = pgste_update_all(ptep, pgste); |
977 | dirty = !!(pgste_val(pgste) & PGSTE_UC_BIT); | 1006 | dirty = !!(pgste_val(pgste) & PGSTE_HC_BIT); |
978 | pgste_val(pgste) &= ~PGSTE_UC_BIT; | 1007 | pgste_val(pgste) &= ~PGSTE_HC_BIT; |
979 | pgste_set_unlock(ptep, pgste); | 1008 | pgste_set_unlock(ptep, pgste); |
980 | return dirty; | 1009 | return dirty; |
981 | } | 1010 | } |
@@ -994,59 +1023,75 @@ static inline int ptep_test_and_clear_user_young(struct mm_struct *mm, | |||
994 | if (mm_has_pgste(mm)) { | 1023 | if (mm_has_pgste(mm)) { |
995 | pgste = pgste_get_lock(ptep); | 1024 | pgste = pgste_get_lock(ptep); |
996 | pgste = pgste_update_young(ptep, pgste); | 1025 | pgste = pgste_update_young(ptep, pgste); |
997 | young = !!(pgste_val(pgste) & PGSTE_UR_BIT); | 1026 | young = !!(pgste_val(pgste) & PGSTE_HR_BIT); |
998 | pgste_val(pgste) &= ~PGSTE_UR_BIT; | 1027 | pgste_val(pgste) &= ~PGSTE_HR_BIT; |
999 | pgste_set_unlock(ptep, pgste); | 1028 | pgste_set_unlock(ptep, pgste); |
1000 | } | 1029 | } |
1001 | return young; | 1030 | return young; |
1002 | } | 1031 | } |
1003 | 1032 | ||
1033 | static inline void __ptep_ipte(unsigned long address, pte_t *ptep) | ||
1034 | { | ||
1035 | if (!(pte_val(*ptep) & _PAGE_INVALID)) { | ||
1036 | #ifndef CONFIG_64BIT | ||
1037 | /* pto must point to the start of the segment table */ | ||
1038 | pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); | ||
1039 | #else | ||
1040 | /* ipte in zarch mode can do the math */ | ||
1041 | pte_t *pto = ptep; | ||
1042 | #endif | ||
1043 | asm volatile( | ||
1044 | " ipte %2,%3" | ||
1045 | : "=m" (*ptep) : "m" (*ptep), | ||
1046 | "a" (pto), "a" (address)); | ||
1047 | } | ||
1048 | } | ||
1049 | |||
1050 | static inline void ptep_flush_lazy(struct mm_struct *mm, | ||
1051 | unsigned long address, pte_t *ptep) | ||
1052 | { | ||
1053 | int active = (mm == current->active_mm) ? 1 : 0; | ||
1054 | |||
1055 | if (atomic_read(&mm->context.attach_count) > active) | ||
1056 | __ptep_ipte(address, ptep); | ||
1057 | else | ||
1058 | mm->context.flush_mm = 1; | ||
1059 | } | ||
1060 | |||
1004 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | 1061 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG |
1005 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, | 1062 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, |
1006 | unsigned long addr, pte_t *ptep) | 1063 | unsigned long addr, pte_t *ptep) |
1007 | { | 1064 | { |
1008 | pgste_t pgste; | 1065 | pgste_t pgste; |
1009 | pte_t pte; | 1066 | pte_t pte; |
1067 | int young; | ||
1010 | 1068 | ||
1011 | if (mm_has_pgste(vma->vm_mm)) { | 1069 | if (mm_has_pgste(vma->vm_mm)) { |
1012 | pgste = pgste_get_lock(ptep); | 1070 | pgste = pgste_get_lock(ptep); |
1013 | pgste = pgste_update_young(ptep, pgste); | 1071 | pgste = pgste_ipte_notify(vma->vm_mm, addr, ptep, pgste); |
1014 | pte = *ptep; | ||
1015 | *ptep = pte_mkold(pte); | ||
1016 | pgste_set_unlock(ptep, pgste); | ||
1017 | return pte_young(pte); | ||
1018 | } | 1072 | } |
1019 | return 0; | 1073 | |
1074 | pte = *ptep; | ||
1075 | __ptep_ipte(addr, ptep); | ||
1076 | young = pte_young(pte); | ||
1077 | pte = pte_mkold(pte); | ||
1078 | |||
1079 | if (mm_has_pgste(vma->vm_mm)) { | ||
1080 | pgste_set_pte(ptep, pte); | ||
1081 | pgste_set_unlock(ptep, pgste); | ||
1082 | } else | ||
1083 | *ptep = pte; | ||
1084 | |||
1085 | return young; | ||
1020 | } | 1086 | } |
1021 | 1087 | ||
1022 | #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH | 1088 | #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH |
1023 | static inline int ptep_clear_flush_young(struct vm_area_struct *vma, | 1089 | static inline int ptep_clear_flush_young(struct vm_area_struct *vma, |
1024 | unsigned long address, pte_t *ptep) | 1090 | unsigned long address, pte_t *ptep) |
1025 | { | 1091 | { |
1026 | /* No need to flush TLB | ||
1027 | * On s390 reference bits are in storage key and never in TLB | ||
1028 | * With virtualization we handle the reference bit, without we | ||
1029 | * we can simply return */ | ||
1030 | return ptep_test_and_clear_young(vma, address, ptep); | 1092 | return ptep_test_and_clear_young(vma, address, ptep); |
1031 | } | 1093 | } |
1032 | 1094 | ||
1033 | static inline void __ptep_ipte(unsigned long address, pte_t *ptep) | ||
1034 | { | ||
1035 | if (!(pte_val(*ptep) & _PAGE_INVALID)) { | ||
1036 | #ifndef CONFIG_64BIT | ||
1037 | /* pto must point to the start of the segment table */ | ||
1038 | pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); | ||
1039 | #else | ||
1040 | /* ipte in zarch mode can do the math */ | ||
1041 | pte_t *pto = ptep; | ||
1042 | #endif | ||
1043 | asm volatile( | ||
1044 | " ipte %2,%3" | ||
1045 | : "=m" (*ptep) : "m" (*ptep), | ||
1046 | "a" (pto), "a" (address)); | ||
1047 | } | ||
1048 | } | ||
1049 | |||
1050 | /* | 1095 | /* |
1051 | * This is hard to understand. ptep_get_and_clear and ptep_clear_flush | 1096 | * This is hard to understand. ptep_get_and_clear and ptep_clear_flush |
1052 | * both clear the TLB for the unmapped pte. The reason is that | 1097 | * both clear the TLB for the unmapped pte. The reason is that |
@@ -1067,16 +1112,14 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, | |||
1067 | pgste_t pgste; | 1112 | pgste_t pgste; |
1068 | pte_t pte; | 1113 | pte_t pte; |
1069 | 1114 | ||
1070 | mm->context.flush_mm = 1; | ||
1071 | if (mm_has_pgste(mm)) { | 1115 | if (mm_has_pgste(mm)) { |
1072 | pgste = pgste_get_lock(ptep); | 1116 | pgste = pgste_get_lock(ptep); |
1073 | pgste = pgste_ipte_notify(mm, address, ptep, pgste); | 1117 | pgste = pgste_ipte_notify(mm, address, ptep, pgste); |
1074 | } | 1118 | } |
1075 | 1119 | ||
1076 | pte = *ptep; | 1120 | pte = *ptep; |
1077 | if (!mm_exclusive(mm)) | 1121 | ptep_flush_lazy(mm, address, ptep); |
1078 | __ptep_ipte(address, ptep); | 1122 | pte_val(*ptep) = _PAGE_INVALID; |
1079 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | ||
1080 | 1123 | ||
1081 | if (mm_has_pgste(mm)) { | 1124 | if (mm_has_pgste(mm)) { |
1082 | pgste = pgste_update_all(&pte, pgste); | 1125 | pgste = pgste_update_all(&pte, pgste); |
@@ -1093,15 +1136,14 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, | |||
1093 | pgste_t pgste; | 1136 | pgste_t pgste; |
1094 | pte_t pte; | 1137 | pte_t pte; |
1095 | 1138 | ||
1096 | mm->context.flush_mm = 1; | ||
1097 | if (mm_has_pgste(mm)) { | 1139 | if (mm_has_pgste(mm)) { |
1098 | pgste = pgste_get_lock(ptep); | 1140 | pgste = pgste_get_lock(ptep); |
1099 | pgste_ipte_notify(mm, address, ptep, pgste); | 1141 | pgste_ipte_notify(mm, address, ptep, pgste); |
1100 | } | 1142 | } |
1101 | 1143 | ||
1102 | pte = *ptep; | 1144 | pte = *ptep; |
1103 | if (!mm_exclusive(mm)) | 1145 | ptep_flush_lazy(mm, address, ptep); |
1104 | __ptep_ipte(address, ptep); | 1146 | pte_val(*ptep) |= _PAGE_INVALID; |
1105 | 1147 | ||
1106 | if (mm_has_pgste(mm)) { | 1148 | if (mm_has_pgste(mm)) { |
1107 | pgste = pgste_update_all(&pte, pgste); | 1149 | pgste = pgste_update_all(&pte, pgste); |
@@ -1117,7 +1159,7 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm, | |||
1117 | pgste_t pgste; | 1159 | pgste_t pgste; |
1118 | 1160 | ||
1119 | if (mm_has_pgste(mm)) { | 1161 | if (mm_has_pgste(mm)) { |
1120 | pgste = *(pgste_t *)(ptep + PTRS_PER_PTE); | 1162 | pgste = pgste_get(ptep); |
1121 | pgste_set_key(ptep, pgste, pte); | 1163 | pgste_set_key(ptep, pgste, pte); |
1122 | pgste_set_pte(ptep, pte); | 1164 | pgste_set_pte(ptep, pte); |
1123 | pgste_set_unlock(ptep, pgste); | 1165 | pgste_set_unlock(ptep, pgste); |
@@ -1139,7 +1181,7 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma, | |||
1139 | 1181 | ||
1140 | pte = *ptep; | 1182 | pte = *ptep; |
1141 | __ptep_ipte(address, ptep); | 1183 | __ptep_ipte(address, ptep); |
1142 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | 1184 | pte_val(*ptep) = _PAGE_INVALID; |
1143 | 1185 | ||
1144 | if (mm_has_pgste(vma->vm_mm)) { | 1186 | if (mm_has_pgste(vma->vm_mm)) { |
1145 | pgste = pgste_update_all(&pte, pgste); | 1187 | pgste = pgste_update_all(&pte, pgste); |
@@ -1163,18 +1205,17 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, | |||
1163 | pgste_t pgste; | 1205 | pgste_t pgste; |
1164 | pte_t pte; | 1206 | pte_t pte; |
1165 | 1207 | ||
1166 | if (mm_has_pgste(mm)) { | 1208 | if (!full && mm_has_pgste(mm)) { |
1167 | pgste = pgste_get_lock(ptep); | 1209 | pgste = pgste_get_lock(ptep); |
1168 | if (!full) | 1210 | pgste = pgste_ipte_notify(mm, address, ptep, pgste); |
1169 | pgste = pgste_ipte_notify(mm, address, ptep, pgste); | ||
1170 | } | 1211 | } |
1171 | 1212 | ||
1172 | pte = *ptep; | 1213 | pte = *ptep; |
1173 | if (!full) | 1214 | if (!full) |
1174 | __ptep_ipte(address, ptep); | 1215 | ptep_flush_lazy(mm, address, ptep); |
1175 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | 1216 | pte_val(*ptep) = _PAGE_INVALID; |
1176 | 1217 | ||
1177 | if (mm_has_pgste(mm)) { | 1218 | if (!full && mm_has_pgste(mm)) { |
1178 | pgste = pgste_update_all(&pte, pgste); | 1219 | pgste = pgste_update_all(&pte, pgste); |
1179 | pgste_set_unlock(ptep, pgste); | 1220 | pgste_set_unlock(ptep, pgste); |
1180 | } | 1221 | } |
@@ -1189,14 +1230,12 @@ static inline pte_t ptep_set_wrprotect(struct mm_struct *mm, | |||
1189 | pte_t pte = *ptep; | 1230 | pte_t pte = *ptep; |
1190 | 1231 | ||
1191 | if (pte_write(pte)) { | 1232 | if (pte_write(pte)) { |
1192 | mm->context.flush_mm = 1; | ||
1193 | if (mm_has_pgste(mm)) { | 1233 | if (mm_has_pgste(mm)) { |
1194 | pgste = pgste_get_lock(ptep); | 1234 | pgste = pgste_get_lock(ptep); |
1195 | pgste = pgste_ipte_notify(mm, address, ptep, pgste); | 1235 | pgste = pgste_ipte_notify(mm, address, ptep, pgste); |
1196 | } | 1236 | } |
1197 | 1237 | ||
1198 | if (!mm_exclusive(mm)) | 1238 | ptep_flush_lazy(mm, address, ptep); |
1199 | __ptep_ipte(address, ptep); | ||
1200 | pte = pte_wrprotect(pte); | 1239 | pte = pte_wrprotect(pte); |
1201 | 1240 | ||
1202 | if (mm_has_pgste(mm)) { | 1241 | if (mm_has_pgste(mm)) { |
@@ -1240,7 +1279,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) | |||
1240 | { | 1279 | { |
1241 | pte_t __pte; | 1280 | pte_t __pte; |
1242 | pte_val(__pte) = physpage + pgprot_val(pgprot); | 1281 | pte_val(__pte) = physpage + pgprot_val(pgprot); |
1243 | return __pte; | 1282 | return pte_mkyoung(__pte); |
1244 | } | 1283 | } |
1245 | 1284 | ||
1246 | static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) | 1285 | static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) |
@@ -1248,10 +1287,8 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) | |||
1248 | unsigned long physpage = page_to_phys(page); | 1287 | unsigned long physpage = page_to_phys(page); |
1249 | pte_t __pte = mk_pte_phys(physpage, pgprot); | 1288 | pte_t __pte = mk_pte_phys(physpage, pgprot); |
1250 | 1289 | ||
1251 | if ((pte_val(__pte) & _PAGE_SWW) && PageDirty(page)) { | 1290 | if (pte_write(__pte) && PageDirty(page)) |
1252 | pte_val(__pte) |= _PAGE_SWC; | 1291 | __pte = pte_mkdirty(__pte); |
1253 | pte_val(__pte) &= ~_PAGE_RO; | ||
1254 | } | ||
1255 | return __pte; | 1292 | return __pte; |
1256 | } | 1293 | } |
1257 | 1294 | ||
@@ -1313,7 +1350,7 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) | |||
1313 | unsigned long sto = (unsigned long) pmdp - | 1350 | unsigned long sto = (unsigned long) pmdp - |
1314 | pmd_index(address) * sizeof(pmd_t); | 1351 | pmd_index(address) * sizeof(pmd_t); |
1315 | 1352 | ||
1316 | if (!(pmd_val(*pmdp) & _SEGMENT_ENTRY_INV)) { | 1353 | if (!(pmd_val(*pmdp) & _SEGMENT_ENTRY_INVALID)) { |
1317 | asm volatile( | 1354 | asm volatile( |
1318 | " .insn rrf,0xb98e0000,%2,%3,0,0" | 1355 | " .insn rrf,0xb98e0000,%2,%3,0,0" |
1319 | : "=m" (*pmdp) | 1356 | : "=m" (*pmdp) |
@@ -1324,24 +1361,68 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) | |||
1324 | } | 1361 | } |
1325 | } | 1362 | } |
1326 | 1363 | ||
1364 | static inline void __pmd_csp(pmd_t *pmdp) | ||
1365 | { | ||
1366 | register unsigned long reg2 asm("2") = pmd_val(*pmdp); | ||
1367 | register unsigned long reg3 asm("3") = pmd_val(*pmdp) | | ||
1368 | _SEGMENT_ENTRY_INVALID; | ||
1369 | register unsigned long reg4 asm("4") = ((unsigned long) pmdp) + 5; | ||
1370 | |||
1371 | asm volatile( | ||
1372 | " csp %1,%3" | ||
1373 | : "=m" (*pmdp) | ||
1374 | : "d" (reg2), "d" (reg3), "d" (reg4), "m" (*pmdp) : "cc"); | ||
1375 | } | ||
1376 | |||
1327 | #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE) | 1377 | #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE) |
1328 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) | 1378 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) |
1329 | { | 1379 | { |
1330 | /* | 1380 | /* |
1331 | * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) | 1381 | * pgprot is PAGE_NONE, PAGE_READ, or PAGE_WRITE (see __Pxxx / __Sxxx) |
1332 | * Convert to segment table entry format. | 1382 | * Convert to segment table entry format. |
1333 | */ | 1383 | */ |
1334 | if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) | 1384 | if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) |
1335 | return pgprot_val(SEGMENT_NONE); | 1385 | return pgprot_val(SEGMENT_NONE); |
1336 | if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) | 1386 | if (pgprot_val(pgprot) == pgprot_val(PAGE_READ)) |
1337 | return pgprot_val(SEGMENT_RO); | 1387 | return pgprot_val(SEGMENT_READ); |
1338 | return pgprot_val(SEGMENT_RW); | 1388 | return pgprot_val(SEGMENT_WRITE); |
1389 | } | ||
1390 | |||
1391 | static inline pmd_t pmd_mkyoung(pmd_t pmd) | ||
1392 | { | ||
1393 | #ifdef CONFIG_64BIT | ||
1394 | if (pmd_prot_none(pmd)) { | ||
1395 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; | ||
1396 | } else { | ||
1397 | pmd_val(pmd) |= _SEGMENT_ENTRY_YOUNG; | ||
1398 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_INVALID; | ||
1399 | } | ||
1400 | #endif | ||
1401 | return pmd; | ||
1402 | } | ||
1403 | |||
1404 | static inline pmd_t pmd_mkold(pmd_t pmd) | ||
1405 | { | ||
1406 | #ifdef CONFIG_64BIT | ||
1407 | if (pmd_prot_none(pmd)) { | ||
1408 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_PROTECT; | ||
1409 | } else { | ||
1410 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_YOUNG; | ||
1411 | pmd_val(pmd) |= _SEGMENT_ENTRY_INVALID; | ||
1412 | } | ||
1413 | #endif | ||
1414 | return pmd; | ||
1339 | } | 1415 | } |
1340 | 1416 | ||
1341 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | 1417 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) |
1342 | { | 1418 | { |
1419 | int young; | ||
1420 | |||
1421 | young = pmd_young(pmd); | ||
1343 | pmd_val(pmd) &= _SEGMENT_CHG_MASK; | 1422 | pmd_val(pmd) &= _SEGMENT_CHG_MASK; |
1344 | pmd_val(pmd) |= massage_pgprot_pmd(newprot); | 1423 | pmd_val(pmd) |= massage_pgprot_pmd(newprot); |
1424 | if (young) | ||
1425 | pmd = pmd_mkyoung(pmd); | ||
1345 | return pmd; | 1426 | return pmd; |
1346 | } | 1427 | } |
1347 | 1428 | ||
@@ -1349,18 +1430,29 @@ static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot) | |||
1349 | { | 1430 | { |
1350 | pmd_t __pmd; | 1431 | pmd_t __pmd; |
1351 | pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot); | 1432 | pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot); |
1352 | return __pmd; | 1433 | return pmd_mkyoung(__pmd); |
1353 | } | 1434 | } |
1354 | 1435 | ||
1355 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | 1436 | static inline pmd_t pmd_mkwrite(pmd_t pmd) |
1356 | { | 1437 | { |
1357 | /* Do not clobber _HPAGE_TYPE_NONE pages! */ | 1438 | /* Do not clobber PROT_NONE segments! */ |
1358 | if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) | 1439 | if (!pmd_prot_none(pmd)) |
1359 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | 1440 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_PROTECT; |
1360 | return pmd; | 1441 | return pmd; |
1361 | } | 1442 | } |
1362 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */ | 1443 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */ |
1363 | 1444 | ||
1445 | static inline void pmdp_flush_lazy(struct mm_struct *mm, | ||
1446 | unsigned long address, pmd_t *pmdp) | ||
1447 | { | ||
1448 | int active = (mm == current->active_mm) ? 1 : 0; | ||
1449 | |||
1450 | if ((atomic_read(&mm->context.attach_count) & 0xffff) > active) | ||
1451 | __pmd_idte(address, pmdp); | ||
1452 | else | ||
1453 | mm->context.flush_mm = 1; | ||
1454 | } | ||
1455 | |||
1364 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 1456 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
1365 | 1457 | ||
1366 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | 1458 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
@@ -1378,7 +1470,7 @@ static inline int pmd_trans_splitting(pmd_t pmd) | |||
1378 | static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, | 1470 | static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, |
1379 | pmd_t *pmdp, pmd_t entry) | 1471 | pmd_t *pmdp, pmd_t entry) |
1380 | { | 1472 | { |
1381 | if (!(pmd_val(entry) & _SEGMENT_ENTRY_INV) && MACHINE_HAS_EDAT1) | 1473 | if (!(pmd_val(entry) & _SEGMENT_ENTRY_INVALID) && MACHINE_HAS_EDAT1) |
1382 | pmd_val(entry) |= _SEGMENT_ENTRY_CO; | 1474 | pmd_val(entry) |= _SEGMENT_ENTRY_CO; |
1383 | *pmdp = entry; | 1475 | *pmdp = entry; |
1384 | } | 1476 | } |
@@ -1391,7 +1483,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) | |||
1391 | 1483 | ||
1392 | static inline pmd_t pmd_wrprotect(pmd_t pmd) | 1484 | static inline pmd_t pmd_wrprotect(pmd_t pmd) |
1393 | { | 1485 | { |
1394 | pmd_val(pmd) |= _SEGMENT_ENTRY_RO; | 1486 | /* Do not clobber PROT_NONE segments! */ |
1487 | if (!pmd_prot_none(pmd)) | ||
1488 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; | ||
1395 | return pmd; | 1489 | return pmd; |
1396 | } | 1490 | } |
1397 | 1491 | ||
@@ -1401,50 +1495,16 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd) | |||
1401 | return pmd; | 1495 | return pmd; |
1402 | } | 1496 | } |
1403 | 1497 | ||
1404 | static inline pmd_t pmd_mkold(pmd_t pmd) | ||
1405 | { | ||
1406 | /* No referenced bit in the segment table entry. */ | ||
1407 | return pmd; | ||
1408 | } | ||
1409 | |||
1410 | static inline pmd_t pmd_mkyoung(pmd_t pmd) | ||
1411 | { | ||
1412 | /* No referenced bit in the segment table entry. */ | ||
1413 | return pmd; | ||
1414 | } | ||
1415 | |||
1416 | #define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG | 1498 | #define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG |
1417 | static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, | 1499 | static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, |
1418 | unsigned long address, pmd_t *pmdp) | 1500 | unsigned long address, pmd_t *pmdp) |
1419 | { | 1501 | { |
1420 | unsigned long pmd_addr = pmd_val(*pmdp) & HPAGE_MASK; | 1502 | pmd_t pmd; |
1421 | long tmp, rc; | ||
1422 | int counter; | ||
1423 | 1503 | ||
1424 | rc = 0; | 1504 | pmd = *pmdp; |
1425 | if (MACHINE_HAS_RRBM) { | 1505 | __pmd_idte(address, pmdp); |
1426 | counter = PTRS_PER_PTE >> 6; | 1506 | *pmdp = pmd_mkold(pmd); |
1427 | asm volatile( | 1507 | return pmd_young(pmd); |
1428 | "0: .insn rre,0xb9ae0000,%0,%3\n" /* rrbm */ | ||
1429 | " ogr %1,%0\n" | ||
1430 | " la %3,0(%4,%3)\n" | ||
1431 | " brct %2,0b\n" | ||
1432 | : "=&d" (tmp), "+&d" (rc), "+d" (counter), | ||
1433 | "+a" (pmd_addr) | ||
1434 | : "a" (64 * 4096UL) : "cc"); | ||
1435 | rc = !!rc; | ||
1436 | } else { | ||
1437 | counter = PTRS_PER_PTE; | ||
1438 | asm volatile( | ||
1439 | "0: rrbe 0,%2\n" | ||
1440 | " la %2,0(%3,%2)\n" | ||
1441 | " brc 12,1f\n" | ||
1442 | " lhi %0,1\n" | ||
1443 | "1: brct %1,0b\n" | ||
1444 | : "+d" (rc), "+d" (counter), "+a" (pmd_addr) | ||
1445 | : "a" (4096UL) : "cc"); | ||
1446 | } | ||
1447 | return rc; | ||
1448 | } | 1508 | } |
1449 | 1509 | ||
1450 | #define __HAVE_ARCH_PMDP_GET_AND_CLEAR | 1510 | #define __HAVE_ARCH_PMDP_GET_AND_CLEAR |
@@ -1510,10 +1570,8 @@ static inline unsigned long pmd_pfn(pmd_t pmd) | |||
1510 | * exception will occur instead of a page translation exception. The | 1570 | * exception will occur instead of a page translation exception. The |
1511 | * specifiation exception has the bad habit not to store necessary | 1571 | * specifiation exception has the bad habit not to store necessary |
1512 | * information in the lowcore. | 1572 | * information in the lowcore. |
1513 | * Bit 21 and bit 22 are the page invalid bit and the page protection | 1573 | * Bits 21, 22, 30 and 31 are used to indicate the page type. |
1514 | * bit. We set both to indicate a swapped page. | 1574 | * A swap pte is indicated by bit pattern (pte & 0x603) == 0x402 |
1515 | * Bit 30 and 31 are used to distinguish the different page types. For | ||
1516 | * a swapped page these bits need to be zero. | ||
1517 | * This leaves the bits 1-19 and bits 24-29 to store type and offset. | 1575 | * This leaves the bits 1-19 and bits 24-29 to store type and offset. |
1518 | * We use the 5 bits from 25-29 for the type and the 20 bits from 1-19 | 1576 | * We use the 5 bits from 25-29 for the type and the 20 bits from 1-19 |
1519 | * plus 24 for the offset. | 1577 | * plus 24 for the offset. |
@@ -1527,10 +1585,8 @@ static inline unsigned long pmd_pfn(pmd_t pmd) | |||
1527 | * exception will occur instead of a page translation exception. The | 1585 | * exception will occur instead of a page translation exception. The |
1528 | * specifiation exception has the bad habit not to store necessary | 1586 | * specifiation exception has the bad habit not to store necessary |
1529 | * information in the lowcore. | 1587 | * information in the lowcore. |
1530 | * Bit 53 and bit 54 are the page invalid bit and the page protection | 1588 | * Bits 53, 54, 62 and 63 are used to indicate the page type. |
1531 | * bit. We set both to indicate a swapped page. | 1589 | * A swap pte is indicated by bit pattern (pte & 0x603) == 0x402 |
1532 | * Bit 62 and 63 are used to distinguish the different page types. For | ||
1533 | * a swapped page these bits need to be zero. | ||
1534 | * This leaves the bits 0-51 and bits 56-61 to store type and offset. | 1590 | * This leaves the bits 0-51 and bits 56-61 to store type and offset. |
1535 | * We use the 5 bits from 57-61 for the type and the 53 bits from 0-51 | 1591 | * We use the 5 bits from 57-61 for the type and the 53 bits from 0-51 |
1536 | * plus 56 for the offset. | 1592 | * plus 56 for the offset. |
@@ -1547,7 +1603,7 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) | |||
1547 | { | 1603 | { |
1548 | pte_t pte; | 1604 | pte_t pte; |
1549 | offset &= __SWP_OFFSET_MASK; | 1605 | offset &= __SWP_OFFSET_MASK; |
1550 | pte_val(pte) = _PAGE_TYPE_SWAP | ((type & 0x1f) << 2) | | 1606 | pte_val(pte) = _PAGE_INVALID | _PAGE_TYPE | ((type & 0x1f) << 2) | |
1551 | ((offset & 1UL) << 7) | ((offset & ~1UL) << 11); | 1607 | ((offset & 1UL) << 7) | ((offset & ~1UL) << 11); |
1552 | return pte; | 1608 | return pte; |
1553 | } | 1609 | } |
@@ -1570,7 +1626,7 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) | |||
1570 | 1626 | ||
1571 | #define pgoff_to_pte(__off) \ | 1627 | #define pgoff_to_pte(__off) \ |
1572 | ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \ | 1628 | ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \ |
1573 | | _PAGE_TYPE_FILE }) | 1629 | | _PAGE_INVALID | _PAGE_PROTECT }) |
1574 | 1630 | ||
1575 | #endif /* !__ASSEMBLY__ */ | 1631 | #endif /* !__ASSEMBLY__ */ |
1576 | 1632 | ||
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index b0e6435b2f02..0eb37505cab1 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -43,6 +43,7 @@ extern void execve_tail(void); | |||
43 | #ifndef CONFIG_64BIT | 43 | #ifndef CONFIG_64BIT |
44 | 44 | ||
45 | #define TASK_SIZE (1UL << 31) | 45 | #define TASK_SIZE (1UL << 31) |
46 | #define TASK_MAX_SIZE (1UL << 31) | ||
46 | #define TASK_UNMAPPED_BASE (1UL << 30) | 47 | #define TASK_UNMAPPED_BASE (1UL << 30) |
47 | 48 | ||
48 | #else /* CONFIG_64BIT */ | 49 | #else /* CONFIG_64BIT */ |
@@ -51,6 +52,7 @@ extern void execve_tail(void); | |||
51 | #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ | 52 | #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ |
52 | (1UL << 30) : (1UL << 41)) | 53 | (1UL << 30) : (1UL << 41)) |
53 | #define TASK_SIZE TASK_SIZE_OF(current) | 54 | #define TASK_SIZE TASK_SIZE_OF(current) |
55 | #define TASK_MAX_SIZE (1UL << 53) | ||
54 | 56 | ||
55 | #endif /* CONFIG_64BIT */ | 57 | #endif /* CONFIG_64BIT */ |
56 | 58 | ||
diff --git a/arch/s390/include/asm/serial.h b/arch/s390/include/asm/serial.h new file mode 100644 index 000000000000..5b3e48ef534b --- /dev/null +++ b/arch/s390/include/asm/serial.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _ASM_S390_SERIAL_H | ||
2 | #define _ASM_S390_SERIAL_H | ||
3 | |||
4 | #define BASE_BAUD 0 | ||
5 | |||
6 | #endif /* _ASM_S390_SERIAL_H */ | ||
diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h index 80b6f11263c4..6dbd559763c9 100644 --- a/arch/s390/include/asm/switch_to.h +++ b/arch/s390/include/asm/switch_to.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #define __ASM_SWITCH_TO_H | 8 | #define __ASM_SWITCH_TO_H |
9 | 9 | ||
10 | #include <linux/thread_info.h> | 10 | #include <linux/thread_info.h> |
11 | #include <asm/ptrace.h> | ||
11 | 12 | ||
12 | extern struct task_struct *__switch_to(void *, void *); | 13 | extern struct task_struct *__switch_to(void *, void *); |
13 | extern void update_cr_regs(struct task_struct *task); | 14 | extern void update_cr_regs(struct task_struct *task); |
@@ -68,12 +69,16 @@ static inline void restore_fp_regs(s390_fp_regs *fpregs) | |||
68 | 69 | ||
69 | static inline void save_access_regs(unsigned int *acrs) | 70 | static inline void save_access_regs(unsigned int *acrs) |
70 | { | 71 | { |
71 | asm volatile("stam 0,15,%0" : "=Q" (*acrs)); | 72 | typedef struct { int _[NUM_ACRS]; } acrstype; |
73 | |||
74 | asm volatile("stam 0,15,%0" : "=Q" (*(acrstype *)acrs)); | ||
72 | } | 75 | } |
73 | 76 | ||
74 | static inline void restore_access_regs(unsigned int *acrs) | 77 | static inline void restore_access_regs(unsigned int *acrs) |
75 | { | 78 | { |
76 | asm volatile("lam 0,15,%0" : : "Q" (*acrs)); | 79 | typedef struct { int _[NUM_ACRS]; } acrstype; |
80 | |||
81 | asm volatile("lam 0,15,%0" : : "Q" (*(acrstype *)acrs)); | ||
77 | } | 82 | } |
78 | 83 | ||
79 | #define switch_to(prev,next,last) do { \ | 84 | #define switch_to(prev,next,last) do { \ |
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index b75d7d686684..2cb846c4b37f 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h | |||
@@ -32,6 +32,7 @@ struct mmu_gather { | |||
32 | struct mm_struct *mm; | 32 | struct mm_struct *mm; |
33 | struct mmu_table_batch *batch; | 33 | struct mmu_table_batch *batch; |
34 | unsigned int fullmm; | 34 | unsigned int fullmm; |
35 | unsigned long start, end; | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | struct mmu_table_batch { | 38 | struct mmu_table_batch { |
@@ -48,10 +49,13 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table); | |||
48 | 49 | ||
49 | static inline void tlb_gather_mmu(struct mmu_gather *tlb, | 50 | static inline void tlb_gather_mmu(struct mmu_gather *tlb, |
50 | struct mm_struct *mm, | 51 | struct mm_struct *mm, |
51 | unsigned int full_mm_flush) | 52 | unsigned long start, |
53 | unsigned long end) | ||
52 | { | 54 | { |
53 | tlb->mm = mm; | 55 | tlb->mm = mm; |
54 | tlb->fullmm = full_mm_flush; | 56 | tlb->start = start; |
57 | tlb->end = end; | ||
58 | tlb->fullmm = !(start | (end+1)); | ||
55 | tlb->batch = NULL; | 59 | tlb->batch = NULL; |
56 | if (tlb->fullmm) | 60 | if (tlb->fullmm) |
57 | __tlb_flush_mm(mm); | 61 | __tlb_flush_mm(mm); |
@@ -59,13 +63,14 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb, | |||
59 | 63 | ||
60 | static inline void tlb_flush_mmu(struct mmu_gather *tlb) | 64 | static inline void tlb_flush_mmu(struct mmu_gather *tlb) |
61 | { | 65 | { |
66 | __tlb_flush_mm_lazy(tlb->mm); | ||
62 | tlb_table_flush(tlb); | 67 | tlb_table_flush(tlb); |
63 | } | 68 | } |
64 | 69 | ||
65 | static inline void tlb_finish_mmu(struct mmu_gather *tlb, | 70 | static inline void tlb_finish_mmu(struct mmu_gather *tlb, |
66 | unsigned long start, unsigned long end) | 71 | unsigned long start, unsigned long end) |
67 | { | 72 | { |
68 | tlb_table_flush(tlb); | 73 | tlb_flush_mmu(tlb); |
69 | } | 74 | } |
70 | 75 | ||
71 | /* | 76 | /* |
diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index 6b32af30878c..f9fef0425fee 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h | |||
@@ -86,7 +86,7 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) | |||
86 | __tlb_flush_full(mm); | 86 | __tlb_flush_full(mm); |
87 | } | 87 | } |
88 | 88 | ||
89 | static inline void __tlb_flush_mm_cond(struct mm_struct * mm) | 89 | static inline void __tlb_flush_mm_lazy(struct mm_struct * mm) |
90 | { | 90 | { |
91 | if (mm->context.flush_mm) { | 91 | if (mm->context.flush_mm) { |
92 | __tlb_flush_mm(mm); | 92 | __tlb_flush_mm(mm); |
@@ -118,13 +118,13 @@ static inline void __tlb_flush_mm_cond(struct mm_struct * mm) | |||
118 | 118 | ||
119 | static inline void flush_tlb_mm(struct mm_struct *mm) | 119 | static inline void flush_tlb_mm(struct mm_struct *mm) |
120 | { | 120 | { |
121 | __tlb_flush_mm_cond(mm); | 121 | __tlb_flush_mm_lazy(mm); |
122 | } | 122 | } |
123 | 123 | ||
124 | static inline void flush_tlb_range(struct vm_area_struct *vma, | 124 | static inline void flush_tlb_range(struct vm_area_struct *vma, |
125 | unsigned long start, unsigned long end) | 125 | unsigned long start, unsigned long end) |
126 | { | 126 | { |
127 | __tlb_flush_mm_cond(vma->vm_mm); | 127 | __tlb_flush_mm_lazy(vma->vm_mm); |
128 | } | 128 | } |
129 | 129 | ||
130 | static inline void flush_tlb_kernel_range(unsigned long start, | 130 | static inline void flush_tlb_kernel_range(unsigned long start, |
diff --git a/arch/s390/include/asm/vtime.h b/arch/s390/include/asm/vtime.h new file mode 100644 index 000000000000..af9896c53eb3 --- /dev/null +++ b/arch/s390/include/asm/vtime.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef _S390_VTIME_H | ||
2 | #define _S390_VTIME_H | ||
3 | |||
4 | #define __ARCH_HAS_VTIME_ACCOUNT | ||
5 | #define __ARCH_HAS_VTIME_TASK_SWITCH | ||
6 | |||
7 | #endif /* _S390_VTIME_H */ | ||
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index be7a408be7a1..cc30d1fb000c 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/unistd.h> | 18 | #include <asm/unistd.h> |
19 | #include <asm/page.h> | 19 | #include <asm/page.h> |
20 | #include <asm/sigp.h> | 20 | #include <asm/sigp.h> |
21 | #include <asm/irq.h> | ||
21 | 22 | ||
22 | __PT_R0 = __PT_GPRS | 23 | __PT_R0 = __PT_GPRS |
23 | __PT_R1 = __PT_GPRS + 4 | 24 | __PT_R1 = __PT_GPRS + 4 |
@@ -435,6 +436,11 @@ io_skip: | |||
435 | io_loop: | 436 | io_loop: |
436 | l %r1,BASED(.Ldo_IRQ) | 437 | l %r1,BASED(.Ldo_IRQ) |
437 | lr %r2,%r11 # pass pointer to pt_regs | 438 | lr %r2,%r11 # pass pointer to pt_regs |
439 | lhi %r3,IO_INTERRUPT | ||
440 | tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ? | ||
441 | jz io_call | ||
442 | lhi %r3,THIN_INTERRUPT | ||
443 | io_call: | ||
438 | basr %r14,%r1 # call do_IRQ | 444 | basr %r14,%r1 # call do_IRQ |
439 | tm __LC_MACHINE_FLAGS+2,0x10 # MACHINE_FLAG_LPAR | 445 | tm __LC_MACHINE_FLAGS+2,0x10 # MACHINE_FLAG_LPAR |
440 | jz io_return | 446 | jz io_return |
@@ -584,9 +590,10 @@ ext_skip: | |||
584 | mvc __PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR | 590 | mvc __PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR |
585 | mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS | 591 | mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS |
586 | TRACE_IRQS_OFF | 592 | TRACE_IRQS_OFF |
593 | l %r1,BASED(.Ldo_IRQ) | ||
587 | lr %r2,%r11 # pass pointer to pt_regs | 594 | lr %r2,%r11 # pass pointer to pt_regs |
588 | l %r1,BASED(.Ldo_extint) | 595 | lhi %r3,EXT_INTERRUPT |
589 | basr %r14,%r1 # call do_extint | 596 | basr %r14,%r1 # call do_IRQ |
590 | j io_return | 597 | j io_return |
591 | 598 | ||
592 | /* | 599 | /* |
@@ -879,13 +886,13 @@ cleanup_idle: | |||
879 | stm %r9,%r10,__LC_SYSTEM_TIMER | 886 | stm %r9,%r10,__LC_SYSTEM_TIMER |
880 | mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) | 887 | mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) |
881 | # prepare return psw | 888 | # prepare return psw |
882 | n %r8,BASED(cleanup_idle_wait) # clear wait state bit | 889 | n %r8,BASED(cleanup_idle_wait) # clear irq & wait state bits |
883 | l %r9,24(%r11) # return from psw_idle | 890 | l %r9,24(%r11) # return from psw_idle |
884 | br %r14 | 891 | br %r14 |
885 | cleanup_idle_insn: | 892 | cleanup_idle_insn: |
886 | .long psw_idle_lpsw + 0x80000000 | 893 | .long psw_idle_lpsw + 0x80000000 |
887 | cleanup_idle_wait: | 894 | cleanup_idle_wait: |
888 | .long 0xfffdffff | 895 | .long 0xfcfdffff |
889 | 896 | ||
890 | /* | 897 | /* |
891 | * Integer constants | 898 | * Integer constants |
@@ -902,7 +909,6 @@ cleanup_idle_wait: | |||
902 | .Ldo_machine_check: .long s390_do_machine_check | 909 | .Ldo_machine_check: .long s390_do_machine_check |
903 | .Lhandle_mcck: .long s390_handle_mcck | 910 | .Lhandle_mcck: .long s390_handle_mcck |
904 | .Ldo_IRQ: .long do_IRQ | 911 | .Ldo_IRQ: .long do_IRQ |
905 | .Ldo_extint: .long do_extint | ||
906 | .Ldo_signal: .long do_signal | 912 | .Ldo_signal: .long do_signal |
907 | .Ldo_notify_resume: .long do_notify_resume | 913 | .Ldo_notify_resume: .long do_notify_resume |
908 | .Ldo_per_trap: .long do_per_trap | 914 | .Ldo_per_trap: .long do_per_trap |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 1c039d0c24c7..2b2188b97c6a 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/unistd.h> | 19 | #include <asm/unistd.h> |
20 | #include <asm/page.h> | 20 | #include <asm/page.h> |
21 | #include <asm/sigp.h> | 21 | #include <asm/sigp.h> |
22 | #include <asm/irq.h> | ||
22 | 23 | ||
23 | __PT_R0 = __PT_GPRS | 24 | __PT_R0 = __PT_GPRS |
24 | __PT_R1 = __PT_GPRS + 8 | 25 | __PT_R1 = __PT_GPRS + 8 |
@@ -468,6 +469,11 @@ io_skip: | |||
468 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 469 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
469 | io_loop: | 470 | io_loop: |
470 | lgr %r2,%r11 # pass pointer to pt_regs | 471 | lgr %r2,%r11 # pass pointer to pt_regs |
472 | lghi %r3,IO_INTERRUPT | ||
473 | tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ? | ||
474 | jz io_call | ||
475 | lghi %r3,THIN_INTERRUPT | ||
476 | io_call: | ||
471 | brasl %r14,do_IRQ | 477 | brasl %r14,do_IRQ |
472 | tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR | 478 | tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR |
473 | jz io_return | 479 | jz io_return |
@@ -623,7 +629,8 @@ ext_skip: | |||
623 | TRACE_IRQS_OFF | 629 | TRACE_IRQS_OFF |
624 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 630 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
625 | lgr %r2,%r11 # pass pointer to pt_regs | 631 | lgr %r2,%r11 # pass pointer to pt_regs |
626 | brasl %r14,do_extint | 632 | lghi %r3,EXT_INTERRUPT |
633 | brasl %r14,do_IRQ | ||
627 | j io_return | 634 | j io_return |
628 | 635 | ||
629 | /* | 636 | /* |
@@ -922,7 +929,7 @@ cleanup_idle: | |||
922 | stg %r9,__LC_SYSTEM_TIMER | 929 | stg %r9,__LC_SYSTEM_TIMER |
923 | mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) | 930 | mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) |
924 | # prepare return psw | 931 | # prepare return psw |
925 | nihh %r8,0xfffd # clear wait state bit | 932 | nihh %r8,0xfcfd # clear irq & wait state bits |
926 | lg %r9,48(%r11) # return from psw_idle | 933 | lg %r9,48(%r11) # return from psw_idle |
927 | br %r14 | 934 | br %r14 |
928 | cleanup_idle_insn: | 935 | cleanup_idle_insn: |
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 54b0995514e8..b34ba0ea96a9 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/cputime.h> | 22 | #include <asm/cputime.h> |
23 | #include <asm/lowcore.h> | 23 | #include <asm/lowcore.h> |
24 | #include <asm/irq.h> | 24 | #include <asm/irq.h> |
25 | #include <asm/hw_irq.h> | ||
25 | #include "entry.h" | 26 | #include "entry.h" |
26 | 27 | ||
27 | DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); | 28 | DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat); |
@@ -42,9 +43,10 @@ struct irq_class { | |||
42 | * Since the external and I/O interrupt fields are already sums we would end | 43 | * Since the external and I/O interrupt fields are already sums we would end |
43 | * up with having a sum which accounts each interrupt twice. | 44 | * up with having a sum which accounts each interrupt twice. |
44 | */ | 45 | */ |
45 | static const struct irq_class irqclass_main_desc[NR_IRQS] = { | 46 | static const struct irq_class irqclass_main_desc[NR_IRQS_BASE] = { |
46 | [EXTERNAL_INTERRUPT] = {.name = "EXT"}, | 47 | [EXT_INTERRUPT] = {.name = "EXT"}, |
47 | [IO_INTERRUPT] = {.name = "I/O"} | 48 | [IO_INTERRUPT] = {.name = "I/O"}, |
49 | [THIN_INTERRUPT] = {.name = "AIO"}, | ||
48 | }; | 50 | }; |
49 | 51 | ||
50 | /* | 52 | /* |
@@ -86,6 +88,28 @@ static const struct irq_class irqclass_sub_desc[NR_ARCH_IRQS] = { | |||
86 | [CPU_RST] = {.name = "RST", .desc = "[CPU] CPU Restart"}, | 88 | [CPU_RST] = {.name = "RST", .desc = "[CPU] CPU Restart"}, |
87 | }; | 89 | }; |
88 | 90 | ||
91 | void __init init_IRQ(void) | ||
92 | { | ||
93 | irq_reserve_irqs(0, THIN_INTERRUPT); | ||
94 | init_cio_interrupts(); | ||
95 | init_airq_interrupts(); | ||
96 | init_ext_interrupts(); | ||
97 | } | ||
98 | |||
99 | void do_IRQ(struct pt_regs *regs, int irq) | ||
100 | { | ||
101 | struct pt_regs *old_regs; | ||
102 | |||
103 | old_regs = set_irq_regs(regs); | ||
104 | irq_enter(); | ||
105 | if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) | ||
106 | /* Serve timer interrupts first. */ | ||
107 | clock_comparator_work(); | ||
108 | generic_handle_irq(irq); | ||
109 | irq_exit(); | ||
110 | set_irq_regs(old_regs); | ||
111 | } | ||
112 | |||
89 | /* | 113 | /* |
90 | * show_interrupts is needed by /proc/interrupts. | 114 | * show_interrupts is needed by /proc/interrupts. |
91 | */ | 115 | */ |
@@ -100,27 +124,36 @@ int show_interrupts(struct seq_file *p, void *v) | |||
100 | for_each_online_cpu(cpu) | 124 | for_each_online_cpu(cpu) |
101 | seq_printf(p, "CPU%d ", cpu); | 125 | seq_printf(p, "CPU%d ", cpu); |
102 | seq_putc(p, '\n'); | 126 | seq_putc(p, '\n'); |
127 | goto out; | ||
103 | } | 128 | } |
104 | if (irq < NR_IRQS) { | 129 | if (irq < NR_IRQS) { |
130 | if (irq >= NR_IRQS_BASE) | ||
131 | goto out; | ||
105 | seq_printf(p, "%s: ", irqclass_main_desc[irq].name); | 132 | seq_printf(p, "%s: ", irqclass_main_desc[irq].name); |
106 | for_each_online_cpu(cpu) | 133 | for_each_online_cpu(cpu) |
107 | seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[irq]); | 134 | seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); |
108 | seq_putc(p, '\n'); | 135 | seq_putc(p, '\n'); |
109 | goto skip_arch_irqs; | 136 | goto out; |
110 | } | 137 | } |
111 | for (irq = 0; irq < NR_ARCH_IRQS; irq++) { | 138 | for (irq = 0; irq < NR_ARCH_IRQS; irq++) { |
112 | seq_printf(p, "%s: ", irqclass_sub_desc[irq].name); | 139 | seq_printf(p, "%s: ", irqclass_sub_desc[irq].name); |
113 | for_each_online_cpu(cpu) | 140 | for_each_online_cpu(cpu) |
114 | seq_printf(p, "%10u ", per_cpu(irq_stat, cpu).irqs[irq]); | 141 | seq_printf(p, "%10u ", |
142 | per_cpu(irq_stat, cpu).irqs[irq]); | ||
115 | if (irqclass_sub_desc[irq].desc) | 143 | if (irqclass_sub_desc[irq].desc) |
116 | seq_printf(p, " %s", irqclass_sub_desc[irq].desc); | 144 | seq_printf(p, " %s", irqclass_sub_desc[irq].desc); |
117 | seq_putc(p, '\n'); | 145 | seq_putc(p, '\n'); |
118 | } | 146 | } |
119 | skip_arch_irqs: | 147 | out: |
120 | put_online_cpus(); | 148 | put_online_cpus(); |
121 | return 0; | 149 | return 0; |
122 | } | 150 | } |
123 | 151 | ||
152 | int arch_show_interrupts(struct seq_file *p, int prec) | ||
153 | { | ||
154 | return 0; | ||
155 | } | ||
156 | |||
124 | /* | 157 | /* |
125 | * Switch to the asynchronous interrupt stack for softirq execution. | 158 | * Switch to the asynchronous interrupt stack for softirq execution. |
126 | */ | 159 | */ |
@@ -159,14 +192,6 @@ asmlinkage void do_softirq(void) | |||
159 | local_irq_restore(flags); | 192 | local_irq_restore(flags); |
160 | } | 193 | } |
161 | 194 | ||
162 | #ifdef CONFIG_PROC_FS | ||
163 | void init_irq_proc(void) | ||
164 | { | ||
165 | if (proc_mkdir("irq", NULL)) | ||
166 | create_prof_cpu_mask(); | ||
167 | } | ||
168 | #endif | ||
169 | |||
170 | /* | 195 | /* |
171 | * ext_int_hash[index] is the list head for all external interrupts that hash | 196 | * ext_int_hash[index] is the list head for all external interrupts that hash |
172 | * to this index. | 197 | * to this index. |
@@ -183,14 +208,6 @@ struct ext_int_info { | |||
183 | /* ext_int_hash_lock protects the handler lists for external interrupts */ | 208 | /* ext_int_hash_lock protects the handler lists for external interrupts */ |
184 | DEFINE_SPINLOCK(ext_int_hash_lock); | 209 | DEFINE_SPINLOCK(ext_int_hash_lock); |
185 | 210 | ||
186 | static void __init init_external_interrupts(void) | ||
187 | { | ||
188 | int idx; | ||
189 | |||
190 | for (idx = 0; idx < ARRAY_SIZE(ext_int_hash); idx++) | ||
191 | INIT_LIST_HEAD(&ext_int_hash[idx]); | ||
192 | } | ||
193 | |||
194 | static inline int ext_hash(u16 code) | 211 | static inline int ext_hash(u16 code) |
195 | { | 212 | { |
196 | return (code + (code >> 9)) & 0xff; | 213 | return (code + (code >> 9)) & 0xff; |
@@ -234,20 +251,13 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler) | |||
234 | } | 251 | } |
235 | EXPORT_SYMBOL(unregister_external_interrupt); | 252 | EXPORT_SYMBOL(unregister_external_interrupt); |
236 | 253 | ||
237 | void __irq_entry do_extint(struct pt_regs *regs) | 254 | static irqreturn_t do_ext_interrupt(int irq, void *dummy) |
238 | { | 255 | { |
256 | struct pt_regs *regs = get_irq_regs(); | ||
239 | struct ext_code ext_code; | 257 | struct ext_code ext_code; |
240 | struct pt_regs *old_regs; | ||
241 | struct ext_int_info *p; | 258 | struct ext_int_info *p; |
242 | int index; | 259 | int index; |
243 | 260 | ||
244 | old_regs = set_irq_regs(regs); | ||
245 | irq_enter(); | ||
246 | if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) { | ||
247 | /* Serve timer interrupts first. */ | ||
248 | clock_comparator_work(); | ||
249 | } | ||
250 | kstat_incr_irqs_this_cpu(EXTERNAL_INTERRUPT, NULL); | ||
251 | ext_code = *(struct ext_code *) ®s->int_code; | 261 | ext_code = *(struct ext_code *) ®s->int_code; |
252 | if (ext_code.code != 0x1004) | 262 | if (ext_code.code != 0x1004) |
253 | __get_cpu_var(s390_idle).nohz_delay = 1; | 263 | __get_cpu_var(s390_idle).nohz_delay = 1; |
@@ -259,13 +269,25 @@ void __irq_entry do_extint(struct pt_regs *regs) | |||
259 | p->handler(ext_code, regs->int_parm, | 269 | p->handler(ext_code, regs->int_parm, |
260 | regs->int_parm_long); | 270 | regs->int_parm_long); |
261 | rcu_read_unlock(); | 271 | rcu_read_unlock(); |
262 | irq_exit(); | 272 | |
263 | set_irq_regs(old_regs); | 273 | return IRQ_HANDLED; |
264 | } | 274 | } |
265 | 275 | ||
266 | void __init init_IRQ(void) | 276 | static struct irqaction external_interrupt = { |
277 | .name = "EXT", | ||
278 | .handler = do_ext_interrupt, | ||
279 | }; | ||
280 | |||
281 | void __init init_ext_interrupts(void) | ||
267 | { | 282 | { |
268 | init_external_interrupts(); | 283 | int idx; |
284 | |||
285 | for (idx = 0; idx < ARRAY_SIZE(ext_int_hash); idx++) | ||
286 | INIT_LIST_HEAD(&ext_int_hash[idx]); | ||
287 | |||
288 | irq_set_chip_and_handler(EXT_INTERRUPT, | ||
289 | &dummy_irq_chip, handle_percpu_irq); | ||
290 | setup_irq(EXT_INTERRUPT, &external_interrupt); | ||
269 | } | 291 | } |
270 | 292 | ||
271 | static DEFINE_SPINLOCK(sc_irq_lock); | 293 | static DEFINE_SPINLOCK(sc_irq_lock); |
@@ -313,69 +335,3 @@ void measurement_alert_subclass_unregister(void) | |||
313 | spin_unlock(&ma_subclass_lock); | 335 | spin_unlock(&ma_subclass_lock); |
314 | } | 336 | } |
315 | EXPORT_SYMBOL(measurement_alert_subclass_unregister); | 337 | EXPORT_SYMBOL(measurement_alert_subclass_unregister); |
316 | |||
317 | #ifdef CONFIG_SMP | ||
318 | void synchronize_irq(unsigned int irq) | ||
319 | { | ||
320 | /* | ||
321 | * Not needed, the handler is protected by a lock and IRQs that occur | ||
322 | * after the handler is deleted are just NOPs. | ||
323 | */ | ||
324 | } | ||
325 | EXPORT_SYMBOL_GPL(synchronize_irq); | ||
326 | #endif | ||
327 | |||
328 | #ifndef CONFIG_PCI | ||
329 | |||
330 | /* Only PCI devices have dynamically-defined IRQ handlers */ | ||
331 | |||
332 | int request_irq(unsigned int irq, irq_handler_t handler, | ||
333 | unsigned long irqflags, const char *devname, void *dev_id) | ||
334 | { | ||
335 | return -EINVAL; | ||
336 | } | ||
337 | EXPORT_SYMBOL_GPL(request_irq); | ||
338 | |||
339 | void free_irq(unsigned int irq, void *dev_id) | ||
340 | { | ||
341 | WARN_ON(1); | ||
342 | } | ||
343 | EXPORT_SYMBOL_GPL(free_irq); | ||
344 | |||
345 | void enable_irq(unsigned int irq) | ||
346 | { | ||
347 | WARN_ON(1); | ||
348 | } | ||
349 | EXPORT_SYMBOL_GPL(enable_irq); | ||
350 | |||
351 | void disable_irq(unsigned int irq) | ||
352 | { | ||
353 | WARN_ON(1); | ||
354 | } | ||
355 | EXPORT_SYMBOL_GPL(disable_irq); | ||
356 | |||
357 | #endif /* !CONFIG_PCI */ | ||
358 | |||
359 | void disable_irq_nosync(unsigned int irq) | ||
360 | { | ||
361 | disable_irq(irq); | ||
362 | } | ||
363 | EXPORT_SYMBOL_GPL(disable_irq_nosync); | ||
364 | |||
365 | unsigned long probe_irq_on(void) | ||
366 | { | ||
367 | return 0; | ||
368 | } | ||
369 | EXPORT_SYMBOL_GPL(probe_irq_on); | ||
370 | |||
371 | int probe_irq_off(unsigned long val) | ||
372 | { | ||
373 | return 0; | ||
374 | } | ||
375 | EXPORT_SYMBOL_GPL(probe_irq_off); | ||
376 | |||
377 | unsigned int probe_irq_mask(unsigned long val) | ||
378 | { | ||
379 | return val; | ||
380 | } | ||
381 | EXPORT_SYMBOL_GPL(probe_irq_mask); | ||
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 3388b2b2a07d..adbbe7f1cb0d 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c | |||
@@ -105,14 +105,31 @@ static int __kprobes get_fixup_type(kprobe_opcode_t *insn) | |||
105 | fixup |= FIXUP_RETURN_REGISTER; | 105 | fixup |= FIXUP_RETURN_REGISTER; |
106 | break; | 106 | break; |
107 | case 0xeb: | 107 | case 0xeb: |
108 | if ((insn[2] & 0xff) == 0x44 || /* bxhg */ | 108 | switch (insn[2] & 0xff) { |
109 | (insn[2] & 0xff) == 0x45) /* bxleg */ | 109 | case 0x44: /* bxhg */ |
110 | case 0x45: /* bxleg */ | ||
110 | fixup = FIXUP_BRANCH_NOT_TAKEN; | 111 | fixup = FIXUP_BRANCH_NOT_TAKEN; |
112 | break; | ||
113 | } | ||
111 | break; | 114 | break; |
112 | case 0xe3: /* bctg */ | 115 | case 0xe3: /* bctg */ |
113 | if ((insn[2] & 0xff) == 0x46) | 116 | if ((insn[2] & 0xff) == 0x46) |
114 | fixup = FIXUP_BRANCH_NOT_TAKEN; | 117 | fixup = FIXUP_BRANCH_NOT_TAKEN; |
115 | break; | 118 | break; |
119 | case 0xec: | ||
120 | switch (insn[2] & 0xff) { | ||
121 | case 0xe5: /* clgrb */ | ||
122 | case 0xe6: /* cgrb */ | ||
123 | case 0xf6: /* crb */ | ||
124 | case 0xf7: /* clrb */ | ||
125 | case 0xfc: /* cgib */ | ||
126 | case 0xfd: /* cglib */ | ||
127 | case 0xfe: /* cib */ | ||
128 | case 0xff: /* clib */ | ||
129 | fixup = FIXUP_BRANCH_NOT_TAKEN; | ||
130 | break; | ||
131 | } | ||
132 | break; | ||
116 | } | 133 | } |
117 | return fixup; | 134 | return fixup; |
118 | } | 135 | } |
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 504175ebf8b0..c4c033819879 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c | |||
@@ -214,10 +214,7 @@ static int notrace s390_revalidate_registers(struct mci *mci) | |||
214 | : "0", "cc"); | 214 | : "0", "cc"); |
215 | #endif | 215 | #endif |
216 | /* Revalidate clock comparator register */ | 216 | /* Revalidate clock comparator register */ |
217 | if (S390_lowcore.clock_comparator == -1) | 217 | set_clock_comparator(S390_lowcore.clock_comparator); |
218 | set_clock_comparator(S390_lowcore.mcck_clock); | ||
219 | else | ||
220 | set_clock_comparator(S390_lowcore.clock_comparator); | ||
221 | /* Check if old PSW is valid */ | 218 | /* Check if old PSW is valid */ |
222 | if (!mci->wp) | 219 | if (!mci->wp) |
223 | /* | 220 | /* |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 2bc3eddae34a..c5dbb335716d 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -71,6 +71,7 @@ void arch_cpu_idle(void) | |||
71 | } | 71 | } |
72 | /* Halt the cpu and keep track of cpu time accounting. */ | 72 | /* Halt the cpu and keep track of cpu time accounting. */ |
73 | vtime_stop_cpu(); | 73 | vtime_stop_cpu(); |
74 | local_irq_enable(); | ||
74 | } | 75 | } |
75 | 76 | ||
76 | void arch_cpu_idle_exit(void) | 77 | void arch_cpu_idle_exit(void) |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index e9fadb04e3c6..9556905bd3ce 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -60,11 +60,11 @@ void update_cr_regs(struct task_struct *task) | |||
60 | 60 | ||
61 | __ctl_store(cr, 0, 2); | 61 | __ctl_store(cr, 0, 2); |
62 | cr_new[1] = cr[1]; | 62 | cr_new[1] = cr[1]; |
63 | /* Set or clear transaction execution TXC/PIFO bits 8 and 9. */ | 63 | /* Set or clear transaction execution TXC bit 8. */ |
64 | if (task->thread.per_flags & PER_FLAG_NO_TE) | 64 | if (task->thread.per_flags & PER_FLAG_NO_TE) |
65 | cr_new[0] = cr[0] & ~(3UL << 54); | 65 | cr_new[0] = cr[0] & ~(1UL << 55); |
66 | else | 66 | else |
67 | cr_new[0] = cr[0] | (3UL << 54); | 67 | cr_new[0] = cr[0] | (1UL << 55); |
68 | /* Set or clear transaction execution TDC bits 62 and 63. */ | 68 | /* Set or clear transaction execution TDC bits 62 and 63. */ |
69 | cr_new[2] = cr[2] & ~3UL; | 69 | cr_new[2] = cr[2] & ~3UL; |
70 | if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) { | 70 | if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) { |
@@ -1299,7 +1299,7 @@ int regs_query_register_offset(const char *name) | |||
1299 | 1299 | ||
1300 | if (!name || *name != 'r') | 1300 | if (!name || *name != 'r') |
1301 | return -EINVAL; | 1301 | return -EINVAL; |
1302 | if (strict_strtoul(name + 1, 10, &offset)) | 1302 | if (kstrtoul(name + 1, 10, &offset)) |
1303 | return -EINVAL; | 1303 | return -EINVAL; |
1304 | if (offset >= NUM_GPRS) | 1304 | if (offset >= NUM_GPRS) |
1305 | return -EINVAL; | 1305 | return -EINVAL; |
diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c index c479d2f9605b..737bff38e3ee 100644 --- a/arch/s390/kernel/suspend.c +++ b/arch/s390/kernel/suspend.c | |||
@@ -10,6 +10,9 @@ | |||
10 | #include <linux/suspend.h> | 10 | #include <linux/suspend.h> |
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <asm/ctl_reg.h> | 12 | #include <asm/ctl_reg.h> |
13 | #include <asm/ipl.h> | ||
14 | #include <asm/cio.h> | ||
15 | #include <asm/pci.h> | ||
13 | 16 | ||
14 | /* | 17 | /* |
15 | * References to section boundaries | 18 | * References to section boundaries |
@@ -211,3 +214,11 @@ void restore_processor_state(void) | |||
211 | __ctl_set_bit(0,28); | 214 | __ctl_set_bit(0,28); |
212 | local_mcck_enable(); | 215 | local_mcck_enable(); |
213 | } | 216 | } |
217 | |||
218 | /* Called at the end of swsusp_arch_resume */ | ||
219 | void s390_early_resume(void) | ||
220 | { | ||
221 | lgr_info_log(); | ||
222 | channel_subsystem_reinit(); | ||
223 | zpci_rescan(); | ||
224 | } | ||
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index c487be4cfc81..6b09fdffbd2f 100644 --- a/arch/s390/kernel/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
@@ -281,11 +281,8 @@ restore_registers: | |||
281 | lghi %r2,0 | 281 | lghi %r2,0 |
282 | brasl %r14,arch_set_page_states | 282 | brasl %r14,arch_set_page_states |
283 | 283 | ||
284 | /* Log potential guest relocation */ | 284 | /* Call arch specific early resume code */ |
285 | brasl %r14,lgr_info_log | 285 | brasl %r14,s390_early_resume |
286 | |||
287 | /* Reinitialize the channel subsystem */ | ||
288 | brasl %r14,channel_subsystem_reinit | ||
289 | 286 | ||
290 | /* Return 0 */ | 287 | /* Return 0 */ |
291 | lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) | 288 | lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 876546b9cfa1..064c3082ab33 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -92,7 +92,6 @@ void clock_comparator_work(void) | |||
92 | struct clock_event_device *cd; | 92 | struct clock_event_device *cd; |
93 | 93 | ||
94 | S390_lowcore.clock_comparator = -1ULL; | 94 | S390_lowcore.clock_comparator = -1ULL; |
95 | set_clock_comparator(S390_lowcore.clock_comparator); | ||
96 | cd = &__get_cpu_var(comparators); | 95 | cd = &__get_cpu_var(comparators); |
97 | cd->event_handler(cd); | 96 | cd->event_handler(cd); |
98 | } | 97 | } |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index d7776281cb60..05d75c413137 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -63,7 +63,7 @@ static int __init vdso_setup(char *s) | |||
63 | else if (strncmp(s, "off", 4) == 0) | 63 | else if (strncmp(s, "off", 4) == 0) |
64 | vdso_enabled = 0; | 64 | vdso_enabled = 0; |
65 | else { | 65 | else { |
66 | rc = strict_strtoul(s, 0, &val); | 66 | rc = kstrtoul(s, 0, &val); |
67 | vdso_enabled = rc ? 0 : !!val; | 67 | vdso_enabled = rc ? 0 : !!val; |
68 | } | 68 | } |
69 | return !rc; | 69 | return !rc; |
@@ -113,11 +113,11 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore) | |||
113 | 113 | ||
114 | clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY, | 114 | clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY, |
115 | PAGE_SIZE << SEGMENT_ORDER); | 115 | PAGE_SIZE << SEGMENT_ORDER); |
116 | clear_table((unsigned long *) page_table, _PAGE_TYPE_EMPTY, | 116 | clear_table((unsigned long *) page_table, _PAGE_INVALID, |
117 | 256*sizeof(unsigned long)); | 117 | 256*sizeof(unsigned long)); |
118 | 118 | ||
119 | *(unsigned long *) segment_table = _SEGMENT_ENTRY + page_table; | 119 | *(unsigned long *) segment_table = _SEGMENT_ENTRY + page_table; |
120 | *(unsigned long *) page_table = _PAGE_RO + page_frame; | 120 | *(unsigned long *) page_table = _PAGE_PROTECT + page_frame; |
121 | 121 | ||
122 | psal = (u32 *) (page_table + 256*sizeof(unsigned long)); | 122 | psal = (u32 *) (page_table + 256*sizeof(unsigned long)); |
123 | aste = psal + 32; | 123 | aste = psal + 32; |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 9b9c1b78ec67..abcfab55f99b 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/irq_regs.h> | 19 | #include <asm/irq_regs.h> |
20 | #include <asm/cputime.h> | 20 | #include <asm/cputime.h> |
21 | #include <asm/vtimer.h> | 21 | #include <asm/vtimer.h> |
22 | #include <asm/vtime.h> | ||
22 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
23 | #include "entry.h" | 24 | #include "entry.h" |
24 | 25 | ||
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 3074475c8ae0..3a74d8af0d69 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c | |||
@@ -119,12 +119,21 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) | |||
119 | * The layout is as follows: | 119 | * The layout is as follows: |
120 | * - gpr 2 contains the subchannel id (passed as addr) | 120 | * - gpr 2 contains the subchannel id (passed as addr) |
121 | * - gpr 3 contains the virtqueue index (passed as datamatch) | 121 | * - gpr 3 contains the virtqueue index (passed as datamatch) |
122 | * - gpr 4 contains the index on the bus (optionally) | ||
122 | */ | 123 | */ |
123 | ret = kvm_io_bus_write(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, | 124 | ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, |
124 | vcpu->run->s.regs.gprs[2], | 125 | vcpu->run->s.regs.gprs[2], |
125 | 8, &vcpu->run->s.regs.gprs[3]); | 126 | 8, &vcpu->run->s.regs.gprs[3], |
127 | vcpu->run->s.regs.gprs[4]); | ||
126 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | 128 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
127 | /* kvm_io_bus_write returns -EOPNOTSUPP if it found no match. */ | 129 | |
130 | /* | ||
131 | * Return cookie in gpr 2, but don't overwrite the register if the | ||
132 | * diagnose will be handled by userspace. | ||
133 | */ | ||
134 | if (ret != -EOPNOTSUPP) | ||
135 | vcpu->run->s.regs.gprs[2] = ret; | ||
136 | /* kvm_io_bus_write_cookie returns -EOPNOTSUPP if it found no match. */ | ||
128 | return ret < 0 ? ret : 0; | 137 | return ret < 0 ? ret : 0; |
129 | } | 138 | } |
130 | 139 | ||
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index 302e0e52b009..99d789e8a018 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h | |||
@@ -42,9 +42,11 @@ static inline void __user *__gptr_to_uptr(struct kvm_vcpu *vcpu, | |||
42 | ({ \ | 42 | ({ \ |
43 | __typeof__(gptr) __uptr = __gptr_to_uptr(vcpu, gptr, 1);\ | 43 | __typeof__(gptr) __uptr = __gptr_to_uptr(vcpu, gptr, 1);\ |
44 | int __mask = sizeof(__typeof__(*(gptr))) - 1; \ | 44 | int __mask = sizeof(__typeof__(*(gptr))) - 1; \ |
45 | int __ret = PTR_RET((void __force *)__uptr); \ | 45 | int __ret; \ |
46 | \ | 46 | \ |
47 | if (!__ret) { \ | 47 | if (IS_ERR((void __force *)__uptr)) { \ |
48 | __ret = PTR_ERR((void __force *)__uptr); \ | ||
49 | } else { \ | ||
48 | BUG_ON((unsigned long)__uptr & __mask); \ | 50 | BUG_ON((unsigned long)__uptr & __mask); \ |
49 | __ret = get_user(x, __uptr); \ | 51 | __ret = get_user(x, __uptr); \ |
50 | } \ | 52 | } \ |
@@ -55,9 +57,11 @@ static inline void __user *__gptr_to_uptr(struct kvm_vcpu *vcpu, | |||
55 | ({ \ | 57 | ({ \ |
56 | __typeof__(gptr) __uptr = __gptr_to_uptr(vcpu, gptr, 1);\ | 58 | __typeof__(gptr) __uptr = __gptr_to_uptr(vcpu, gptr, 1);\ |
57 | int __mask = sizeof(__typeof__(*(gptr))) - 1; \ | 59 | int __mask = sizeof(__typeof__(*(gptr))) - 1; \ |
58 | int __ret = PTR_RET((void __force *)__uptr); \ | 60 | int __ret; \ |
59 | \ | 61 | \ |
60 | if (!__ret) { \ | 62 | if (IS_ERR((void __force *)__uptr)) { \ |
63 | __ret = PTR_ERR((void __force *)__uptr); \ | ||
64 | } else { \ | ||
61 | BUG_ON((unsigned long)__uptr & __mask); \ | 65 | BUG_ON((unsigned long)__uptr & __mask); \ |
62 | __ret = put_user(x, __uptr); \ | 66 | __ret = put_user(x, __uptr); \ |
63 | } \ | 67 | } \ |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 34c1c9a90be2..776dafe918db 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/pgtable.h> | 28 | #include <asm/pgtable.h> |
29 | #include <asm/nmi.h> | 29 | #include <asm/nmi.h> |
30 | #include <asm/switch_to.h> | 30 | #include <asm/switch_to.h> |
31 | #include <asm/facility.h> | ||
31 | #include <asm/sclp.h> | 32 | #include <asm/sclp.h> |
32 | #include "kvm-s390.h" | 33 | #include "kvm-s390.h" |
33 | #include "gaccess.h" | 34 | #include "gaccess.h" |
@@ -84,9 +85,15 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
84 | { NULL } | 85 | { NULL } |
85 | }; | 86 | }; |
86 | 87 | ||
87 | static unsigned long long *facilities; | 88 | unsigned long *vfacilities; |
88 | static struct gmap_notifier gmap_notifier; | 89 | static struct gmap_notifier gmap_notifier; |
89 | 90 | ||
91 | /* test availability of vfacility */ | ||
92 | static inline int test_vfacility(unsigned long nr) | ||
93 | { | ||
94 | return __test_facility(nr, (void *) vfacilities); | ||
95 | } | ||
96 | |||
90 | /* Section: not file related */ | 97 | /* Section: not file related */ |
91 | int kvm_arch_hardware_enable(void *garbage) | 98 | int kvm_arch_hardware_enable(void *garbage) |
92 | { | 99 | { |
@@ -387,7 +394,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
387 | vcpu->arch.sie_block->ecb = 6; | 394 | vcpu->arch.sie_block->ecb = 6; |
388 | vcpu->arch.sie_block->ecb2 = 8; | 395 | vcpu->arch.sie_block->ecb2 = 8; |
389 | vcpu->arch.sie_block->eca = 0xC1002001U; | 396 | vcpu->arch.sie_block->eca = 0xC1002001U; |
390 | vcpu->arch.sie_block->fac = (int) (long) facilities; | 397 | vcpu->arch.sie_block->fac = (int) (long) vfacilities; |
391 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); | 398 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); |
392 | tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, | 399 | tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, |
393 | (unsigned long) vcpu); | 400 | (unsigned long) vcpu); |
@@ -1063,6 +1070,10 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | |||
1063 | return 0; | 1070 | return 0; |
1064 | } | 1071 | } |
1065 | 1072 | ||
1073 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
1074 | { | ||
1075 | } | ||
1076 | |||
1066 | /* Section: memory related */ | 1077 | /* Section: memory related */ |
1067 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 1078 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
1068 | struct kvm_memory_slot *memslot, | 1079 | struct kvm_memory_slot *memslot, |
@@ -1129,20 +1140,20 @@ static int __init kvm_s390_init(void) | |||
1129 | * to hold the maximum amount of facilities. On the other hand, we | 1140 | * to hold the maximum amount of facilities. On the other hand, we |
1130 | * only set facilities that are known to work in KVM. | 1141 | * only set facilities that are known to work in KVM. |
1131 | */ | 1142 | */ |
1132 | facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); | 1143 | vfacilities = (unsigned long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); |
1133 | if (!facilities) { | 1144 | if (!vfacilities) { |
1134 | kvm_exit(); | 1145 | kvm_exit(); |
1135 | return -ENOMEM; | 1146 | return -ENOMEM; |
1136 | } | 1147 | } |
1137 | memcpy(facilities, S390_lowcore.stfle_fac_list, 16); | 1148 | memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16); |
1138 | facilities[0] &= 0xff82fff3f47c0000ULL; | 1149 | vfacilities[0] &= 0xff82fff3f47c0000UL; |
1139 | facilities[1] &= 0x001c000000000000ULL; | 1150 | vfacilities[1] &= 0x001c000000000000UL; |
1140 | return 0; | 1151 | return 0; |
1141 | } | 1152 | } |
1142 | 1153 | ||
1143 | static void __exit kvm_s390_exit(void) | 1154 | static void __exit kvm_s390_exit(void) |
1144 | { | 1155 | { |
1145 | free_page((unsigned long) facilities); | 1156 | free_page((unsigned long) vfacilities); |
1146 | kvm_exit(); | 1157 | kvm_exit(); |
1147 | } | 1158 | } |
1148 | 1159 | ||
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 028ca9fd2158..dc99f1ca4267 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -24,6 +24,9 @@ | |||
24 | 24 | ||
25 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); | 25 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); |
26 | 26 | ||
27 | /* declare vfacilities extern */ | ||
28 | extern unsigned long *vfacilities; | ||
29 | |||
27 | /* negativ values are error codes, positive values for internal conditions */ | 30 | /* negativ values are error codes, positive values for internal conditions */ |
28 | #define SIE_INTERCEPT_RERUNVCPU (1<<0) | 31 | #define SIE_INTERCEPT_RERUNVCPU (1<<0) |
29 | #define SIE_INTERCEPT_UCONTROL (1<<1) | 32 | #define SIE_INTERCEPT_UCONTROL (1<<1) |
@@ -112,6 +115,13 @@ static inline u64 kvm_s390_get_base_disp_rs(struct kvm_vcpu *vcpu) | |||
112 | return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; | 115 | return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; |
113 | } | 116 | } |
114 | 117 | ||
118 | /* Set the condition code in the guest program status word */ | ||
119 | static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc) | ||
120 | { | ||
121 | vcpu->arch.sie_block->gpsw.mask &= ~(3UL << 44); | ||
122 | vcpu->arch.sie_block->gpsw.mask |= cc << 44; | ||
123 | } | ||
124 | |||
115 | int kvm_s390_handle_wait(struct kvm_vcpu *vcpu); | 125 | int kvm_s390_handle_wait(struct kvm_vcpu *vcpu); |
116 | enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer); | 126 | enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer); |
117 | void kvm_s390_tasklet(unsigned long parm); | 127 | void kvm_s390_tasklet(unsigned long parm); |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 4cdc54e63ebc..59200ee275e5 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -164,8 +164,7 @@ static int handle_tpi(struct kvm_vcpu *vcpu) | |||
164 | kfree(inti); | 164 | kfree(inti); |
165 | no_interrupt: | 165 | no_interrupt: |
166 | /* Set condition code and we're done. */ | 166 | /* Set condition code and we're done. */ |
167 | vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); | 167 | kvm_s390_set_psw_cc(vcpu, cc); |
168 | vcpu->arch.sie_block->gpsw.mask |= (cc & 3ul) << 44; | ||
169 | return 0; | 168 | return 0; |
170 | } | 169 | } |
171 | 170 | ||
@@ -220,15 +219,13 @@ static int handle_io_inst(struct kvm_vcpu *vcpu) | |||
220 | * Set condition code 3 to stop the guest from issueing channel | 219 | * Set condition code 3 to stop the guest from issueing channel |
221 | * I/O instructions. | 220 | * I/O instructions. |
222 | */ | 221 | */ |
223 | vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); | 222 | kvm_s390_set_psw_cc(vcpu, 3); |
224 | vcpu->arch.sie_block->gpsw.mask |= (3 & 3ul) << 44; | ||
225 | return 0; | 223 | return 0; |
226 | } | 224 | } |
227 | } | 225 | } |
228 | 226 | ||
229 | static int handle_stfl(struct kvm_vcpu *vcpu) | 227 | static int handle_stfl(struct kvm_vcpu *vcpu) |
230 | { | 228 | { |
231 | unsigned int facility_list; | ||
232 | int rc; | 229 | int rc; |
233 | 230 | ||
234 | vcpu->stat.instruction_stfl++; | 231 | vcpu->stat.instruction_stfl++; |
@@ -236,15 +233,13 @@ static int handle_stfl(struct kvm_vcpu *vcpu) | |||
236 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 233 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
237 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 234 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
238 | 235 | ||
239 | /* only pass the facility bits, which we can handle */ | ||
240 | facility_list = S390_lowcore.stfl_fac_list & 0xff82fff3; | ||
241 | |||
242 | rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), | 236 | rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), |
243 | &facility_list, sizeof(facility_list)); | 237 | vfacilities, 4); |
244 | if (rc) | 238 | if (rc) |
245 | return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | 239 | return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); |
246 | VCPU_EVENT(vcpu, 5, "store facility list value %x", facility_list); | 240 | VCPU_EVENT(vcpu, 5, "store facility list value %x", |
247 | trace_kvm_s390_handle_stfl(vcpu, facility_list); | 241 | *(unsigned int *) vfacilities); |
242 | trace_kvm_s390_handle_stfl(vcpu, *(unsigned int *) vfacilities); | ||
248 | return 0; | 243 | return 0; |
249 | } | 244 | } |
250 | 245 | ||
@@ -387,7 +382,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu) | |||
387 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 382 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
388 | 383 | ||
389 | if (fc > 3) { | 384 | if (fc > 3) { |
390 | vcpu->arch.sie_block->gpsw.mask |= 3ul << 44; /* cc 3 */ | 385 | kvm_s390_set_psw_cc(vcpu, 3); |
391 | return 0; | 386 | return 0; |
392 | } | 387 | } |
393 | 388 | ||
@@ -397,7 +392,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu) | |||
397 | 392 | ||
398 | if (fc == 0) { | 393 | if (fc == 0) { |
399 | vcpu->run->s.regs.gprs[0] = 3 << 28; | 394 | vcpu->run->s.regs.gprs[0] = 3 << 28; |
400 | vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); /* cc 0 */ | 395 | kvm_s390_set_psw_cc(vcpu, 0); |
401 | return 0; | 396 | return 0; |
402 | } | 397 | } |
403 | 398 | ||
@@ -431,12 +426,11 @@ static int handle_stsi(struct kvm_vcpu *vcpu) | |||
431 | } | 426 | } |
432 | trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2); | 427 | trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2); |
433 | free_page(mem); | 428 | free_page(mem); |
434 | vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); | 429 | kvm_s390_set_psw_cc(vcpu, 0); |
435 | vcpu->run->s.regs.gprs[0] = 0; | 430 | vcpu->run->s.regs.gprs[0] = 0; |
436 | return 0; | 431 | return 0; |
437 | out_no_data: | 432 | out_no_data: |
438 | /* condition code 3 */ | 433 | kvm_s390_set_psw_cc(vcpu, 3); |
439 | vcpu->arch.sie_block->gpsw.mask |= 3ul << 44; | ||
440 | out_exception: | 434 | out_exception: |
441 | free_page(mem); | 435 | free_page(mem); |
442 | return rc; | 436 | return rc; |
@@ -494,12 +488,12 @@ static int handle_epsw(struct kvm_vcpu *vcpu) | |||
494 | kvm_s390_get_regs_rre(vcpu, ®1, ®2); | 488 | kvm_s390_get_regs_rre(vcpu, ®1, ®2); |
495 | 489 | ||
496 | /* This basically extracts the mask half of the psw. */ | 490 | /* This basically extracts the mask half of the psw. */ |
497 | vcpu->run->s.regs.gprs[reg1] &= 0xffffffff00000000; | 491 | vcpu->run->s.regs.gprs[reg1] &= 0xffffffff00000000UL; |
498 | vcpu->run->s.regs.gprs[reg1] |= vcpu->arch.sie_block->gpsw.mask >> 32; | 492 | vcpu->run->s.regs.gprs[reg1] |= vcpu->arch.sie_block->gpsw.mask >> 32; |
499 | if (reg2) { | 493 | if (reg2) { |
500 | vcpu->run->s.regs.gprs[reg2] &= 0xffffffff00000000; | 494 | vcpu->run->s.regs.gprs[reg2] &= 0xffffffff00000000UL; |
501 | vcpu->run->s.regs.gprs[reg2] |= | 495 | vcpu->run->s.regs.gprs[reg2] |= |
502 | vcpu->arch.sie_block->gpsw.mask & 0x00000000ffffffff; | 496 | vcpu->arch.sie_block->gpsw.mask & 0x00000000ffffffffUL; |
503 | } | 497 | } |
504 | return 0; | 498 | return 0; |
505 | } | 499 | } |
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index c61b9fad43cc..57c87d7d7ede 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c | |||
@@ -44,7 +44,6 @@ static void __udelay_disabled(unsigned long long usecs) | |||
44 | do { | 44 | do { |
45 | set_clock_comparator(end); | 45 | set_clock_comparator(end); |
46 | vtime_stop_cpu(); | 46 | vtime_stop_cpu(); |
47 | local_irq_disable(); | ||
48 | } while (get_tod_clock() < end); | 47 | } while (get_tod_clock() < end); |
49 | lockdep_on(); | 48 | lockdep_on(); |
50 | __ctl_load(cr0, 0, 0); | 49 | __ctl_load(cr0, 0, 0); |
@@ -64,7 +63,6 @@ static void __udelay_enabled(unsigned long long usecs) | |||
64 | set_clock_comparator(end); | 63 | set_clock_comparator(end); |
65 | } | 64 | } |
66 | vtime_stop_cpu(); | 65 | vtime_stop_cpu(); |
67 | local_irq_disable(); | ||
68 | if (clock_saved) | 66 | if (clock_saved) |
69 | local_tick_enable(clock_saved); | 67 | local_tick_enable(clock_saved); |
70 | } while (get_tod_clock() < end); | 68 | } while (get_tod_clock() < end); |
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 50ea137a2d3c..1694d738b175 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c | |||
@@ -86,28 +86,28 @@ static unsigned long follow_table(struct mm_struct *mm, | |||
86 | switch (mm->context.asce_bits & _ASCE_TYPE_MASK) { | 86 | switch (mm->context.asce_bits & _ASCE_TYPE_MASK) { |
87 | case _ASCE_TYPE_REGION1: | 87 | case _ASCE_TYPE_REGION1: |
88 | table = table + ((address >> 53) & 0x7ff); | 88 | table = table + ((address >> 53) & 0x7ff); |
89 | if (unlikely(*table & _REGION_ENTRY_INV)) | 89 | if (unlikely(*table & _REGION_ENTRY_INVALID)) |
90 | return -0x39UL; | 90 | return -0x39UL; |
91 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 91 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
92 | /* fallthrough */ | 92 | /* fallthrough */ |
93 | case _ASCE_TYPE_REGION2: | 93 | case _ASCE_TYPE_REGION2: |
94 | table = table + ((address >> 42) & 0x7ff); | 94 | table = table + ((address >> 42) & 0x7ff); |
95 | if (unlikely(*table & _REGION_ENTRY_INV)) | 95 | if (unlikely(*table & _REGION_ENTRY_INVALID)) |
96 | return -0x3aUL; | 96 | return -0x3aUL; |
97 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 97 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
98 | /* fallthrough */ | 98 | /* fallthrough */ |
99 | case _ASCE_TYPE_REGION3: | 99 | case _ASCE_TYPE_REGION3: |
100 | table = table + ((address >> 31) & 0x7ff); | 100 | table = table + ((address >> 31) & 0x7ff); |
101 | if (unlikely(*table & _REGION_ENTRY_INV)) | 101 | if (unlikely(*table & _REGION_ENTRY_INVALID)) |
102 | return -0x3bUL; | 102 | return -0x3bUL; |
103 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 103 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
104 | /* fallthrough */ | 104 | /* fallthrough */ |
105 | case _ASCE_TYPE_SEGMENT: | 105 | case _ASCE_TYPE_SEGMENT: |
106 | table = table + ((address >> 20) & 0x7ff); | 106 | table = table + ((address >> 20) & 0x7ff); |
107 | if (unlikely(*table & _SEGMENT_ENTRY_INV)) | 107 | if (unlikely(*table & _SEGMENT_ENTRY_INVALID)) |
108 | return -0x10UL; | 108 | return -0x10UL; |
109 | if (unlikely(*table & _SEGMENT_ENTRY_LARGE)) { | 109 | if (unlikely(*table & _SEGMENT_ENTRY_LARGE)) { |
110 | if (write && (*table & _SEGMENT_ENTRY_RO)) | 110 | if (write && (*table & _SEGMENT_ENTRY_PROTECT)) |
111 | return -0x04UL; | 111 | return -0x04UL; |
112 | return (*table & _SEGMENT_ENTRY_ORIGIN_LARGE) + | 112 | return (*table & _SEGMENT_ENTRY_ORIGIN_LARGE) + |
113 | (address & ~_SEGMENT_ENTRY_ORIGIN_LARGE); | 113 | (address & ~_SEGMENT_ENTRY_ORIGIN_LARGE); |
@@ -117,7 +117,7 @@ static unsigned long follow_table(struct mm_struct *mm, | |||
117 | table = table + ((address >> 12) & 0xff); | 117 | table = table + ((address >> 12) & 0xff); |
118 | if (unlikely(*table & _PAGE_INVALID)) | 118 | if (unlikely(*table & _PAGE_INVALID)) |
119 | return -0x11UL; | 119 | return -0x11UL; |
120 | if (write && (*table & _PAGE_RO)) | 120 | if (write && (*table & _PAGE_PROTECT)) |
121 | return -0x04UL; | 121 | return -0x04UL; |
122 | return (*table & PAGE_MASK) + (address & ~PAGE_MASK); | 122 | return (*table & PAGE_MASK) + (address & ~PAGE_MASK); |
123 | } | 123 | } |
@@ -130,13 +130,13 @@ static unsigned long follow_table(struct mm_struct *mm, | |||
130 | unsigned long *table = (unsigned long *)__pa(mm->pgd); | 130 | unsigned long *table = (unsigned long *)__pa(mm->pgd); |
131 | 131 | ||
132 | table = table + ((address >> 20) & 0x7ff); | 132 | table = table + ((address >> 20) & 0x7ff); |
133 | if (unlikely(*table & _SEGMENT_ENTRY_INV)) | 133 | if (unlikely(*table & _SEGMENT_ENTRY_INVALID)) |
134 | return -0x10UL; | 134 | return -0x10UL; |
135 | table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); | 135 | table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); |
136 | table = table + ((address >> 12) & 0xff); | 136 | table = table + ((address >> 12) & 0xff); |
137 | if (unlikely(*table & _PAGE_INVALID)) | 137 | if (unlikely(*table & _PAGE_INVALID)) |
138 | return -0x11UL; | 138 | return -0x11UL; |
139 | if (write && (*table & _PAGE_RO)) | 139 | if (write && (*table & _PAGE_PROTECT)) |
140 | return -0x04UL; | 140 | return -0x04UL; |
141 | return (*table & PAGE_MASK) + (address & ~PAGE_MASK); | 141 | return (*table & PAGE_MASK) + (address & ~PAGE_MASK); |
142 | } | 142 | } |
diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c index 3ad65b04ac15..46d517c3c763 100644 --- a/arch/s390/mm/dump_pagetables.c +++ b/arch/s390/mm/dump_pagetables.c | |||
@@ -53,7 +53,7 @@ static void print_prot(struct seq_file *m, unsigned int pr, int level) | |||
53 | seq_printf(m, "I\n"); | 53 | seq_printf(m, "I\n"); |
54 | return; | 54 | return; |
55 | } | 55 | } |
56 | seq_printf(m, "%s", pr & _PAGE_RO ? "RO " : "RW "); | 56 | seq_printf(m, "%s", pr & _PAGE_PROTECT ? "RO " : "RW "); |
57 | seq_printf(m, "%s", pr & _PAGE_CO ? "CO " : " "); | 57 | seq_printf(m, "%s", pr & _PAGE_CO ? "CO " : " "); |
58 | seq_putc(m, '\n'); | 58 | seq_putc(m, '\n'); |
59 | } | 59 | } |
@@ -105,12 +105,12 @@ static void note_page(struct seq_file *m, struct pg_state *st, | |||
105 | } | 105 | } |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * The actual page table walker functions. In order to keep the implementation | 108 | * The actual page table walker functions. In order to keep the |
109 | * of print_prot() short, we only check and pass _PAGE_INVALID and _PAGE_RO | 109 | * implementation of print_prot() short, we only check and pass |
110 | * flags to note_page() if a region, segment or page table entry is invalid or | 110 | * _PAGE_INVALID and _PAGE_PROTECT flags to note_page() if a region, |
111 | * read-only. | 111 | * segment or page table entry is invalid or read-only. |
112 | * After all it's just a hint that the current level being walked contains an | 112 | * After all it's just a hint that the current level being walked |
113 | * invalid or read-only entry. | 113 | * contains an invalid or read-only entry. |
114 | */ | 114 | */ |
115 | static void walk_pte_level(struct seq_file *m, struct pg_state *st, | 115 | static void walk_pte_level(struct seq_file *m, struct pg_state *st, |
116 | pmd_t *pmd, unsigned long addr) | 116 | pmd_t *pmd, unsigned long addr) |
@@ -122,14 +122,14 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, | |||
122 | for (i = 0; i < PTRS_PER_PTE && addr < max_addr; i++) { | 122 | for (i = 0; i < PTRS_PER_PTE && addr < max_addr; i++) { |
123 | st->current_address = addr; | 123 | st->current_address = addr; |
124 | pte = pte_offset_kernel(pmd, addr); | 124 | pte = pte_offset_kernel(pmd, addr); |
125 | prot = pte_val(*pte) & (_PAGE_RO | _PAGE_INVALID); | 125 | prot = pte_val(*pte) & (_PAGE_PROTECT | _PAGE_INVALID); |
126 | note_page(m, st, prot, 4); | 126 | note_page(m, st, prot, 4); |
127 | addr += PAGE_SIZE; | 127 | addr += PAGE_SIZE; |
128 | } | 128 | } |
129 | } | 129 | } |
130 | 130 | ||
131 | #ifdef CONFIG_64BIT | 131 | #ifdef CONFIG_64BIT |
132 | #define _PMD_PROT_MASK (_SEGMENT_ENTRY_RO | _SEGMENT_ENTRY_CO) | 132 | #define _PMD_PROT_MASK (_SEGMENT_ENTRY_PROTECT | _SEGMENT_ENTRY_CO) |
133 | #else | 133 | #else |
134 | #define _PMD_PROT_MASK 0 | 134 | #define _PMD_PROT_MASK 0 |
135 | #endif | 135 | #endif |
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 1f5315d1215c..5d758db27bdc 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c | |||
@@ -24,7 +24,7 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, | |||
24 | pte_t *ptep, pte; | 24 | pte_t *ptep, pte; |
25 | struct page *page; | 25 | struct page *page; |
26 | 26 | ||
27 | mask = (write ? _PAGE_RO : 0) | _PAGE_INVALID | _PAGE_SPECIAL; | 27 | mask = (write ? _PAGE_PROTECT : 0) | _PAGE_INVALID | _PAGE_SPECIAL; |
28 | 28 | ||
29 | ptep = ((pte_t *) pmd_deref(pmd)) + pte_index(addr); | 29 | ptep = ((pte_t *) pmd_deref(pmd)) + pte_index(addr); |
30 | do { | 30 | do { |
@@ -55,8 +55,8 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, | |||
55 | struct page *head, *page, *tail; | 55 | struct page *head, *page, *tail; |
56 | int refs; | 56 | int refs; |
57 | 57 | ||
58 | result = write ? 0 : _SEGMENT_ENTRY_RO; | 58 | result = write ? 0 : _SEGMENT_ENTRY_PROTECT; |
59 | mask = result | _SEGMENT_ENTRY_INV; | 59 | mask = result | _SEGMENT_ENTRY_INVALID; |
60 | if ((pmd_val(pmd) & mask) != result) | 60 | if ((pmd_val(pmd) & mask) != result) |
61 | return 0; | 61 | return 0; |
62 | VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT)); | 62 | VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT)); |
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 121089d57802..248445f92604 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c | |||
@@ -8,21 +8,127 @@ | |||
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/hugetlb.h> | 9 | #include <linux/hugetlb.h> |
10 | 10 | ||
11 | static inline pmd_t __pte_to_pmd(pte_t pte) | ||
12 | { | ||
13 | int none, young, prot; | ||
14 | pmd_t pmd; | ||
15 | |||
16 | /* | ||
17 | * Convert encoding pte bits pmd bits | ||
18 | * .IR...wrdytp ..R...I...y. | ||
19 | * empty .10...000000 -> ..0...1...0. | ||
20 | * prot-none, clean, old .11...000001 -> ..0...1...1. | ||
21 | * prot-none, clean, young .11...000101 -> ..1...1...1. | ||
22 | * prot-none, dirty, old .10...001001 -> ..0...1...1. | ||
23 | * prot-none, dirty, young .10...001101 -> ..1...1...1. | ||
24 | * read-only, clean, old .11...010001 -> ..1...1...0. | ||
25 | * read-only, clean, young .01...010101 -> ..1...0...1. | ||
26 | * read-only, dirty, old .11...011001 -> ..1...1...0. | ||
27 | * read-only, dirty, young .01...011101 -> ..1...0...1. | ||
28 | * read-write, clean, old .11...110001 -> ..0...1...0. | ||
29 | * read-write, clean, young .01...110101 -> ..0...0...1. | ||
30 | * read-write, dirty, old .10...111001 -> ..0...1...0. | ||
31 | * read-write, dirty, young .00...111101 -> ..0...0...1. | ||
32 | * Huge ptes are dirty by definition, a clean pte is made dirty | ||
33 | * by the conversion. | ||
34 | */ | ||
35 | if (pte_present(pte)) { | ||
36 | pmd_val(pmd) = pte_val(pte) & PAGE_MASK; | ||
37 | if (pte_val(pte) & _PAGE_INVALID) | ||
38 | pmd_val(pmd) |= _SEGMENT_ENTRY_INVALID; | ||
39 | none = (pte_val(pte) & _PAGE_PRESENT) && | ||
40 | !(pte_val(pte) & _PAGE_READ) && | ||
41 | !(pte_val(pte) & _PAGE_WRITE); | ||
42 | prot = (pte_val(pte) & _PAGE_PROTECT) && | ||
43 | !(pte_val(pte) & _PAGE_WRITE); | ||
44 | young = pte_val(pte) & _PAGE_YOUNG; | ||
45 | if (none || young) | ||
46 | pmd_val(pmd) |= _SEGMENT_ENTRY_YOUNG; | ||
47 | if (prot || (none && young)) | ||
48 | pmd_val(pmd) |= _SEGMENT_ENTRY_PROTECT; | ||
49 | } else | ||
50 | pmd_val(pmd) = _SEGMENT_ENTRY_INVALID; | ||
51 | return pmd; | ||
52 | } | ||
53 | |||
54 | static inline pte_t __pmd_to_pte(pmd_t pmd) | ||
55 | { | ||
56 | pte_t pte; | ||
57 | |||
58 | /* | ||
59 | * Convert encoding pmd bits pte bits | ||
60 | * ..R...I...y. .IR...wrdytp | ||
61 | * empty ..0...1...0. -> .10...000000 | ||
62 | * prot-none, old ..0...1...1. -> .10...001001 | ||
63 | * prot-none, young ..1...1...1. -> .10...001101 | ||
64 | * read-only, old ..1...1...0. -> .11...011001 | ||
65 | * read-only, young ..1...0...1. -> .01...011101 | ||
66 | * read-write, old ..0...1...0. -> .10...111001 | ||
67 | * read-write, young ..0...0...1. -> .00...111101 | ||
68 | * Huge ptes are dirty by definition | ||
69 | */ | ||
70 | if (pmd_present(pmd)) { | ||
71 | pte_val(pte) = _PAGE_PRESENT | _PAGE_LARGE | _PAGE_DIRTY | | ||
72 | (pmd_val(pmd) & PAGE_MASK); | ||
73 | if (pmd_val(pmd) & _SEGMENT_ENTRY_INVALID) | ||
74 | pte_val(pte) |= _PAGE_INVALID; | ||
75 | if (pmd_prot_none(pmd)) { | ||
76 | if (pmd_val(pmd) & _SEGMENT_ENTRY_PROTECT) | ||
77 | pte_val(pte) |= _PAGE_YOUNG; | ||
78 | } else { | ||
79 | pte_val(pte) |= _PAGE_READ; | ||
80 | if (pmd_val(pmd) & _SEGMENT_ENTRY_PROTECT) | ||
81 | pte_val(pte) |= _PAGE_PROTECT; | ||
82 | else | ||
83 | pte_val(pte) |= _PAGE_WRITE; | ||
84 | if (pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG) | ||
85 | pte_val(pte) |= _PAGE_YOUNG; | ||
86 | } | ||
87 | } else | ||
88 | pte_val(pte) = _PAGE_INVALID; | ||
89 | return pte; | ||
90 | } | ||
11 | 91 | ||
12 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 92 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
13 | pte_t *pteptr, pte_t pteval) | 93 | pte_t *ptep, pte_t pte) |
14 | { | 94 | { |
15 | pmd_t *pmdp = (pmd_t *) pteptr; | 95 | pmd_t pmd; |
16 | unsigned long mask; | ||
17 | 96 | ||
97 | pmd = __pte_to_pmd(pte); | ||
18 | if (!MACHINE_HAS_HPAGE) { | 98 | if (!MACHINE_HAS_HPAGE) { |
19 | pteptr = (pte_t *) pte_page(pteval)[1].index; | 99 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_ORIGIN; |
20 | mask = pte_val(pteval) & | 100 | pmd_val(pmd) |= pte_page(pte)[1].index; |
21 | (_SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO); | 101 | } else |
22 | pte_val(pteval) = (_SEGMENT_ENTRY + __pa(pteptr)) | mask; | 102 | pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO; |
103 | *(pmd_t *) ptep = pmd; | ||
104 | } | ||
105 | |||
106 | pte_t huge_ptep_get(pte_t *ptep) | ||
107 | { | ||
108 | unsigned long origin; | ||
109 | pmd_t pmd; | ||
110 | |||
111 | pmd = *(pmd_t *) ptep; | ||
112 | if (!MACHINE_HAS_HPAGE && pmd_present(pmd)) { | ||
113 | origin = pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN; | ||
114 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_ORIGIN; | ||
115 | pmd_val(pmd) |= *(unsigned long *) origin; | ||
23 | } | 116 | } |
117 | return __pmd_to_pte(pmd); | ||
118 | } | ||
24 | 119 | ||
25 | pmd_val(*pmdp) = pte_val(pteval); | 120 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, |
121 | unsigned long addr, pte_t *ptep) | ||
122 | { | ||
123 | pmd_t *pmdp = (pmd_t *) ptep; | ||
124 | pte_t pte = huge_ptep_get(ptep); | ||
125 | |||
126 | if (MACHINE_HAS_IDTE) | ||
127 | __pmd_idte(addr, pmdp); | ||
128 | else | ||
129 | __pmd_csp(pmdp); | ||
130 | pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY; | ||
131 | return pte; | ||
26 | } | 132 | } |
27 | 133 | ||
28 | int arch_prepare_hugepage(struct page *page) | 134 | int arch_prepare_hugepage(struct page *page) |
@@ -58,7 +164,7 @@ void arch_release_hugepage(struct page *page) | |||
58 | ptep = (pte_t *) page[1].index; | 164 | ptep = (pte_t *) page[1].index; |
59 | if (!ptep) | 165 | if (!ptep) |
60 | return; | 166 | return; |
61 | clear_table((unsigned long *) ptep, _PAGE_TYPE_EMPTY, | 167 | clear_table((unsigned long *) ptep, _PAGE_INVALID, |
62 | PTRS_PER_PTE * sizeof(pte_t)); | 168 | PTRS_PER_PTE * sizeof(pte_t)); |
63 | page_table_free(&init_mm, (unsigned long *) ptep); | 169 | page_table_free(&init_mm, (unsigned long *) ptep); |
64 | page[1].index = 0; | 170 | page[1].index = 0; |
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index 80adfbf75065..990397420e6b 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c | |||
@@ -118,7 +118,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable) | |||
118 | pte = pte_offset_kernel(pmd, address); | 118 | pte = pte_offset_kernel(pmd, address); |
119 | if (!enable) { | 119 | if (!enable) { |
120 | __ptep_ipte(address, pte); | 120 | __ptep_ipte(address, pte); |
121 | pte_val(*pte) = _PAGE_TYPE_EMPTY; | 121 | pte_val(*pte) = _PAGE_INVALID; |
122 | continue; | 122 | continue; |
123 | } | 123 | } |
124 | pte_val(*pte) = __pa(address); | 124 | pte_val(*pte) = __pa(address); |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index a8154a1a2c94..bf7c0dc64a76 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -161,7 +161,7 @@ static int gmap_unlink_segment(struct gmap *gmap, unsigned long *table) | |||
161 | struct gmap_rmap *rmap; | 161 | struct gmap_rmap *rmap; |
162 | struct page *page; | 162 | struct page *page; |
163 | 163 | ||
164 | if (*table & _SEGMENT_ENTRY_INV) | 164 | if (*table & _SEGMENT_ENTRY_INVALID) |
165 | return 0; | 165 | return 0; |
166 | page = pfn_to_page(*table >> PAGE_SHIFT); | 166 | page = pfn_to_page(*table >> PAGE_SHIFT); |
167 | mp = (struct gmap_pgtable *) page->index; | 167 | mp = (struct gmap_pgtable *) page->index; |
@@ -172,7 +172,7 @@ static int gmap_unlink_segment(struct gmap *gmap, unsigned long *table) | |||
172 | kfree(rmap); | 172 | kfree(rmap); |
173 | break; | 173 | break; |
174 | } | 174 | } |
175 | *table = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | mp->vmaddr; | 175 | *table = mp->vmaddr | _SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_PROTECT; |
176 | return 1; | 176 | return 1; |
177 | } | 177 | } |
178 | 178 | ||
@@ -258,7 +258,7 @@ static int gmap_alloc_table(struct gmap *gmap, | |||
258 | return -ENOMEM; | 258 | return -ENOMEM; |
259 | new = (unsigned long *) page_to_phys(page); | 259 | new = (unsigned long *) page_to_phys(page); |
260 | crst_table_init(new, init); | 260 | crst_table_init(new, init); |
261 | if (*table & _REGION_ENTRY_INV) { | 261 | if (*table & _REGION_ENTRY_INVALID) { |
262 | list_add(&page->lru, &gmap->crst_list); | 262 | list_add(&page->lru, &gmap->crst_list); |
263 | *table = (unsigned long) new | _REGION_ENTRY_LENGTH | | 263 | *table = (unsigned long) new | _REGION_ENTRY_LENGTH | |
264 | (*table & _REGION_ENTRY_TYPE_MASK); | 264 | (*table & _REGION_ENTRY_TYPE_MASK); |
@@ -292,22 +292,22 @@ int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len) | |||
292 | for (off = 0; off < len; off += PMD_SIZE) { | 292 | for (off = 0; off < len; off += PMD_SIZE) { |
293 | /* Walk the guest addr space page table */ | 293 | /* Walk the guest addr space page table */ |
294 | table = gmap->table + (((to + off) >> 53) & 0x7ff); | 294 | table = gmap->table + (((to + off) >> 53) & 0x7ff); |
295 | if (*table & _REGION_ENTRY_INV) | 295 | if (*table & _REGION_ENTRY_INVALID) |
296 | goto out; | 296 | goto out; |
297 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 297 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
298 | table = table + (((to + off) >> 42) & 0x7ff); | 298 | table = table + (((to + off) >> 42) & 0x7ff); |
299 | if (*table & _REGION_ENTRY_INV) | 299 | if (*table & _REGION_ENTRY_INVALID) |
300 | goto out; | 300 | goto out; |
301 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 301 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
302 | table = table + (((to + off) >> 31) & 0x7ff); | 302 | table = table + (((to + off) >> 31) & 0x7ff); |
303 | if (*table & _REGION_ENTRY_INV) | 303 | if (*table & _REGION_ENTRY_INVALID) |
304 | goto out; | 304 | goto out; |
305 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 305 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
306 | table = table + (((to + off) >> 20) & 0x7ff); | 306 | table = table + (((to + off) >> 20) & 0x7ff); |
307 | 307 | ||
308 | /* Clear segment table entry in guest address space. */ | 308 | /* Clear segment table entry in guest address space. */ |
309 | flush |= gmap_unlink_segment(gmap, table); | 309 | flush |= gmap_unlink_segment(gmap, table); |
310 | *table = _SEGMENT_ENTRY_INV; | 310 | *table = _SEGMENT_ENTRY_INVALID; |
311 | } | 311 | } |
312 | out: | 312 | out: |
313 | spin_unlock(&gmap->mm->page_table_lock); | 313 | spin_unlock(&gmap->mm->page_table_lock); |
@@ -335,7 +335,7 @@ int gmap_map_segment(struct gmap *gmap, unsigned long from, | |||
335 | 335 | ||
336 | if ((from | to | len) & (PMD_SIZE - 1)) | 336 | if ((from | to | len) & (PMD_SIZE - 1)) |
337 | return -EINVAL; | 337 | return -EINVAL; |
338 | if (len == 0 || from + len > PGDIR_SIZE || | 338 | if (len == 0 || from + len > TASK_MAX_SIZE || |
339 | from + len < from || to + len < to) | 339 | from + len < from || to + len < to) |
340 | return -EINVAL; | 340 | return -EINVAL; |
341 | 341 | ||
@@ -345,17 +345,17 @@ int gmap_map_segment(struct gmap *gmap, unsigned long from, | |||
345 | for (off = 0; off < len; off += PMD_SIZE) { | 345 | for (off = 0; off < len; off += PMD_SIZE) { |
346 | /* Walk the gmap address space page table */ | 346 | /* Walk the gmap address space page table */ |
347 | table = gmap->table + (((to + off) >> 53) & 0x7ff); | 347 | table = gmap->table + (((to + off) >> 53) & 0x7ff); |
348 | if ((*table & _REGION_ENTRY_INV) && | 348 | if ((*table & _REGION_ENTRY_INVALID) && |
349 | gmap_alloc_table(gmap, table, _REGION2_ENTRY_EMPTY)) | 349 | gmap_alloc_table(gmap, table, _REGION2_ENTRY_EMPTY)) |
350 | goto out_unmap; | 350 | goto out_unmap; |
351 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 351 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
352 | table = table + (((to + off) >> 42) & 0x7ff); | 352 | table = table + (((to + off) >> 42) & 0x7ff); |
353 | if ((*table & _REGION_ENTRY_INV) && | 353 | if ((*table & _REGION_ENTRY_INVALID) && |
354 | gmap_alloc_table(gmap, table, _REGION3_ENTRY_EMPTY)) | 354 | gmap_alloc_table(gmap, table, _REGION3_ENTRY_EMPTY)) |
355 | goto out_unmap; | 355 | goto out_unmap; |
356 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 356 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
357 | table = table + (((to + off) >> 31) & 0x7ff); | 357 | table = table + (((to + off) >> 31) & 0x7ff); |
358 | if ((*table & _REGION_ENTRY_INV) && | 358 | if ((*table & _REGION_ENTRY_INVALID) && |
359 | gmap_alloc_table(gmap, table, _SEGMENT_ENTRY_EMPTY)) | 359 | gmap_alloc_table(gmap, table, _SEGMENT_ENTRY_EMPTY)) |
360 | goto out_unmap; | 360 | goto out_unmap; |
361 | table = (unsigned long *) (*table & _REGION_ENTRY_ORIGIN); | 361 | table = (unsigned long *) (*table & _REGION_ENTRY_ORIGIN); |
@@ -363,7 +363,8 @@ int gmap_map_segment(struct gmap *gmap, unsigned long from, | |||
363 | 363 | ||
364 | /* Store 'from' address in an invalid segment table entry. */ | 364 | /* Store 'from' address in an invalid segment table entry. */ |
365 | flush |= gmap_unlink_segment(gmap, table); | 365 | flush |= gmap_unlink_segment(gmap, table); |
366 | *table = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | (from + off); | 366 | *table = (from + off) | (_SEGMENT_ENTRY_INVALID | |
367 | _SEGMENT_ENTRY_PROTECT); | ||
367 | } | 368 | } |
368 | spin_unlock(&gmap->mm->page_table_lock); | 369 | spin_unlock(&gmap->mm->page_table_lock); |
369 | up_read(&gmap->mm->mmap_sem); | 370 | up_read(&gmap->mm->mmap_sem); |
@@ -384,15 +385,15 @@ static unsigned long *gmap_table_walk(unsigned long address, struct gmap *gmap) | |||
384 | unsigned long *table; | 385 | unsigned long *table; |
385 | 386 | ||
386 | table = gmap->table + ((address >> 53) & 0x7ff); | 387 | table = gmap->table + ((address >> 53) & 0x7ff); |
387 | if (unlikely(*table & _REGION_ENTRY_INV)) | 388 | if (unlikely(*table & _REGION_ENTRY_INVALID)) |
388 | return ERR_PTR(-EFAULT); | 389 | return ERR_PTR(-EFAULT); |
389 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 390 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
390 | table = table + ((address >> 42) & 0x7ff); | 391 | table = table + ((address >> 42) & 0x7ff); |
391 | if (unlikely(*table & _REGION_ENTRY_INV)) | 392 | if (unlikely(*table & _REGION_ENTRY_INVALID)) |
392 | return ERR_PTR(-EFAULT); | 393 | return ERR_PTR(-EFAULT); |
393 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 394 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
394 | table = table + ((address >> 31) & 0x7ff); | 395 | table = table + ((address >> 31) & 0x7ff); |
395 | if (unlikely(*table & _REGION_ENTRY_INV)) | 396 | if (unlikely(*table & _REGION_ENTRY_INVALID)) |
396 | return ERR_PTR(-EFAULT); | 397 | return ERR_PTR(-EFAULT); |
397 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 398 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
398 | table = table + ((address >> 20) & 0x7ff); | 399 | table = table + ((address >> 20) & 0x7ff); |
@@ -422,11 +423,11 @@ unsigned long __gmap_translate(unsigned long address, struct gmap *gmap) | |||
422 | return PTR_ERR(segment_ptr); | 423 | return PTR_ERR(segment_ptr); |
423 | /* Convert the gmap address to an mm address. */ | 424 | /* Convert the gmap address to an mm address. */ |
424 | segment = *segment_ptr; | 425 | segment = *segment_ptr; |
425 | if (!(segment & _SEGMENT_ENTRY_INV)) { | 426 | if (!(segment & _SEGMENT_ENTRY_INVALID)) { |
426 | page = pfn_to_page(segment >> PAGE_SHIFT); | 427 | page = pfn_to_page(segment >> PAGE_SHIFT); |
427 | mp = (struct gmap_pgtable *) page->index; | 428 | mp = (struct gmap_pgtable *) page->index; |
428 | return mp->vmaddr | (address & ~PMD_MASK); | 429 | return mp->vmaddr | (address & ~PMD_MASK); |
429 | } else if (segment & _SEGMENT_ENTRY_RO) { | 430 | } else if (segment & _SEGMENT_ENTRY_PROTECT) { |
430 | vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; | 431 | vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; |
431 | return vmaddr | (address & ~PMD_MASK); | 432 | return vmaddr | (address & ~PMD_MASK); |
432 | } | 433 | } |
@@ -517,8 +518,8 @@ static void gmap_disconnect_pgtable(struct mm_struct *mm, unsigned long *table) | |||
517 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | 518 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); |
518 | mp = (struct gmap_pgtable *) page->index; | 519 | mp = (struct gmap_pgtable *) page->index; |
519 | list_for_each_entry_safe(rmap, next, &mp->mapper, list) { | 520 | list_for_each_entry_safe(rmap, next, &mp->mapper, list) { |
520 | *rmap->entry = | 521 | *rmap->entry = mp->vmaddr | (_SEGMENT_ENTRY_INVALID | |
521 | _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | mp->vmaddr; | 522 | _SEGMENT_ENTRY_PROTECT); |
522 | list_del(&rmap->list); | 523 | list_del(&rmap->list); |
523 | kfree(rmap); | 524 | kfree(rmap); |
524 | flush = 1; | 525 | flush = 1; |
@@ -545,13 +546,13 @@ unsigned long __gmap_fault(unsigned long address, struct gmap *gmap) | |||
545 | /* Convert the gmap address to an mm address. */ | 546 | /* Convert the gmap address to an mm address. */ |
546 | while (1) { | 547 | while (1) { |
547 | segment = *segment_ptr; | 548 | segment = *segment_ptr; |
548 | if (!(segment & _SEGMENT_ENTRY_INV)) { | 549 | if (!(segment & _SEGMENT_ENTRY_INVALID)) { |
549 | /* Page table is present */ | 550 | /* Page table is present */ |
550 | page = pfn_to_page(segment >> PAGE_SHIFT); | 551 | page = pfn_to_page(segment >> PAGE_SHIFT); |
551 | mp = (struct gmap_pgtable *) page->index; | 552 | mp = (struct gmap_pgtable *) page->index; |
552 | return mp->vmaddr | (address & ~PMD_MASK); | 553 | return mp->vmaddr | (address & ~PMD_MASK); |
553 | } | 554 | } |
554 | if (!(segment & _SEGMENT_ENTRY_RO)) | 555 | if (!(segment & _SEGMENT_ENTRY_PROTECT)) |
555 | /* Nothing mapped in the gmap address space. */ | 556 | /* Nothing mapped in the gmap address space. */ |
556 | break; | 557 | break; |
557 | rc = gmap_connect_pgtable(address, segment, segment_ptr, gmap); | 558 | rc = gmap_connect_pgtable(address, segment, segment_ptr, gmap); |
@@ -586,25 +587,25 @@ void gmap_discard(unsigned long from, unsigned long to, struct gmap *gmap) | |||
586 | while (address < to) { | 587 | while (address < to) { |
587 | /* Walk the gmap address space page table */ | 588 | /* Walk the gmap address space page table */ |
588 | table = gmap->table + ((address >> 53) & 0x7ff); | 589 | table = gmap->table + ((address >> 53) & 0x7ff); |
589 | if (unlikely(*table & _REGION_ENTRY_INV)) { | 590 | if (unlikely(*table & _REGION_ENTRY_INVALID)) { |
590 | address = (address + PMD_SIZE) & PMD_MASK; | 591 | address = (address + PMD_SIZE) & PMD_MASK; |
591 | continue; | 592 | continue; |
592 | } | 593 | } |
593 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 594 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
594 | table = table + ((address >> 42) & 0x7ff); | 595 | table = table + ((address >> 42) & 0x7ff); |
595 | if (unlikely(*table & _REGION_ENTRY_INV)) { | 596 | if (unlikely(*table & _REGION_ENTRY_INVALID)) { |
596 | address = (address + PMD_SIZE) & PMD_MASK; | 597 | address = (address + PMD_SIZE) & PMD_MASK; |
597 | continue; | 598 | continue; |
598 | } | 599 | } |
599 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 600 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
600 | table = table + ((address >> 31) & 0x7ff); | 601 | table = table + ((address >> 31) & 0x7ff); |
601 | if (unlikely(*table & _REGION_ENTRY_INV)) { | 602 | if (unlikely(*table & _REGION_ENTRY_INVALID)) { |
602 | address = (address + PMD_SIZE) & PMD_MASK; | 603 | address = (address + PMD_SIZE) & PMD_MASK; |
603 | continue; | 604 | continue; |
604 | } | 605 | } |
605 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 606 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
606 | table = table + ((address >> 20) & 0x7ff); | 607 | table = table + ((address >> 20) & 0x7ff); |
607 | if (unlikely(*table & _SEGMENT_ENTRY_INV)) { | 608 | if (unlikely(*table & _SEGMENT_ENTRY_INVALID)) { |
608 | address = (address + PMD_SIZE) & PMD_MASK; | 609 | address = (address + PMD_SIZE) & PMD_MASK; |
609 | continue; | 610 | continue; |
610 | } | 611 | } |
@@ -687,7 +688,7 @@ int gmap_ipte_notify(struct gmap *gmap, unsigned long start, unsigned long len) | |||
687 | continue; | 688 | continue; |
688 | /* Set notification bit in the pgste of the pte */ | 689 | /* Set notification bit in the pgste of the pte */ |
689 | entry = *ptep; | 690 | entry = *ptep; |
690 | if ((pte_val(entry) & (_PAGE_INVALID | _PAGE_RO)) == 0) { | 691 | if ((pte_val(entry) & (_PAGE_INVALID | _PAGE_PROTECT)) == 0) { |
691 | pgste = pgste_get_lock(ptep); | 692 | pgste = pgste_get_lock(ptep); |
692 | pgste_val(pgste) |= PGSTE_IN_BIT; | 693 | pgste_val(pgste) |= PGSTE_IN_BIT; |
693 | pgste_set_unlock(ptep, pgste); | 694 | pgste_set_unlock(ptep, pgste); |
@@ -731,6 +732,11 @@ void gmap_do_ipte_notify(struct mm_struct *mm, unsigned long addr, pte_t *pte) | |||
731 | spin_unlock(&gmap_notifier_lock); | 732 | spin_unlock(&gmap_notifier_lock); |
732 | } | 733 | } |
733 | 734 | ||
735 | static inline int page_table_with_pgste(struct page *page) | ||
736 | { | ||
737 | return atomic_read(&page->_mapcount) == 0; | ||
738 | } | ||
739 | |||
734 | static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, | 740 | static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, |
735 | unsigned long vmaddr) | 741 | unsigned long vmaddr) |
736 | { | 742 | { |
@@ -750,10 +756,11 @@ static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, | |||
750 | mp->vmaddr = vmaddr & PMD_MASK; | 756 | mp->vmaddr = vmaddr & PMD_MASK; |
751 | INIT_LIST_HEAD(&mp->mapper); | 757 | INIT_LIST_HEAD(&mp->mapper); |
752 | page->index = (unsigned long) mp; | 758 | page->index = (unsigned long) mp; |
753 | atomic_set(&page->_mapcount, 3); | 759 | atomic_set(&page->_mapcount, 0); |
754 | table = (unsigned long *) page_to_phys(page); | 760 | table = (unsigned long *) page_to_phys(page); |
755 | clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE/2); | 761 | clear_table(table, _PAGE_INVALID, PAGE_SIZE/2); |
756 | clear_table(table + PTRS_PER_PTE, 0, PAGE_SIZE/2); | 762 | clear_table(table + PTRS_PER_PTE, PGSTE_HR_BIT | PGSTE_HC_BIT, |
763 | PAGE_SIZE/2); | ||
757 | return table; | 764 | return table; |
758 | } | 765 | } |
759 | 766 | ||
@@ -791,26 +798,21 @@ int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, | |||
791 | pgste_val(new) |= (key & (_PAGE_CHANGED | _PAGE_REFERENCED)) << 48; | 798 | pgste_val(new) |= (key & (_PAGE_CHANGED | _PAGE_REFERENCED)) << 48; |
792 | pgste_val(new) |= (key & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56; | 799 | pgste_val(new) |= (key & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56; |
793 | if (!(pte_val(*ptep) & _PAGE_INVALID)) { | 800 | if (!(pte_val(*ptep) & _PAGE_INVALID)) { |
794 | unsigned long address, bits; | 801 | unsigned long address, bits, skey; |
795 | unsigned char skey; | ||
796 | 802 | ||
797 | address = pte_val(*ptep) & PAGE_MASK; | 803 | address = pte_val(*ptep) & PAGE_MASK; |
798 | skey = page_get_storage_key(address); | 804 | skey = (unsigned long) page_get_storage_key(address); |
799 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); | 805 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); |
806 | skey = key & (_PAGE_ACC_BITS | _PAGE_FP_BIT); | ||
800 | /* Set storage key ACC and FP */ | 807 | /* Set storage key ACC and FP */ |
801 | page_set_storage_key(address, | 808 | page_set_storage_key(address, skey, !nq); |
802 | (key & (_PAGE_ACC_BITS | _PAGE_FP_BIT)), | ||
803 | !nq); | ||
804 | |||
805 | /* Merge host changed & referenced into pgste */ | 809 | /* Merge host changed & referenced into pgste */ |
806 | pgste_val(new) |= bits << 52; | 810 | pgste_val(new) |= bits << 52; |
807 | /* Transfer skey changed & referenced bit to kvm user bits */ | ||
808 | pgste_val(new) |= bits << 45; /* PGSTE_UR_BIT & PGSTE_UC_BIT */ | ||
809 | } | 811 | } |
810 | /* changing the guest storage key is considered a change of the page */ | 812 | /* changing the guest storage key is considered a change of the page */ |
811 | if ((pgste_val(new) ^ pgste_val(old)) & | 813 | if ((pgste_val(new) ^ pgste_val(old)) & |
812 | (PGSTE_ACC_BITS | PGSTE_FP_BIT | PGSTE_GR_BIT | PGSTE_GC_BIT)) | 814 | (PGSTE_ACC_BITS | PGSTE_FP_BIT | PGSTE_GR_BIT | PGSTE_GC_BIT)) |
813 | pgste_val(new) |= PGSTE_UC_BIT; | 815 | pgste_val(new) |= PGSTE_HC_BIT; |
814 | 816 | ||
815 | pgste_set_unlock(ptep, new); | 817 | pgste_set_unlock(ptep, new); |
816 | pte_unmap_unlock(*ptep, ptl); | 818 | pte_unmap_unlock(*ptep, ptl); |
@@ -821,6 +823,11 @@ EXPORT_SYMBOL(set_guest_storage_key); | |||
821 | 823 | ||
822 | #else /* CONFIG_PGSTE */ | 824 | #else /* CONFIG_PGSTE */ |
823 | 825 | ||
826 | static inline int page_table_with_pgste(struct page *page) | ||
827 | { | ||
828 | return 0; | ||
829 | } | ||
830 | |||
824 | static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, | 831 | static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, |
825 | unsigned long vmaddr) | 832 | unsigned long vmaddr) |
826 | { | 833 | { |
@@ -878,7 +885,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm, unsigned long vmaddr) | |||
878 | pgtable_page_ctor(page); | 885 | pgtable_page_ctor(page); |
879 | atomic_set(&page->_mapcount, 1); | 886 | atomic_set(&page->_mapcount, 1); |
880 | table = (unsigned long *) page_to_phys(page); | 887 | table = (unsigned long *) page_to_phys(page); |
881 | clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); | 888 | clear_table(table, _PAGE_INVALID, PAGE_SIZE); |
882 | spin_lock_bh(&mm->context.list_lock); | 889 | spin_lock_bh(&mm->context.list_lock); |
883 | list_add(&page->lru, &mm->context.pgtable_list); | 890 | list_add(&page->lru, &mm->context.pgtable_list); |
884 | } else { | 891 | } else { |
@@ -897,12 +904,12 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) | |||
897 | struct page *page; | 904 | struct page *page; |
898 | unsigned int bit, mask; | 905 | unsigned int bit, mask; |
899 | 906 | ||
900 | if (mm_has_pgste(mm)) { | 907 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); |
908 | if (page_table_with_pgste(page)) { | ||
901 | gmap_disconnect_pgtable(mm, table); | 909 | gmap_disconnect_pgtable(mm, table); |
902 | return page_table_free_pgste(table); | 910 | return page_table_free_pgste(table); |
903 | } | 911 | } |
904 | /* Free 1K/2K page table fragment of a 4K page */ | 912 | /* Free 1K/2K page table fragment of a 4K page */ |
905 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | ||
906 | bit = 1 << ((__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t))); | 913 | bit = 1 << ((__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t))); |
907 | spin_lock_bh(&mm->context.list_lock); | 914 | spin_lock_bh(&mm->context.list_lock); |
908 | if ((atomic_read(&page->_mapcount) & FRAG_MASK) != FRAG_MASK) | 915 | if ((atomic_read(&page->_mapcount) & FRAG_MASK) != FRAG_MASK) |
@@ -940,14 +947,14 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table) | |||
940 | unsigned int bit, mask; | 947 | unsigned int bit, mask; |
941 | 948 | ||
942 | mm = tlb->mm; | 949 | mm = tlb->mm; |
943 | if (mm_has_pgste(mm)) { | 950 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); |
951 | if (page_table_with_pgste(page)) { | ||
944 | gmap_disconnect_pgtable(mm, table); | 952 | gmap_disconnect_pgtable(mm, table); |
945 | table = (unsigned long *) (__pa(table) | FRAG_MASK); | 953 | table = (unsigned long *) (__pa(table) | FRAG_MASK); |
946 | tlb_remove_table(tlb, table); | 954 | tlb_remove_table(tlb, table); |
947 | return; | 955 | return; |
948 | } | 956 | } |
949 | bit = 1 << ((__pa(table) & ~PAGE_MASK) / (PTRS_PER_PTE*sizeof(pte_t))); | 957 | bit = 1 << ((__pa(table) & ~PAGE_MASK) / (PTRS_PER_PTE*sizeof(pte_t))); |
950 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | ||
951 | spin_lock_bh(&mm->context.list_lock); | 958 | spin_lock_bh(&mm->context.list_lock); |
952 | if ((atomic_read(&page->_mapcount) & FRAG_MASK) != FRAG_MASK) | 959 | if ((atomic_read(&page->_mapcount) & FRAG_MASK) != FRAG_MASK) |
953 | list_del(&page->lru); | 960 | list_del(&page->lru); |
@@ -1007,7 +1014,6 @@ void tlb_table_flush(struct mmu_gather *tlb) | |||
1007 | struct mmu_table_batch **batch = &tlb->batch; | 1014 | struct mmu_table_batch **batch = &tlb->batch; |
1008 | 1015 | ||
1009 | if (*batch) { | 1016 | if (*batch) { |
1010 | __tlb_flush_mm(tlb->mm); | ||
1011 | call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); | 1017 | call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); |
1012 | *batch = NULL; | 1018 | *batch = NULL; |
1013 | } | 1019 | } |
@@ -1017,11 +1023,12 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table) | |||
1017 | { | 1023 | { |
1018 | struct mmu_table_batch **batch = &tlb->batch; | 1024 | struct mmu_table_batch **batch = &tlb->batch; |
1019 | 1025 | ||
1026 | tlb->mm->context.flush_mm = 1; | ||
1020 | if (*batch == NULL) { | 1027 | if (*batch == NULL) { |
1021 | *batch = (struct mmu_table_batch *) | 1028 | *batch = (struct mmu_table_batch *) |
1022 | __get_free_page(GFP_NOWAIT | __GFP_NOWARN); | 1029 | __get_free_page(GFP_NOWAIT | __GFP_NOWARN); |
1023 | if (*batch == NULL) { | 1030 | if (*batch == NULL) { |
1024 | __tlb_flush_mm(tlb->mm); | 1031 | __tlb_flush_mm_lazy(tlb->mm); |
1025 | tlb_remove_table_one(table); | 1032 | tlb_remove_table_one(table); |
1026 | return; | 1033 | return; |
1027 | } | 1034 | } |
@@ -1029,40 +1036,124 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table) | |||
1029 | } | 1036 | } |
1030 | (*batch)->tables[(*batch)->nr++] = table; | 1037 | (*batch)->tables[(*batch)->nr++] = table; |
1031 | if ((*batch)->nr == MAX_TABLE_BATCH) | 1038 | if ((*batch)->nr == MAX_TABLE_BATCH) |
1032 | tlb_table_flush(tlb); | 1039 | tlb_flush_mmu(tlb); |
1033 | } | 1040 | } |
1034 | 1041 | ||
1035 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 1042 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
1036 | void thp_split_vma(struct vm_area_struct *vma) | 1043 | static inline void thp_split_vma(struct vm_area_struct *vma) |
1037 | { | 1044 | { |
1038 | unsigned long addr; | 1045 | unsigned long addr; |
1039 | struct page *page; | ||
1040 | 1046 | ||
1041 | for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { | 1047 | for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) |
1042 | page = follow_page(vma, addr, FOLL_SPLIT); | 1048 | follow_page(vma, addr, FOLL_SPLIT); |
1043 | } | ||
1044 | } | 1049 | } |
1045 | 1050 | ||
1046 | void thp_split_mm(struct mm_struct *mm) | 1051 | static inline void thp_split_mm(struct mm_struct *mm) |
1047 | { | 1052 | { |
1048 | struct vm_area_struct *vma = mm->mmap; | 1053 | struct vm_area_struct *vma; |
1049 | 1054 | ||
1050 | while (vma != NULL) { | 1055 | for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) { |
1051 | thp_split_vma(vma); | 1056 | thp_split_vma(vma); |
1052 | vma->vm_flags &= ~VM_HUGEPAGE; | 1057 | vma->vm_flags &= ~VM_HUGEPAGE; |
1053 | vma->vm_flags |= VM_NOHUGEPAGE; | 1058 | vma->vm_flags |= VM_NOHUGEPAGE; |
1054 | vma = vma->vm_next; | ||
1055 | } | 1059 | } |
1060 | mm->def_flags |= VM_NOHUGEPAGE; | ||
1061 | } | ||
1062 | #else | ||
1063 | static inline void thp_split_mm(struct mm_struct *mm) | ||
1064 | { | ||
1056 | } | 1065 | } |
1057 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 1066 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
1058 | 1067 | ||
1068 | static unsigned long page_table_realloc_pmd(struct mmu_gather *tlb, | ||
1069 | struct mm_struct *mm, pud_t *pud, | ||
1070 | unsigned long addr, unsigned long end) | ||
1071 | { | ||
1072 | unsigned long next, *table, *new; | ||
1073 | struct page *page; | ||
1074 | pmd_t *pmd; | ||
1075 | |||
1076 | pmd = pmd_offset(pud, addr); | ||
1077 | do { | ||
1078 | next = pmd_addr_end(addr, end); | ||
1079 | again: | ||
1080 | if (pmd_none_or_clear_bad(pmd)) | ||
1081 | continue; | ||
1082 | table = (unsigned long *) pmd_deref(*pmd); | ||
1083 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | ||
1084 | if (page_table_with_pgste(page)) | ||
1085 | continue; | ||
1086 | /* Allocate new page table with pgstes */ | ||
1087 | new = page_table_alloc_pgste(mm, addr); | ||
1088 | if (!new) { | ||
1089 | mm->context.has_pgste = 0; | ||
1090 | continue; | ||
1091 | } | ||
1092 | spin_lock(&mm->page_table_lock); | ||
1093 | if (likely((unsigned long *) pmd_deref(*pmd) == table)) { | ||
1094 | /* Nuke pmd entry pointing to the "short" page table */ | ||
1095 | pmdp_flush_lazy(mm, addr, pmd); | ||
1096 | pmd_clear(pmd); | ||
1097 | /* Copy ptes from old table to new table */ | ||
1098 | memcpy(new, table, PAGE_SIZE/2); | ||
1099 | clear_table(table, _PAGE_INVALID, PAGE_SIZE/2); | ||
1100 | /* Establish new table */ | ||
1101 | pmd_populate(mm, pmd, (pte_t *) new); | ||
1102 | /* Free old table with rcu, there might be a walker! */ | ||
1103 | page_table_free_rcu(tlb, table); | ||
1104 | new = NULL; | ||
1105 | } | ||
1106 | spin_unlock(&mm->page_table_lock); | ||
1107 | if (new) { | ||
1108 | page_table_free_pgste(new); | ||
1109 | goto again; | ||
1110 | } | ||
1111 | } while (pmd++, addr = next, addr != end); | ||
1112 | |||
1113 | return addr; | ||
1114 | } | ||
1115 | |||
1116 | static unsigned long page_table_realloc_pud(struct mmu_gather *tlb, | ||
1117 | struct mm_struct *mm, pgd_t *pgd, | ||
1118 | unsigned long addr, unsigned long end) | ||
1119 | { | ||
1120 | unsigned long next; | ||
1121 | pud_t *pud; | ||
1122 | |||
1123 | pud = pud_offset(pgd, addr); | ||
1124 | do { | ||
1125 | next = pud_addr_end(addr, end); | ||
1126 | if (pud_none_or_clear_bad(pud)) | ||
1127 | continue; | ||
1128 | next = page_table_realloc_pmd(tlb, mm, pud, addr, next); | ||
1129 | } while (pud++, addr = next, addr != end); | ||
1130 | |||
1131 | return addr; | ||
1132 | } | ||
1133 | |||
1134 | static void page_table_realloc(struct mmu_gather *tlb, struct mm_struct *mm, | ||
1135 | unsigned long addr, unsigned long end) | ||
1136 | { | ||
1137 | unsigned long next; | ||
1138 | pgd_t *pgd; | ||
1139 | |||
1140 | pgd = pgd_offset(mm, addr); | ||
1141 | do { | ||
1142 | next = pgd_addr_end(addr, end); | ||
1143 | if (pgd_none_or_clear_bad(pgd)) | ||
1144 | continue; | ||
1145 | next = page_table_realloc_pud(tlb, mm, pgd, addr, next); | ||
1146 | } while (pgd++, addr = next, addr != end); | ||
1147 | } | ||
1148 | |||
1059 | /* | 1149 | /* |
1060 | * switch on pgstes for its userspace process (for kvm) | 1150 | * switch on pgstes for its userspace process (for kvm) |
1061 | */ | 1151 | */ |
1062 | int s390_enable_sie(void) | 1152 | int s390_enable_sie(void) |
1063 | { | 1153 | { |
1064 | struct task_struct *tsk = current; | 1154 | struct task_struct *tsk = current; |
1065 | struct mm_struct *mm, *old_mm; | 1155 | struct mm_struct *mm = tsk->mm; |
1156 | struct mmu_gather tlb; | ||
1066 | 1157 | ||
1067 | /* Do we have switched amode? If no, we cannot do sie */ | 1158 | /* Do we have switched amode? If no, we cannot do sie */ |
1068 | if (s390_user_mode == HOME_SPACE_MODE) | 1159 | if (s390_user_mode == HOME_SPACE_MODE) |
@@ -1072,57 +1163,16 @@ int s390_enable_sie(void) | |||
1072 | if (mm_has_pgste(tsk->mm)) | 1163 | if (mm_has_pgste(tsk->mm)) |
1073 | return 0; | 1164 | return 0; |
1074 | 1165 | ||
1075 | /* lets check if we are allowed to replace the mm */ | 1166 | down_write(&mm->mmap_sem); |
1076 | task_lock(tsk); | ||
1077 | if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || | ||
1078 | #ifdef CONFIG_AIO | ||
1079 | !hlist_empty(&tsk->mm->ioctx_list) || | ||
1080 | #endif | ||
1081 | tsk->mm != tsk->active_mm) { | ||
1082 | task_unlock(tsk); | ||
1083 | return -EINVAL; | ||
1084 | } | ||
1085 | task_unlock(tsk); | ||
1086 | |||
1087 | /* we copy the mm and let dup_mm create the page tables with_pgstes */ | ||
1088 | tsk->mm->context.alloc_pgste = 1; | ||
1089 | /* make sure that both mms have a correct rss state */ | ||
1090 | sync_mm_rss(tsk->mm); | ||
1091 | mm = dup_mm(tsk); | ||
1092 | tsk->mm->context.alloc_pgste = 0; | ||
1093 | if (!mm) | ||
1094 | return -ENOMEM; | ||
1095 | |||
1096 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
1097 | /* split thp mappings and disable thp for future mappings */ | 1167 | /* split thp mappings and disable thp for future mappings */ |
1098 | thp_split_mm(mm); | 1168 | thp_split_mm(mm); |
1099 | mm->def_flags |= VM_NOHUGEPAGE; | 1169 | /* Reallocate the page tables with pgstes */ |
1100 | #endif | 1170 | mm->context.has_pgste = 1; |
1101 | 1171 | tlb_gather_mmu(&tlb, mm, 0, TASK_SIZE); | |
1102 | /* Now lets check again if something happened */ | 1172 | page_table_realloc(&tlb, mm, 0, TASK_SIZE); |
1103 | task_lock(tsk); | 1173 | tlb_finish_mmu(&tlb, 0, TASK_SIZE); |
1104 | if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || | 1174 | up_write(&mm->mmap_sem); |
1105 | #ifdef CONFIG_AIO | 1175 | return mm->context.has_pgste ? 0 : -ENOMEM; |
1106 | !hlist_empty(&tsk->mm->ioctx_list) || | ||
1107 | #endif | ||
1108 | tsk->mm != tsk->active_mm) { | ||
1109 | mmput(mm); | ||
1110 | task_unlock(tsk); | ||
1111 | return -EINVAL; | ||
1112 | } | ||
1113 | |||
1114 | /* ok, we are alone. No ptrace, no threads, etc. */ | ||
1115 | old_mm = tsk->mm; | ||
1116 | tsk->mm = tsk->active_mm = mm; | ||
1117 | preempt_disable(); | ||
1118 | update_mm(mm, tsk); | ||
1119 | atomic_inc(&mm->context.attach_count); | ||
1120 | atomic_dec(&old_mm->context.attach_count); | ||
1121 | cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); | ||
1122 | preempt_enable(); | ||
1123 | task_unlock(tsk); | ||
1124 | mmput(old_mm); | ||
1125 | return 0; | ||
1126 | } | 1176 | } |
1127 | EXPORT_SYMBOL_GPL(s390_enable_sie); | 1177 | EXPORT_SYMBOL_GPL(s390_enable_sie); |
1128 | 1178 | ||
@@ -1198,9 +1248,9 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) | |||
1198 | list_del(lh); | 1248 | list_del(lh); |
1199 | } | 1249 | } |
1200 | ptep = (pte_t *) pgtable; | 1250 | ptep = (pte_t *) pgtable; |
1201 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | 1251 | pte_val(*ptep) = _PAGE_INVALID; |
1202 | ptep++; | 1252 | ptep++; |
1203 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | 1253 | pte_val(*ptep) = _PAGE_INVALID; |
1204 | return pgtable; | 1254 | return pgtable; |
1205 | } | 1255 | } |
1206 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 1256 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index 8b268fcc4612..bcfb70b60be6 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
@@ -69,7 +69,7 @@ static pte_t __ref *vmem_pte_alloc(unsigned long address) | |||
69 | pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t)); | 69 | pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t)); |
70 | if (!pte) | 70 | if (!pte) |
71 | return NULL; | 71 | return NULL; |
72 | clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, | 72 | clear_table((unsigned long *) pte, _PAGE_INVALID, |
73 | PTRS_PER_PTE * sizeof(pte_t)); | 73 | PTRS_PER_PTE * sizeof(pte_t)); |
74 | return pte; | 74 | return pte; |
75 | } | 75 | } |
@@ -101,7 +101,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) | |||
101 | !(address & ~PUD_MASK) && (address + PUD_SIZE <= end)) { | 101 | !(address & ~PUD_MASK) && (address + PUD_SIZE <= end)) { |
102 | pud_val(*pu_dir) = __pa(address) | | 102 | pud_val(*pu_dir) = __pa(address) | |
103 | _REGION_ENTRY_TYPE_R3 | _REGION3_ENTRY_LARGE | | 103 | _REGION_ENTRY_TYPE_R3 | _REGION3_ENTRY_LARGE | |
104 | (ro ? _REGION_ENTRY_RO : 0); | 104 | (ro ? _REGION_ENTRY_PROTECT : 0); |
105 | address += PUD_SIZE; | 105 | address += PUD_SIZE; |
106 | continue; | 106 | continue; |
107 | } | 107 | } |
@@ -118,7 +118,8 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) | |||
118 | !(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) { | 118 | !(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) { |
119 | pmd_val(*pm_dir) = __pa(address) | | 119 | pmd_val(*pm_dir) = __pa(address) | |
120 | _SEGMENT_ENTRY | _SEGMENT_ENTRY_LARGE | | 120 | _SEGMENT_ENTRY | _SEGMENT_ENTRY_LARGE | |
121 | (ro ? _SEGMENT_ENTRY_RO : 0); | 121 | _SEGMENT_ENTRY_YOUNG | |
122 | (ro ? _SEGMENT_ENTRY_PROTECT : 0); | ||
122 | address += PMD_SIZE; | 123 | address += PMD_SIZE; |
123 | continue; | 124 | continue; |
124 | } | 125 | } |
@@ -131,7 +132,8 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) | |||
131 | } | 132 | } |
132 | 133 | ||
133 | pt_dir = pte_offset_kernel(pm_dir, address); | 134 | pt_dir = pte_offset_kernel(pm_dir, address); |
134 | pte_val(*pt_dir) = __pa(address) | (ro ? _PAGE_RO : 0); | 135 | pte_val(*pt_dir) = __pa(address) | |
136 | pgprot_val(ro ? PAGE_KERNEL_RO : PAGE_KERNEL); | ||
135 | address += PAGE_SIZE; | 137 | address += PAGE_SIZE; |
136 | } | 138 | } |
137 | ret = 0; | 139 | ret = 0; |
@@ -154,7 +156,7 @@ static void vmem_remove_range(unsigned long start, unsigned long size) | |||
154 | pte_t *pt_dir; | 156 | pte_t *pt_dir; |
155 | pte_t pte; | 157 | pte_t pte; |
156 | 158 | ||
157 | pte_val(pte) = _PAGE_TYPE_EMPTY; | 159 | pte_val(pte) = _PAGE_INVALID; |
158 | while (address < end) { | 160 | while (address < end) { |
159 | pg_dir = pgd_offset_k(address); | 161 | pg_dir = pgd_offset_k(address); |
160 | if (pgd_none(*pg_dir)) { | 162 | if (pgd_none(*pg_dir)) { |
@@ -255,7 +257,8 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) | |||
255 | new_page =__pa(vmem_alloc_pages(0)); | 257 | new_page =__pa(vmem_alloc_pages(0)); |
256 | if (!new_page) | 258 | if (!new_page) |
257 | goto out; | 259 | goto out; |
258 | pte_val(*pt_dir) = __pa(new_page); | 260 | pte_val(*pt_dir) = |
261 | __pa(new_page) | pgprot_val(PAGE_KERNEL); | ||
259 | } | 262 | } |
260 | address += PAGE_SIZE; | 263 | address += PAGE_SIZE; |
261 | } | 264 | } |
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 930783d2c99b..04e1b6a85362 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c | |||
@@ -346,16 +346,15 @@ static const struct file_operations timer_enabled_fops = { | |||
346 | }; | 346 | }; |
347 | 347 | ||
348 | 348 | ||
349 | static int oprofile_create_hwsampling_files(struct super_block *sb, | 349 | static int oprofile_create_hwsampling_files(struct dentry *root) |
350 | struct dentry *root) | ||
351 | { | 350 | { |
352 | struct dentry *dir; | 351 | struct dentry *dir; |
353 | 352 | ||
354 | dir = oprofilefs_mkdir(sb, root, "timer"); | 353 | dir = oprofilefs_mkdir(root, "timer"); |
355 | if (!dir) | 354 | if (!dir) |
356 | return -EINVAL; | 355 | return -EINVAL; |
357 | 356 | ||
358 | oprofilefs_create_file(sb, dir, "enabled", &timer_enabled_fops); | 357 | oprofilefs_create_file(dir, "enabled", &timer_enabled_fops); |
359 | 358 | ||
360 | if (!hwsampler_available) | 359 | if (!hwsampler_available) |
361 | return 0; | 360 | return 0; |
@@ -376,17 +375,17 @@ static int oprofile_create_hwsampling_files(struct super_block *sb, | |||
376 | * and can only be set to 0. | 375 | * and can only be set to 0. |
377 | */ | 376 | */ |
378 | 377 | ||
379 | dir = oprofilefs_mkdir(sb, root, "0"); | 378 | dir = oprofilefs_mkdir(root, "0"); |
380 | if (!dir) | 379 | if (!dir) |
381 | return -EINVAL; | 380 | return -EINVAL; |
382 | 381 | ||
383 | oprofilefs_create_file(sb, dir, "enabled", &hwsampler_fops); | 382 | oprofilefs_create_file(dir, "enabled", &hwsampler_fops); |
384 | oprofilefs_create_file(sb, dir, "event", &zero_fops); | 383 | oprofilefs_create_file(dir, "event", &zero_fops); |
385 | oprofilefs_create_file(sb, dir, "count", &hw_interval_fops); | 384 | oprofilefs_create_file(dir, "count", &hw_interval_fops); |
386 | oprofilefs_create_file(sb, dir, "unit_mask", &zero_fops); | 385 | oprofilefs_create_file(dir, "unit_mask", &zero_fops); |
387 | oprofilefs_create_file(sb, dir, "kernel", &kernel_fops); | 386 | oprofilefs_create_file(dir, "kernel", &kernel_fops); |
388 | oprofilefs_create_file(sb, dir, "user", &user_fops); | 387 | oprofilefs_create_file(dir, "user", &user_fops); |
389 | oprofilefs_create_ulong(sb, dir, "hw_sdbt_blocks", | 388 | oprofilefs_create_ulong(dir, "hw_sdbt_blocks", |
390 | &oprofile_sdbt_blocks); | 389 | &oprofile_sdbt_blocks); |
391 | 390 | ||
392 | } else { | 391 | } else { |
@@ -396,19 +395,19 @@ static int oprofile_create_hwsampling_files(struct super_block *sb, | |||
396 | * space tools. The /dev/oprofile/hwsampling fs is | 395 | * space tools. The /dev/oprofile/hwsampling fs is |
397 | * provided in that case. | 396 | * provided in that case. |
398 | */ | 397 | */ |
399 | dir = oprofilefs_mkdir(sb, root, "hwsampling"); | 398 | dir = oprofilefs_mkdir(root, "hwsampling"); |
400 | if (!dir) | 399 | if (!dir) |
401 | return -EINVAL; | 400 | return -EINVAL; |
402 | 401 | ||
403 | oprofilefs_create_file(sb, dir, "hwsampler", | 402 | oprofilefs_create_file(dir, "hwsampler", |
404 | &hwsampler_fops); | 403 | &hwsampler_fops); |
405 | oprofilefs_create_file(sb, dir, "hw_interval", | 404 | oprofilefs_create_file(dir, "hw_interval", |
406 | &hw_interval_fops); | 405 | &hw_interval_fops); |
407 | oprofilefs_create_ro_ulong(sb, dir, "hw_min_interval", | 406 | oprofilefs_create_ro_ulong(dir, "hw_min_interval", |
408 | &oprofile_min_interval); | 407 | &oprofile_min_interval); |
409 | oprofilefs_create_ro_ulong(sb, dir, "hw_max_interval", | 408 | oprofilefs_create_ro_ulong(dir, "hw_max_interval", |
410 | &oprofile_max_interval); | 409 | &oprofile_max_interval); |
411 | oprofilefs_create_ulong(sb, dir, "hw_sdbt_blocks", | 410 | oprofilefs_create_ulong(dir, "hw_sdbt_blocks", |
412 | &oprofile_sdbt_blocks); | 411 | &oprofile_sdbt_blocks); |
413 | } | 412 | } |
414 | return 0; | 413 | return 0; |
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile index 086a2e37935d..a9e1dc4ae442 100644 --- a/arch/s390/pci/Makefile +++ b/arch/s390/pci/Makefile | |||
@@ -2,5 +2,5 @@ | |||
2 | # Makefile for the s390 PCI subsystem. | 2 | # Makefile for the s390 PCI subsystem. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o pci_sysfs.o \ | 5 | obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_sysfs.o \ |
6 | pci_event.o pci_debug.o pci_insn.o | 6 | pci_event.o pci_debug.o pci_insn.o |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index e2956ad39a4f..f17a8343e360 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -42,45 +42,26 @@ | |||
42 | #define SIC_IRQ_MODE_SINGLE 1 | 42 | #define SIC_IRQ_MODE_SINGLE 1 |
43 | 43 | ||
44 | #define ZPCI_NR_DMA_SPACES 1 | 44 | #define ZPCI_NR_DMA_SPACES 1 |
45 | #define ZPCI_MSI_VEC_BITS 6 | ||
46 | #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS | 45 | #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS |
47 | 46 | ||
48 | /* list of all detected zpci devices */ | 47 | /* list of all detected zpci devices */ |
49 | LIST_HEAD(zpci_list); | 48 | static LIST_HEAD(zpci_list); |
50 | EXPORT_SYMBOL_GPL(zpci_list); | 49 | static DEFINE_SPINLOCK(zpci_list_lock); |
51 | DEFINE_MUTEX(zpci_list_lock); | ||
52 | EXPORT_SYMBOL_GPL(zpci_list_lock); | ||
53 | 50 | ||
54 | static struct pci_hp_callback_ops *hotplug_ops; | 51 | static void zpci_enable_irq(struct irq_data *data); |
52 | static void zpci_disable_irq(struct irq_data *data); | ||
55 | 53 | ||
56 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); | 54 | static struct irq_chip zpci_irq_chip = { |
57 | static DEFINE_SPINLOCK(zpci_domain_lock); | 55 | .name = "zPCI", |
58 | 56 | .irq_unmask = zpci_enable_irq, | |
59 | struct callback { | 57 | .irq_mask = zpci_disable_irq, |
60 | irq_handler_t handler; | ||
61 | void *data; | ||
62 | }; | 58 | }; |
63 | 59 | ||
64 | struct zdev_irq_map { | 60 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); |
65 | unsigned long aibv; /* AI bit vector */ | 61 | static DEFINE_SPINLOCK(zpci_domain_lock); |
66 | int msi_vecs; /* consecutive MSI-vectors used */ | ||
67 | int __unused; | ||
68 | struct callback cb[ZPCI_NR_MSI_VECS]; /* callback handler array */ | ||
69 | spinlock_t lock; /* protect callbacks against de-reg */ | ||
70 | }; | ||
71 | |||
72 | struct intr_bucket { | ||
73 | /* amap of adapters, one bit per dev, corresponds to one irq nr */ | ||
74 | unsigned long *alloc; | ||
75 | /* AI summary bit, global page for all devices */ | ||
76 | unsigned long *aisb; | ||
77 | /* pointer to aibv and callback data in zdev */ | ||
78 | struct zdev_irq_map *imap[ZPCI_NR_DEVICES]; | ||
79 | /* protects the whole bucket struct */ | ||
80 | spinlock_t lock; | ||
81 | }; | ||
82 | 62 | ||
83 | static struct intr_bucket *bucket; | 63 | static struct airq_iv *zpci_aisb_iv; |
64 | static struct airq_iv *zpci_aibv[ZPCI_NR_DEVICES]; | ||
84 | 65 | ||
85 | /* Adapter interrupt definitions */ | 66 | /* Adapter interrupt definitions */ |
86 | static void zpci_irq_handler(struct airq_struct *airq); | 67 | static void zpci_irq_handler(struct airq_struct *airq); |
@@ -96,27 +77,8 @@ static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); | |||
96 | struct zpci_iomap_entry *zpci_iomap_start; | 77 | struct zpci_iomap_entry *zpci_iomap_start; |
97 | EXPORT_SYMBOL_GPL(zpci_iomap_start); | 78 | EXPORT_SYMBOL_GPL(zpci_iomap_start); |
98 | 79 | ||
99 | /* highest irq summary bit */ | ||
100 | static int __read_mostly aisb_max; | ||
101 | |||
102 | static struct kmem_cache *zdev_irq_cache; | ||
103 | static struct kmem_cache *zdev_fmb_cache; | 80 | static struct kmem_cache *zdev_fmb_cache; |
104 | 81 | ||
105 | static inline int irq_to_msi_nr(unsigned int irq) | ||
106 | { | ||
107 | return irq & ZPCI_MSI_MASK; | ||
108 | } | ||
109 | |||
110 | static inline int irq_to_dev_nr(unsigned int irq) | ||
111 | { | ||
112 | return irq >> ZPCI_MSI_VEC_BITS; | ||
113 | } | ||
114 | |||
115 | static inline struct zdev_irq_map *get_imap(unsigned int irq) | ||
116 | { | ||
117 | return bucket->imap[irq_to_dev_nr(irq)]; | ||
118 | } | ||
119 | |||
120 | struct zpci_dev *get_zdev(struct pci_dev *pdev) | 82 | struct zpci_dev *get_zdev(struct pci_dev *pdev) |
121 | { | 83 | { |
122 | return (struct zpci_dev *) pdev->sysdata; | 84 | return (struct zpci_dev *) pdev->sysdata; |
@@ -126,22 +88,17 @@ struct zpci_dev *get_zdev_by_fid(u32 fid) | |||
126 | { | 88 | { |
127 | struct zpci_dev *tmp, *zdev = NULL; | 89 | struct zpci_dev *tmp, *zdev = NULL; |
128 | 90 | ||
129 | mutex_lock(&zpci_list_lock); | 91 | spin_lock(&zpci_list_lock); |
130 | list_for_each_entry(tmp, &zpci_list, entry) { | 92 | list_for_each_entry(tmp, &zpci_list, entry) { |
131 | if (tmp->fid == fid) { | 93 | if (tmp->fid == fid) { |
132 | zdev = tmp; | 94 | zdev = tmp; |
133 | break; | 95 | break; |
134 | } | 96 | } |
135 | } | 97 | } |
136 | mutex_unlock(&zpci_list_lock); | 98 | spin_unlock(&zpci_list_lock); |
137 | return zdev; | 99 | return zdev; |
138 | } | 100 | } |
139 | 101 | ||
140 | bool zpci_fid_present(u32 fid) | ||
141 | { | ||
142 | return (get_zdev_by_fid(fid) != NULL) ? true : false; | ||
143 | } | ||
144 | |||
145 | static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) | 102 | static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) |
146 | { | 103 | { |
147 | return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; | 104 | return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; |
@@ -160,8 +117,7 @@ int pci_proc_domain(struct pci_bus *bus) | |||
160 | EXPORT_SYMBOL_GPL(pci_proc_domain); | 117 | EXPORT_SYMBOL_GPL(pci_proc_domain); |
161 | 118 | ||
162 | /* Modify PCI: Register adapter interruptions */ | 119 | /* Modify PCI: Register adapter interruptions */ |
163 | static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, | 120 | static int zpci_set_airq(struct zpci_dev *zdev) |
164 | u64 aibv) | ||
165 | { | 121 | { |
166 | u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT); | 122 | u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT); |
167 | struct zpci_fib *fib; | 123 | struct zpci_fib *fib; |
@@ -172,14 +128,14 @@ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, | |||
172 | return -ENOMEM; | 128 | return -ENOMEM; |
173 | 129 | ||
174 | fib->isc = PCI_ISC; | 130 | fib->isc = PCI_ISC; |
175 | fib->noi = zdev->irq_map->msi_vecs; | ||
176 | fib->sum = 1; /* enable summary notifications */ | 131 | fib->sum = 1; /* enable summary notifications */ |
177 | fib->aibv = aibv; | 132 | fib->noi = airq_iv_end(zdev->aibv); |
178 | fib->aibvo = 0; /* every function has its own page */ | 133 | fib->aibv = (unsigned long) zdev->aibv->vector; |
179 | fib->aisb = (u64) bucket->aisb + aisb / 8; | 134 | fib->aibvo = 0; /* each zdev has its own interrupt vector */ |
180 | fib->aisbo = aisb & ZPCI_MSI_MASK; | 135 | fib->aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8; |
136 | fib->aisbo = zdev->aisb & 63; | ||
181 | 137 | ||
182 | rc = s390pci_mod_fc(req, fib); | 138 | rc = zpci_mod_fc(req, fib); |
183 | pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); | 139 | pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); |
184 | 140 | ||
185 | free_page((unsigned long) fib); | 141 | free_page((unsigned long) fib); |
@@ -209,7 +165,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args | |||
209 | fib->iota = args->iota; | 165 | fib->iota = args->iota; |
210 | fib->fmb_addr = args->fmb_addr; | 166 | fib->fmb_addr = args->fmb_addr; |
211 | 167 | ||
212 | rc = s390pci_mod_fc(req, fib); | 168 | rc = zpci_mod_fc(req, fib); |
213 | free_page((unsigned long) fib); | 169 | free_page((unsigned long) fib); |
214 | return rc; | 170 | return rc; |
215 | } | 171 | } |
@@ -234,7 +190,7 @@ int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas) | |||
234 | } | 190 | } |
235 | 191 | ||
236 | /* Modify PCI: Unregister adapter interruptions */ | 192 | /* Modify PCI: Unregister adapter interruptions */ |
237 | static int zpci_unregister_airq(struct zpci_dev *zdev) | 193 | static int zpci_clear_airq(struct zpci_dev *zdev) |
238 | { | 194 | { |
239 | struct mod_pci_args args = { 0, 0, 0, 0 }; | 195 | struct mod_pci_args args = { 0, 0, 0, 0 }; |
240 | 196 | ||
@@ -283,7 +239,7 @@ static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) | |||
283 | u64 data; | 239 | u64 data; |
284 | int rc; | 240 | int rc; |
285 | 241 | ||
286 | rc = s390pci_load(&data, req, offset); | 242 | rc = zpci_load(&data, req, offset); |
287 | if (!rc) { | 243 | if (!rc) { |
288 | data = data << ((8 - len) * 8); | 244 | data = data << ((8 - len) * 8); |
289 | data = le64_to_cpu(data); | 245 | data = le64_to_cpu(data); |
@@ -301,25 +257,46 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) | |||
301 | 257 | ||
302 | data = cpu_to_le64(data); | 258 | data = cpu_to_le64(data); |
303 | data = data >> ((8 - len) * 8); | 259 | data = data >> ((8 - len) * 8); |
304 | rc = s390pci_store(data, req, offset); | 260 | rc = zpci_store(data, req, offset); |
305 | return rc; | 261 | return rc; |
306 | } | 262 | } |
307 | 263 | ||
308 | void enable_irq(unsigned int irq) | 264 | static int zpci_msi_set_mask_bits(struct msi_desc *msi, u32 mask, u32 flag) |
265 | { | ||
266 | int offset, pos; | ||
267 | u32 mask_bits; | ||
268 | |||
269 | if (msi->msi_attrib.is_msix) { | ||
270 | offset = msi->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
271 | PCI_MSIX_ENTRY_VECTOR_CTRL; | ||
272 | msi->masked = readl(msi->mask_base + offset); | ||
273 | writel(flag, msi->mask_base + offset); | ||
274 | } else if (msi->msi_attrib.maskbit) { | ||
275 | pos = (long) msi->mask_base; | ||
276 | pci_read_config_dword(msi->dev, pos, &mask_bits); | ||
277 | mask_bits &= ~(mask); | ||
278 | mask_bits |= flag & mask; | ||
279 | pci_write_config_dword(msi->dev, pos, mask_bits); | ||
280 | } else | ||
281 | return 0; | ||
282 | |||
283 | msi->msi_attrib.maskbit = !!flag; | ||
284 | return 1; | ||
285 | } | ||
286 | |||
287 | static void zpci_enable_irq(struct irq_data *data) | ||
309 | { | 288 | { |
310 | struct msi_desc *msi = irq_get_msi_desc(irq); | 289 | struct msi_desc *msi = irq_get_msi_desc(data->irq); |
311 | 290 | ||
312 | zpci_msi_set_mask_bits(msi, 1, 0); | 291 | zpci_msi_set_mask_bits(msi, 1, 0); |
313 | } | 292 | } |
314 | EXPORT_SYMBOL_GPL(enable_irq); | ||
315 | 293 | ||
316 | void disable_irq(unsigned int irq) | 294 | static void zpci_disable_irq(struct irq_data *data) |
317 | { | 295 | { |
318 | struct msi_desc *msi = irq_get_msi_desc(irq); | 296 | struct msi_desc *msi = irq_get_msi_desc(data->irq); |
319 | 297 | ||
320 | zpci_msi_set_mask_bits(msi, 1, 1); | 298 | zpci_msi_set_mask_bits(msi, 1, 1); |
321 | } | 299 | } |
322 | EXPORT_SYMBOL_GPL(disable_irq); | ||
323 | 300 | ||
324 | void pcibios_fixup_bus(struct pci_bus *bus) | 301 | void pcibios_fixup_bus(struct pci_bus *bus) |
325 | { | 302 | { |
@@ -404,152 +381,147 @@ static struct pci_ops pci_root_ops = { | |||
404 | .write = pci_write, | 381 | .write = pci_write, |
405 | }; | 382 | }; |
406 | 383 | ||
407 | /* store the last handled bit to implement fair scheduling of devices */ | ||
408 | static DEFINE_PER_CPU(unsigned long, next_sbit); | ||
409 | |||
410 | static void zpci_irq_handler(struct airq_struct *airq) | 384 | static void zpci_irq_handler(struct airq_struct *airq) |
411 | { | 385 | { |
412 | unsigned long sbit, mbit, last = 0, start = __get_cpu_var(next_sbit); | 386 | unsigned long si, ai; |
413 | int rescan = 0, max = aisb_max; | 387 | struct airq_iv *aibv; |
414 | struct zdev_irq_map *imap; | 388 | int irqs_on = 0; |
415 | 389 | ||
416 | inc_irq_stat(IRQIO_PCI); | 390 | inc_irq_stat(IRQIO_PCI); |
417 | sbit = start; | 391 | for (si = 0;;) { |
418 | 392 | /* Scan adapter summary indicator bit vector */ | |
419 | scan: | 393 | si = airq_iv_scan(zpci_aisb_iv, si, airq_iv_end(zpci_aisb_iv)); |
420 | /* find summary_bit */ | 394 | if (si == -1UL) { |
421 | for_each_set_bit_left_cont(sbit, bucket->aisb, max) { | 395 | if (irqs_on++) |
422 | clear_bit(63 - (sbit & 63), bucket->aisb + (sbit >> 6)); | 396 | /* End of second scan with interrupts on. */ |
423 | last = sbit; | 397 | break; |
398 | /* First scan complete, reenable interrupts. */ | ||
399 | zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | ||
400 | si = 0; | ||
401 | continue; | ||
402 | } | ||
424 | 403 | ||
425 | /* find vector bit */ | 404 | /* Scan the adapter interrupt vector for this device. */ |
426 | imap = bucket->imap[sbit]; | 405 | aibv = zpci_aibv[si]; |
427 | for_each_set_bit_left(mbit, &imap->aibv, imap->msi_vecs) { | 406 | for (ai = 0;;) { |
407 | ai = airq_iv_scan(aibv, ai, airq_iv_end(aibv)); | ||
408 | if (ai == -1UL) | ||
409 | break; | ||
428 | inc_irq_stat(IRQIO_MSI); | 410 | inc_irq_stat(IRQIO_MSI); |
429 | clear_bit(63 - mbit, &imap->aibv); | 411 | airq_iv_lock(aibv, ai); |
430 | 412 | generic_handle_irq(airq_iv_get_data(aibv, ai)); | |
431 | spin_lock(&imap->lock); | 413 | airq_iv_unlock(aibv, ai); |
432 | if (imap->cb[mbit].handler) | ||
433 | imap->cb[mbit].handler(mbit, | ||
434 | imap->cb[mbit].data); | ||
435 | spin_unlock(&imap->lock); | ||
436 | } | 414 | } |
437 | } | 415 | } |
438 | |||
439 | if (rescan) | ||
440 | goto out; | ||
441 | |||
442 | /* scan the skipped bits */ | ||
443 | if (start > 0) { | ||
444 | sbit = 0; | ||
445 | max = start; | ||
446 | start = 0; | ||
447 | goto scan; | ||
448 | } | ||
449 | |||
450 | /* enable interrupts again */ | ||
451 | set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | ||
452 | |||
453 | /* check again to not lose initiative */ | ||
454 | rmb(); | ||
455 | max = aisb_max; | ||
456 | sbit = find_first_bit_left(bucket->aisb, max); | ||
457 | if (sbit != max) { | ||
458 | rescan++; | ||
459 | goto scan; | ||
460 | } | ||
461 | out: | ||
462 | /* store next device bit to scan */ | ||
463 | __get_cpu_var(next_sbit) = (++last >= aisb_max) ? 0 : last; | ||
464 | } | 416 | } |
465 | 417 | ||
466 | /* msi_vecs - number of requested interrupts, 0 place function to error state */ | 418 | int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
467 | static int zpci_setup_msi(struct pci_dev *pdev, int msi_vecs) | ||
468 | { | 419 | { |
469 | struct zpci_dev *zdev = get_zdev(pdev); | 420 | struct zpci_dev *zdev = get_zdev(pdev); |
470 | unsigned int aisb, msi_nr; | 421 | unsigned int hwirq, irq, msi_vecs; |
422 | unsigned long aisb; | ||
471 | struct msi_desc *msi; | 423 | struct msi_desc *msi; |
424 | struct msi_msg msg; | ||
472 | int rc; | 425 | int rc; |
473 | 426 | ||
474 | /* store the number of used MSI vectors */ | 427 | pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec); |
475 | zdev->irq_map->msi_vecs = min(msi_vecs, ZPCI_NR_MSI_VECS); | 428 | if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) |
476 | 429 | return -EINVAL; | |
477 | spin_lock(&bucket->lock); | 430 | msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); |
478 | aisb = find_first_zero_bit(bucket->alloc, PAGE_SIZE); | 431 | msi_vecs = min_t(unsigned int, msi_vecs, CONFIG_PCI_NR_MSI); |
479 | /* alloc map exhausted? */ | ||
480 | if (aisb == PAGE_SIZE) { | ||
481 | spin_unlock(&bucket->lock); | ||
482 | return -EIO; | ||
483 | } | ||
484 | set_bit(aisb, bucket->alloc); | ||
485 | spin_unlock(&bucket->lock); | ||
486 | 432 | ||
433 | /* Allocate adapter summary indicator bit */ | ||
434 | rc = -EIO; | ||
435 | aisb = airq_iv_alloc_bit(zpci_aisb_iv); | ||
436 | if (aisb == -1UL) | ||
437 | goto out; | ||
487 | zdev->aisb = aisb; | 438 | zdev->aisb = aisb; |
488 | if (aisb + 1 > aisb_max) | ||
489 | aisb_max = aisb + 1; | ||
490 | 439 | ||
491 | /* wire up IRQ shortcut pointer */ | 440 | /* Create adapter interrupt vector */ |
492 | bucket->imap[zdev->aisb] = zdev->irq_map; | 441 | rc = -ENOMEM; |
493 | pr_debug("%s: imap[%u] linked to %p\n", __func__, zdev->aisb, zdev->irq_map); | 442 | zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK); |
443 | if (!zdev->aibv) | ||
444 | goto out_si; | ||
494 | 445 | ||
495 | /* TODO: irq number 0 wont be found if we return less than requested MSIs. | 446 | /* Wire up shortcut pointer */ |
496 | * ignore it for now and fix in common code. | 447 | zpci_aibv[aisb] = zdev->aibv; |
497 | */ | ||
498 | msi_nr = aisb << ZPCI_MSI_VEC_BITS; | ||
499 | 448 | ||
449 | /* Request MSI interrupts */ | ||
450 | hwirq = 0; | ||
500 | list_for_each_entry(msi, &pdev->msi_list, list) { | 451 | list_for_each_entry(msi, &pdev->msi_list, list) { |
501 | rc = zpci_setup_msi_irq(zdev, msi, msi_nr, | 452 | rc = -EIO; |
502 | aisb << ZPCI_MSI_VEC_BITS); | 453 | irq = irq_alloc_desc(0); /* Alloc irq on node 0 */ |
454 | if (irq == NO_IRQ) | ||
455 | goto out_msi; | ||
456 | rc = irq_set_msi_desc(irq, msi); | ||
503 | if (rc) | 457 | if (rc) |
504 | return rc; | 458 | goto out_msi; |
505 | msi_nr++; | 459 | irq_set_chip_and_handler(irq, &zpci_irq_chip, |
460 | handle_simple_irq); | ||
461 | msg.data = hwirq; | ||
462 | msg.address_lo = zdev->msi_addr & 0xffffffff; | ||
463 | msg.address_hi = zdev->msi_addr >> 32; | ||
464 | write_msi_msg(irq, &msg); | ||
465 | airq_iv_set_data(zdev->aibv, hwirq, irq); | ||
466 | hwirq++; | ||
506 | } | 467 | } |
507 | 468 | ||
508 | rc = zpci_register_airq(zdev, aisb, (u64) &zdev->irq_map->aibv); | 469 | /* Enable adapter interrupts */ |
509 | if (rc) { | 470 | rc = zpci_set_airq(zdev); |
510 | clear_bit(aisb, bucket->alloc); | 471 | if (rc) |
511 | dev_err(&pdev->dev, "register MSI failed with: %d\n", rc); | 472 | goto out_msi; |
512 | return rc; | 473 | |
474 | return (msi_vecs == nvec) ? 0 : msi_vecs; | ||
475 | |||
476 | out_msi: | ||
477 | list_for_each_entry(msi, &pdev->msi_list, list) { | ||
478 | if (hwirq-- == 0) | ||
479 | break; | ||
480 | irq_set_msi_desc(msi->irq, NULL); | ||
481 | irq_free_desc(msi->irq); | ||
482 | msi->msg.address_lo = 0; | ||
483 | msi->msg.address_hi = 0; | ||
484 | msi->msg.data = 0; | ||
485 | msi->irq = 0; | ||
513 | } | 486 | } |
514 | return (zdev->irq_map->msi_vecs == msi_vecs) ? | 487 | zpci_aibv[aisb] = NULL; |
515 | 0 : zdev->irq_map->msi_vecs; | 488 | airq_iv_release(zdev->aibv); |
489 | out_si: | ||
490 | airq_iv_free_bit(zpci_aisb_iv, aisb); | ||
491 | out: | ||
492 | dev_err(&pdev->dev, "register MSI failed with: %d\n", rc); | ||
493 | return rc; | ||
516 | } | 494 | } |
517 | 495 | ||
518 | static void zpci_teardown_msi(struct pci_dev *pdev) | 496 | void arch_teardown_msi_irqs(struct pci_dev *pdev) |
519 | { | 497 | { |
520 | struct zpci_dev *zdev = get_zdev(pdev); | 498 | struct zpci_dev *zdev = get_zdev(pdev); |
521 | struct msi_desc *msi; | 499 | struct msi_desc *msi; |
522 | int aisb, rc; | 500 | int rc; |
523 | 501 | ||
524 | rc = zpci_unregister_airq(zdev); | 502 | pr_info("%s: on pdev: %p\n", __func__, pdev); |
503 | |||
504 | /* Disable adapter interrupts */ | ||
505 | rc = zpci_clear_airq(zdev); | ||
525 | if (rc) { | 506 | if (rc) { |
526 | dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc); | 507 | dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc); |
527 | return; | 508 | return; |
528 | } | 509 | } |
529 | 510 | ||
530 | msi = list_first_entry(&pdev->msi_list, struct msi_desc, list); | 511 | /* Release MSI interrupts */ |
531 | aisb = irq_to_dev_nr(msi->irq); | 512 | list_for_each_entry(msi, &pdev->msi_list, list) { |
532 | 513 | zpci_msi_set_mask_bits(msi, 1, 1); | |
533 | list_for_each_entry(msi, &pdev->msi_list, list) | 514 | irq_set_msi_desc(msi->irq, NULL); |
534 | zpci_teardown_msi_irq(zdev, msi); | 515 | irq_free_desc(msi->irq); |
535 | 516 | msi->msg.address_lo = 0; | |
536 | clear_bit(aisb, bucket->alloc); | 517 | msi->msg.address_hi = 0; |
537 | if (aisb + 1 == aisb_max) | 518 | msi->msg.data = 0; |
538 | aisb_max--; | 519 | msi->irq = 0; |
539 | } | 520 | } |
540 | |||
541 | int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | ||
542 | { | ||
543 | pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec); | ||
544 | if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) | ||
545 | return -EINVAL; | ||
546 | return zpci_setup_msi(pdev, nvec); | ||
547 | } | ||
548 | 521 | ||
549 | void arch_teardown_msi_irqs(struct pci_dev *pdev) | 522 | zpci_aibv[zdev->aisb] = NULL; |
550 | { | 523 | airq_iv_release(zdev->aibv); |
551 | pr_info("%s: on pdev: %p\n", __func__, pdev); | 524 | airq_iv_free_bit(zpci_aisb_iv, zdev->aisb); |
552 | zpci_teardown_msi(pdev); | ||
553 | } | 525 | } |
554 | 526 | ||
555 | static void zpci_map_resources(struct zpci_dev *zdev) | 527 | static void zpci_map_resources(struct zpci_dev *zdev) |
@@ -564,8 +536,6 @@ static void zpci_map_resources(struct zpci_dev *zdev) | |||
564 | continue; | 536 | continue; |
565 | pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); | 537 | pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); |
566 | pdev->resource[i].end = pdev->resource[i].start + len - 1; | 538 | pdev->resource[i].end = pdev->resource[i].start + len - 1; |
567 | pr_debug("BAR%i: -> start: %Lx end: %Lx\n", | ||
568 | i, pdev->resource[i].start, pdev->resource[i].end); | ||
569 | } | 539 | } |
570 | } | 540 | } |
571 | 541 | ||
@@ -589,162 +559,47 @@ struct zpci_dev *zpci_alloc_device(void) | |||
589 | 559 | ||
590 | /* Alloc memory for our private pci device data */ | 560 | /* Alloc memory for our private pci device data */ |
591 | zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); | 561 | zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); |
592 | if (!zdev) | 562 | return zdev ? : ERR_PTR(-ENOMEM); |
593 | return ERR_PTR(-ENOMEM); | ||
594 | |||
595 | /* Alloc aibv & callback space */ | ||
596 | zdev->irq_map = kmem_cache_zalloc(zdev_irq_cache, GFP_KERNEL); | ||
597 | if (!zdev->irq_map) | ||
598 | goto error; | ||
599 | WARN_ON((u64) zdev->irq_map & 0xff); | ||
600 | return zdev; | ||
601 | |||
602 | error: | ||
603 | kfree(zdev); | ||
604 | return ERR_PTR(-ENOMEM); | ||
605 | } | 563 | } |
606 | 564 | ||
607 | void zpci_free_device(struct zpci_dev *zdev) | 565 | void zpci_free_device(struct zpci_dev *zdev) |
608 | { | 566 | { |
609 | kmem_cache_free(zdev_irq_cache, zdev->irq_map); | ||
610 | kfree(zdev); | 567 | kfree(zdev); |
611 | } | 568 | } |
612 | 569 | ||
613 | /* | ||
614 | * Too late for any s390 specific setup, since interrupts must be set up | ||
615 | * already which requires DMA setup too and the pci scan will access the | ||
616 | * config space, which only works if the function handle is enabled. | ||
617 | */ | ||
618 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | ||
619 | { | ||
620 | struct resource *res; | ||
621 | u16 cmd; | ||
622 | int i; | ||
623 | |||
624 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
625 | |||
626 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
627 | res = &pdev->resource[i]; | ||
628 | |||
629 | if (res->flags & IORESOURCE_IO) | ||
630 | return -EINVAL; | ||
631 | |||
632 | if (res->flags & IORESOURCE_MEM) | ||
633 | cmd |= PCI_COMMAND_MEMORY; | ||
634 | } | ||
635 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | int pcibios_add_platform_entries(struct pci_dev *pdev) | 570 | int pcibios_add_platform_entries(struct pci_dev *pdev) |
640 | { | 571 | { |
641 | return zpci_sysfs_add_device(&pdev->dev); | 572 | return zpci_sysfs_add_device(&pdev->dev); |
642 | } | 573 | } |
643 | 574 | ||
644 | int zpci_request_irq(unsigned int irq, irq_handler_t handler, void *data) | ||
645 | { | ||
646 | int msi_nr = irq_to_msi_nr(irq); | ||
647 | struct zdev_irq_map *imap; | ||
648 | struct msi_desc *msi; | ||
649 | |||
650 | msi = irq_get_msi_desc(irq); | ||
651 | if (!msi) | ||
652 | return -EIO; | ||
653 | |||
654 | imap = get_imap(irq); | ||
655 | spin_lock_init(&imap->lock); | ||
656 | |||
657 | pr_debug("%s: register handler for IRQ:MSI %d:%d\n", __func__, irq >> 6, msi_nr); | ||
658 | imap->cb[msi_nr].handler = handler; | ||
659 | imap->cb[msi_nr].data = data; | ||
660 | |||
661 | /* | ||
662 | * The generic MSI code returns with the interrupt disabled on the | ||
663 | * card, using the MSI mask bits. Firmware doesn't appear to unmask | ||
664 | * at that level, so we do it here by hand. | ||
665 | */ | ||
666 | zpci_msi_set_mask_bits(msi, 1, 0); | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | void zpci_free_irq(unsigned int irq) | ||
671 | { | ||
672 | struct zdev_irq_map *imap = get_imap(irq); | ||
673 | int msi_nr = irq_to_msi_nr(irq); | ||
674 | unsigned long flags; | ||
675 | |||
676 | pr_debug("%s: for irq: %d\n", __func__, irq); | ||
677 | |||
678 | spin_lock_irqsave(&imap->lock, flags); | ||
679 | imap->cb[msi_nr].handler = NULL; | ||
680 | imap->cb[msi_nr].data = NULL; | ||
681 | spin_unlock_irqrestore(&imap->lock, flags); | ||
682 | } | ||
683 | |||
684 | int request_irq(unsigned int irq, irq_handler_t handler, | ||
685 | unsigned long irqflags, const char *devname, void *dev_id) | ||
686 | { | ||
687 | pr_debug("%s: irq: %d handler: %p flags: %lx dev: %s\n", | ||
688 | __func__, irq, handler, irqflags, devname); | ||
689 | |||
690 | return zpci_request_irq(irq, handler, dev_id); | ||
691 | } | ||
692 | EXPORT_SYMBOL_GPL(request_irq); | ||
693 | |||
694 | void free_irq(unsigned int irq, void *dev_id) | ||
695 | { | ||
696 | zpci_free_irq(irq); | ||
697 | } | ||
698 | EXPORT_SYMBOL_GPL(free_irq); | ||
699 | |||
700 | static int __init zpci_irq_init(void) | 575 | static int __init zpci_irq_init(void) |
701 | { | 576 | { |
702 | int cpu, rc; | 577 | int rc; |
703 | |||
704 | bucket = kzalloc(sizeof(*bucket), GFP_KERNEL); | ||
705 | if (!bucket) | ||
706 | return -ENOMEM; | ||
707 | |||
708 | bucket->aisb = (unsigned long *) get_zeroed_page(GFP_KERNEL); | ||
709 | if (!bucket->aisb) { | ||
710 | rc = -ENOMEM; | ||
711 | goto out_aisb; | ||
712 | } | ||
713 | |||
714 | bucket->alloc = (unsigned long *) get_zeroed_page(GFP_KERNEL); | ||
715 | if (!bucket->alloc) { | ||
716 | rc = -ENOMEM; | ||
717 | goto out_alloc; | ||
718 | } | ||
719 | 578 | ||
720 | rc = register_adapter_interrupt(&zpci_airq); | 579 | rc = register_adapter_interrupt(&zpci_airq); |
721 | if (rc) | 580 | if (rc) |
722 | goto out_ai; | 581 | goto out; |
723 | /* Set summary to 1 to be called every time for the ISC. */ | 582 | /* Set summary to 1 to be called every time for the ISC. */ |
724 | *zpci_airq.lsi_ptr = 1; | 583 | *zpci_airq.lsi_ptr = 1; |
725 | 584 | ||
726 | for_each_online_cpu(cpu) | 585 | rc = -ENOMEM; |
727 | per_cpu(next_sbit, cpu) = 0; | 586 | zpci_aisb_iv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC); |
587 | if (!zpci_aisb_iv) | ||
588 | goto out_airq; | ||
728 | 589 | ||
729 | spin_lock_init(&bucket->lock); | 590 | zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); |
730 | set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | ||
731 | return 0; | 591 | return 0; |
732 | 592 | ||
733 | out_ai: | 593 | out_airq: |
734 | free_page((unsigned long) bucket->alloc); | 594 | unregister_adapter_interrupt(&zpci_airq); |
735 | out_alloc: | 595 | out: |
736 | free_page((unsigned long) bucket->aisb); | ||
737 | out_aisb: | ||
738 | kfree(bucket); | ||
739 | return rc; | 596 | return rc; |
740 | } | 597 | } |
741 | 598 | ||
742 | static void zpci_irq_exit(void) | 599 | static void zpci_irq_exit(void) |
743 | { | 600 | { |
744 | free_page((unsigned long) bucket->alloc); | 601 | airq_iv_release(zpci_aisb_iv); |
745 | free_page((unsigned long) bucket->aisb); | ||
746 | unregister_adapter_interrupt(&zpci_airq); | 602 | unregister_adapter_interrupt(&zpci_airq); |
747 | kfree(bucket); | ||
748 | } | 603 | } |
749 | 604 | ||
750 | static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, | 605 | static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, |
@@ -801,16 +656,49 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) | |||
801 | int pcibios_add_device(struct pci_dev *pdev) | 656 | int pcibios_add_device(struct pci_dev *pdev) |
802 | { | 657 | { |
803 | struct zpci_dev *zdev = get_zdev(pdev); | 658 | struct zpci_dev *zdev = get_zdev(pdev); |
659 | struct resource *res; | ||
660 | int i; | ||
661 | |||
662 | zdev->pdev = pdev; | ||
663 | zpci_map_resources(zdev); | ||
664 | |||
665 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
666 | res = &pdev->resource[i]; | ||
667 | if (res->parent || !res->flags) | ||
668 | continue; | ||
669 | pci_claim_resource(pdev, i); | ||
670 | } | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | ||
676 | { | ||
677 | struct zpci_dev *zdev = get_zdev(pdev); | ||
678 | struct resource *res; | ||
679 | u16 cmd; | ||
680 | int i; | ||
804 | 681 | ||
805 | zdev->pdev = pdev; | 682 | zdev->pdev = pdev; |
806 | zpci_debug_init_device(zdev); | 683 | zpci_debug_init_device(zdev); |
807 | zpci_fmb_enable_device(zdev); | 684 | zpci_fmb_enable_device(zdev); |
808 | zpci_map_resources(zdev); | 685 | zpci_map_resources(zdev); |
809 | 686 | ||
687 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
688 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
689 | res = &pdev->resource[i]; | ||
690 | |||
691 | if (res->flags & IORESOURCE_IO) | ||
692 | return -EINVAL; | ||
693 | |||
694 | if (res->flags & IORESOURCE_MEM) | ||
695 | cmd |= PCI_COMMAND_MEMORY; | ||
696 | } | ||
697 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
810 | return 0; | 698 | return 0; |
811 | } | 699 | } |
812 | 700 | ||
813 | void pcibios_release_device(struct pci_dev *pdev) | 701 | void pcibios_disable_device(struct pci_dev *pdev) |
814 | { | 702 | { |
815 | struct zpci_dev *zdev = get_zdev(pdev); | 703 | struct zpci_dev *zdev = get_zdev(pdev); |
816 | 704 | ||
@@ -898,6 +786,8 @@ int zpci_enable_device(struct zpci_dev *zdev) | |||
898 | rc = zpci_dma_init_device(zdev); | 786 | rc = zpci_dma_init_device(zdev); |
899 | if (rc) | 787 | if (rc) |
900 | goto out_dma; | 788 | goto out_dma; |
789 | |||
790 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
901 | return 0; | 791 | return 0; |
902 | 792 | ||
903 | out_dma: | 793 | out_dma: |
@@ -926,18 +816,16 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
926 | rc = zpci_enable_device(zdev); | 816 | rc = zpci_enable_device(zdev); |
927 | if (rc) | 817 | if (rc) |
928 | goto out_free; | 818 | goto out_free; |
929 | |||
930 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
931 | } | 819 | } |
932 | rc = zpci_scan_bus(zdev); | 820 | rc = zpci_scan_bus(zdev); |
933 | if (rc) | 821 | if (rc) |
934 | goto out_disable; | 822 | goto out_disable; |
935 | 823 | ||
936 | mutex_lock(&zpci_list_lock); | 824 | spin_lock(&zpci_list_lock); |
937 | list_add_tail(&zdev->entry, &zpci_list); | 825 | list_add_tail(&zdev->entry, &zpci_list); |
938 | if (hotplug_ops) | 826 | spin_unlock(&zpci_list_lock); |
939 | hotplug_ops->create_slot(zdev); | 827 | |
940 | mutex_unlock(&zpci_list_lock); | 828 | zpci_init_slot(zdev); |
941 | 829 | ||
942 | return 0; | 830 | return 0; |
943 | 831 | ||
@@ -967,15 +855,10 @@ static inline int barsize(u8 size) | |||
967 | 855 | ||
968 | static int zpci_mem_init(void) | 856 | static int zpci_mem_init(void) |
969 | { | 857 | { |
970 | zdev_irq_cache = kmem_cache_create("PCI_IRQ_cache", sizeof(struct zdev_irq_map), | ||
971 | L1_CACHE_BYTES, SLAB_HWCACHE_ALIGN, NULL); | ||
972 | if (!zdev_irq_cache) | ||
973 | goto error_zdev; | ||
974 | |||
975 | zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb), | 858 | zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb), |
976 | 16, 0, NULL); | 859 | 16, 0, NULL); |
977 | if (!zdev_fmb_cache) | 860 | if (!zdev_fmb_cache) |
978 | goto error_fmb; | 861 | goto error_zdev; |
979 | 862 | ||
980 | /* TODO: use realloc */ | 863 | /* TODO: use realloc */ |
981 | zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), | 864 | zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), |
@@ -986,8 +869,6 @@ static int zpci_mem_init(void) | |||
986 | 869 | ||
987 | error_iomap: | 870 | error_iomap: |
988 | kmem_cache_destroy(zdev_fmb_cache); | 871 | kmem_cache_destroy(zdev_fmb_cache); |
989 | error_fmb: | ||
990 | kmem_cache_destroy(zdev_irq_cache); | ||
991 | error_zdev: | 872 | error_zdev: |
992 | return -ENOMEM; | 873 | return -ENOMEM; |
993 | } | 874 | } |
@@ -995,28 +876,10 @@ error_zdev: | |||
995 | static void zpci_mem_exit(void) | 876 | static void zpci_mem_exit(void) |
996 | { | 877 | { |
997 | kfree(zpci_iomap_start); | 878 | kfree(zpci_iomap_start); |
998 | kmem_cache_destroy(zdev_irq_cache); | ||
999 | kmem_cache_destroy(zdev_fmb_cache); | 879 | kmem_cache_destroy(zdev_fmb_cache); |
1000 | } | 880 | } |
1001 | 881 | ||
1002 | void zpci_register_hp_ops(struct pci_hp_callback_ops *ops) | 882 | static unsigned int s390_pci_probe; |
1003 | { | ||
1004 | mutex_lock(&zpci_list_lock); | ||
1005 | hotplug_ops = ops; | ||
1006 | mutex_unlock(&zpci_list_lock); | ||
1007 | } | ||
1008 | EXPORT_SYMBOL_GPL(zpci_register_hp_ops); | ||
1009 | |||
1010 | void zpci_deregister_hp_ops(void) | ||
1011 | { | ||
1012 | mutex_lock(&zpci_list_lock); | ||
1013 | hotplug_ops = NULL; | ||
1014 | mutex_unlock(&zpci_list_lock); | ||
1015 | } | ||
1016 | EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); | ||
1017 | |||
1018 | unsigned int s390_pci_probe; | ||
1019 | EXPORT_SYMBOL_GPL(s390_pci_probe); | ||
1020 | 883 | ||
1021 | char * __init pcibios_setup(char *str) | 884 | char * __init pcibios_setup(char *str) |
1022 | { | 885 | { |
@@ -1044,16 +907,12 @@ static int __init pci_base_init(void) | |||
1044 | 907 | ||
1045 | rc = zpci_debug_init(); | 908 | rc = zpci_debug_init(); |
1046 | if (rc) | 909 | if (rc) |
1047 | return rc; | 910 | goto out; |
1048 | 911 | ||
1049 | rc = zpci_mem_init(); | 912 | rc = zpci_mem_init(); |
1050 | if (rc) | 913 | if (rc) |
1051 | goto out_mem; | 914 | goto out_mem; |
1052 | 915 | ||
1053 | rc = zpci_msihash_init(); | ||
1054 | if (rc) | ||
1055 | goto out_hash; | ||
1056 | |||
1057 | rc = zpci_irq_init(); | 916 | rc = zpci_irq_init(); |
1058 | if (rc) | 917 | if (rc) |
1059 | goto out_irq; | 918 | goto out_irq; |
@@ -1062,7 +921,7 @@ static int __init pci_base_init(void) | |||
1062 | if (rc) | 921 | if (rc) |
1063 | goto out_dma; | 922 | goto out_dma; |
1064 | 923 | ||
1065 | rc = clp_find_pci_devices(); | 924 | rc = clp_scan_pci_devices(); |
1066 | if (rc) | 925 | if (rc) |
1067 | goto out_find; | 926 | goto out_find; |
1068 | 927 | ||
@@ -1073,11 +932,15 @@ out_find: | |||
1073 | out_dma: | 932 | out_dma: |
1074 | zpci_irq_exit(); | 933 | zpci_irq_exit(); |
1075 | out_irq: | 934 | out_irq: |
1076 | zpci_msihash_exit(); | ||
1077 | out_hash: | ||
1078 | zpci_mem_exit(); | 935 | zpci_mem_exit(); |
1079 | out_mem: | 936 | out_mem: |
1080 | zpci_debug_exit(); | 937 | zpci_debug_exit(); |
938 | out: | ||
1081 | return rc; | 939 | return rc; |
1082 | } | 940 | } |
1083 | subsys_initcall(pci_base_init); | 941 | subsys_initcall_sync(pci_base_init); |
942 | |||
943 | void zpci_rescan(void) | ||
944 | { | ||
945 | clp_rescan_pci_devices_simple(); | ||
946 | } | ||
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 2e9539625d93..475563c3d1e4 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c | |||
@@ -36,9 +36,9 @@ static inline u8 clp_instr(void *data) | |||
36 | return cc; | 36 | return cc; |
37 | } | 37 | } |
38 | 38 | ||
39 | static void *clp_alloc_block(void) | 39 | static void *clp_alloc_block(gfp_t gfp_mask) |
40 | { | 40 | { |
41 | return (void *) __get_free_pages(GFP_KERNEL, get_order(CLP_BLK_SIZE)); | 41 | return (void *) __get_free_pages(gfp_mask, get_order(CLP_BLK_SIZE)); |
42 | } | 42 | } |
43 | 43 | ||
44 | static void clp_free_block(void *ptr) | 44 | static void clp_free_block(void *ptr) |
@@ -70,7 +70,7 @@ static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid) | |||
70 | struct clp_req_rsp_query_pci_grp *rrb; | 70 | struct clp_req_rsp_query_pci_grp *rrb; |
71 | int rc; | 71 | int rc; |
72 | 72 | ||
73 | rrb = clp_alloc_block(); | 73 | rrb = clp_alloc_block(GFP_KERNEL); |
74 | if (!rrb) | 74 | if (!rrb) |
75 | return -ENOMEM; | 75 | return -ENOMEM; |
76 | 76 | ||
@@ -113,7 +113,7 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh) | |||
113 | struct clp_req_rsp_query_pci *rrb; | 113 | struct clp_req_rsp_query_pci *rrb; |
114 | int rc; | 114 | int rc; |
115 | 115 | ||
116 | rrb = clp_alloc_block(); | 116 | rrb = clp_alloc_block(GFP_KERNEL); |
117 | if (!rrb) | 117 | if (!rrb) |
118 | return -ENOMEM; | 118 | return -ENOMEM; |
119 | 119 | ||
@@ -179,9 +179,9 @@ error: | |||
179 | static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) | 179 | static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) |
180 | { | 180 | { |
181 | struct clp_req_rsp_set_pci *rrb; | 181 | struct clp_req_rsp_set_pci *rrb; |
182 | int rc, retries = 1000; | 182 | int rc, retries = 100; |
183 | 183 | ||
184 | rrb = clp_alloc_block(); | 184 | rrb = clp_alloc_block(GFP_KERNEL); |
185 | if (!rrb) | 185 | if (!rrb) |
186 | return -ENOMEM; | 186 | return -ENOMEM; |
187 | 187 | ||
@@ -199,7 +199,7 @@ static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) | |||
199 | retries--; | 199 | retries--; |
200 | if (retries < 0) | 200 | if (retries < 0) |
201 | break; | 201 | break; |
202 | msleep(1); | 202 | msleep(20); |
203 | } | 203 | } |
204 | } while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY); | 204 | } while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY); |
205 | 205 | ||
@@ -245,49 +245,12 @@ int clp_disable_fh(struct zpci_dev *zdev) | |||
245 | return rc; | 245 | return rc; |
246 | } | 246 | } |
247 | 247 | ||
248 | static void clp_check_pcifn_entry(struct clp_fh_list_entry *entry) | 248 | static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, |
249 | void (*cb)(struct clp_fh_list_entry *entry)) | ||
249 | { | 250 | { |
250 | int present, rc; | ||
251 | |||
252 | if (!entry->vendor_id) | ||
253 | return; | ||
254 | |||
255 | /* TODO: be a little bit more scalable */ | ||
256 | present = zpci_fid_present(entry->fid); | ||
257 | |||
258 | if (present) | ||
259 | pr_debug("%s: device %x already present\n", __func__, entry->fid); | ||
260 | |||
261 | /* skip already used functions */ | ||
262 | if (present && entry->config_state) | ||
263 | return; | ||
264 | |||
265 | /* aev 306: function moved to stand-by state */ | ||
266 | if (present && !entry->config_state) { | ||
267 | /* | ||
268 | * The handle is already disabled, that means no iota/irq freeing via | ||
269 | * the firmware interfaces anymore. Need to free resources manually | ||
270 | * (DMA memory, debug, sysfs)... | ||
271 | */ | ||
272 | zpci_stop_device(get_zdev_by_fid(entry->fid)); | ||
273 | return; | ||
274 | } | ||
275 | |||
276 | rc = clp_add_pci_device(entry->fid, entry->fh, entry->config_state); | ||
277 | if (rc) | ||
278 | pr_err("Failed to add fid: 0x%x\n", entry->fid); | ||
279 | } | ||
280 | |||
281 | int clp_find_pci_devices(void) | ||
282 | { | ||
283 | struct clp_req_rsp_list_pci *rrb; | ||
284 | u64 resume_token = 0; | 251 | u64 resume_token = 0; |
285 | int entries, i, rc; | 252 | int entries, i, rc; |
286 | 253 | ||
287 | rrb = clp_alloc_block(); | ||
288 | if (!rrb) | ||
289 | return -ENOMEM; | ||
290 | |||
291 | do { | 254 | do { |
292 | memset(rrb, 0, sizeof(*rrb)); | 255 | memset(rrb, 0, sizeof(*rrb)); |
293 | rrb->request.hdr.len = sizeof(rrb->request); | 256 | rrb->request.hdr.len = sizeof(rrb->request); |
@@ -316,12 +279,101 @@ int clp_find_pci_devices(void) | |||
316 | resume_token = rrb->response.resume_token; | 279 | resume_token = rrb->response.resume_token; |
317 | 280 | ||
318 | for (i = 0; i < entries; i++) | 281 | for (i = 0; i < entries; i++) |
319 | clp_check_pcifn_entry(&rrb->response.fh_list[i]); | 282 | cb(&rrb->response.fh_list[i]); |
320 | } while (resume_token); | 283 | } while (resume_token); |
321 | 284 | ||
322 | pr_debug("Maximum number of supported PCI functions: %u\n", | 285 | pr_debug("Maximum number of supported PCI functions: %u\n", |
323 | rrb->response.max_fn); | 286 | rrb->response.max_fn); |
324 | out: | 287 | out: |
288 | return rc; | ||
289 | } | ||
290 | |||
291 | static void __clp_add(struct clp_fh_list_entry *entry) | ||
292 | { | ||
293 | if (!entry->vendor_id) | ||
294 | return; | ||
295 | |||
296 | clp_add_pci_device(entry->fid, entry->fh, entry->config_state); | ||
297 | } | ||
298 | |||
299 | static void __clp_rescan(struct clp_fh_list_entry *entry) | ||
300 | { | ||
301 | struct zpci_dev *zdev; | ||
302 | |||
303 | if (!entry->vendor_id) | ||
304 | return; | ||
305 | |||
306 | zdev = get_zdev_by_fid(entry->fid); | ||
307 | if (!zdev) { | ||
308 | clp_add_pci_device(entry->fid, entry->fh, entry->config_state); | ||
309 | return; | ||
310 | } | ||
311 | |||
312 | if (!entry->config_state) { | ||
313 | /* | ||
314 | * The handle is already disabled, that means no iota/irq freeing via | ||
315 | * the firmware interfaces anymore. Need to free resources manually | ||
316 | * (DMA memory, debug, sysfs)... | ||
317 | */ | ||
318 | zpci_stop_device(zdev); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | static void __clp_update(struct clp_fh_list_entry *entry) | ||
323 | { | ||
324 | struct zpci_dev *zdev; | ||
325 | |||
326 | if (!entry->vendor_id) | ||
327 | return; | ||
328 | |||
329 | zdev = get_zdev_by_fid(entry->fid); | ||
330 | if (!zdev) | ||
331 | return; | ||
332 | |||
333 | zdev->fh = entry->fh; | ||
334 | } | ||
335 | |||
336 | int clp_scan_pci_devices(void) | ||
337 | { | ||
338 | struct clp_req_rsp_list_pci *rrb; | ||
339 | int rc; | ||
340 | |||
341 | rrb = clp_alloc_block(GFP_KERNEL); | ||
342 | if (!rrb) | ||
343 | return -ENOMEM; | ||
344 | |||
345 | rc = clp_list_pci(rrb, __clp_add); | ||
346 | |||
347 | clp_free_block(rrb); | ||
348 | return rc; | ||
349 | } | ||
350 | |||
351 | int clp_rescan_pci_devices(void) | ||
352 | { | ||
353 | struct clp_req_rsp_list_pci *rrb; | ||
354 | int rc; | ||
355 | |||
356 | rrb = clp_alloc_block(GFP_KERNEL); | ||
357 | if (!rrb) | ||
358 | return -ENOMEM; | ||
359 | |||
360 | rc = clp_list_pci(rrb, __clp_rescan); | ||
361 | |||
362 | clp_free_block(rrb); | ||
363 | return rc; | ||
364 | } | ||
365 | |||
366 | int clp_rescan_pci_devices_simple(void) | ||
367 | { | ||
368 | struct clp_req_rsp_list_pci *rrb; | ||
369 | int rc; | ||
370 | |||
371 | rrb = clp_alloc_block(GFP_NOWAIT); | ||
372 | if (!rrb) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | rc = clp_list_pci(rrb, __clp_update); | ||
376 | |||
325 | clp_free_block(rrb); | 377 | clp_free_block(rrb); |
326 | return rc; | 378 | return rc; |
327 | } | 379 | } |
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index a2343c1f6e04..7e5573acb063 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/export.h> | 10 | #include <linux/export.h> |
11 | #include <linux/iommu-helper.h> | 11 | #include <linux/iommu-helper.h> |
12 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
13 | #include <linux/vmalloc.h> | ||
13 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
14 | #include <asm/pci_dma.h> | 15 | #include <asm/pci_dma.h> |
15 | 16 | ||
@@ -170,8 +171,8 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa, | |||
170 | */ | 171 | */ |
171 | goto no_refresh; | 172 | goto no_refresh; |
172 | 173 | ||
173 | rc = s390pci_refresh_trans((u64) zdev->fh << 32, start_dma_addr, | 174 | rc = zpci_refresh_trans((u64) zdev->fh << 32, start_dma_addr, |
174 | nr_pages * PAGE_SIZE); | 175 | nr_pages * PAGE_SIZE); |
175 | 176 | ||
176 | no_refresh: | 177 | no_refresh: |
177 | spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags); | 178 | spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags); |
@@ -407,7 +408,6 @@ static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg, | |||
407 | 408 | ||
408 | int zpci_dma_init_device(struct zpci_dev *zdev) | 409 | int zpci_dma_init_device(struct zpci_dev *zdev) |
409 | { | 410 | { |
410 | unsigned int bitmap_order; | ||
411 | int rc; | 411 | int rc; |
412 | 412 | ||
413 | spin_lock_init(&zdev->iommu_bitmap_lock); | 413 | spin_lock_init(&zdev->iommu_bitmap_lock); |
@@ -421,12 +421,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) | |||
421 | 421 | ||
422 | zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET; | 422 | zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET; |
423 | zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; | 423 | zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; |
424 | bitmap_order = get_order(zdev->iommu_pages / 8); | 424 | zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); |
425 | pr_info("iommu_size: 0x%lx iommu_pages: 0x%lx bitmap_order: %i\n", | ||
426 | zdev->iommu_size, zdev->iommu_pages, bitmap_order); | ||
427 | |||
428 | zdev->iommu_bitmap = (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, | ||
429 | bitmap_order); | ||
430 | if (!zdev->iommu_bitmap) { | 425 | if (!zdev->iommu_bitmap) { |
431 | rc = -ENOMEM; | 426 | rc = -ENOMEM; |
432 | goto out_reg; | 427 | goto out_reg; |
@@ -451,8 +446,7 @@ void zpci_dma_exit_device(struct zpci_dev *zdev) | |||
451 | { | 446 | { |
452 | zpci_unregister_ioat(zdev, 0); | 447 | zpci_unregister_ioat(zdev, 0); |
453 | dma_cleanup_tables(zdev); | 448 | dma_cleanup_tables(zdev); |
454 | free_pages((unsigned long) zdev->iommu_bitmap, | 449 | vfree(zdev->iommu_bitmap); |
455 | get_order(zdev->iommu_pages / 8)); | ||
456 | zdev->iommu_bitmap = NULL; | 450 | zdev->iommu_bitmap = NULL; |
457 | zdev->next_bit = 0; | 451 | zdev->next_bit = 0; |
458 | } | 452 | } |
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index ec62e3a0dc09..0aecaf954845 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c | |||
@@ -69,7 +69,7 @@ static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf) | |||
69 | clp_add_pci_device(ccdf->fid, ccdf->fh, 0); | 69 | clp_add_pci_device(ccdf->fid, ccdf->fh, 0); |
70 | break; | 70 | break; |
71 | case 0x0306: | 71 | case 0x0306: |
72 | clp_find_pci_devices(); | 72 | clp_rescan_pci_devices(); |
73 | break; | 73 | break; |
74 | default: | 74 | default: |
75 | break; | 75 | break; |
diff --git a/arch/s390/pci/pci_insn.c b/arch/s390/pci/pci_insn.c index 22eeb9d7ffeb..85267c058af8 100644 --- a/arch/s390/pci/pci_insn.c +++ b/arch/s390/pci/pci_insn.c | |||
@@ -27,7 +27,7 @@ static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) | |||
27 | return cc; | 27 | return cc; |
28 | } | 28 | } |
29 | 29 | ||
30 | int s390pci_mod_fc(u64 req, struct zpci_fib *fib) | 30 | int zpci_mod_fc(u64 req, struct zpci_fib *fib) |
31 | { | 31 | { |
32 | u8 cc, status; | 32 | u8 cc, status; |
33 | 33 | ||
@@ -61,7 +61,7 @@ static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) | |||
61 | return cc; | 61 | return cc; |
62 | } | 62 | } |
63 | 63 | ||
64 | int s390pci_refresh_trans(u64 fn, u64 addr, u64 range) | 64 | int zpci_refresh_trans(u64 fn, u64 addr, u64 range) |
65 | { | 65 | { |
66 | u8 cc, status; | 66 | u8 cc, status; |
67 | 67 | ||
@@ -78,7 +78,7 @@ int s390pci_refresh_trans(u64 fn, u64 addr, u64 range) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | /* Set Interruption Controls */ | 80 | /* Set Interruption Controls */ |
81 | void set_irq_ctrl(u16 ctl, char *unused, u8 isc) | 81 | void zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc) |
82 | { | 82 | { |
83 | asm volatile ( | 83 | asm volatile ( |
84 | " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" | 84 | " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" |
@@ -109,7 +109,7 @@ static inline int __pcilg(u64 *data, u64 req, u64 offset, u8 *status) | |||
109 | return cc; | 109 | return cc; |
110 | } | 110 | } |
111 | 111 | ||
112 | int s390pci_load(u64 *data, u64 req, u64 offset) | 112 | int zpci_load(u64 *data, u64 req, u64 offset) |
113 | { | 113 | { |
114 | u8 status; | 114 | u8 status; |
115 | int cc; | 115 | int cc; |
@@ -125,7 +125,7 @@ int s390pci_load(u64 *data, u64 req, u64 offset) | |||
125 | __func__, cc, status, req, offset); | 125 | __func__, cc, status, req, offset); |
126 | return (cc > 0) ? -EIO : cc; | 126 | return (cc > 0) ? -EIO : cc; |
127 | } | 127 | } |
128 | EXPORT_SYMBOL_GPL(s390pci_load); | 128 | EXPORT_SYMBOL_GPL(zpci_load); |
129 | 129 | ||
130 | /* PCI Store */ | 130 | /* PCI Store */ |
131 | static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status) | 131 | static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status) |
@@ -147,7 +147,7 @@ static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status) | |||
147 | return cc; | 147 | return cc; |
148 | } | 148 | } |
149 | 149 | ||
150 | int s390pci_store(u64 data, u64 req, u64 offset) | 150 | int zpci_store(u64 data, u64 req, u64 offset) |
151 | { | 151 | { |
152 | u8 status; | 152 | u8 status; |
153 | int cc; | 153 | int cc; |
@@ -163,7 +163,7 @@ int s390pci_store(u64 data, u64 req, u64 offset) | |||
163 | __func__, cc, status, req, offset); | 163 | __func__, cc, status, req, offset); |
164 | return (cc > 0) ? -EIO : cc; | 164 | return (cc > 0) ? -EIO : cc; |
165 | } | 165 | } |
166 | EXPORT_SYMBOL_GPL(s390pci_store); | 166 | EXPORT_SYMBOL_GPL(zpci_store); |
167 | 167 | ||
168 | /* PCI Store Block */ | 168 | /* PCI Store Block */ |
169 | static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) | 169 | static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) |
@@ -183,7 +183,7 @@ static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) | |||
183 | return cc; | 183 | return cc; |
184 | } | 184 | } |
185 | 185 | ||
186 | int s390pci_store_block(const u64 *data, u64 req, u64 offset) | 186 | int zpci_store_block(const u64 *data, u64 req, u64 offset) |
187 | { | 187 | { |
188 | u8 status; | 188 | u8 status; |
189 | int cc; | 189 | int cc; |
@@ -199,4 +199,4 @@ int s390pci_store_block(const u64 *data, u64 req, u64 offset) | |||
199 | __func__, cc, status, req, offset); | 199 | __func__, cc, status, req, offset); |
200 | return (cc > 0) ? -EIO : cc; | 200 | return (cc > 0) ? -EIO : cc; |
201 | } | 201 | } |
202 | EXPORT_SYMBOL_GPL(s390pci_store_block); | 202 | EXPORT_SYMBOL_GPL(zpci_store_block); |
diff --git a/arch/s390/pci/pci_msi.c b/arch/s390/pci/pci_msi.c deleted file mode 100644 index b097aed05a9b..000000000000 --- a/arch/s390/pci/pci_msi.c +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 2012 | ||
3 | * | ||
4 | * Author(s): | ||
5 | * Jan Glauber <jang@linux.vnet.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #define COMPONENT "zPCI" | ||
9 | #define pr_fmt(fmt) COMPONENT ": " fmt | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/rculist.h> | ||
14 | #include <linux/hash.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/msi.h> | ||
17 | #include <asm/hw_irq.h> | ||
18 | |||
19 | /* mapping of irq numbers to msi_desc */ | ||
20 | static struct hlist_head *msi_hash; | ||
21 | static const unsigned int msi_hash_bits = 8; | ||
22 | #define MSI_HASH_BUCKETS (1U << msi_hash_bits) | ||
23 | #define msi_hashfn(nr) hash_long(nr, msi_hash_bits) | ||
24 | |||
25 | static DEFINE_SPINLOCK(msi_map_lock); | ||
26 | |||
27 | struct msi_desc *__irq_get_msi_desc(unsigned int irq) | ||
28 | { | ||
29 | struct msi_map *map; | ||
30 | |||
31 | hlist_for_each_entry_rcu(map, | ||
32 | &msi_hash[msi_hashfn(irq)], msi_chain) | ||
33 | if (map->irq == irq) | ||
34 | return map->msi; | ||
35 | return NULL; | ||
36 | } | ||
37 | |||
38 | int zpci_msi_set_mask_bits(struct msi_desc *msi, u32 mask, u32 flag) | ||
39 | { | ||
40 | if (msi->msi_attrib.is_msix) { | ||
41 | int offset = msi->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
42 | PCI_MSIX_ENTRY_VECTOR_CTRL; | ||
43 | msi->masked = readl(msi->mask_base + offset); | ||
44 | writel(flag, msi->mask_base + offset); | ||
45 | } else { | ||
46 | if (msi->msi_attrib.maskbit) { | ||
47 | int pos; | ||
48 | u32 mask_bits; | ||
49 | |||
50 | pos = (long) msi->mask_base; | ||
51 | pci_read_config_dword(msi->dev, pos, &mask_bits); | ||
52 | mask_bits &= ~(mask); | ||
53 | mask_bits |= flag & mask; | ||
54 | pci_write_config_dword(msi->dev, pos, mask_bits); | ||
55 | } else { | ||
56 | return 0; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | msi->msi_attrib.maskbit = !!flag; | ||
61 | return 1; | ||
62 | } | ||
63 | |||
64 | int zpci_setup_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi, | ||
65 | unsigned int nr, int offset) | ||
66 | { | ||
67 | struct msi_map *map; | ||
68 | struct msi_msg msg; | ||
69 | int rc; | ||
70 | |||
71 | map = kmalloc(sizeof(*map), GFP_KERNEL); | ||
72 | if (map == NULL) | ||
73 | return -ENOMEM; | ||
74 | |||
75 | map->irq = nr; | ||
76 | map->msi = msi; | ||
77 | zdev->msi_map[nr & ZPCI_MSI_MASK] = map; | ||
78 | INIT_HLIST_NODE(&map->msi_chain); | ||
79 | |||
80 | pr_debug("%s hashing irq: %u to bucket nr: %llu\n", | ||
81 | __func__, nr, msi_hashfn(nr)); | ||
82 | hlist_add_head_rcu(&map->msi_chain, &msi_hash[msi_hashfn(nr)]); | ||
83 | |||
84 | spin_lock(&msi_map_lock); | ||
85 | rc = irq_set_msi_desc(nr, msi); | ||
86 | if (rc) { | ||
87 | spin_unlock(&msi_map_lock); | ||
88 | hlist_del_rcu(&map->msi_chain); | ||
89 | kfree(map); | ||
90 | zdev->msi_map[nr & ZPCI_MSI_MASK] = NULL; | ||
91 | return rc; | ||
92 | } | ||
93 | spin_unlock(&msi_map_lock); | ||
94 | |||
95 | msg.data = nr - offset; | ||
96 | msg.address_lo = zdev->msi_addr & 0xffffffff; | ||
97 | msg.address_hi = zdev->msi_addr >> 32; | ||
98 | write_msi_msg(nr, &msg); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | void zpci_teardown_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi) | ||
103 | { | ||
104 | int irq = msi->irq & ZPCI_MSI_MASK; | ||
105 | struct msi_map *map; | ||
106 | |||
107 | msi->msg.address_lo = 0; | ||
108 | msi->msg.address_hi = 0; | ||
109 | msi->msg.data = 0; | ||
110 | msi->irq = 0; | ||
111 | zpci_msi_set_mask_bits(msi, 1, 1); | ||
112 | |||
113 | spin_lock(&msi_map_lock); | ||
114 | map = zdev->msi_map[irq]; | ||
115 | hlist_del_rcu(&map->msi_chain); | ||
116 | kfree(map); | ||
117 | zdev->msi_map[irq] = NULL; | ||
118 | spin_unlock(&msi_map_lock); | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * The msi hash table has 256 entries which is good for 4..20 | ||
123 | * devices (a typical device allocates 10 + CPUs MSI's). Maybe make | ||
124 | * the hash table size adjustable later. | ||
125 | */ | ||
126 | int __init zpci_msihash_init(void) | ||
127 | { | ||
128 | unsigned int i; | ||
129 | |||
130 | msi_hash = kmalloc(MSI_HASH_BUCKETS * sizeof(*msi_hash), GFP_KERNEL); | ||
131 | if (!msi_hash) | ||
132 | return -ENOMEM; | ||
133 | |||
134 | for (i = 0; i < MSI_HASH_BUCKETS; i++) | ||
135 | INIT_HLIST_HEAD(&msi_hash[i]); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | void __init zpci_msihash_exit(void) | ||
140 | { | ||
141 | kfree(msi_hash); | ||
142 | } | ||
diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c index e99a2557f186..cf8a12ff733b 100644 --- a/arch/s390/pci/pci_sysfs.c +++ b/arch/s390/pci/pci_sysfs.c | |||
@@ -48,11 +48,38 @@ static ssize_t show_pfgid(struct device *dev, struct device_attribute *attr, | |||
48 | } | 48 | } |
49 | static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL); | 49 | static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL); |
50 | 50 | ||
51 | static void recover_callback(struct device *dev) | ||
52 | { | ||
53 | struct pci_dev *pdev = to_pci_dev(dev); | ||
54 | struct zpci_dev *zdev = get_zdev(pdev); | ||
55 | int ret; | ||
56 | |||
57 | pci_stop_and_remove_bus_device(pdev); | ||
58 | ret = zpci_disable_device(zdev); | ||
59 | if (ret) | ||
60 | return; | ||
61 | |||
62 | ret = zpci_enable_device(zdev); | ||
63 | if (ret) | ||
64 | return; | ||
65 | |||
66 | pci_rescan_bus(zdev->bus); | ||
67 | } | ||
68 | |||
69 | static ssize_t store_recover(struct device *dev, struct device_attribute *attr, | ||
70 | const char *buf, size_t count) | ||
71 | { | ||
72 | int rc = device_schedule_callback(dev, recover_callback); | ||
73 | return rc ? rc : count; | ||
74 | } | ||
75 | static DEVICE_ATTR(recover, S_IWUSR, NULL, store_recover); | ||
76 | |||
51 | static struct device_attribute *zpci_dev_attrs[] = { | 77 | static struct device_attribute *zpci_dev_attrs[] = { |
52 | &dev_attr_function_id, | 78 | &dev_attr_function_id, |
53 | &dev_attr_function_handle, | 79 | &dev_attr_function_handle, |
54 | &dev_attr_pchid, | 80 | &dev_attr_pchid, |
55 | &dev_attr_pfgid, | 81 | &dev_attr_pfgid, |
82 | &dev_attr_recover, | ||
56 | NULL, | 83 | NULL, |
57 | }; | 84 | }; |
58 | 85 | ||
diff --git a/arch/score/Kconfig b/arch/score/Kconfig index c8def8bc9020..5fc237581caf 100644 --- a/arch/score/Kconfig +++ b/arch/score/Kconfig | |||
@@ -87,6 +87,8 @@ config STACKTRACE_SUPPORT | |||
87 | 87 | ||
88 | source "init/Kconfig" | 88 | source "init/Kconfig" |
89 | 89 | ||
90 | source "kernel/Kconfig.freezer" | ||
91 | |||
90 | config MMU | 92 | config MMU |
91 | def_bool y | 93 | def_bool y |
92 | 94 | ||
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 1020dd85431a..1018ed3a3ca5 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -643,9 +643,9 @@ config KEXEC | |||
643 | 643 | ||
644 | It is an ongoing process to be certain the hardware in a machine | 644 | It is an ongoing process to be certain the hardware in a machine |
645 | is properly shutdown, so do not be surprised if this code does not | 645 | is properly shutdown, so do not be surprised if this code does not |
646 | initially work for you. It may help to enable device hotplugging | 646 | initially work for you. As of this writing the exact hardware |
647 | support. As of this writing the exact hardware interface is | 647 | interface is strongly in flux, so no good recommendation can be |
648 | strongly in flux, so no good recommendation can be made. | 648 | made. |
649 | 649 | ||
650 | config CRASH_DUMP | 650 | config CRASH_DUMP |
651 | bool "kernel crash dumps (EXPERIMENTAL)" | 651 | bool "kernel crash dumps (EXPERIMENTAL)" |
diff --git a/arch/sh/boards/board-espt.c b/arch/sh/boards/board-espt.c index 4d94dff9015c..7291e2f11a47 100644 --- a/arch/sh/boards/board-espt.c +++ b/arch/sh/boards/board-espt.c | |||
@@ -80,7 +80,6 @@ static struct resource sh_eth_resources[] = { | |||
80 | static struct sh_eth_plat_data sh7763_eth_pdata = { | 80 | static struct sh_eth_plat_data sh7763_eth_pdata = { |
81 | .phy = 0, | 81 | .phy = 0, |
82 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 82 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
83 | .register_type = SH_ETH_REG_GIGABIT, | ||
84 | .phy_interface = PHY_INTERFACE_MODE_MII, | 83 | .phy_interface = PHY_INTERFACE_MODE_MII, |
85 | }; | 84 | }; |
86 | 85 | ||
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c index 4f114d1cd019..25c5a932f9fe 100644 --- a/arch/sh/boards/board-sh7757lcr.c +++ b/arch/sh/boards/board-sh7757lcr.c | |||
@@ -77,7 +77,6 @@ static struct resource sh_eth0_resources[] = { | |||
77 | static struct sh_eth_plat_data sh7757_eth0_pdata = { | 77 | static struct sh_eth_plat_data sh7757_eth0_pdata = { |
78 | .phy = 1, | 78 | .phy = 1, |
79 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 79 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
80 | .register_type = SH_ETH_REG_FAST_SH4, | ||
81 | .set_mdio_gate = sh7757_eth_set_mdio_gate, | 80 | .set_mdio_gate = sh7757_eth_set_mdio_gate, |
82 | }; | 81 | }; |
83 | 82 | ||
@@ -106,7 +105,6 @@ static struct resource sh_eth1_resources[] = { | |||
106 | static struct sh_eth_plat_data sh7757_eth1_pdata = { | 105 | static struct sh_eth_plat_data sh7757_eth1_pdata = { |
107 | .phy = 1, | 106 | .phy = 1, |
108 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 107 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
109 | .register_type = SH_ETH_REG_FAST_SH4, | ||
110 | .set_mdio_gate = sh7757_eth_set_mdio_gate, | 108 | .set_mdio_gate = sh7757_eth_set_mdio_gate, |
111 | }; | 109 | }; |
112 | 110 | ||
@@ -151,7 +149,6 @@ static struct resource sh_eth_giga0_resources[] = { | |||
151 | static struct sh_eth_plat_data sh7757_eth_giga0_pdata = { | 149 | static struct sh_eth_plat_data sh7757_eth_giga0_pdata = { |
152 | .phy = 18, | 150 | .phy = 18, |
153 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 151 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
154 | .register_type = SH_ETH_REG_GIGABIT, | ||
155 | .set_mdio_gate = sh7757_eth_giga_set_mdio_gate, | 152 | .set_mdio_gate = sh7757_eth_giga_set_mdio_gate, |
156 | .phy_interface = PHY_INTERFACE_MODE_RGMII_ID, | 153 | .phy_interface = PHY_INTERFACE_MODE_RGMII_ID, |
157 | }; | 154 | }; |
@@ -186,7 +183,6 @@ static struct resource sh_eth_giga1_resources[] = { | |||
186 | static struct sh_eth_plat_data sh7757_eth_giga1_pdata = { | 183 | static struct sh_eth_plat_data sh7757_eth_giga1_pdata = { |
187 | .phy = 19, | 184 | .phy = 19, |
188 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 185 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
189 | .register_type = SH_ETH_REG_GIGABIT, | ||
190 | .set_mdio_gate = sh7757_eth_giga_set_mdio_gate, | 186 | .set_mdio_gate = sh7757_eth_giga_set_mdio_gate, |
191 | .phy_interface = PHY_INTERFACE_MODE_RGMII_ID, | 187 | .phy_interface = PHY_INTERFACE_MODE_RGMII_ID, |
192 | }; | 188 | }; |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 61fade0ffa96..a4f630f04ea3 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -159,7 +159,6 @@ static struct resource sh_eth_resources[] = { | |||
159 | static struct sh_eth_plat_data sh_eth_plat = { | 159 | static struct sh_eth_plat_data sh_eth_plat = { |
160 | .phy = 0x1f, /* SMSC LAN8700 */ | 160 | .phy = 0x1f, /* SMSC LAN8700 */ |
161 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 161 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
162 | .register_type = SH_ETH_REG_FAST_SH4, | ||
163 | .phy_interface = PHY_INTERFACE_MODE_MII, | 162 | .phy_interface = PHY_INTERFACE_MODE_MII, |
164 | .ether_link_active_low = 1 | 163 | .ether_link_active_low = 1 |
165 | }; | 164 | }; |
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index b70180ef3e29..21e4230659a5 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c | |||
@@ -365,7 +365,7 @@ static struct platform_device keysc_device = { | |||
365 | static struct resource sh_eth_resources[] = { | 365 | static struct resource sh_eth_resources[] = { |
366 | [0] = { | 366 | [0] = { |
367 | .start = SH_ETH_ADDR, | 367 | .start = SH_ETH_ADDR, |
368 | .end = SH_ETH_ADDR + 0x1FC, | 368 | .end = SH_ETH_ADDR + 0x1FC - 1, |
369 | .flags = IORESOURCE_MEM, | 369 | .flags = IORESOURCE_MEM, |
370 | }, | 370 | }, |
371 | [1] = { | 371 | [1] = { |
@@ -377,6 +377,7 @@ static struct resource sh_eth_resources[] = { | |||
377 | static struct sh_eth_plat_data sh_eth_plat = { | 377 | static struct sh_eth_plat_data sh_eth_plat = { |
378 | .phy = 0x1f, /* SMSC LAN8187 */ | 378 | .phy = 0x1f, /* SMSC LAN8187 */ |
379 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 379 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
380 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
380 | }; | 381 | }; |
381 | 382 | ||
382 | static struct platform_device sh_eth_device = { | 383 | static struct platform_device sh_eth_device = { |
diff --git a/arch/sh/boards/mach-sh7763rdp/setup.c b/arch/sh/boards/mach-sh7763rdp/setup.c index 50ba481fa240..2c8fb04685d4 100644 --- a/arch/sh/boards/mach-sh7763rdp/setup.c +++ b/arch/sh/boards/mach-sh7763rdp/setup.c | |||
@@ -88,7 +88,6 @@ static struct resource sh_eth_resources[] = { | |||
88 | static struct sh_eth_plat_data sh7763_eth_pdata = { | 88 | static struct sh_eth_plat_data sh7763_eth_pdata = { |
89 | .phy = 1, | 89 | .phy = 1, |
90 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | 90 | .edmac_endian = EDMAC_LITTLE_ENDIAN, |
91 | .register_type = SH_ETH_REG_GIGABIT, | ||
92 | .phy_interface = PHY_INTERFACE_MODE_MII, | 91 | .phy_interface = PHY_INTERFACE_MODE_MII, |
93 | }; | 92 | }; |
94 | 93 | ||
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 102f5d58b037..60ed3e1c4b75 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -69,7 +69,6 @@ static void pcibios_scanbus(struct pci_channel *hose) | |||
69 | 69 | ||
70 | pci_bus_size_bridges(bus); | 70 | pci_bus_size_bridges(bus); |
71 | pci_bus_assign_resources(bus); | 71 | pci_bus_assign_resources(bus); |
72 | pci_enable_bridges(bus); | ||
73 | } else { | 72 | } else { |
74 | pci_free_resource_list(&resources); | 73 | pci_free_resource_list(&resources); |
75 | } | 74 | } |
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index e61d43d9f689..362192ed12fe 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h | |||
@@ -36,10 +36,12 @@ static inline void init_tlb_gather(struct mmu_gather *tlb) | |||
36 | } | 36 | } |
37 | 37 | ||
38 | static inline void | 38 | static inline void |
39 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush) | 39 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) |
40 | { | 40 | { |
41 | tlb->mm = mm; | 41 | tlb->mm = mm; |
42 | tlb->fullmm = full_mm_flush; | 42 | tlb->start = start; |
43 | tlb->end = end; | ||
44 | tlb->fullmm = !(start | (end+1)); | ||
43 | 45 | ||
44 | init_tlb_gather(tlb); | 46 | init_tlb_gather(tlb); |
45 | } | 47 | } |
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index bb11e1925178..4df4d4ffe39b 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/serial.h> | 13 | #include <linux/serial.h> |
14 | #include <linux/serial_sci.h> | 14 | #include <linux/serial_sci.h> |
15 | #include <linux/sh_eth.h> | ||
15 | #include <linux/sh_timer.h> | 16 | #include <linux/sh_timer.h> |
16 | #include <linux/io.h> | 17 | #include <linux/io.h> |
17 | 18 | ||
@@ -110,10 +111,16 @@ static struct platform_device scif2_device = { | |||
110 | }, | 111 | }, |
111 | }; | 112 | }; |
112 | 113 | ||
114 | static struct sh_eth_plat_data eth_platform_data = { | ||
115 | .phy = 1, | ||
116 | .edmac_endian = EDMAC_LITTLE_ENDIAN, | ||
117 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
118 | }; | ||
119 | |||
113 | static struct resource eth_resources[] = { | 120 | static struct resource eth_resources[] = { |
114 | [0] = { | 121 | [0] = { |
115 | .start = 0xfb000000, | 122 | .start = 0xfb000000, |
116 | .end = 0xfb0001c8, | 123 | .end = 0xfb0001c7, |
117 | .flags = IORESOURCE_MEM, | 124 | .flags = IORESOURCE_MEM, |
118 | }, | 125 | }, |
119 | [1] = { | 126 | [1] = { |
@@ -127,7 +134,7 @@ static struct platform_device eth_device = { | |||
127 | .name = "sh7619-ether", | 134 | .name = "sh7619-ether", |
128 | .id = -1, | 135 | .id = -1, |
129 | .dev = { | 136 | .dev = { |
130 | .platform_data = (void *)1, | 137 | .platform_data = ð_platform_data, |
131 | }, | 138 | }, |
132 | .num_resources = ARRAY_SIZE(eth_resources), | 139 | .num_resources = ARRAY_SIZE(eth_resources), |
133 | .resource = eth_resources, | 140 | .resource = eth_resources, |
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c index d30622592116..e3abfd4277e2 100644 --- a/arch/sh/kernel/cpu/shmobile/cpuidle.c +++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c | |||
@@ -91,13 +91,11 @@ static struct cpuidle_driver cpuidle_driver = { | |||
91 | 91 | ||
92 | int __init sh_mobile_setup_cpuidle(void) | 92 | int __init sh_mobile_setup_cpuidle(void) |
93 | { | 93 | { |
94 | int ret; | ||
95 | |||
96 | if (sh_mobile_sleep_supported & SUSP_SH_SF) | 94 | if (sh_mobile_sleep_supported & SUSP_SH_SF) |
97 | cpuidle_driver.states[1].disabled = false; | 95 | cpuidle_driver.states[1].disabled = false; |
98 | 96 | ||
99 | if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) | 97 | if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) |
100 | cpuidle_driver.states[2].disabled = false; | 98 | cpuidle_driver.states[2].disabled = false; |
101 | 99 | ||
102 | return cpuidle_register(&cpuidle_driver); | 100 | return cpuidle_register(&cpuidle_driver, NULL); |
103 | } | 101 | } |
diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h index c7de3323819c..8d284801f232 100644 --- a/arch/sparc/include/asm/switch_to_64.h +++ b/arch/sparc/include/asm/switch_to_64.h | |||
@@ -48,8 +48,8 @@ do { save_and_clear_fpu(); \ | |||
48 | "wrpr %%g0, 14, %%pil\n\t" \ | 48 | "wrpr %%g0, 14, %%pil\n\t" \ |
49 | "brz,pt %%o7, switch_to_pc\n\t" \ | 49 | "brz,pt %%o7, switch_to_pc\n\t" \ |
50 | " mov %%g7, %0\n\t" \ | 50 | " mov %%g7, %0\n\t" \ |
51 | "sethi %%hi(ret_from_syscall), %%g1\n\t" \ | 51 | "sethi %%hi(ret_from_fork), %%g1\n\t" \ |
52 | "jmpl %%g1 + %%lo(ret_from_syscall), %%g0\n\t" \ | 52 | "jmpl %%g1 + %%lo(ret_from_fork), %%g0\n\t" \ |
53 | " nop\n\t" \ | 53 | " nop\n\t" \ |
54 | ".globl switch_to_pc\n\t" \ | 54 | ".globl switch_to_pc\n\t" \ |
55 | "switch_to_pc:\n\t" \ | 55 | "switch_to_pc:\n\t" \ |
diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index e4de74c2c9b0..cb5d272d658a 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c | |||
@@ -327,6 +327,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) | |||
327 | case SUN4V_CHIP_NIAGARA3: | 327 | case SUN4V_CHIP_NIAGARA3: |
328 | case SUN4V_CHIP_NIAGARA4: | 328 | case SUN4V_CHIP_NIAGARA4: |
329 | case SUN4V_CHIP_NIAGARA5: | 329 | case SUN4V_CHIP_NIAGARA5: |
330 | case SUN4V_CHIP_SPARC64X: | ||
330 | rover_inc_table = niagara_iterate_method; | 331 | rover_inc_table = niagara_iterate_method; |
331 | break; | 332 | break; |
332 | default: | 333 | default: |
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index e2a030045089..33c02b15f478 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -839,7 +839,7 @@ sys_sigreturn: | |||
839 | nop | 839 | nop |
840 | 840 | ||
841 | call syscall_trace | 841 | call syscall_trace |
842 | nop | 842 | mov 1, %o1 |
843 | 843 | ||
844 | 1: | 844 | 1: |
845 | /* We don't want to muck with user registers like a | 845 | /* We don't want to muck with user registers like a |
diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index c8759550799f..53c0a82e6030 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c | |||
@@ -42,7 +42,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) | |||
42 | { | 42 | { |
43 | struct thread_info *t = task_thread_info(p); | 43 | struct thread_info *t = task_thread_info(p); |
44 | extern unsigned int switch_to_pc; | 44 | extern unsigned int switch_to_pc; |
45 | extern unsigned int ret_from_syscall; | 45 | extern unsigned int ret_from_fork; |
46 | struct reg_window *win; | 46 | struct reg_window *win; |
47 | unsigned long pc, cwp; | 47 | unsigned long pc, cwp; |
48 | int i; | 48 | int i; |
@@ -66,7 +66,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) | |||
66 | gdb_regs[i] = 0; | 66 | gdb_regs[i] = 0; |
67 | 67 | ||
68 | if (t->new_child) | 68 | if (t->new_child) |
69 | pc = (unsigned long) &ret_from_syscall; | 69 | pc = (unsigned long) &ret_from_fork; |
70 | else | 70 | else |
71 | pc = (unsigned long) &switch_to_pc; | 71 | pc = (unsigned long) &switch_to_pc; |
72 | 72 | ||
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index 0746e5e32b37..fde5a419cf27 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S | |||
@@ -25,11 +25,10 @@ kvmap_itlb: | |||
25 | */ | 25 | */ |
26 | kvmap_itlb_4v: | 26 | kvmap_itlb_4v: |
27 | 27 | ||
28 | kvmap_itlb_nonlinear: | ||
29 | /* Catch kernel NULL pointer calls. */ | 28 | /* Catch kernel NULL pointer calls. */ |
30 | sethi %hi(PAGE_SIZE), %g5 | 29 | sethi %hi(PAGE_SIZE), %g5 |
31 | cmp %g4, %g5 | 30 | cmp %g4, %g5 |
32 | bleu,pn %xcc, kvmap_dtlb_longpath | 31 | blu,pn %xcc, kvmap_itlb_longpath |
33 | nop | 32 | nop |
34 | 33 | ||
35 | KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_itlb_load) | 34 | KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_itlb_load) |
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 7ff45e4ba681..773c1f2983ce 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/export.h> | ||
17 | #include <linux/ptrace.h> | 18 | #include <linux/ptrace.h> |
18 | #include <linux/user.h> | 19 | #include <linux/user.h> |
19 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
@@ -116,6 +117,7 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | |||
116 | 117 | ||
117 | preempt_enable(); | 118 | preempt_enable(); |
118 | } | 119 | } |
120 | EXPORT_SYMBOL_GPL(flush_ptrace_access); | ||
119 | 121 | ||
120 | static int get_from_target(struct task_struct *target, unsigned long uaddr, | 122 | static int get_from_target(struct task_struct *target, unsigned long uaddr, |
121 | void *kbuf, int len) | 123 | void *kbuf, int len) |
@@ -1087,7 +1089,7 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) | |||
1087 | audit_syscall_exit(regs); | 1089 | audit_syscall_exit(regs); |
1088 | 1090 | ||
1089 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | 1091 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
1090 | trace_sys_exit(regs, regs->u_regs[UREG_G1]); | 1092 | trace_sys_exit(regs, regs->u_regs[UREG_I0]); |
1091 | 1093 | ||
1092 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1094 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
1093 | tracehook_report_syscall_exit(regs, 0); | 1095 | tracehook_report_syscall_exit(regs, 0); |
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 13785547e435..3fdb455e3318 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
@@ -499,12 +499,14 @@ static void __init init_sparc64_elf_hwcap(void) | |||
499 | sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || | 499 | sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
500 | sun4v_chip_type == SUN4V_CHIP_NIAGARA3 || | 500 | sun4v_chip_type == SUN4V_CHIP_NIAGARA3 || |
501 | sun4v_chip_type == SUN4V_CHIP_NIAGARA4 || | 501 | sun4v_chip_type == SUN4V_CHIP_NIAGARA4 || |
502 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5) | 502 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
503 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) | ||
503 | cap |= HWCAP_SPARC_BLKINIT; | 504 | cap |= HWCAP_SPARC_BLKINIT; |
504 | if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || | 505 | if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
505 | sun4v_chip_type == SUN4V_CHIP_NIAGARA3 || | 506 | sun4v_chip_type == SUN4V_CHIP_NIAGARA3 || |
506 | sun4v_chip_type == SUN4V_CHIP_NIAGARA4 || | 507 | sun4v_chip_type == SUN4V_CHIP_NIAGARA4 || |
507 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5) | 508 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
509 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) | ||
508 | cap |= HWCAP_SPARC_N2; | 510 | cap |= HWCAP_SPARC_N2; |
509 | } | 511 | } |
510 | 512 | ||
@@ -530,13 +532,15 @@ static void __init init_sparc64_elf_hwcap(void) | |||
530 | if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || | 532 | if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
531 | sun4v_chip_type == SUN4V_CHIP_NIAGARA3 || | 533 | sun4v_chip_type == SUN4V_CHIP_NIAGARA3 || |
532 | sun4v_chip_type == SUN4V_CHIP_NIAGARA4 || | 534 | sun4v_chip_type == SUN4V_CHIP_NIAGARA4 || |
533 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5) | 535 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
536 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) | ||
534 | cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | | 537 | cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | |
535 | AV_SPARC_ASI_BLK_INIT | | 538 | AV_SPARC_ASI_BLK_INIT | |
536 | AV_SPARC_POPC); | 539 | AV_SPARC_POPC); |
537 | if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3 || | 540 | if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3 || |
538 | sun4v_chip_type == SUN4V_CHIP_NIAGARA4 || | 541 | sun4v_chip_type == SUN4V_CHIP_NIAGARA4 || |
539 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5) | 542 | sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || |
543 | sun4v_chip_type == SUN4V_CHIP_SPARC64X) | ||
540 | cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | | 544 | cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | |
541 | AV_SPARC_FMAF); | 545 | AV_SPARC_FMAF); |
542 | } | 546 | } |
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 22a1098961f5..d950197a17e1 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S | |||
@@ -98,8 +98,8 @@ sys_clone: | |||
98 | ba,pt %xcc, sparc_do_fork | 98 | ba,pt %xcc, sparc_do_fork |
99 | add %sp, PTREGS_OFF, %o2 | 99 | add %sp, PTREGS_OFF, %o2 |
100 | 100 | ||
101 | .globl ret_from_syscall | 101 | .globl ret_from_fork |
102 | ret_from_syscall: | 102 | ret_from_fork: |
103 | /* Clear current_thread_info()->new_child. */ | 103 | /* Clear current_thread_info()->new_child. */ |
104 | stb %g0, [%g6 + TI_NEW_CHILD] | 104 | stb %g0, [%g6 + TI_NEW_CHILD] |
105 | call schedule_tail | 105 | call schedule_tail |
@@ -152,7 +152,7 @@ linux_syscall_trace32: | |||
152 | srl %i4, 0, %o4 | 152 | srl %i4, 0, %o4 |
153 | srl %i1, 0, %o1 | 153 | srl %i1, 0, %o1 |
154 | srl %i2, 0, %o2 | 154 | srl %i2, 0, %o2 |
155 | ba,pt %xcc, 2f | 155 | ba,pt %xcc, 5f |
156 | srl %i3, 0, %o3 | 156 | srl %i3, 0, %o3 |
157 | 157 | ||
158 | linux_syscall_trace: | 158 | linux_syscall_trace: |
@@ -182,13 +182,13 @@ linux_sparc_syscall32: | |||
182 | srl %i1, 0, %o1 ! IEU0 Group | 182 | srl %i1, 0, %o1 ! IEU0 Group |
183 | ldx [%g6 + TI_FLAGS], %l0 ! Load | 183 | ldx [%g6 + TI_FLAGS], %l0 ! Load |
184 | 184 | ||
185 | srl %i5, 0, %o5 ! IEU1 | 185 | srl %i3, 0, %o3 ! IEU0 |
186 | srl %i2, 0, %o2 ! IEU0 Group | 186 | srl %i2, 0, %o2 ! IEU0 Group |
187 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 | 187 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 |
188 | bne,pn %icc, linux_syscall_trace32 ! CTI | 188 | bne,pn %icc, linux_syscall_trace32 ! CTI |
189 | mov %i0, %l5 ! IEU1 | 189 | mov %i0, %l5 ! IEU1 |
190 | call %l7 ! CTI Group brk forced | 190 | 5: call %l7 ! CTI Group brk forced |
191 | srl %i3, 0, %o3 ! IEU0 | 191 | srl %i5, 0, %o5 ! IEU1 |
192 | ba,a,pt %xcc, 3f | 192 | ba,a,pt %xcc, 3f |
193 | 193 | ||
194 | /* Linux native system calls enter here... */ | 194 | /* Linux native system calls enter here... */ |
diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S index e0b1e13a0736..ad4bde3bb61e 100644 --- a/arch/sparc/kernel/trampoline_64.S +++ b/arch/sparc/kernel/trampoline_64.S | |||
@@ -129,7 +129,6 @@ startup_continue: | |||
129 | clr %l5 | 129 | clr %l5 |
130 | sethi %hi(num_kernel_image_mappings), %l6 | 130 | sethi %hi(num_kernel_image_mappings), %l6 |
131 | lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 | 131 | lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 |
132 | add %l6, 1, %l6 | ||
133 | 132 | ||
134 | mov 15, %l7 | 133 | mov 15, %l7 |
135 | BRANCH_IF_ANY_CHEETAH(g1,g5,2f) | 134 | BRANCH_IF_ANY_CHEETAH(g1,g5,2f) |
@@ -222,7 +221,6 @@ niagara_lock_tlb: | |||
222 | clr %l5 | 221 | clr %l5 |
223 | sethi %hi(num_kernel_image_mappings), %l6 | 222 | sethi %hi(num_kernel_image_mappings), %l6 |
224 | lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 | 223 | lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 |
225 | add %l6, 1, %l6 | ||
226 | 224 | ||
227 | 1: | 225 | 1: |
228 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 | 226 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 |
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c index 0c4e35e522fa..323335b9cd2b 100644 --- a/arch/sparc/lib/ksyms.c +++ b/arch/sparc/lib/ksyms.c | |||
@@ -98,15 +98,6 @@ EXPORT_SYMBOL(___copy_from_user); | |||
98 | EXPORT_SYMBOL(___copy_in_user); | 98 | EXPORT_SYMBOL(___copy_in_user); |
99 | EXPORT_SYMBOL(__clear_user); | 99 | EXPORT_SYMBOL(__clear_user); |
100 | 100 | ||
101 | /* RW semaphores */ | ||
102 | EXPORT_SYMBOL(__down_read); | ||
103 | EXPORT_SYMBOL(__down_read_trylock); | ||
104 | EXPORT_SYMBOL(__down_write); | ||
105 | EXPORT_SYMBOL(__down_write_trylock); | ||
106 | EXPORT_SYMBOL(__up_read); | ||
107 | EXPORT_SYMBOL(__up_write); | ||
108 | EXPORT_SYMBOL(__downgrade_write); | ||
109 | |||
110 | /* Atomic counter implementation. */ | 101 | /* Atomic counter implementation. */ |
111 | EXPORT_SYMBOL(atomic_add); | 102 | EXPORT_SYMBOL(atomic_add); |
112 | EXPORT_SYMBOL(atomic_add_ret); | 103 | EXPORT_SYMBOL(atomic_add_ret); |
diff --git a/arch/tile/gxio/iorpc_mpipe.c b/arch/tile/gxio/iorpc_mpipe.c index 31b87bf8c027..4f8f3d619c4a 100644 --- a/arch/tile/gxio/iorpc_mpipe.c +++ b/arch/tile/gxio/iorpc_mpipe.c | |||
@@ -387,6 +387,27 @@ int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac) | |||
387 | 387 | ||
388 | EXPORT_SYMBOL(gxio_mpipe_link_close_aux); | 388 | EXPORT_SYMBOL(gxio_mpipe_link_close_aux); |
389 | 389 | ||
390 | struct link_set_attr_aux_param { | ||
391 | int mac; | ||
392 | uint32_t attr; | ||
393 | int64_t val; | ||
394 | }; | ||
395 | |||
396 | int gxio_mpipe_link_set_attr_aux(gxio_mpipe_context_t * context, int mac, | ||
397 | uint32_t attr, int64_t val) | ||
398 | { | ||
399 | struct link_set_attr_aux_param temp; | ||
400 | struct link_set_attr_aux_param *params = &temp; | ||
401 | |||
402 | params->mac = mac; | ||
403 | params->attr = attr; | ||
404 | params->val = val; | ||
405 | |||
406 | return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params, | ||
407 | sizeof(*params), GXIO_MPIPE_OP_LINK_SET_ATTR_AUX); | ||
408 | } | ||
409 | |||
410 | EXPORT_SYMBOL(gxio_mpipe_link_set_attr_aux); | ||
390 | 411 | ||
391 | struct get_timestamp_aux_param { | 412 | struct get_timestamp_aux_param { |
392 | uint64_t sec; | 413 | uint64_t sec; |
@@ -454,6 +475,51 @@ int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context, | |||
454 | 475 | ||
455 | EXPORT_SYMBOL(gxio_mpipe_adjust_timestamp_aux); | 476 | EXPORT_SYMBOL(gxio_mpipe_adjust_timestamp_aux); |
456 | 477 | ||
478 | struct adjust_timestamp_freq_param { | ||
479 | int32_t ppb; | ||
480 | }; | ||
481 | |||
482 | int gxio_mpipe_adjust_timestamp_freq(gxio_mpipe_context_t * context, | ||
483 | int32_t ppb) | ||
484 | { | ||
485 | struct adjust_timestamp_freq_param temp; | ||
486 | struct adjust_timestamp_freq_param *params = &temp; | ||
487 | |||
488 | params->ppb = ppb; | ||
489 | |||
490 | return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params, | ||
491 | sizeof(*params), | ||
492 | GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ); | ||
493 | } | ||
494 | |||
495 | EXPORT_SYMBOL(gxio_mpipe_adjust_timestamp_freq); | ||
496 | |||
497 | struct config_edma_ring_blks_param { | ||
498 | unsigned int ering; | ||
499 | unsigned int max_blks; | ||
500 | unsigned int min_snf_blks; | ||
501 | unsigned int db; | ||
502 | }; | ||
503 | |||
504 | int gxio_mpipe_config_edma_ring_blks(gxio_mpipe_context_t * context, | ||
505 | unsigned int ering, unsigned int max_blks, | ||
506 | unsigned int min_snf_blks, unsigned int db) | ||
507 | { | ||
508 | struct config_edma_ring_blks_param temp; | ||
509 | struct config_edma_ring_blks_param *params = &temp; | ||
510 | |||
511 | params->ering = ering; | ||
512 | params->max_blks = max_blks; | ||
513 | params->min_snf_blks = min_snf_blks; | ||
514 | params->db = db; | ||
515 | |||
516 | return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params, | ||
517 | sizeof(*params), | ||
518 | GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS); | ||
519 | } | ||
520 | |||
521 | EXPORT_SYMBOL(gxio_mpipe_config_edma_ring_blks); | ||
522 | |||
457 | struct arm_pollfd_param { | 523 | struct arm_pollfd_param { |
458 | union iorpc_pollfd pollfd; | 524 | union iorpc_pollfd pollfd; |
459 | }; | 525 | }; |
diff --git a/arch/tile/gxio/iorpc_mpipe_info.c b/arch/tile/gxio/iorpc_mpipe_info.c index d0254aa60cba..64883aabeb9c 100644 --- a/arch/tile/gxio/iorpc_mpipe_info.c +++ b/arch/tile/gxio/iorpc_mpipe_info.c | |||
@@ -16,6 +16,24 @@ | |||
16 | #include "gxio/iorpc_mpipe_info.h" | 16 | #include "gxio/iorpc_mpipe_info.h" |
17 | 17 | ||
18 | 18 | ||
19 | struct instance_aux_param { | ||
20 | _gxio_mpipe_link_name_t name; | ||
21 | }; | ||
22 | |||
23 | int gxio_mpipe_info_instance_aux(gxio_mpipe_info_context_t * context, | ||
24 | _gxio_mpipe_link_name_t name) | ||
25 | { | ||
26 | struct instance_aux_param temp; | ||
27 | struct instance_aux_param *params = &temp; | ||
28 | |||
29 | params->name = name; | ||
30 | |||
31 | return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params, | ||
32 | sizeof(*params), GXIO_MPIPE_INFO_OP_INSTANCE_AUX); | ||
33 | } | ||
34 | |||
35 | EXPORT_SYMBOL(gxio_mpipe_info_instance_aux); | ||
36 | |||
19 | struct enumerate_aux_param { | 37 | struct enumerate_aux_param { |
20 | _gxio_mpipe_link_name_t name; | 38 | _gxio_mpipe_link_name_t name; |
21 | _gxio_mpipe_link_mac_t mac; | 39 | _gxio_mpipe_link_mac_t mac; |
diff --git a/arch/tile/gxio/mpipe.c b/arch/tile/gxio/mpipe.c index e71c63390acc..5301a9ffbae1 100644 --- a/arch/tile/gxio/mpipe.c +++ b/arch/tile/gxio/mpipe.c | |||
@@ -36,8 +36,14 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index) | |||
36 | int fd; | 36 | int fd; |
37 | int i; | 37 | int i; |
38 | 38 | ||
39 | if (mpipe_index >= GXIO_MPIPE_INSTANCE_MAX) | ||
40 | return -EINVAL; | ||
41 | |||
39 | snprintf(file, sizeof(file), "mpipe/%d/iorpc", mpipe_index); | 42 | snprintf(file, sizeof(file), "mpipe/%d/iorpc", mpipe_index); |
40 | fd = hv_dev_open((HV_VirtAddr) file, 0); | 43 | fd = hv_dev_open((HV_VirtAddr) file, 0); |
44 | |||
45 | context->fd = fd; | ||
46 | |||
41 | if (fd < 0) { | 47 | if (fd < 0) { |
42 | if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX) | 48 | if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX) |
43 | return fd; | 49 | return fd; |
@@ -45,8 +51,6 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index) | |||
45 | return -ENODEV; | 51 | return -ENODEV; |
46 | } | 52 | } |
47 | 53 | ||
48 | context->fd = fd; | ||
49 | |||
50 | /* Map in the MMIO space. */ | 54 | /* Map in the MMIO space. */ |
51 | context->mmio_cfg_base = (void __force *) | 55 | context->mmio_cfg_base = (void __force *) |
52 | iorpc_ioremap(fd, HV_MPIPE_CONFIG_MMIO_OFFSET, | 56 | iorpc_ioremap(fd, HV_MPIPE_CONFIG_MMIO_OFFSET, |
@@ -64,12 +68,15 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index) | |||
64 | for (i = 0; i < 8; i++) | 68 | for (i = 0; i < 8; i++) |
65 | context->__stacks.stacks[i] = 255; | 69 | context->__stacks.stacks[i] = 255; |
66 | 70 | ||
71 | context->instance = mpipe_index; | ||
72 | |||
67 | return 0; | 73 | return 0; |
68 | 74 | ||
69 | fast_failed: | 75 | fast_failed: |
70 | iounmap((void __force __iomem *)(context->mmio_cfg_base)); | 76 | iounmap((void __force __iomem *)(context->mmio_cfg_base)); |
71 | cfg_failed: | 77 | cfg_failed: |
72 | hv_dev_close(context->fd); | 78 | hv_dev_close(context->fd); |
79 | context->fd = -1; | ||
73 | return -ENODEV; | 80 | return -ENODEV; |
74 | } | 81 | } |
75 | 82 | ||
@@ -383,7 +390,7 @@ EXPORT_SYMBOL_GPL(gxio_mpipe_iqueue_init); | |||
383 | 390 | ||
384 | int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, | 391 | int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, |
385 | gxio_mpipe_context_t *context, | 392 | gxio_mpipe_context_t *context, |
386 | unsigned int edma_ring_id, | 393 | unsigned int ering, |
387 | unsigned int channel, | 394 | unsigned int channel, |
388 | void *mem, unsigned int mem_size, | 395 | void *mem, unsigned int mem_size, |
389 | unsigned int mem_flags) | 396 | unsigned int mem_flags) |
@@ -394,7 +401,7 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, | |||
394 | /* Offset used to read number of completed commands. */ | 401 | /* Offset used to read number of completed commands. */ |
395 | MPIPE_EDMA_POST_REGION_ADDR_t offset; | 402 | MPIPE_EDMA_POST_REGION_ADDR_t offset; |
396 | 403 | ||
397 | int result = gxio_mpipe_init_edma_ring(context, edma_ring_id, channel, | 404 | int result = gxio_mpipe_init_edma_ring(context, ering, channel, |
398 | mem, mem_size, mem_flags); | 405 | mem, mem_size, mem_flags); |
399 | if (result < 0) | 406 | if (result < 0) |
400 | return result; | 407 | return result; |
@@ -405,7 +412,7 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, | |||
405 | offset.region = | 412 | offset.region = |
406 | MPIPE_MMIO_ADDR__REGION_VAL_EDMA - | 413 | MPIPE_MMIO_ADDR__REGION_VAL_EDMA - |
407 | MPIPE_MMIO_ADDR__REGION_VAL_IDMA; | 414 | MPIPE_MMIO_ADDR__REGION_VAL_IDMA; |
408 | offset.ring = edma_ring_id; | 415 | offset.ring = ering; |
409 | 416 | ||
410 | __gxio_dma_queue_init(&equeue->dma_queue, | 417 | __gxio_dma_queue_init(&equeue->dma_queue, |
411 | context->mmio_fast_base + offset.word, | 418 | context->mmio_fast_base + offset.word, |
@@ -413,6 +420,9 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, | |||
413 | equeue->edescs = mem; | 420 | equeue->edescs = mem; |
414 | equeue->mask_num_entries = num_entries - 1; | 421 | equeue->mask_num_entries = num_entries - 1; |
415 | equeue->log2_num_entries = __builtin_ctz(num_entries); | 422 | equeue->log2_num_entries = __builtin_ctz(num_entries); |
423 | equeue->context = context; | ||
424 | equeue->ering = ering; | ||
425 | equeue->channel = channel; | ||
416 | 426 | ||
417 | return 0; | 427 | return 0; |
418 | } | 428 | } |
@@ -493,6 +503,20 @@ static gxio_mpipe_context_t *_gxio_get_link_context(void) | |||
493 | return contextp; | 503 | return contextp; |
494 | } | 504 | } |
495 | 505 | ||
506 | int gxio_mpipe_link_instance(const char *link_name) | ||
507 | { | ||
508 | _gxio_mpipe_link_name_t name; | ||
509 | gxio_mpipe_context_t *context = _gxio_get_link_context(); | ||
510 | |||
511 | if (!context) | ||
512 | return GXIO_ERR_NO_DEVICE; | ||
513 | |||
514 | strncpy(name.name, link_name, sizeof(name.name)); | ||
515 | name.name[GXIO_MPIPE_LINK_NAME_LEN - 1] = '\0'; | ||
516 | |||
517 | return gxio_mpipe_info_instance_aux(context, name); | ||
518 | } | ||
519 | |||
496 | int gxio_mpipe_link_enumerate_mac(int idx, char *link_name, uint8_t *link_mac) | 520 | int gxio_mpipe_link_enumerate_mac(int idx, char *link_name, uint8_t *link_mac) |
497 | { | 521 | { |
498 | int rv; | 522 | int rv; |
@@ -543,3 +567,12 @@ int gxio_mpipe_link_close(gxio_mpipe_link_t *link) | |||
543 | } | 567 | } |
544 | 568 | ||
545 | EXPORT_SYMBOL_GPL(gxio_mpipe_link_close); | 569 | EXPORT_SYMBOL_GPL(gxio_mpipe_link_close); |
570 | |||
571 | int gxio_mpipe_link_set_attr(gxio_mpipe_link_t *link, uint32_t attr, | ||
572 | int64_t val) | ||
573 | { | ||
574 | return gxio_mpipe_link_set_attr_aux(link->context, link->mac, attr, | ||
575 | val); | ||
576 | } | ||
577 | |||
578 | EXPORT_SYMBOL_GPL(gxio_mpipe_link_set_attr); | ||
diff --git a/arch/tile/include/asm/topology.h b/arch/tile/include/asm/topology.h index d5e86c9f74fd..d15c0d8d550f 100644 --- a/arch/tile/include/asm/topology.h +++ b/arch/tile/include/asm/topology.h | |||
@@ -89,9 +89,6 @@ static inline const struct cpumask *cpumask_of_node(int node) | |||
89 | #define topology_core_id(cpu) (cpu) | 89 | #define topology_core_id(cpu) (cpu) |
90 | #define topology_core_cpumask(cpu) ((void)(cpu), cpu_online_mask) | 90 | #define topology_core_cpumask(cpu) ((void)(cpu), cpu_online_mask) |
91 | #define topology_thread_cpumask(cpu) cpumask_of(cpu) | 91 | #define topology_thread_cpumask(cpu) cpumask_of(cpu) |
92 | |||
93 | /* indicates that pointers to the topology struct cpumask maps are valid */ | ||
94 | #define arch_provides_topology_pointers yes | ||
95 | #endif | 92 | #endif |
96 | 93 | ||
97 | #endif /* _ASM_TILE_TOPOLOGY_H */ | 94 | #endif /* _ASM_TILE_TOPOLOGY_H */ |
diff --git a/arch/tile/include/gxio/iorpc_mpipe.h b/arch/tile/include/gxio/iorpc_mpipe.h index 9d50fce1b1a7..fdd07f88cfd7 100644 --- a/arch/tile/include/gxio/iorpc_mpipe.h +++ b/arch/tile/include/gxio/iorpc_mpipe.h | |||
@@ -44,10 +44,13 @@ | |||
44 | #define GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1210) | 44 | #define GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1210) |
45 | #define GXIO_MPIPE_OP_LINK_OPEN_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1211) | 45 | #define GXIO_MPIPE_OP_LINK_OPEN_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1211) |
46 | #define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212) | 46 | #define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212) |
47 | #define GXIO_MPIPE_OP_LINK_SET_ATTR_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1213) | ||
47 | 48 | ||
48 | #define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e) | 49 | #define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x121e) |
49 | #define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f) | 50 | #define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x121f) |
50 | #define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220) | 51 | #define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1220) |
52 | #define GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1221) | ||
53 | #define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1222) | ||
51 | #define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000) | 54 | #define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000) |
52 | #define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001) | 55 | #define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001) |
53 | #define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000) | 56 | #define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000) |
@@ -114,6 +117,8 @@ int gxio_mpipe_link_open_aux(gxio_mpipe_context_t * context, | |||
114 | 117 | ||
115 | int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac); | 118 | int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac); |
116 | 119 | ||
120 | int gxio_mpipe_link_set_attr_aux(gxio_mpipe_context_t * context, int mac, | ||
121 | uint32_t attr, int64_t val); | ||
117 | 122 | ||
118 | int gxio_mpipe_get_timestamp_aux(gxio_mpipe_context_t * context, uint64_t * sec, | 123 | int gxio_mpipe_get_timestamp_aux(gxio_mpipe_context_t * context, uint64_t * sec, |
119 | uint64_t * nsec, uint64_t * cycles); | 124 | uint64_t * nsec, uint64_t * cycles); |
@@ -124,6 +129,9 @@ int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec, | |||
124 | int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context, | 129 | int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context, |
125 | int64_t nsec); | 130 | int64_t nsec); |
126 | 131 | ||
132 | int gxio_mpipe_adjust_timestamp_freq(gxio_mpipe_context_t * context, | ||
133 | int32_t ppb); | ||
134 | |||
127 | int gxio_mpipe_arm_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie); | 135 | int gxio_mpipe_arm_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie); |
128 | 136 | ||
129 | int gxio_mpipe_close_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie); | 137 | int gxio_mpipe_close_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie); |
diff --git a/arch/tile/include/gxio/iorpc_mpipe_info.h b/arch/tile/include/gxio/iorpc_mpipe_info.h index 0bcf3f71ce8b..476c5e5ca22c 100644 --- a/arch/tile/include/gxio/iorpc_mpipe_info.h +++ b/arch/tile/include/gxio/iorpc_mpipe_info.h | |||
@@ -27,11 +27,15 @@ | |||
27 | #include <asm/pgtable.h> | 27 | #include <asm/pgtable.h> |
28 | 28 | ||
29 | 29 | ||
30 | #define GXIO_MPIPE_INFO_OP_INSTANCE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1250) | ||
30 | #define GXIO_MPIPE_INFO_OP_ENUMERATE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1251) | 31 | #define GXIO_MPIPE_INFO_OP_ENUMERATE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1251) |
31 | #define GXIO_MPIPE_INFO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000) | 32 | #define GXIO_MPIPE_INFO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000) |
32 | #define GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001) | 33 | #define GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001) |
33 | 34 | ||
34 | 35 | ||
36 | int gxio_mpipe_info_instance_aux(gxio_mpipe_info_context_t * context, | ||
37 | _gxio_mpipe_link_name_t name); | ||
38 | |||
35 | int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context, | 39 | int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context, |
36 | unsigned int idx, | 40 | unsigned int idx, |
37 | _gxio_mpipe_link_name_t * name, | 41 | _gxio_mpipe_link_name_t * name, |
diff --git a/arch/tile/include/gxio/mpipe.h b/arch/tile/include/gxio/mpipe.h index b74f470ed11e..e37cf4f0cffd 100644 --- a/arch/tile/include/gxio/mpipe.h +++ b/arch/tile/include/gxio/mpipe.h | |||
@@ -220,6 +220,13 @@ typedef MPIPE_PDESC_t gxio_mpipe_idesc_t; | |||
220 | */ | 220 | */ |
221 | typedef MPIPE_EDMA_DESC_t gxio_mpipe_edesc_t; | 221 | typedef MPIPE_EDMA_DESC_t gxio_mpipe_edesc_t; |
222 | 222 | ||
223 | /* | ||
224 | * Max # of mpipe instances. 2 currently. | ||
225 | */ | ||
226 | #define GXIO_MPIPE_INSTANCE_MAX HV_MPIPE_INSTANCE_MAX | ||
227 | |||
228 | #define NR_MPIPE_MAX GXIO_MPIPE_INSTANCE_MAX | ||
229 | |||
223 | /* Get the "va" field from an "idesc". | 230 | /* Get the "va" field from an "idesc". |
224 | * | 231 | * |
225 | * This is the address at which the ingress hardware copied the first | 232 | * This is the address at which the ingress hardware copied the first |
@@ -311,6 +318,9 @@ typedef struct { | |||
311 | /* File descriptor for calling up to Linux (and thus the HV). */ | 318 | /* File descriptor for calling up to Linux (and thus the HV). */ |
312 | int fd; | 319 | int fd; |
313 | 320 | ||
321 | /* Corresponding mpipe instance #. */ | ||
322 | int instance; | ||
323 | |||
314 | /* The VA at which configuration registers are mapped. */ | 324 | /* The VA at which configuration registers are mapped. */ |
315 | char *mmio_cfg_base; | 325 | char *mmio_cfg_base; |
316 | 326 | ||
@@ -810,7 +820,7 @@ extern int gxio_mpipe_alloc_edma_rings(gxio_mpipe_context_t *context, | |||
810 | /* Initialize an eDMA ring, using the given memory and size. | 820 | /* Initialize an eDMA ring, using the given memory and size. |
811 | * | 821 | * |
812 | * @param context An initialized mPIPE context. | 822 | * @param context An initialized mPIPE context. |
813 | * @param ring The eDMA ring index. | 823 | * @param ering The eDMA ring index. |
814 | * @param channel The channel to use. This must be one of the channels | 824 | * @param channel The channel to use. This must be one of the channels |
815 | * associated with the context's set of open links. | 825 | * associated with the context's set of open links. |
816 | * @param mem A physically contiguous region of memory to be filled | 826 | * @param mem A physically contiguous region of memory to be filled |
@@ -823,10 +833,37 @@ extern int gxio_mpipe_alloc_edma_rings(gxio_mpipe_context_t *context, | |||
823 | * ::GXIO_ERR_INVAL_MEMORY_SIZE on failure. | 833 | * ::GXIO_ERR_INVAL_MEMORY_SIZE on failure. |
824 | */ | 834 | */ |
825 | extern int gxio_mpipe_init_edma_ring(gxio_mpipe_context_t *context, | 835 | extern int gxio_mpipe_init_edma_ring(gxio_mpipe_context_t *context, |
826 | unsigned int ring, unsigned int channel, | 836 | unsigned int ering, unsigned int channel, |
827 | void *mem, size_t mem_size, | 837 | void *mem, size_t mem_size, |
828 | unsigned int mem_flags); | 838 | unsigned int mem_flags); |
829 | 839 | ||
840 | /* Set the "max_blks", "min_snf_blks", and "db" fields of | ||
841 | * ::MPIPE_EDMA_RG_INIT_DAT_THRESH_t for a given edma ring. | ||
842 | * | ||
843 | * The global pool of dynamic blocks will be automatically adjusted. | ||
844 | * | ||
845 | * This function should not be called after any egress has been done | ||
846 | * on the edma ring. | ||
847 | * | ||
848 | * Most applications should just use gxio_mpipe_equeue_set_snf_size(). | ||
849 | * | ||
850 | * @param context An initialized mPIPE context. | ||
851 | * @param ering The eDMA ring index. | ||
852 | * @param max_blks The number of blocks to dedicate to the ring | ||
853 | * (normally min_snf_blks + 1). Must be greater than min_snf_blocks. | ||
854 | * @param min_snf_blks The number of blocks which must be stored | ||
855 | * prior to starting to send the packet (normally 12). | ||
856 | * @param db Whether to allow use of dynamic blocks by the ring | ||
857 | * (normally 1). | ||
858 | * | ||
859 | * @return 0 on success, negative on error. | ||
860 | */ | ||
861 | extern int gxio_mpipe_config_edma_ring_blks(gxio_mpipe_context_t *context, | ||
862 | unsigned int ering, | ||
863 | unsigned int max_blks, | ||
864 | unsigned int min_snf_blks, | ||
865 | unsigned int db); | ||
866 | |||
830 | /***************************************************************** | 867 | /***************************************************************** |
831 | * Classifier Program * | 868 | * Classifier Program * |
832 | ******************************************************************/ | 869 | ******************************************************************/ |
@@ -1288,15 +1325,39 @@ typedef struct { | |||
1288 | /* The log2() of the number of entries. */ | 1325 | /* The log2() of the number of entries. */ |
1289 | unsigned long log2_num_entries; | 1326 | unsigned long log2_num_entries; |
1290 | 1327 | ||
1328 | /* The context. */ | ||
1329 | gxio_mpipe_context_t *context; | ||
1330 | |||
1331 | /* The ering. */ | ||
1332 | unsigned int ering; | ||
1333 | |||
1334 | /* The channel. */ | ||
1335 | unsigned int channel; | ||
1336 | |||
1291 | } gxio_mpipe_equeue_t; | 1337 | } gxio_mpipe_equeue_t; |
1292 | 1338 | ||
1293 | /* Initialize an "equeue". | 1339 | /* Initialize an "equeue". |
1294 | * | 1340 | * |
1295 | * Takes the equeue plus the same args as gxio_mpipe_init_edma_ring(). | 1341 | * This function uses gxio_mpipe_init_edma_ring() to initialize the |
1342 | * underlying edma_ring using the provided arguments. | ||
1343 | * | ||
1344 | * @param equeue An egress queue to be initialized. | ||
1345 | * @param context An initialized mPIPE context. | ||
1346 | * @param ering The eDMA ring index. | ||
1347 | * @param channel The channel to use. This must be one of the channels | ||
1348 | * associated with the context's set of open links. | ||
1349 | * @param mem A physically contiguous region of memory to be filled | ||
1350 | * with a ring of ::gxio_mpipe_edesc_t structures. | ||
1351 | * @param mem_size Number of bytes in the ring. Must be 512, 2048, | ||
1352 | * 8192 or 65536, times 16 (i.e. sizeof(gxio_mpipe_edesc_t)). | ||
1353 | * @param mem_flags ::gxio_mpipe_mem_flags_e memory flags. | ||
1354 | * | ||
1355 | * @return 0 on success, ::GXIO_MPIPE_ERR_BAD_EDMA_RING or | ||
1356 | * ::GXIO_ERR_INVAL_MEMORY_SIZE on failure. | ||
1296 | */ | 1357 | */ |
1297 | extern int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, | 1358 | extern int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, |
1298 | gxio_mpipe_context_t *context, | 1359 | gxio_mpipe_context_t *context, |
1299 | unsigned int edma_ring_id, | 1360 | unsigned int ering, |
1300 | unsigned int channel, | 1361 | unsigned int channel, |
1301 | void *mem, unsigned int mem_size, | 1362 | void *mem, unsigned int mem_size, |
1302 | unsigned int mem_flags); | 1363 | unsigned int mem_flags); |
@@ -1494,6 +1555,37 @@ static inline int gxio_mpipe_equeue_is_complete(gxio_mpipe_equeue_t *equeue, | |||
1494 | completion_slot, update); | 1555 | completion_slot, update); |
1495 | } | 1556 | } |
1496 | 1557 | ||
1558 | /* Set the snf (store and forward) size for an equeue. | ||
1559 | * | ||
1560 | * The snf size for an equeue defaults to 1536, and encodes the size | ||
1561 | * of the largest packet for which egress is guaranteed to avoid | ||
1562 | * transmission underruns and/or corrupt checksums under heavy load. | ||
1563 | * | ||
1564 | * The snf size affects a global resource pool which cannot support, | ||
1565 | * for example, all 24 equeues each requesting an snf size of 8K. | ||
1566 | * | ||
1567 | * To ensure that jumbo packets can be egressed properly, the snf size | ||
1568 | * should be set to the size of the largest possible packet, which | ||
1569 | * will usually be limited by the size of the app's largest buffer. | ||
1570 | * | ||
1571 | * This is a convenience wrapper around | ||
1572 | * gxio_mpipe_config_edma_ring_blks(). | ||
1573 | * | ||
1574 | * This function should not be called after any egress has been done | ||
1575 | * on the equeue. | ||
1576 | * | ||
1577 | * @param equeue An egress queue initialized via gxio_mpipe_equeue_init(). | ||
1578 | * @param size The snf size, in bytes. | ||
1579 | * @return Zero on success, negative error otherwise. | ||
1580 | */ | ||
1581 | static inline int gxio_mpipe_equeue_set_snf_size(gxio_mpipe_equeue_t *equeue, | ||
1582 | size_t size) | ||
1583 | { | ||
1584 | int blks = (size + 127) / 128; | ||
1585 | return gxio_mpipe_config_edma_ring_blks(equeue->context, equeue->ering, | ||
1586 | blks + 1, blks, 1); | ||
1587 | } | ||
1588 | |||
1497 | /***************************************************************** | 1589 | /***************************************************************** |
1498 | * Link Management * | 1590 | * Link Management * |
1499 | ******************************************************************/ | 1591 | ******************************************************************/ |
@@ -1634,6 +1726,24 @@ typedef struct { | |||
1634 | uint8_t mac; | 1726 | uint8_t mac; |
1635 | } gxio_mpipe_link_t; | 1727 | } gxio_mpipe_link_t; |
1636 | 1728 | ||
1729 | /* Translate a link name to the instance number of the mPIPE shim which is | ||
1730 | * connected to that link. This call does not verify whether the link is | ||
1731 | * currently available, and does not reserve any link resources; | ||
1732 | * gxio_mpipe_link_open() must be called to perform those functions. | ||
1733 | * | ||
1734 | * Typically applications will call this function to translate a link name | ||
1735 | * to an mPIPE instance number; call gxio_mpipe_init(), passing it that | ||
1736 | * instance number, to initialize the mPIPE shim; and then call | ||
1737 | * gxio_mpipe_link_open(), passing it the same link name plus the mPIPE | ||
1738 | * context, to configure the link. | ||
1739 | * | ||
1740 | * @param link_name Name of the link; see @ref gxio_mpipe_link_names. | ||
1741 | * @return The mPIPE instance number which is associated with the named | ||
1742 | * link, or a negative error code (::GXIO_ERR_NO_DEVICE) if the link does | ||
1743 | * not exist. | ||
1744 | */ | ||
1745 | extern int gxio_mpipe_link_instance(const char *link_name); | ||
1746 | |||
1637 | /* Retrieve one of this system's legal link names, and its MAC address. | 1747 | /* Retrieve one of this system's legal link names, and its MAC address. |
1638 | * | 1748 | * |
1639 | * @param index Link name index. If a system supports N legal link names, | 1749 | * @param index Link name index. If a system supports N legal link names, |
@@ -1697,6 +1807,17 @@ static inline int gxio_mpipe_link_channel(gxio_mpipe_link_t *link) | |||
1697 | return link->channel; | 1807 | return link->channel; |
1698 | } | 1808 | } |
1699 | 1809 | ||
1810 | /* Set a link attribute. | ||
1811 | * | ||
1812 | * @param link A properly initialized link state object. | ||
1813 | * @param attr An attribute from the set of @ref gxio_mpipe_link_attrs. | ||
1814 | * @param val New value of the attribute. | ||
1815 | * @return 0 if the attribute was successfully set, or a negative error | ||
1816 | * code. | ||
1817 | */ | ||
1818 | extern int gxio_mpipe_link_set_attr(gxio_mpipe_link_t *link, uint32_t attr, | ||
1819 | int64_t val); | ||
1820 | |||
1700 | /////////////////////////////////////////////////////////////////// | 1821 | /////////////////////////////////////////////////////////////////// |
1701 | // Timestamp // | 1822 | // Timestamp // |
1702 | /////////////////////////////////////////////////////////////////// | 1823 | /////////////////////////////////////////////////////////////////// |
@@ -1733,4 +1854,18 @@ extern int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context, | |||
1733 | extern int gxio_mpipe_adjust_timestamp(gxio_mpipe_context_t *context, | 1854 | extern int gxio_mpipe_adjust_timestamp(gxio_mpipe_context_t *context, |
1734 | int64_t delta); | 1855 | int64_t delta); |
1735 | 1856 | ||
1857 | /** Adjust the mPIPE timestamp clock frequency. | ||
1858 | * | ||
1859 | * @param context An initialized mPIPE context. | ||
1860 | * @param ppb A 32-bit signed PPB (Parts Per Billion) value to adjust. | ||
1861 | * The absolute value of ppb must be less than or equal to 1000000000. | ||
1862 | * Values less than about 30000 will generally cause a GXIO_ERR_INVAL | ||
1863 | * return due to the granularity of the hardware that converts reference | ||
1864 | * clock cycles into seconds and nanoseconds. | ||
1865 | * @return If the call was successful, zero; otherwise, a negative error | ||
1866 | * code. | ||
1867 | */ | ||
1868 | extern int gxio_mpipe_adjust_timestamp_freq(gxio_mpipe_context_t* context, | ||
1869 | int32_t ppb); | ||
1870 | |||
1736 | #endif /* !_GXIO_MPIPE_H_ */ | 1871 | #endif /* !_GXIO_MPIPE_H_ */ |
diff --git a/arch/tile/include/hv/drv_mpipe_intf.h b/arch/tile/include/hv/drv_mpipe_intf.h index 6cdae3bf046e..c97e416dd963 100644 --- a/arch/tile/include/hv/drv_mpipe_intf.h +++ b/arch/tile/include/hv/drv_mpipe_intf.h | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <arch/mpipe_constants.h> | 23 | #include <arch/mpipe_constants.h> |
24 | 24 | ||
25 | 25 | ||
26 | /** Number of mPIPE instances supported */ | ||
27 | #define HV_MPIPE_INSTANCE_MAX (2) | ||
28 | |||
26 | /** Number of buffer stacks (32). */ | 29 | /** Number of buffer stacks (32). */ |
27 | #define HV_MPIPE_NUM_BUFFER_STACKS \ | 30 | #define HV_MPIPE_NUM_BUFFER_STACKS \ |
28 | (MPIPE_MMIO_INIT_DAT_GX36_1__BUFFER_STACK_MASK_WIDTH) | 31 | (MPIPE_MMIO_INIT_DAT_GX36_1__BUFFER_STACK_MASK_WIDTH) |
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index 11425633b2d7..6640e7bbeaa2 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c | |||
@@ -508,13 +508,8 @@ static void fixup_read_and_payload_sizes(struct pci_controller *controller) | |||
508 | rc_dev_cap.word); | 508 | rc_dev_cap.word); |
509 | 509 | ||
510 | /* Configure PCI Express MPS setting. */ | 510 | /* Configure PCI Express MPS setting. */ |
511 | list_for_each_entry(child, &root_bus->children, node) { | 511 | list_for_each_entry(child, &root_bus->children, node) |
512 | struct pci_dev *self = child->self; | 512 | pcie_bus_configure_settings(child); |
513 | if (!self) | ||
514 | continue; | ||
515 | |||
516 | pcie_bus_configure_settings(child, self->pcie_mpss); | ||
517 | } | ||
518 | 513 | ||
519 | /* | 514 | /* |
520 | * Set the mac_config register in trio based on the MPS/MRS of the link. | 515 | * Set the mac_config register in trio based on the MPS/MRS of the link. |
diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h index 4febacd1a8a1..29b0301c18aa 100644 --- a/arch/um/include/asm/tlb.h +++ b/arch/um/include/asm/tlb.h | |||
@@ -45,10 +45,12 @@ static inline void init_tlb_gather(struct mmu_gather *tlb) | |||
45 | } | 45 | } |
46 | 46 | ||
47 | static inline void | 47 | static inline void |
48 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush) | 48 | tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) |
49 | { | 49 | { |
50 | tlb->mm = mm; | 50 | tlb->mm = mm; |
51 | tlb->fullmm = full_mm_flush; | 51 | tlb->start = start; |
52 | tlb->end = end; | ||
53 | tlb->fullmm = !(start | (end+1)); | ||
52 | 54 | ||
53 | init_tlb_gather(tlb); | 55 | init_tlb_gather(tlb); |
54 | } | 56 | } |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index b32ebf92b0ce..5c0ed72c02a2 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -16,6 +16,7 @@ config X86_64 | |||
16 | def_bool y | 16 | def_bool y |
17 | depends on 64BIT | 17 | depends on 64BIT |
18 | select X86_DEV_DMA_OPS | 18 | select X86_DEV_DMA_OPS |
19 | select ARCH_USE_CMPXCHG_LOCKREF | ||
19 | 20 | ||
20 | ### Arch settings | 21 | ### Arch settings |
21 | config X86 | 22 | config X86 |
@@ -81,7 +82,6 @@ config X86 | |||
81 | select HAVE_USER_RETURN_NOTIFIER | 82 | select HAVE_USER_RETURN_NOTIFIER |
82 | select ARCH_BINFMT_ELF_RANDOMIZE_PIE | 83 | select ARCH_BINFMT_ELF_RANDOMIZE_PIE |
83 | select HAVE_ARCH_JUMP_LABEL | 84 | select HAVE_ARCH_JUMP_LABEL |
84 | select HAVE_TEXT_POKE_SMP | ||
85 | select HAVE_GENERIC_HARDIRQS | 85 | select HAVE_GENERIC_HARDIRQS |
86 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 86 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
87 | select SPARSE_IRQ | 87 | select SPARSE_IRQ |
@@ -632,6 +632,7 @@ config PARAVIRT_DEBUG | |||
632 | config PARAVIRT_SPINLOCKS | 632 | config PARAVIRT_SPINLOCKS |
633 | bool "Paravirtualization layer for spinlocks" | 633 | bool "Paravirtualization layer for spinlocks" |
634 | depends on PARAVIRT && SMP | 634 | depends on PARAVIRT && SMP |
635 | select UNINLINE_SPIN_UNLOCK | ||
635 | ---help--- | 636 | ---help--- |
636 | Paravirtualized spinlocks allow a pvops backend to replace the | 637 | Paravirtualized spinlocks allow a pvops backend to replace the |
637 | spinlock implementation with something virtualization-friendly | 638 | spinlock implementation with something virtualization-friendly |
@@ -656,6 +657,15 @@ config KVM_GUEST | |||
656 | underlying device model, the host provides the guest with | 657 | underlying device model, the host provides the guest with |
657 | timing infrastructure such as time of day, and system time | 658 | timing infrastructure such as time of day, and system time |
658 | 659 | ||
660 | config KVM_DEBUG_FS | ||
661 | bool "Enable debug information for KVM Guests in debugfs" | ||
662 | depends on KVM_GUEST && DEBUG_FS | ||
663 | default n | ||
664 | ---help--- | ||
665 | This option enables collection of various statistics for KVM guest. | ||
666 | Statistics are displayed in debugfs filesystem. Enabling this option | ||
667 | may incur significant overhead. | ||
668 | |||
659 | source "arch/x86/lguest/Kconfig" | 669 | source "arch/x86/lguest/Kconfig" |
660 | 670 | ||
661 | config PARAVIRT_TIME_ACCOUNTING | 671 | config PARAVIRT_TIME_ACCOUNTING |
@@ -1344,8 +1354,12 @@ config ARCH_SELECT_MEMORY_MODEL | |||
1344 | depends on ARCH_SPARSEMEM_ENABLE | 1354 | depends on ARCH_SPARSEMEM_ENABLE |
1345 | 1355 | ||
1346 | config ARCH_MEMORY_PROBE | 1356 | config ARCH_MEMORY_PROBE |
1347 | def_bool y | 1357 | bool "Enable sysfs memory/probe interface" |
1348 | depends on X86_64 && MEMORY_HOTPLUG | 1358 | depends on X86_64 && MEMORY_HOTPLUG |
1359 | help | ||
1360 | This option enables a sysfs memory/probe interface for testing. | ||
1361 | See Documentation/memory-hotplug.txt for more information. | ||
1362 | If you are unsure how to answer this question, answer N. | ||
1349 | 1363 | ||
1350 | config ARCH_PROC_KCORE_TEXT | 1364 | config ARCH_PROC_KCORE_TEXT |
1351 | def_bool y | 1365 | def_bool y |
@@ -1627,9 +1641,9 @@ config KEXEC | |||
1627 | 1641 | ||
1628 | It is an ongoing process to be certain the hardware in a machine | 1642 | It is an ongoing process to be certain the hardware in a machine |
1629 | is properly shutdown, so do not be surprised if this code does not | 1643 | is properly shutdown, so do not be surprised if this code does not |
1630 | initially work for you. It may help to enable device hotplugging | 1644 | initially work for you. As of this writing the exact hardware |
1631 | support. As of this writing the exact hardware interface is | 1645 | interface is strongly in flux, so no good recommendation can be |
1632 | strongly in flux, so no good recommendation can be made. | 1646 | made. |
1633 | 1647 | ||
1634 | config CRASH_DUMP | 1648 | config CRASH_DUMP |
1635 | bool "kernel crash dumps" | 1649 | bool "kernel crash dumps" |
@@ -1716,9 +1730,10 @@ config X86_NEED_RELOCS | |||
1716 | depends on X86_32 && RELOCATABLE | 1730 | depends on X86_32 && RELOCATABLE |
1717 | 1731 | ||
1718 | config PHYSICAL_ALIGN | 1732 | config PHYSICAL_ALIGN |
1719 | hex "Alignment value to which kernel should be aligned" if X86_32 | 1733 | hex "Alignment value to which kernel should be aligned" |
1720 | default "0x1000000" | 1734 | default "0x1000000" |
1721 | range 0x2000 0x1000000 | 1735 | range 0x2000 0x1000000 if X86_32 |
1736 | range 0x200000 0x1000000 if X86_64 | ||
1722 | ---help--- | 1737 | ---help--- |
1723 | This value puts the alignment restrictions on physical address | 1738 | This value puts the alignment restrictions on physical address |
1724 | where kernel is loaded and run from. Kernel is compiled for an | 1739 | where kernel is loaded and run from. Kernel is compiled for an |
@@ -1736,6 +1751,9 @@ config PHYSICAL_ALIGN | |||
1736 | end result is that kernel runs from a physical address meeting | 1751 | end result is that kernel runs from a physical address meeting |
1737 | above alignment restrictions. | 1752 | above alignment restrictions. |
1738 | 1753 | ||
1754 | On 32-bit this value must be a multiple of 0x2000. On 64-bit | ||
1755 | this value must be a multiple of 0x200000. | ||
1756 | |||
1739 | Don't change this unless you know what you are doing. | 1757 | Don't change this unless you know what you are doing. |
1740 | 1758 | ||
1741 | config HOTPLUG_CPU | 1759 | config HOTPLUG_CPU |
@@ -2270,6 +2288,32 @@ config RAPIDIO | |||
2270 | 2288 | ||
2271 | source "drivers/rapidio/Kconfig" | 2289 | source "drivers/rapidio/Kconfig" |
2272 | 2290 | ||
2291 | config X86_SYSFB | ||
2292 | bool "Mark VGA/VBE/EFI FB as generic system framebuffer" | ||
2293 | help | ||
2294 | Firmwares often provide initial graphics framebuffers so the BIOS, | ||
2295 | bootloader or kernel can show basic video-output during boot for | ||
2296 | user-guidance and debugging. Historically, x86 used the VESA BIOS | ||
2297 | Extensions and EFI-framebuffers for this, which are mostly limited | ||
2298 | to x86. | ||
2299 | This option, if enabled, marks VGA/VBE/EFI framebuffers as generic | ||
2300 | framebuffers so the new generic system-framebuffer drivers can be | ||
2301 | used on x86. If the framebuffer is not compatible with the generic | ||
2302 | modes, it is adverticed as fallback platform framebuffer so legacy | ||
2303 | drivers like efifb, vesafb and uvesafb can pick it up. | ||
2304 | If this option is not selected, all system framebuffers are always | ||
2305 | marked as fallback platform framebuffers as usual. | ||
2306 | |||
2307 | Note: Legacy fbdev drivers, including vesafb, efifb, uvesafb, will | ||
2308 | not be able to pick up generic system framebuffers if this option | ||
2309 | is selected. You are highly encouraged to enable simplefb as | ||
2310 | replacement if you select this option. simplefb can correctly deal | ||
2311 | with generic system framebuffers. But you should still keep vesafb | ||
2312 | and others enabled as fallback if a system framebuffer is | ||
2313 | incompatible with simplefb. | ||
2314 | |||
2315 | If unsure, say Y. | ||
2316 | |||
2273 | endmenu | 2317 | endmenu |
2274 | 2318 | ||
2275 | 2319 | ||
@@ -2332,10 +2376,6 @@ config HAVE_ATOMIC_IOMAP | |||
2332 | def_bool y | 2376 | def_bool y |
2333 | depends on X86_32 | 2377 | depends on X86_32 |
2334 | 2378 | ||
2335 | config HAVE_TEXT_POKE_SMP | ||
2336 | bool | ||
2337 | select STOP_MACHINE if SMP | ||
2338 | |||
2339 | config X86_DEV_DMA_OPS | 2379 | config X86_DEV_DMA_OPS |
2340 | bool | 2380 | bool |
2341 | depends on X86_64 || STA2X11 | 2381 | depends on X86_64 || STA2X11 |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 07639c656fcd..41250fb33985 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -16,6 +16,10 @@ endif | |||
16 | # e.g.: obj-y += foo_$(BITS).o | 16 | # e.g.: obj-y += foo_$(BITS).o |
17 | export BITS | 17 | export BITS |
18 | 18 | ||
19 | ifdef CONFIG_X86_NEED_RELOCS | ||
20 | LDFLAGS_vmlinux := --emit-relocs | ||
21 | endif | ||
22 | |||
19 | ifeq ($(CONFIG_X86_32),y) | 23 | ifeq ($(CONFIG_X86_32),y) |
20 | BITS := 32 | 24 | BITS := 32 |
21 | UTS_MACHINE := i386 | 25 | UTS_MACHINE := i386 |
@@ -25,10 +29,6 @@ ifeq ($(CONFIG_X86_32),y) | |||
25 | KBUILD_AFLAGS += $(biarch) | 29 | KBUILD_AFLAGS += $(biarch) |
26 | KBUILD_CFLAGS += $(biarch) | 30 | KBUILD_CFLAGS += $(biarch) |
27 | 31 | ||
28 | ifdef CONFIG_RELOCATABLE | ||
29 | LDFLAGS_vmlinux := --emit-relocs | ||
30 | endif | ||
31 | |||
32 | KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return | 32 | KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return |
33 | 33 | ||
34 | # Never want PIC in a 32-bit kernel, prevent breakage with GCC built | 34 | # Never want PIC in a 32-bit kernel, prevent breakage with GCC built |
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index 5b7531966b84..ef72baeff484 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h | |||
@@ -355,6 +355,7 @@ int strncmp(const char *cs, const char *ct, size_t count); | |||
355 | size_t strnlen(const char *s, size_t maxlen); | 355 | size_t strnlen(const char *s, size_t maxlen); |
356 | unsigned int atou(const char *s); | 356 | unsigned int atou(const char *s); |
357 | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base); | 357 | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base); |
358 | size_t strlen(const char *s); | ||
358 | 359 | ||
359 | /* tty.c */ | 360 | /* tty.c */ |
360 | void puts(const char *); | 361 | void puts(const char *); |
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 1e3184f6072f..5d6f6891b188 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
@@ -181,8 +181,9 @@ relocated: | |||
181 | /* | 181 | /* |
182 | * Do the decompression, and jump to the new kernel.. | 182 | * Do the decompression, and jump to the new kernel.. |
183 | */ | 183 | */ |
184 | leal z_extract_offset_negative(%ebx), %ebp | ||
185 | /* push arguments for decompress_kernel: */ | 184 | /* push arguments for decompress_kernel: */ |
185 | pushl $z_output_len /* decompressed length */ | ||
186 | leal z_extract_offset_negative(%ebx), %ebp | ||
186 | pushl %ebp /* output address */ | 187 | pushl %ebp /* output address */ |
187 | pushl $z_input_len /* input_len */ | 188 | pushl $z_input_len /* input_len */ |
188 | leal input_data(%ebx), %eax | 189 | leal input_data(%ebx), %eax |
@@ -191,33 +192,7 @@ relocated: | |||
191 | pushl %eax /* heap area */ | 192 | pushl %eax /* heap area */ |
192 | pushl %esi /* real mode pointer */ | 193 | pushl %esi /* real mode pointer */ |
193 | call decompress_kernel | 194 | call decompress_kernel |
194 | addl $20, %esp | 195 | addl $24, %esp |
195 | |||
196 | #if CONFIG_RELOCATABLE | ||
197 | /* | ||
198 | * Find the address of the relocations. | ||
199 | */ | ||
200 | leal z_output_len(%ebp), %edi | ||
201 | |||
202 | /* | ||
203 | * Calculate the delta between where vmlinux was compiled to run | ||
204 | * and where it was actually loaded. | ||
205 | */ | ||
206 | movl %ebp, %ebx | ||
207 | subl $LOAD_PHYSICAL_ADDR, %ebx | ||
208 | jz 2f /* Nothing to be done if loaded at compiled addr. */ | ||
209 | /* | ||
210 | * Process relocations. | ||
211 | */ | ||
212 | |||
213 | 1: subl $4, %edi | ||
214 | movl (%edi), %ecx | ||
215 | testl %ecx, %ecx | ||
216 | jz 2f | ||
217 | addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) | ||
218 | jmp 1b | ||
219 | 2: | ||
220 | #endif | ||
221 | 196 | ||
222 | /* | 197 | /* |
223 | * Jump to the decompressed kernel. | 198 | * Jump to the decompressed kernel. |
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 06e71c2c16bf..c337422b575d 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
@@ -338,6 +338,7 @@ relocated: | |||
338 | leaq input_data(%rip), %rdx /* input_data */ | 338 | leaq input_data(%rip), %rdx /* input_data */ |
339 | movl $z_input_len, %ecx /* input_len */ | 339 | movl $z_input_len, %ecx /* input_len */ |
340 | movq %rbp, %r8 /* output target address */ | 340 | movq %rbp, %r8 /* output target address */ |
341 | movq $z_output_len, %r9 /* decompressed length */ | ||
341 | call decompress_kernel | 342 | call decompress_kernel |
342 | popq %rsi | 343 | popq %rsi |
343 | 344 | ||
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 0319c88290a5..434f077d2c4d 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -271,6 +271,79 @@ static void error(char *x) | |||
271 | asm("hlt"); | 271 | asm("hlt"); |
272 | } | 272 | } |
273 | 273 | ||
274 | #if CONFIG_X86_NEED_RELOCS | ||
275 | static void handle_relocations(void *output, unsigned long output_len) | ||
276 | { | ||
277 | int *reloc; | ||
278 | unsigned long delta, map, ptr; | ||
279 | unsigned long min_addr = (unsigned long)output; | ||
280 | unsigned long max_addr = min_addr + output_len; | ||
281 | |||
282 | /* | ||
283 | * Calculate the delta between where vmlinux was linked to load | ||
284 | * and where it was actually loaded. | ||
285 | */ | ||
286 | delta = min_addr - LOAD_PHYSICAL_ADDR; | ||
287 | if (!delta) { | ||
288 | debug_putstr("No relocation needed... "); | ||
289 | return; | ||
290 | } | ||
291 | debug_putstr("Performing relocations... "); | ||
292 | |||
293 | /* | ||
294 | * The kernel contains a table of relocation addresses. Those | ||
295 | * addresses have the final load address of the kernel in virtual | ||
296 | * memory. We are currently working in the self map. So we need to | ||
297 | * create an adjustment for kernel memory addresses to the self map. | ||
298 | * This will involve subtracting out the base address of the kernel. | ||
299 | */ | ||
300 | map = delta - __START_KERNEL_map; | ||
301 | |||
302 | /* | ||
303 | * Process relocations: 32 bit relocations first then 64 bit after. | ||
304 | * Two sets of binary relocations are added to the end of the kernel | ||
305 | * before compression. Each relocation table entry is the kernel | ||
306 | * address of the location which needs to be updated stored as a | ||
307 | * 32-bit value which is sign extended to 64 bits. | ||
308 | * | ||
309 | * Format is: | ||
310 | * | ||
311 | * kernel bits... | ||
312 | * 0 - zero terminator for 64 bit relocations | ||
313 | * 64 bit relocation repeated | ||
314 | * 0 - zero terminator for 32 bit relocations | ||
315 | * 32 bit relocation repeated | ||
316 | * | ||
317 | * So we work backwards from the end of the decompressed image. | ||
318 | */ | ||
319 | for (reloc = output + output_len - sizeof(*reloc); *reloc; reloc--) { | ||
320 | int extended = *reloc; | ||
321 | extended += map; | ||
322 | |||
323 | ptr = (unsigned long)extended; | ||
324 | if (ptr < min_addr || ptr > max_addr) | ||
325 | error("32-bit relocation outside of kernel!\n"); | ||
326 | |||
327 | *(uint32_t *)ptr += delta; | ||
328 | } | ||
329 | #ifdef CONFIG_X86_64 | ||
330 | for (reloc--; *reloc; reloc--) { | ||
331 | long extended = *reloc; | ||
332 | extended += map; | ||
333 | |||
334 | ptr = (unsigned long)extended; | ||
335 | if (ptr < min_addr || ptr > max_addr) | ||
336 | error("64-bit relocation outside of kernel!\n"); | ||
337 | |||
338 | *(uint64_t *)ptr += delta; | ||
339 | } | ||
340 | #endif | ||
341 | } | ||
342 | #else | ||
343 | static inline void handle_relocations(void *output, unsigned long output_len) | ||
344 | { } | ||
345 | #endif | ||
346 | |||
274 | static void parse_elf(void *output) | 347 | static void parse_elf(void *output) |
275 | { | 348 | { |
276 | #ifdef CONFIG_X86_64 | 349 | #ifdef CONFIG_X86_64 |
@@ -325,7 +398,8 @@ static void parse_elf(void *output) | |||
325 | asmlinkage void decompress_kernel(void *rmode, memptr heap, | 398 | asmlinkage void decompress_kernel(void *rmode, memptr heap, |
326 | unsigned char *input_data, | 399 | unsigned char *input_data, |
327 | unsigned long input_len, | 400 | unsigned long input_len, |
328 | unsigned char *output) | 401 | unsigned char *output, |
402 | unsigned long output_len) | ||
329 | { | 403 | { |
330 | real_mode = rmode; | 404 | real_mode = rmode; |
331 | 405 | ||
@@ -365,6 +439,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
365 | debug_putstr("\nDecompressing Linux... "); | 439 | debug_putstr("\nDecompressing Linux... "); |
366 | decompress(input_data, input_len, NULL, NULL, output, NULL, error); | 440 | decompress(input_data, input_len, NULL, NULL, output, NULL, error); |
367 | parse_elf(output); | 441 | parse_elf(output); |
442 | handle_relocations(output, output_len); | ||
368 | debug_putstr("done.\nBooting the kernel.\n"); | 443 | debug_putstr("done.\nBooting the kernel.\n"); |
369 | return; | 444 | return; |
370 | } | 445 | } |
diff --git a/arch/x86/boot/printf.c b/arch/x86/boot/printf.c index cdac91ca55d3..565083c16e5c 100644 --- a/arch/x86/boot/printf.c +++ b/arch/x86/boot/printf.c | |||
@@ -55,7 +55,7 @@ static char *number(char *str, long num, int base, int size, int precision, | |||
55 | locase = (type & SMALL); | 55 | locase = (type & SMALL); |
56 | if (type & LEFT) | 56 | if (type & LEFT) |
57 | type &= ~ZEROPAD; | 57 | type &= ~ZEROPAD; |
58 | if (base < 2 || base > 36) | 58 | if (base < 2 || base > 16) |
59 | return NULL; | 59 | return NULL; |
60 | c = (type & ZEROPAD) ? '0' : ' '; | 60 | c = (type & ZEROPAD) ? '0' : ' '; |
61 | sign = 0; | 61 | sign = 0; |
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index bccfca68430e..665a730307f2 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c | |||
@@ -457,7 +457,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig, | |||
457 | else | 457 | else |
458 | put_user_ex(0, &frame->uc.uc_flags); | 458 | put_user_ex(0, &frame->uc.uc_flags); |
459 | put_user_ex(0, &frame->uc.uc_link); | 459 | put_user_ex(0, &frame->uc.uc_link); |
460 | err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp); | 460 | compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); |
461 | 461 | ||
462 | if (ksig->ka.sa.sa_flags & SA_RESTORER) | 462 | if (ksig->ka.sa.sa_flags & SA_RESTORER) |
463 | restorer = ksig->ka.sa.sa_restorer; | 463 | restorer = ksig->ka.sa.sa_restorer; |
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 474dc1b59f72..4299eb05023c 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -452,7 +452,7 @@ ia32_badsys: | |||
452 | 452 | ||
453 | CFI_ENDPROC | 453 | CFI_ENDPROC |
454 | 454 | ||
455 | .macro PTREGSCALL label, func, arg | 455 | .macro PTREGSCALL label, func |
456 | ALIGN | 456 | ALIGN |
457 | GLOBAL(\label) | 457 | GLOBAL(\label) |
458 | leaq \func(%rip),%rax | 458 | leaq \func(%rip),%rax |
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 2dfac58f3b11..b1977bad5435 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
@@ -86,6 +86,7 @@ extern int acpi_pci_disabled; | |||
86 | extern int acpi_skip_timer_override; | 86 | extern int acpi_skip_timer_override; |
87 | extern int acpi_use_timer_override; | 87 | extern int acpi_use_timer_override; |
88 | extern int acpi_fix_pin2_polarity; | 88 | extern int acpi_fix_pin2_polarity; |
89 | extern int acpi_disable_cmcff; | ||
89 | 90 | ||
90 | extern u8 acpi_sci_flags; | 91 | extern u8 acpi_sci_flags; |
91 | extern int acpi_sci_override_gsi; | 92 | extern int acpi_sci_override_gsi; |
@@ -168,6 +169,7 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf) | |||
168 | 169 | ||
169 | #define acpi_lapic 0 | 170 | #define acpi_lapic 0 |
170 | #define acpi_ioapic 0 | 171 | #define acpi_ioapic 0 |
172 | #define acpi_disable_cmcff 0 | ||
171 | static inline void acpi_noirq_set(void) { } | 173 | static inline void acpi_noirq_set(void) { } |
172 | static inline void acpi_disable_pci(void) { } | 174 | static inline void acpi_disable_pci(void) { } |
173 | static inline void disable_acpi(void) { } | 175 | static inline void disable_acpi(void) { } |
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 58ed6d96a6ac..0a3f9c9f98d5 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
6 | #include <linux/stringify.h> | 6 | #include <linux/stringify.h> |
7 | #include <asm/asm.h> | 7 | #include <asm/asm.h> |
8 | #include <asm/ptrace.h> | ||
8 | 9 | ||
9 | /* | 10 | /* |
10 | * Alternative inline assembly for SMP. | 11 | * Alternative inline assembly for SMP. |
@@ -220,20 +221,11 @@ extern void *text_poke_early(void *addr, const void *opcode, size_t len); | |||
220 | * no thread can be preempted in the instructions being modified (no iret to an | 221 | * no thread can be preempted in the instructions being modified (no iret to an |
221 | * invalid instruction possible) or if the instructions are changed from a | 222 | * invalid instruction possible) or if the instructions are changed from a |
222 | * consistent state to another consistent state atomically. | 223 | * consistent state to another consistent state atomically. |
223 | * More care must be taken when modifying code in the SMP case because of | ||
224 | * Intel's errata. text_poke_smp() takes care that errata, but still | ||
225 | * doesn't support NMI/MCE handler code modifying. | ||
226 | * On the local CPU you need to be protected again NMI or MCE handlers seeing an | 224 | * On the local CPU you need to be protected again NMI or MCE handlers seeing an |
227 | * inconsistent instruction while you patch. | 225 | * inconsistent instruction while you patch. |
228 | */ | 226 | */ |
229 | struct text_poke_param { | ||
230 | void *addr; | ||
231 | const void *opcode; | ||
232 | size_t len; | ||
233 | }; | ||
234 | |||
235 | extern void *text_poke(void *addr, const void *opcode, size_t len); | 227 | extern void *text_poke(void *addr, const void *opcode, size_t len); |
236 | extern void *text_poke_smp(void *addr, const void *opcode, size_t len); | 228 | extern int poke_int3_handler(struct pt_regs *regs); |
237 | extern void text_poke_smp_batch(struct text_poke_param *params, int n); | 229 | extern void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler); |
238 | 230 | ||
239 | #endif /* _ASM_X86_ALTERNATIVE_H */ | 231 | #endif /* _ASM_X86_ALTERNATIVE_H */ |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index f8119b582c3c..1d2091a226bc 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
@@ -715,4 +715,6 @@ static inline void exiting_ack_irq(void) | |||
715 | ack_APIC_irq(); | 715 | ack_APIC_irq(); |
716 | } | 716 | } |
717 | 717 | ||
718 | extern void ioapic_zap_locks(void); | ||
719 | |||
718 | #endif /* _ASM_X86_APIC_H */ | 720 | #endif /* _ASM_X86_APIC_H */ |
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 1c2d247f65ce..4582e8e1cd1a 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h | |||
@@ -3,21 +3,25 @@ | |||
3 | 3 | ||
4 | #ifdef __ASSEMBLY__ | 4 | #ifdef __ASSEMBLY__ |
5 | # define __ASM_FORM(x) x | 5 | # define __ASM_FORM(x) x |
6 | # define __ASM_FORM_RAW(x) x | ||
6 | # define __ASM_FORM_COMMA(x) x, | 7 | # define __ASM_FORM_COMMA(x) x, |
7 | #else | 8 | #else |
8 | # define __ASM_FORM(x) " " #x " " | 9 | # define __ASM_FORM(x) " " #x " " |
10 | # define __ASM_FORM_RAW(x) #x | ||
9 | # define __ASM_FORM_COMMA(x) " " #x "," | 11 | # define __ASM_FORM_COMMA(x) " " #x "," |
10 | #endif | 12 | #endif |
11 | 13 | ||
12 | #ifdef CONFIG_X86_32 | 14 | #ifdef CONFIG_X86_32 |
13 | # define __ASM_SEL(a,b) __ASM_FORM(a) | 15 | # define __ASM_SEL(a,b) __ASM_FORM(a) |
16 | # define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(a) | ||
14 | #else | 17 | #else |
15 | # define __ASM_SEL(a,b) __ASM_FORM(b) | 18 | # define __ASM_SEL(a,b) __ASM_FORM(b) |
19 | # define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b) | ||
16 | #endif | 20 | #endif |
17 | 21 | ||
18 | #define __ASM_SIZE(inst, ...) __ASM_SEL(inst##l##__VA_ARGS__, \ | 22 | #define __ASM_SIZE(inst, ...) __ASM_SEL(inst##l##__VA_ARGS__, \ |
19 | inst##q##__VA_ARGS__) | 23 | inst##q##__VA_ARGS__) |
20 | #define __ASM_REG(reg) __ASM_SEL(e##reg, r##reg) | 24 | #define __ASM_REG(reg) __ASM_SEL_RAW(e##reg, r##reg) |
21 | 25 | ||
22 | #define _ASM_PTR __ASM_SEL(.long, .quad) | 26 | #define _ASM_PTR __ASM_SEL(.long, .quad) |
23 | #define _ASM_ALIGN __ASM_SEL(.balign 4, .balign 8) | 27 | #define _ASM_ALIGN __ASM_SEL(.balign 4, .balign 8) |
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 6dfd0195bb55..41639ce8fd63 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h | |||
@@ -15,6 +15,14 @@ | |||
15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
16 | #include <asm/alternative.h> | 16 | #include <asm/alternative.h> |
17 | 17 | ||
18 | #if BITS_PER_LONG == 32 | ||
19 | # define _BITOPS_LONG_SHIFT 5 | ||
20 | #elif BITS_PER_LONG == 64 | ||
21 | # define _BITOPS_LONG_SHIFT 6 | ||
22 | #else | ||
23 | # error "Unexpected BITS_PER_LONG" | ||
24 | #endif | ||
25 | |||
18 | #define BIT_64(n) (U64_C(1) << (n)) | 26 | #define BIT_64(n) (U64_C(1) << (n)) |
19 | 27 | ||
20 | /* | 28 | /* |
@@ -59,7 +67,7 @@ | |||
59 | * restricted to acting on a single-word quantity. | 67 | * restricted to acting on a single-word quantity. |
60 | */ | 68 | */ |
61 | static __always_inline void | 69 | static __always_inline void |
62 | set_bit(unsigned int nr, volatile unsigned long *addr) | 70 | set_bit(long nr, volatile unsigned long *addr) |
63 | { | 71 | { |
64 | if (IS_IMMEDIATE(nr)) { | 72 | if (IS_IMMEDIATE(nr)) { |
65 | asm volatile(LOCK_PREFIX "orb %1,%0" | 73 | asm volatile(LOCK_PREFIX "orb %1,%0" |
@@ -81,7 +89,7 @@ set_bit(unsigned int nr, volatile unsigned long *addr) | |||
81 | * If it's called on the same region of memory simultaneously, the effect | 89 | * If it's called on the same region of memory simultaneously, the effect |
82 | * may be that only one operation succeeds. | 90 | * may be that only one operation succeeds. |
83 | */ | 91 | */ |
84 | static inline void __set_bit(int nr, volatile unsigned long *addr) | 92 | static inline void __set_bit(long nr, volatile unsigned long *addr) |
85 | { | 93 | { |
86 | asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); | 94 | asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); |
87 | } | 95 | } |
@@ -97,7 +105,7 @@ static inline void __set_bit(int nr, volatile unsigned long *addr) | |||
97 | * in order to ensure changes are visible on other processors. | 105 | * in order to ensure changes are visible on other processors. |
98 | */ | 106 | */ |
99 | static __always_inline void | 107 | static __always_inline void |
100 | clear_bit(int nr, volatile unsigned long *addr) | 108 | clear_bit(long nr, volatile unsigned long *addr) |
101 | { | 109 | { |
102 | if (IS_IMMEDIATE(nr)) { | 110 | if (IS_IMMEDIATE(nr)) { |
103 | asm volatile(LOCK_PREFIX "andb %1,%0" | 111 | asm volatile(LOCK_PREFIX "andb %1,%0" |
@@ -118,13 +126,13 @@ clear_bit(int nr, volatile unsigned long *addr) | |||
118 | * clear_bit() is atomic and implies release semantics before the memory | 126 | * clear_bit() is atomic and implies release semantics before the memory |
119 | * operation. It can be used for an unlock. | 127 | * operation. It can be used for an unlock. |
120 | */ | 128 | */ |
121 | static inline void clear_bit_unlock(unsigned nr, volatile unsigned long *addr) | 129 | static inline void clear_bit_unlock(long nr, volatile unsigned long *addr) |
122 | { | 130 | { |
123 | barrier(); | 131 | barrier(); |
124 | clear_bit(nr, addr); | 132 | clear_bit(nr, addr); |
125 | } | 133 | } |
126 | 134 | ||
127 | static inline void __clear_bit(int nr, volatile unsigned long *addr) | 135 | static inline void __clear_bit(long nr, volatile unsigned long *addr) |
128 | { | 136 | { |
129 | asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); | 137 | asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); |
130 | } | 138 | } |
@@ -141,7 +149,7 @@ static inline void __clear_bit(int nr, volatile unsigned long *addr) | |||
141 | * No memory barrier is required here, because x86 cannot reorder stores past | 149 | * No memory barrier is required here, because x86 cannot reorder stores past |
142 | * older loads. Same principle as spin_unlock. | 150 | * older loads. Same principle as spin_unlock. |
143 | */ | 151 | */ |
144 | static inline void __clear_bit_unlock(unsigned nr, volatile unsigned long *addr) | 152 | static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr) |
145 | { | 153 | { |
146 | barrier(); | 154 | barrier(); |
147 | __clear_bit(nr, addr); | 155 | __clear_bit(nr, addr); |
@@ -159,7 +167,7 @@ static inline void __clear_bit_unlock(unsigned nr, volatile unsigned long *addr) | |||
159 | * If it's called on the same region of memory simultaneously, the effect | 167 | * If it's called on the same region of memory simultaneously, the effect |
160 | * may be that only one operation succeeds. | 168 | * may be that only one operation succeeds. |
161 | */ | 169 | */ |
162 | static inline void __change_bit(int nr, volatile unsigned long *addr) | 170 | static inline void __change_bit(long nr, volatile unsigned long *addr) |
163 | { | 171 | { |
164 | asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); | 172 | asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); |
165 | } | 173 | } |
@@ -173,7 +181,7 @@ static inline void __change_bit(int nr, volatile unsigned long *addr) | |||
173 | * Note that @nr may be almost arbitrarily large; this function is not | 181 | * Note that @nr may be almost arbitrarily large; this function is not |
174 | * restricted to acting on a single-word quantity. | 182 | * restricted to acting on a single-word quantity. |
175 | */ | 183 | */ |
176 | static inline void change_bit(int nr, volatile unsigned long *addr) | 184 | static inline void change_bit(long nr, volatile unsigned long *addr) |
177 | { | 185 | { |
178 | if (IS_IMMEDIATE(nr)) { | 186 | if (IS_IMMEDIATE(nr)) { |
179 | asm volatile(LOCK_PREFIX "xorb %1,%0" | 187 | asm volatile(LOCK_PREFIX "xorb %1,%0" |
@@ -194,7 +202,7 @@ static inline void change_bit(int nr, volatile unsigned long *addr) | |||
194 | * This operation is atomic and cannot be reordered. | 202 | * This operation is atomic and cannot be reordered. |
195 | * It also implies a memory barrier. | 203 | * It also implies a memory barrier. |
196 | */ | 204 | */ |
197 | static inline int test_and_set_bit(int nr, volatile unsigned long *addr) | 205 | static inline int test_and_set_bit(long nr, volatile unsigned long *addr) |
198 | { | 206 | { |
199 | int oldbit; | 207 | int oldbit; |
200 | 208 | ||
@@ -212,7 +220,7 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr) | |||
212 | * This is the same as test_and_set_bit on x86. | 220 | * This is the same as test_and_set_bit on x86. |
213 | */ | 221 | */ |
214 | static __always_inline int | 222 | static __always_inline int |
215 | test_and_set_bit_lock(int nr, volatile unsigned long *addr) | 223 | test_and_set_bit_lock(long nr, volatile unsigned long *addr) |
216 | { | 224 | { |
217 | return test_and_set_bit(nr, addr); | 225 | return test_and_set_bit(nr, addr); |
218 | } | 226 | } |
@@ -226,7 +234,7 @@ test_and_set_bit_lock(int nr, volatile unsigned long *addr) | |||
226 | * If two examples of this operation race, one can appear to succeed | 234 | * If two examples of this operation race, one can appear to succeed |
227 | * but actually fail. You must protect multiple accesses with a lock. | 235 | * but actually fail. You must protect multiple accesses with a lock. |
228 | */ | 236 | */ |
229 | static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) | 237 | static inline int __test_and_set_bit(long nr, volatile unsigned long *addr) |
230 | { | 238 | { |
231 | int oldbit; | 239 | int oldbit; |
232 | 240 | ||
@@ -245,7 +253,7 @@ static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) | |||
245 | * This operation is atomic and cannot be reordered. | 253 | * This operation is atomic and cannot be reordered. |
246 | * It also implies a memory barrier. | 254 | * It also implies a memory barrier. |
247 | */ | 255 | */ |
248 | static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) | 256 | static inline int test_and_clear_bit(long nr, volatile unsigned long *addr) |
249 | { | 257 | { |
250 | int oldbit; | 258 | int oldbit; |
251 | 259 | ||
@@ -272,7 +280,7 @@ static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) | |||
272 | * accessed from a hypervisor on the same CPU if running in a VM: don't change | 280 | * accessed from a hypervisor on the same CPU if running in a VM: don't change |
273 | * this without also updating arch/x86/kernel/kvm.c | 281 | * this without also updating arch/x86/kernel/kvm.c |
274 | */ | 282 | */ |
275 | static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) | 283 | static inline int __test_and_clear_bit(long nr, volatile unsigned long *addr) |
276 | { | 284 | { |
277 | int oldbit; | 285 | int oldbit; |
278 | 286 | ||
@@ -284,7 +292,7 @@ static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) | |||
284 | } | 292 | } |
285 | 293 | ||
286 | /* WARNING: non atomic and it can be reordered! */ | 294 | /* WARNING: non atomic and it can be reordered! */ |
287 | static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) | 295 | static inline int __test_and_change_bit(long nr, volatile unsigned long *addr) |
288 | { | 296 | { |
289 | int oldbit; | 297 | int oldbit; |
290 | 298 | ||
@@ -304,7 +312,7 @@ static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) | |||
304 | * This operation is atomic and cannot be reordered. | 312 | * This operation is atomic and cannot be reordered. |
305 | * It also implies a memory barrier. | 313 | * It also implies a memory barrier. |
306 | */ | 314 | */ |
307 | static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | 315 | static inline int test_and_change_bit(long nr, volatile unsigned long *addr) |
308 | { | 316 | { |
309 | int oldbit; | 317 | int oldbit; |
310 | 318 | ||
@@ -315,13 +323,13 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
315 | return oldbit; | 323 | return oldbit; |
316 | } | 324 | } |
317 | 325 | ||
318 | static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) | 326 | static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr) |
319 | { | 327 | { |
320 | return ((1UL << (nr % BITS_PER_LONG)) & | 328 | return ((1UL << (nr & (BITS_PER_LONG-1))) & |
321 | (addr[nr / BITS_PER_LONG])) != 0; | 329 | (addr[nr >> _BITOPS_LONG_SHIFT])) != 0; |
322 | } | 330 | } |
323 | 331 | ||
324 | static inline int variable_test_bit(int nr, volatile const unsigned long *addr) | 332 | static inline int variable_test_bit(long nr, volatile const unsigned long *addr) |
325 | { | 333 | { |
326 | int oldbit; | 334 | int oldbit; |
327 | 335 | ||
diff --git a/arch/x86/include/asm/bootparam_utils.h b/arch/x86/include/asm/bootparam_utils.h index 653668d140f9..4a8cb8d7cbd5 100644 --- a/arch/x86/include/asm/bootparam_utils.h +++ b/arch/x86/include/asm/bootparam_utils.h | |||
@@ -35,9 +35,9 @@ static void sanitize_boot_params(struct boot_params *boot_params) | |||
35 | */ | 35 | */ |
36 | if (boot_params->sentinel) { | 36 | if (boot_params->sentinel) { |
37 | /* fields in boot_params are left uninitialized, clear them */ | 37 | /* fields in boot_params are left uninitialized, clear them */ |
38 | memset(&boot_params->olpc_ofw_header, 0, | 38 | memset(&boot_params->ext_ramdisk_image, 0, |
39 | (char *)&boot_params->efi_info - | 39 | (char *)&boot_params->efi_info - |
40 | (char *)&boot_params->olpc_ofw_header); | 40 | (char *)&boot_params->ext_ramdisk_image); |
41 | memset(&boot_params->kbd_status, 0, | 41 | memset(&boot_params->kbd_status, 0, |
42 | (char *)&boot_params->hdr - | 42 | (char *)&boot_params->hdr - |
43 | (char *)&boot_params->kbd_status); | 43 | (char *)&boot_params->kbd_status); |
diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h index 46fc474fd819..f50de6951738 100644 --- a/arch/x86/include/asm/checksum_32.h +++ b/arch/x86/include/asm/checksum_32.h | |||
@@ -49,9 +49,15 @@ static inline __wsum csum_partial_copy_from_user(const void __user *src, | |||
49 | int len, __wsum sum, | 49 | int len, __wsum sum, |
50 | int *err_ptr) | 50 | int *err_ptr) |
51 | { | 51 | { |
52 | __wsum ret; | ||
53 | |||
52 | might_sleep(); | 54 | might_sleep(); |
53 | return csum_partial_copy_generic((__force void *)src, dst, | 55 | stac(); |
54 | len, sum, err_ptr, NULL); | 56 | ret = csum_partial_copy_generic((__force void *)src, dst, |
57 | len, sum, err_ptr, NULL); | ||
58 | clac(); | ||
59 | |||
60 | return ret; | ||
55 | } | 61 | } |
56 | 62 | ||
57 | /* | 63 | /* |
@@ -176,10 +182,16 @@ static inline __wsum csum_and_copy_to_user(const void *src, | |||
176 | int len, __wsum sum, | 182 | int len, __wsum sum, |
177 | int *err_ptr) | 183 | int *err_ptr) |
178 | { | 184 | { |
185 | __wsum ret; | ||
186 | |||
179 | might_sleep(); | 187 | might_sleep(); |
180 | if (access_ok(VERIFY_WRITE, dst, len)) | 188 | if (access_ok(VERIFY_WRITE, dst, len)) { |
181 | return csum_partial_copy_generic(src, (__force void *)dst, | 189 | stac(); |
182 | len, sum, NULL, err_ptr); | 190 | ret = csum_partial_copy_generic(src, (__force void *)dst, |
191 | len, sum, NULL, err_ptr); | ||
192 | clac(); | ||
193 | return ret; | ||
194 | } | ||
183 | 195 | ||
184 | if (len) | 196 | if (len) |
185 | *err_ptr = -EFAULT; | 197 | *err_ptr = -EFAULT; |
diff --git a/arch/x86/include/asm/checksum_64.h b/arch/x86/include/asm/checksum_64.h index 9bfdc41629ec..e6fd8a026c7b 100644 --- a/arch/x86/include/asm/checksum_64.h +++ b/arch/x86/include/asm/checksum_64.h | |||
@@ -133,7 +133,7 @@ extern __wsum csum_partial(const void *buff, int len, __wsum sum); | |||
133 | 133 | ||
134 | 134 | ||
135 | /* Do not call this directly. Use the wrappers below */ | 135 | /* Do not call this directly. Use the wrappers below */ |
136 | extern __wsum csum_partial_copy_generic(const void *src, const void *dst, | 136 | extern __visible __wsum csum_partial_copy_generic(const void *src, const void *dst, |
137 | int len, __wsum sum, | 137 | int len, __wsum sum, |
138 | int *src_err_ptr, int *dst_err_ptr); | 138 | int *src_err_ptr, int *dst_err_ptr); |
139 | 139 | ||
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 47538a61c91b..d3f5c63078d8 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -366,9 +366,10 @@ extern bool __static_cpu_has_safe(u16 bit); | |||
366 | */ | 366 | */ |
367 | static __always_inline __pure bool __static_cpu_has(u16 bit) | 367 | static __always_inline __pure bool __static_cpu_has(u16 bit) |
368 | { | 368 | { |
369 | #if __GNUC__ > 4 || __GNUC_MINOR__ >= 5 | 369 | #ifdef CC_HAVE_ASM_GOTO |
370 | 370 | ||
371 | #ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS | 371 | #ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS |
372 | |||
372 | /* | 373 | /* |
373 | * Catch too early usage of this before alternatives | 374 | * Catch too early usage of this before alternatives |
374 | * have run. | 375 | * have run. |
@@ -384,6 +385,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) | |||
384 | ".previous\n" | 385 | ".previous\n" |
385 | /* skipping size check since replacement size = 0 */ | 386 | /* skipping size check since replacement size = 0 */ |
386 | : : "i" (X86_FEATURE_ALWAYS) : : t_warn); | 387 | : : "i" (X86_FEATURE_ALWAYS) : : t_warn); |
388 | |||
387 | #endif | 389 | #endif |
388 | 390 | ||
389 | asm goto("1: jmp %l[t_no]\n" | 391 | asm goto("1: jmp %l[t_no]\n" |
@@ -406,7 +408,9 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) | |||
406 | warn_pre_alternatives(); | 408 | warn_pre_alternatives(); |
407 | return false; | 409 | return false; |
408 | #endif | 410 | #endif |
409 | #else /* GCC_VERSION >= 40500 */ | 411 | |
412 | #else /* CC_HAVE_ASM_GOTO */ | ||
413 | |||
410 | u8 flag; | 414 | u8 flag; |
411 | /* Open-coded due to __stringify() in ALTERNATIVE() */ | 415 | /* Open-coded due to __stringify() in ALTERNATIVE() */ |
412 | asm volatile("1: movb $0,%0\n" | 416 | asm volatile("1: movb $0,%0\n" |
@@ -427,7 +431,8 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) | |||
427 | ".previous\n" | 431 | ".previous\n" |
428 | : "=qm" (flag) : "i" (bit)); | 432 | : "=qm" (flag) : "i" (bit)); |
429 | return flag; | 433 | return flag; |
430 | #endif | 434 | |
435 | #endif /* CC_HAVE_ASM_GOTO */ | ||
431 | } | 436 | } |
432 | 437 | ||
433 | #define static_cpu_has(bit) \ | 438 | #define static_cpu_has(bit) \ |
@@ -441,7 +446,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) | |||
441 | 446 | ||
442 | static __always_inline __pure bool _static_cpu_has_safe(u16 bit) | 447 | static __always_inline __pure bool _static_cpu_has_safe(u16 bit) |
443 | { | 448 | { |
444 | #if __GNUC__ > 4 || __GNUC_MINOR__ >= 5 | 449 | #ifdef CC_HAVE_ASM_GOTO |
445 | /* | 450 | /* |
446 | * We need to spell the jumps to the compiler because, depending on the offset, | 451 | * We need to spell the jumps to the compiler because, depending on the offset, |
447 | * the replacement jump can be bigger than the original jump, and this we cannot | 452 | * the replacement jump can be bigger than the original jump, and this we cannot |
@@ -475,7 +480,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) | |||
475 | return false; | 480 | return false; |
476 | t_dynamic: | 481 | t_dynamic: |
477 | return __static_cpu_has_safe(bit); | 482 | return __static_cpu_has_safe(bit); |
478 | #else /* GCC_VERSION >= 40500 */ | 483 | #else |
479 | u8 flag; | 484 | u8 flag; |
480 | /* Open-coded due to __stringify() in ALTERNATIVE() */ | 485 | /* Open-coded due to __stringify() in ALTERNATIVE() */ |
481 | asm volatile("1: movb $2,%0\n" | 486 | asm volatile("1: movb $2,%0\n" |
@@ -511,7 +516,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) | |||
511 | : "=qm" (flag) | 516 | : "=qm" (flag) |
512 | : "i" (bit), "i" (X86_FEATURE_ALWAYS)); | 517 | : "i" (bit), "i" (X86_FEATURE_ALWAYS)); |
513 | return (flag == 2 ? __static_cpu_has_safe(bit) : flag); | 518 | return (flag == 2 ? __static_cpu_has_safe(bit) : flag); |
514 | #endif | 519 | #endif /* CC_HAVE_ASM_GOTO */ |
515 | } | 520 | } |
516 | 521 | ||
517 | #define static_cpu_has_safe(bit) \ | 522 | #define static_cpu_has_safe(bit) \ |
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index cccd07fa5e3a..779c2efe2e97 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h | |||
@@ -29,7 +29,7 @@ extern void e820_setup_gap(void); | |||
29 | extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize, | 29 | extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize, |
30 | unsigned long start_addr, unsigned long long end_addr); | 30 | unsigned long start_addr, unsigned long long end_addr); |
31 | struct setup_data; | 31 | struct setup_data; |
32 | extern void parse_e820_ext(struct setup_data *data); | 32 | extern void parse_e820_ext(u64 phys_addr, u32 data_len); |
33 | 33 | ||
34 | #if defined(CONFIG_X86_64) || \ | 34 | #if defined(CONFIG_X86_64) || \ |
35 | (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) | 35 | (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) |
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index e4ac559c4a24..92b3bae08b74 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h | |||
@@ -26,56 +26,56 @@ | |||
26 | #include <asm/sections.h> | 26 | #include <asm/sections.h> |
27 | 27 | ||
28 | /* Interrupt handlers registered during init_IRQ */ | 28 | /* Interrupt handlers registered during init_IRQ */ |
29 | extern void apic_timer_interrupt(void); | 29 | extern asmlinkage void apic_timer_interrupt(void); |
30 | extern void x86_platform_ipi(void); | 30 | extern asmlinkage void x86_platform_ipi(void); |
31 | extern void kvm_posted_intr_ipi(void); | 31 | extern asmlinkage void kvm_posted_intr_ipi(void); |
32 | extern void error_interrupt(void); | 32 | extern asmlinkage void error_interrupt(void); |
33 | extern void irq_work_interrupt(void); | 33 | extern asmlinkage void irq_work_interrupt(void); |
34 | 34 | ||
35 | extern void spurious_interrupt(void); | 35 | extern asmlinkage void spurious_interrupt(void); |
36 | extern void thermal_interrupt(void); | 36 | extern asmlinkage void thermal_interrupt(void); |
37 | extern void reschedule_interrupt(void); | 37 | extern asmlinkage void reschedule_interrupt(void); |
38 | 38 | ||
39 | extern void invalidate_interrupt(void); | 39 | extern asmlinkage void invalidate_interrupt(void); |
40 | extern void invalidate_interrupt0(void); | 40 | extern asmlinkage void invalidate_interrupt0(void); |
41 | extern void invalidate_interrupt1(void); | 41 | extern asmlinkage void invalidate_interrupt1(void); |
42 | extern void invalidate_interrupt2(void); | 42 | extern asmlinkage void invalidate_interrupt2(void); |
43 | extern void invalidate_interrupt3(void); | 43 | extern asmlinkage void invalidate_interrupt3(void); |
44 | extern void invalidate_interrupt4(void); | 44 | extern asmlinkage void invalidate_interrupt4(void); |
45 | extern void invalidate_interrupt5(void); | 45 | extern asmlinkage void invalidate_interrupt5(void); |
46 | extern void invalidate_interrupt6(void); | 46 | extern asmlinkage void invalidate_interrupt6(void); |
47 | extern void invalidate_interrupt7(void); | 47 | extern asmlinkage void invalidate_interrupt7(void); |
48 | extern void invalidate_interrupt8(void); | 48 | extern asmlinkage void invalidate_interrupt8(void); |
49 | extern void invalidate_interrupt9(void); | 49 | extern asmlinkage void invalidate_interrupt9(void); |
50 | extern void invalidate_interrupt10(void); | 50 | extern asmlinkage void invalidate_interrupt10(void); |
51 | extern void invalidate_interrupt11(void); | 51 | extern asmlinkage void invalidate_interrupt11(void); |
52 | extern void invalidate_interrupt12(void); | 52 | extern asmlinkage void invalidate_interrupt12(void); |
53 | extern void invalidate_interrupt13(void); | 53 | extern asmlinkage void invalidate_interrupt13(void); |
54 | extern void invalidate_interrupt14(void); | 54 | extern asmlinkage void invalidate_interrupt14(void); |
55 | extern void invalidate_interrupt15(void); | 55 | extern asmlinkage void invalidate_interrupt15(void); |
56 | extern void invalidate_interrupt16(void); | 56 | extern asmlinkage void invalidate_interrupt16(void); |
57 | extern void invalidate_interrupt17(void); | 57 | extern asmlinkage void invalidate_interrupt17(void); |
58 | extern void invalidate_interrupt18(void); | 58 | extern asmlinkage void invalidate_interrupt18(void); |
59 | extern void invalidate_interrupt19(void); | 59 | extern asmlinkage void invalidate_interrupt19(void); |
60 | extern void invalidate_interrupt20(void); | 60 | extern asmlinkage void invalidate_interrupt20(void); |
61 | extern void invalidate_interrupt21(void); | 61 | extern asmlinkage void invalidate_interrupt21(void); |
62 | extern void invalidate_interrupt22(void); | 62 | extern asmlinkage void invalidate_interrupt22(void); |
63 | extern void invalidate_interrupt23(void); | 63 | extern asmlinkage void invalidate_interrupt23(void); |
64 | extern void invalidate_interrupt24(void); | 64 | extern asmlinkage void invalidate_interrupt24(void); |
65 | extern void invalidate_interrupt25(void); | 65 | extern asmlinkage void invalidate_interrupt25(void); |
66 | extern void invalidate_interrupt26(void); | 66 | extern asmlinkage void invalidate_interrupt26(void); |
67 | extern void invalidate_interrupt27(void); | 67 | extern asmlinkage void invalidate_interrupt27(void); |
68 | extern void invalidate_interrupt28(void); | 68 | extern asmlinkage void invalidate_interrupt28(void); |
69 | extern void invalidate_interrupt29(void); | 69 | extern asmlinkage void invalidate_interrupt29(void); |
70 | extern void invalidate_interrupt30(void); | 70 | extern asmlinkage void invalidate_interrupt30(void); |
71 | extern void invalidate_interrupt31(void); | 71 | extern asmlinkage void invalidate_interrupt31(void); |
72 | 72 | ||
73 | extern void irq_move_cleanup_interrupt(void); | 73 | extern asmlinkage void irq_move_cleanup_interrupt(void); |
74 | extern void reboot_interrupt(void); | 74 | extern asmlinkage void reboot_interrupt(void); |
75 | extern void threshold_interrupt(void); | 75 | extern asmlinkage void threshold_interrupt(void); |
76 | 76 | ||
77 | extern void call_function_interrupt(void); | 77 | extern asmlinkage void call_function_interrupt(void); |
78 | extern void call_function_single_interrupt(void); | 78 | extern asmlinkage void call_function_single_interrupt(void); |
79 | 79 | ||
80 | #ifdef CONFIG_TRACING | 80 | #ifdef CONFIG_TRACING |
81 | /* Interrupt handlers registered during init_IRQ */ | 81 | /* Interrupt handlers registered during init_IRQ */ |
@@ -172,22 +172,18 @@ extern atomic_t irq_mis_count; | |||
172 | extern void eisa_set_level_irq(unsigned int irq); | 172 | extern void eisa_set_level_irq(unsigned int irq); |
173 | 173 | ||
174 | /* SMP */ | 174 | /* SMP */ |
175 | extern void smp_apic_timer_interrupt(struct pt_regs *); | 175 | extern __visible void smp_apic_timer_interrupt(struct pt_regs *); |
176 | extern void smp_spurious_interrupt(struct pt_regs *); | 176 | extern __visible void smp_spurious_interrupt(struct pt_regs *); |
177 | extern void smp_x86_platform_ipi(struct pt_regs *); | 177 | extern __visible void smp_x86_platform_ipi(struct pt_regs *); |
178 | extern void smp_error_interrupt(struct pt_regs *); | 178 | extern __visible void smp_error_interrupt(struct pt_regs *); |
179 | #ifdef CONFIG_X86_IO_APIC | 179 | #ifdef CONFIG_X86_IO_APIC |
180 | extern asmlinkage void smp_irq_move_cleanup_interrupt(void); | 180 | extern asmlinkage void smp_irq_move_cleanup_interrupt(void); |
181 | #endif | 181 | #endif |
182 | #ifdef CONFIG_SMP | 182 | #ifdef CONFIG_SMP |
183 | extern void smp_reschedule_interrupt(struct pt_regs *); | 183 | extern __visible void smp_reschedule_interrupt(struct pt_regs *); |
184 | extern void smp_call_function_interrupt(struct pt_regs *); | 184 | extern __visible void smp_call_function_interrupt(struct pt_regs *); |
185 | extern void smp_call_function_single_interrupt(struct pt_regs *); | 185 | extern __visible void smp_call_function_single_interrupt(struct pt_regs *); |
186 | #ifdef CONFIG_X86_32 | 186 | extern __visible void smp_invalidate_interrupt(struct pt_regs *); |
187 | extern void smp_invalidate_interrupt(struct pt_regs *); | ||
188 | #else | ||
189 | extern asmlinkage void smp_invalidate_interrupt(struct pt_regs *); | ||
190 | #endif | ||
191 | #endif | 187 | #endif |
192 | 188 | ||
193 | extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void); | 189 | extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void); |
diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index 2d4b5e6107cd..e42f758a0fbd 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h | |||
@@ -33,7 +33,7 @@ struct hypervisor_x86 { | |||
33 | const char *name; | 33 | const char *name; |
34 | 34 | ||
35 | /* Detection routine */ | 35 | /* Detection routine */ |
36 | bool (*detect)(void); | 36 | uint32_t (*detect)(void); |
37 | 37 | ||
38 | /* Adjust CPU feature bits (run once per CPU) */ | 38 | /* Adjust CPU feature bits (run once per CPU) */ |
39 | void (*set_cpu_features)(struct cpuinfo_x86 *); | 39 | void (*set_cpu_features)(struct cpuinfo_x86 *); |
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 57873beb3292..0ea10f27d613 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h | |||
@@ -33,7 +33,7 @@ extern void (*x86_platform_ipi_callback)(void); | |||
33 | extern void native_init_IRQ(void); | 33 | extern void native_init_IRQ(void); |
34 | extern bool handle_irq(unsigned irq, struct pt_regs *regs); | 34 | extern bool handle_irq(unsigned irq, struct pt_regs *regs); |
35 | 35 | ||
36 | extern unsigned int do_IRQ(struct pt_regs *regs); | 36 | extern __visible unsigned int do_IRQ(struct pt_regs *regs); |
37 | 37 | ||
38 | /* Interrupt vector management */ | 38 | /* Interrupt vector management */ |
39 | extern DECLARE_BITMAP(used_vectors, NR_VECTORS); | 39 | extern DECLARE_BITMAP(used_vectors, NR_VECTORS); |
diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h index 5a6d2873f80e..9454c167629f 100644 --- a/arch/x86/include/asm/kprobes.h +++ b/arch/x86/include/asm/kprobes.h | |||
@@ -49,10 +49,10 @@ typedef u8 kprobe_opcode_t; | |||
49 | #define flush_insn_slot(p) do { } while (0) | 49 | #define flush_insn_slot(p) do { } while (0) |
50 | 50 | ||
51 | /* optinsn template addresses */ | 51 | /* optinsn template addresses */ |
52 | extern kprobe_opcode_t optprobe_template_entry; | 52 | extern __visible kprobe_opcode_t optprobe_template_entry; |
53 | extern kprobe_opcode_t optprobe_template_val; | 53 | extern __visible kprobe_opcode_t optprobe_template_val; |
54 | extern kprobe_opcode_t optprobe_template_call; | 54 | extern __visible kprobe_opcode_t optprobe_template_call; |
55 | extern kprobe_opcode_t optprobe_template_end; | 55 | extern __visible kprobe_opcode_t optprobe_template_end; |
56 | #define MAX_OPTIMIZED_LENGTH (MAX_INSN_SIZE + RELATIVE_ADDR_SIZE) | 56 | #define MAX_OPTIMIZED_LENGTH (MAX_INSN_SIZE + RELATIVE_ADDR_SIZE) |
57 | #define MAX_OPTINSN_SIZE \ | 57 | #define MAX_OPTINSN_SIZE \ |
58 | (((unsigned long)&optprobe_template_end - \ | 58 | (((unsigned long)&optprobe_template_end - \ |
@@ -62,7 +62,7 @@ extern kprobe_opcode_t optprobe_template_end; | |||
62 | extern const int kretprobe_blacklist_size; | 62 | extern const int kretprobe_blacklist_size; |
63 | 63 | ||
64 | void arch_remove_kprobe(struct kprobe *p); | 64 | void arch_remove_kprobe(struct kprobe *p); |
65 | void kretprobe_trampoline(void); | 65 | asmlinkage void kretprobe_trampoline(void); |
66 | 66 | ||
67 | /* Architecture specific copy of original instruction*/ | 67 | /* Architecture specific copy of original instruction*/ |
68 | struct arch_specific_insn { | 68 | struct arch_specific_insn { |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index f87f7fcefa0a..c76ff74a98f2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -286,6 +286,7 @@ struct kvm_mmu { | |||
286 | u64 *pae_root; | 286 | u64 *pae_root; |
287 | u64 *lm_root; | 287 | u64 *lm_root; |
288 | u64 rsvd_bits_mask[2][4]; | 288 | u64 rsvd_bits_mask[2][4]; |
289 | u64 bad_mt_xwr; | ||
289 | 290 | ||
290 | /* | 291 | /* |
291 | * Bitmap: bit set = last pte in walk | 292 | * Bitmap: bit set = last pte in walk |
@@ -323,6 +324,7 @@ struct kvm_pmu { | |||
323 | u64 global_ovf_ctrl; | 324 | u64 global_ovf_ctrl; |
324 | u64 counter_bitmask[2]; | 325 | u64 counter_bitmask[2]; |
325 | u64 global_ctrl_mask; | 326 | u64 global_ctrl_mask; |
327 | u64 reserved_bits; | ||
326 | u8 version; | 328 | u8 version; |
327 | struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC]; | 329 | struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC]; |
328 | struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED]; | 330 | struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED]; |
@@ -511,6 +513,14 @@ struct kvm_vcpu_arch { | |||
511 | * instruction. | 513 | * instruction. |
512 | */ | 514 | */ |
513 | bool write_fault_to_shadow_pgtable; | 515 | bool write_fault_to_shadow_pgtable; |
516 | |||
517 | /* set at EPT violation at this point */ | ||
518 | unsigned long exit_qualification; | ||
519 | |||
520 | /* pv related host specific info */ | ||
521 | struct { | ||
522 | bool pv_unhalted; | ||
523 | } pv; | ||
514 | }; | 524 | }; |
515 | 525 | ||
516 | struct kvm_lpage_info { | 526 | struct kvm_lpage_info { |
@@ -802,8 +812,8 @@ extern u32 kvm_min_guest_tsc_khz; | |||
802 | extern u32 kvm_max_guest_tsc_khz; | 812 | extern u32 kvm_max_guest_tsc_khz; |
803 | 813 | ||
804 | enum emulation_result { | 814 | enum emulation_result { |
805 | EMULATE_DONE, /* no further processing */ | 815 | EMULATE_DONE, /* no further processing */ |
806 | EMULATE_DO_MMIO, /* kvm_run filled with mmio request */ | 816 | EMULATE_USER_EXIT, /* kvm_run ready for userspace exit */ |
807 | EMULATE_FAIL, /* can't emulate this instruction */ | 817 | EMULATE_FAIL, /* can't emulate this instruction */ |
808 | }; | 818 | }; |
809 | 819 | ||
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 695399f2d5eb..1df115909758 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h | |||
@@ -85,26 +85,20 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, | |||
85 | return ret; | 85 | return ret; |
86 | } | 86 | } |
87 | 87 | ||
88 | static inline bool kvm_para_available(void) | 88 | static inline uint32_t kvm_cpuid_base(void) |
89 | { | 89 | { |
90 | unsigned int eax, ebx, ecx, edx; | ||
91 | char signature[13]; | ||
92 | |||
93 | if (boot_cpu_data.cpuid_level < 0) | 90 | if (boot_cpu_data.cpuid_level < 0) |
94 | return false; /* So we don't blow up on old processors */ | 91 | return 0; /* So we don't blow up on old processors */ |
95 | 92 | ||
96 | if (cpu_has_hypervisor) { | 93 | if (cpu_has_hypervisor) |
97 | cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); | 94 | return hypervisor_cpuid_base("KVMKVMKVM\0\0\0", 0); |
98 | memcpy(signature + 0, &ebx, 4); | ||
99 | memcpy(signature + 4, &ecx, 4); | ||
100 | memcpy(signature + 8, &edx, 4); | ||
101 | signature[12] = 0; | ||
102 | 95 | ||
103 | if (strcmp(signature, "KVMKVMKVM") == 0) | 96 | return 0; |
104 | return true; | 97 | } |
105 | } | ||
106 | 98 | ||
107 | return false; | 99 | static inline bool kvm_para_available(void) |
100 | { | ||
101 | return kvm_cpuid_base() != 0; | ||
108 | } | 102 | } |
109 | 103 | ||
110 | static inline unsigned int kvm_arch_para_features(void) | 104 | static inline unsigned int kvm_arch_para_features(void) |
@@ -118,10 +112,20 @@ void kvm_async_pf_task_wait(u32 token); | |||
118 | void kvm_async_pf_task_wake(u32 token); | 112 | void kvm_async_pf_task_wake(u32 token); |
119 | u32 kvm_read_and_reset_pf_reason(void); | 113 | u32 kvm_read_and_reset_pf_reason(void); |
120 | extern void kvm_disable_steal_time(void); | 114 | extern void kvm_disable_steal_time(void); |
121 | #else | 115 | |
122 | #define kvm_guest_init() do { } while (0) | 116 | #ifdef CONFIG_PARAVIRT_SPINLOCKS |
117 | void __init kvm_spinlock_init(void); | ||
118 | #else /* !CONFIG_PARAVIRT_SPINLOCKS */ | ||
119 | static inline void kvm_spinlock_init(void) | ||
120 | { | ||
121 | } | ||
122 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ | ||
123 | |||
124 | #else /* CONFIG_KVM_GUEST */ | ||
125 | #define kvm_guest_init() do {} while (0) | ||
123 | #define kvm_async_pf_task_wait(T) do {} while(0) | 126 | #define kvm_async_pf_task_wait(T) do {} while(0) |
124 | #define kvm_async_pf_task_wake(T) do {} while(0) | 127 | #define kvm_async_pf_task_wake(T) do {} while(0) |
128 | |||
125 | static inline u32 kvm_read_and_reset_pf_reason(void) | 129 | static inline u32 kvm_read_and_reset_pf_reason(void) |
126 | { | 130 | { |
127 | return 0; | 131 | return 0; |
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 29e3093bbd21..cbe6b9e404ce 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -32,11 +32,20 @@ | |||
32 | #define MCI_STATUS_PCC (1ULL<<57) /* processor context corrupt */ | 32 | #define MCI_STATUS_PCC (1ULL<<57) /* processor context corrupt */ |
33 | #define MCI_STATUS_S (1ULL<<56) /* Signaled machine check */ | 33 | #define MCI_STATUS_S (1ULL<<56) /* Signaled machine check */ |
34 | #define MCI_STATUS_AR (1ULL<<55) /* Action required */ | 34 | #define MCI_STATUS_AR (1ULL<<55) /* Action required */ |
35 | #define MCACOD 0xffff /* MCA Error Code */ | 35 | |
36 | /* | ||
37 | * Note that the full MCACOD field of IA32_MCi_STATUS MSR is | ||
38 | * bits 15:0. But bit 12 is the 'F' bit, defined for corrected | ||
39 | * errors to indicate that errors are being filtered by hardware. | ||
40 | * We should mask out bit 12 when looking for specific signatures | ||
41 | * of uncorrected errors - so the F bit is deliberately skipped | ||
42 | * in this #define. | ||
43 | */ | ||
44 | #define MCACOD 0xefff /* MCA Error Code */ | ||
36 | 45 | ||
37 | /* Architecturally defined codes from SDM Vol. 3B Chapter 15 */ | 46 | /* Architecturally defined codes from SDM Vol. 3B Chapter 15 */ |
38 | #define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */ | 47 | #define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */ |
39 | #define MCACOD_SCRUBMSK 0xfff0 | 48 | #define MCACOD_SCRUBMSK 0xeff0 /* Skip bit 12 ('F' bit) */ |
40 | #define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */ | 49 | #define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */ |
41 | #define MCACOD_DATA 0x0134 /* Data Load */ | 50 | #define MCACOD_DATA 0x0134 /* Data Load */ |
42 | #define MCACOD_INSTR 0x0150 /* Instruction Fetch */ | 51 | #define MCACOD_INSTR 0x0150 /* Instruction Fetch */ |
@@ -188,6 +197,9 @@ extern void register_mce_write_callback(ssize_t (*)(struct file *filp, | |||
188 | const char __user *ubuf, | 197 | const char __user *ubuf, |
189 | size_t usize, loff_t *off)); | 198 | size_t usize, loff_t *off)); |
190 | 199 | ||
200 | /* Disable CMCI/polling for MCA bank claimed by firmware */ | ||
201 | extern void mce_disable_bank(int bank); | ||
202 | |||
191 | /* | 203 | /* |
192 | * Exception handler | 204 | * Exception handler |
193 | */ | 205 | */ |
diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h index 50e5c58ced23..4c019179a57d 100644 --- a/arch/x86/include/asm/microcode_amd.h +++ b/arch/x86/include/asm/microcode_amd.h | |||
@@ -59,7 +59,7 @@ static inline u16 find_equiv_id(struct equiv_cpu_entry *equiv_cpu_table, | |||
59 | 59 | ||
60 | extern int __apply_microcode_amd(struct microcode_amd *mc_amd); | 60 | extern int __apply_microcode_amd(struct microcode_amd *mc_amd); |
61 | extern int apply_microcode_amd(int cpu); | 61 | extern int apply_microcode_amd(int cpu); |
62 | extern enum ucode_state load_microcode_amd(int cpu, const u8 *data, size_t size); | 62 | extern enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); |
63 | 63 | ||
64 | #ifdef CONFIG_MICROCODE_AMD_EARLY | 64 | #ifdef CONFIG_MICROCODE_AMD_EARLY |
65 | #ifdef CONFIG_X86_32 | 65 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index cdbf36776106..be12c534fd59 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h | |||
@@ -45,22 +45,28 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
45 | /* Re-load page tables */ | 45 | /* Re-load page tables */ |
46 | load_cr3(next->pgd); | 46 | load_cr3(next->pgd); |
47 | 47 | ||
48 | /* stop flush ipis for the previous mm */ | 48 | /* Stop flush ipis for the previous mm */ |
49 | cpumask_clear_cpu(cpu, mm_cpumask(prev)); | 49 | cpumask_clear_cpu(cpu, mm_cpumask(prev)); |
50 | 50 | ||
51 | /* | 51 | /* Load the LDT, if the LDT is different: */ |
52 | * load the LDT, if the LDT is different: | ||
53 | */ | ||
54 | if (unlikely(prev->context.ldt != next->context.ldt)) | 52 | if (unlikely(prev->context.ldt != next->context.ldt)) |
55 | load_LDT_nolock(&next->context); | 53 | load_LDT_nolock(&next->context); |
56 | } | 54 | } |
57 | #ifdef CONFIG_SMP | 55 | #ifdef CONFIG_SMP |
58 | else { | 56 | else { |
59 | this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK); | 57 | this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK); |
60 | BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next); | 58 | BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next); |
61 | 59 | ||
62 | if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next))) { | 60 | if (!cpumask_test_cpu(cpu, mm_cpumask(next))) { |
63 | /* We were in lazy tlb mode and leave_mm disabled | 61 | /* |
62 | * On established mms, the mm_cpumask is only changed | ||
63 | * from irq context, from ptep_clear_flush() while in | ||
64 | * lazy tlb mode, and here. Irqs are blocked during | ||
65 | * schedule, protecting us from simultaneous changes. | ||
66 | */ | ||
67 | cpumask_set_cpu(cpu, mm_cpumask(next)); | ||
68 | /* | ||
69 | * We were in lazy tlb mode and leave_mm disabled | ||
64 | * tlb flush IPI delivery. We must reload CR3 | 70 | * tlb flush IPI delivery. We must reload CR3 |
65 | * to make sure to use no freed page tables. | 71 | * to make sure to use no freed page tables. |
66 | */ | 72 | */ |
diff --git a/arch/x86/include/asm/mutex_64.h b/arch/x86/include/asm/mutex_64.h index 2c543fff241b..e7e6751648ed 100644 --- a/arch/x86/include/asm/mutex_64.h +++ b/arch/x86/include/asm/mutex_64.h | |||
@@ -16,6 +16,20 @@ | |||
16 | * | 16 | * |
17 | * Atomically decrements @v and calls <fail_fn> if the result is negative. | 17 | * Atomically decrements @v and calls <fail_fn> if the result is negative. |
18 | */ | 18 | */ |
19 | #ifdef CC_HAVE_ASM_GOTO | ||
20 | static inline void __mutex_fastpath_lock(atomic_t *v, | ||
21 | void (*fail_fn)(atomic_t *)) | ||
22 | { | ||
23 | asm volatile goto(LOCK_PREFIX " decl %0\n" | ||
24 | " jns %l[exit]\n" | ||
25 | : : "m" (v->counter) | ||
26 | : "memory", "cc" | ||
27 | : exit); | ||
28 | fail_fn(v); | ||
29 | exit: | ||
30 | return; | ||
31 | } | ||
32 | #else | ||
19 | #define __mutex_fastpath_lock(v, fail_fn) \ | 33 | #define __mutex_fastpath_lock(v, fail_fn) \ |
20 | do { \ | 34 | do { \ |
21 | unsigned long dummy; \ | 35 | unsigned long dummy; \ |
@@ -32,6 +46,7 @@ do { \ | |||
32 | : "rax", "rsi", "rdx", "rcx", \ | 46 | : "rax", "rsi", "rdx", "rcx", \ |
33 | "r8", "r9", "r10", "r11", "memory"); \ | 47 | "r8", "r9", "r10", "r11", "memory"); \ |
34 | } while (0) | 48 | } while (0) |
49 | #endif | ||
35 | 50 | ||
36 | /** | 51 | /** |
37 | * __mutex_fastpath_lock_retval - try to take the lock by moving the count | 52 | * __mutex_fastpath_lock_retval - try to take the lock by moving the count |
@@ -56,6 +71,20 @@ static inline int __mutex_fastpath_lock_retval(atomic_t *count) | |||
56 | * | 71 | * |
57 | * Atomically increments @v and calls <fail_fn> if the result is nonpositive. | 72 | * Atomically increments @v and calls <fail_fn> if the result is nonpositive. |
58 | */ | 73 | */ |
74 | #ifdef CC_HAVE_ASM_GOTO | ||
75 | static inline void __mutex_fastpath_unlock(atomic_t *v, | ||
76 | void (*fail_fn)(atomic_t *)) | ||
77 | { | ||
78 | asm volatile goto(LOCK_PREFIX " incl %0\n" | ||
79 | " jg %l[exit]\n" | ||
80 | : : "m" (v->counter) | ||
81 | : "memory", "cc" | ||
82 | : exit); | ||
83 | fail_fn(v); | ||
84 | exit: | ||
85 | return; | ||
86 | } | ||
87 | #else | ||
59 | #define __mutex_fastpath_unlock(v, fail_fn) \ | 88 | #define __mutex_fastpath_unlock(v, fail_fn) \ |
60 | do { \ | 89 | do { \ |
61 | unsigned long dummy; \ | 90 | unsigned long dummy; \ |
@@ -72,6 +101,7 @@ do { \ | |||
72 | : "rax", "rsi", "rdx", "rcx", \ | 101 | : "rax", "rsi", "rdx", "rcx", \ |
73 | "r8", "r9", "r10", "r11", "memory"); \ | 102 | "r8", "r9", "r10", "r11", "memory"); \ |
74 | } while (0) | 103 | } while (0) |
104 | #endif | ||
75 | 105 | ||
76 | #define __mutex_slowpath_needs_to_unlock() 1 | 106 | #define __mutex_slowpath_needs_to_unlock() 1 |
77 | 107 | ||
diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h index ef17af013475..f48b17df4224 100644 --- a/arch/x86/include/asm/page_32_types.h +++ b/arch/x86/include/asm/page_32_types.h | |||
@@ -15,6 +15,8 @@ | |||
15 | */ | 15 | */ |
16 | #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) | 16 | #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) |
17 | 17 | ||
18 | #define __START_KERNEL_map __PAGE_OFFSET | ||
19 | |||
18 | #define THREAD_SIZE_ORDER 1 | 20 | #define THREAD_SIZE_ORDER 1 |
19 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) | 21 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
20 | 22 | ||
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 6c896fbe21db..43dcd804ebd5 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h | |||
@@ -32,11 +32,6 @@ | |||
32 | */ | 32 | */ |
33 | #define __PAGE_OFFSET _AC(0xffff880000000000, UL) | 33 | #define __PAGE_OFFSET _AC(0xffff880000000000, UL) |
34 | 34 | ||
35 | #define __PHYSICAL_START ((CONFIG_PHYSICAL_START + \ | ||
36 | (CONFIG_PHYSICAL_ALIGN - 1)) & \ | ||
37 | ~(CONFIG_PHYSICAL_ALIGN - 1)) | ||
38 | |||
39 | #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) | ||
40 | #define __START_KERNEL_map _AC(0xffffffff80000000, UL) | 35 | #define __START_KERNEL_map _AC(0xffffffff80000000, UL) |
41 | 36 | ||
42 | /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */ | 37 | /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */ |
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 54c97879195e..f97fbe3abb67 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h | |||
@@ -33,6 +33,11 @@ | |||
33 | (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ | 33 | (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ |
34 | VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 34 | VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
35 | 35 | ||
36 | #define __PHYSICAL_START ALIGN(CONFIG_PHYSICAL_START, \ | ||
37 | CONFIG_PHYSICAL_ALIGN) | ||
38 | |||
39 | #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) | ||
40 | |||
36 | #ifdef CONFIG_X86_64 | 41 | #ifdef CONFIG_X86_64 |
37 | #include <asm/page_64_types.h> | 42 | #include <asm/page_64_types.h> |
38 | #else | 43 | #else |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index cfdc9ee4c900..401f350ef71b 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -712,36 +712,16 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | |||
712 | 712 | ||
713 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) | 713 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) |
714 | 714 | ||
715 | static inline int arch_spin_is_locked(struct arch_spinlock *lock) | 715 | static __always_inline void __ticket_lock_spinning(struct arch_spinlock *lock, |
716 | __ticket_t ticket) | ||
716 | { | 717 | { |
717 | return PVOP_CALL1(int, pv_lock_ops.spin_is_locked, lock); | 718 | PVOP_VCALLEE2(pv_lock_ops.lock_spinning, lock, ticket); |
718 | } | 719 | } |
719 | 720 | ||
720 | static inline int arch_spin_is_contended(struct arch_spinlock *lock) | 721 | static __always_inline void __ticket_unlock_kick(struct arch_spinlock *lock, |
722 | __ticket_t ticket) | ||
721 | { | 723 | { |
722 | return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock); | 724 | PVOP_VCALL2(pv_lock_ops.unlock_kick, lock, ticket); |
723 | } | ||
724 | #define arch_spin_is_contended arch_spin_is_contended | ||
725 | |||
726 | static __always_inline void arch_spin_lock(struct arch_spinlock *lock) | ||
727 | { | ||
728 | PVOP_VCALL1(pv_lock_ops.spin_lock, lock); | ||
729 | } | ||
730 | |||
731 | static __always_inline void arch_spin_lock_flags(struct arch_spinlock *lock, | ||
732 | unsigned long flags) | ||
733 | { | ||
734 | PVOP_VCALL2(pv_lock_ops.spin_lock_flags, lock, flags); | ||
735 | } | ||
736 | |||
737 | static __always_inline int arch_spin_trylock(struct arch_spinlock *lock) | ||
738 | { | ||
739 | return PVOP_CALL1(int, pv_lock_ops.spin_trylock, lock); | ||
740 | } | ||
741 | |||
742 | static __always_inline void arch_spin_unlock(struct arch_spinlock *lock) | ||
743 | { | ||
744 | PVOP_VCALL1(pv_lock_ops.spin_unlock, lock); | ||
745 | } | 725 | } |
746 | 726 | ||
747 | #endif | 727 | #endif |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 0db1fcac668c..aab8f671b523 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -327,13 +327,15 @@ struct pv_mmu_ops { | |||
327 | }; | 327 | }; |
328 | 328 | ||
329 | struct arch_spinlock; | 329 | struct arch_spinlock; |
330 | #ifdef CONFIG_SMP | ||
331 | #include <asm/spinlock_types.h> | ||
332 | #else | ||
333 | typedef u16 __ticket_t; | ||
334 | #endif | ||
335 | |||
330 | struct pv_lock_ops { | 336 | struct pv_lock_ops { |
331 | int (*spin_is_locked)(struct arch_spinlock *lock); | 337 | struct paravirt_callee_save lock_spinning; |
332 | int (*spin_is_contended)(struct arch_spinlock *lock); | 338 | void (*unlock_kick)(struct arch_spinlock *lock, __ticket_t ticket); |
333 | void (*spin_lock)(struct arch_spinlock *lock); | ||
334 | void (*spin_lock_flags)(struct arch_spinlock *lock, unsigned long flags); | ||
335 | int (*spin_trylock)(struct arch_spinlock *lock); | ||
336 | void (*spin_unlock)(struct arch_spinlock *lock); | ||
337 | }; | 339 | }; |
338 | 340 | ||
339 | /* This contains all the paravirt structures: we get a convenient | 341 | /* This contains all the paravirt structures: we get a convenient |
@@ -387,7 +389,8 @@ extern struct pv_lock_ops pv_lock_ops; | |||
387 | 389 | ||
388 | /* Simple instruction patching code. */ | 390 | /* Simple instruction patching code. */ |
389 | #define DEF_NATIVE(ops, name, code) \ | 391 | #define DEF_NATIVE(ops, name, code) \ |
390 | extern const char start_##ops##_##name[], end_##ops##_##name[]; \ | 392 | extern const char start_##ops##_##name[] __visible, \ |
393 | end_##ops##_##name[] __visible; \ | ||
391 | asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") | 394 | asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") |
392 | 395 | ||
393 | unsigned paravirt_patch_nop(void); | 396 | unsigned paravirt_patch_nop(void); |
diff --git a/arch/x86/include/asm/pgtable-2level.h b/arch/x86/include/asm/pgtable-2level.h index f2b489cf1602..3bf2dd0cf61f 100644 --- a/arch/x86/include/asm/pgtable-2level.h +++ b/arch/x86/include/asm/pgtable-2level.h | |||
@@ -55,9 +55,53 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp) | |||
55 | #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp) | 55 | #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp) |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | #ifdef CONFIG_MEM_SOFT_DIRTY | ||
59 | |||
60 | /* | ||
61 | * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE, _PAGE_BIT_SOFT_DIRTY and | ||
62 | * _PAGE_BIT_PROTNONE are taken, split up the 28 bits of offset | ||
63 | * into this range. | ||
64 | */ | ||
65 | #define PTE_FILE_MAX_BITS 28 | ||
66 | #define PTE_FILE_SHIFT1 (_PAGE_BIT_PRESENT + 1) | ||
67 | #define PTE_FILE_SHIFT2 (_PAGE_BIT_FILE + 1) | ||
68 | #define PTE_FILE_SHIFT3 (_PAGE_BIT_PROTNONE + 1) | ||
69 | #define PTE_FILE_SHIFT4 (_PAGE_BIT_SOFT_DIRTY + 1) | ||
70 | #define PTE_FILE_BITS1 (PTE_FILE_SHIFT2 - PTE_FILE_SHIFT1 - 1) | ||
71 | #define PTE_FILE_BITS2 (PTE_FILE_SHIFT3 - PTE_FILE_SHIFT2 - 1) | ||
72 | #define PTE_FILE_BITS3 (PTE_FILE_SHIFT4 - PTE_FILE_SHIFT3 - 1) | ||
73 | |||
74 | #define pte_to_pgoff(pte) \ | ||
75 | ((((pte).pte_low >> (PTE_FILE_SHIFT1)) \ | ||
76 | & ((1U << PTE_FILE_BITS1) - 1))) \ | ||
77 | + ((((pte).pte_low >> (PTE_FILE_SHIFT2)) \ | ||
78 | & ((1U << PTE_FILE_BITS2) - 1)) \ | ||
79 | << (PTE_FILE_BITS1)) \ | ||
80 | + ((((pte).pte_low >> (PTE_FILE_SHIFT3)) \ | ||
81 | & ((1U << PTE_FILE_BITS3) - 1)) \ | ||
82 | << (PTE_FILE_BITS1 + PTE_FILE_BITS2)) \ | ||
83 | + ((((pte).pte_low >> (PTE_FILE_SHIFT4))) \ | ||
84 | << (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)) | ||
85 | |||
86 | #define pgoff_to_pte(off) \ | ||
87 | ((pte_t) { .pte_low = \ | ||
88 | ((((off)) & ((1U << PTE_FILE_BITS1) - 1)) << PTE_FILE_SHIFT1) \ | ||
89 | + ((((off) >> PTE_FILE_BITS1) \ | ||
90 | & ((1U << PTE_FILE_BITS2) - 1)) \ | ||
91 | << PTE_FILE_SHIFT2) \ | ||
92 | + ((((off) >> (PTE_FILE_BITS1 + PTE_FILE_BITS2)) \ | ||
93 | & ((1U << PTE_FILE_BITS3) - 1)) \ | ||
94 | << PTE_FILE_SHIFT3) \ | ||
95 | + ((((off) >> \ | ||
96 | (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3))) \ | ||
97 | << PTE_FILE_SHIFT4) \ | ||
98 | + _PAGE_FILE }) | ||
99 | |||
100 | #else /* CONFIG_MEM_SOFT_DIRTY */ | ||
101 | |||
58 | /* | 102 | /* |
59 | * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE and _PAGE_BIT_PROTNONE are taken, | 103 | * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE and _PAGE_BIT_PROTNONE are taken, |
60 | * split up the 29 bits of offset into this range: | 104 | * split up the 29 bits of offset into this range. |
61 | */ | 105 | */ |
62 | #define PTE_FILE_MAX_BITS 29 | 106 | #define PTE_FILE_MAX_BITS 29 |
63 | #define PTE_FILE_SHIFT1 (_PAGE_BIT_PRESENT + 1) | 107 | #define PTE_FILE_SHIFT1 (_PAGE_BIT_PRESENT + 1) |
@@ -88,6 +132,8 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp) | |||
88 | << PTE_FILE_SHIFT3) \ | 132 | << PTE_FILE_SHIFT3) \ |
89 | + _PAGE_FILE }) | 133 | + _PAGE_FILE }) |
90 | 134 | ||
135 | #endif /* CONFIG_MEM_SOFT_DIRTY */ | ||
136 | |||
91 | /* Encode and de-code a swap entry */ | 137 | /* Encode and de-code a swap entry */ |
92 | #if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE | 138 | #if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE |
93 | #define SWP_TYPE_BITS (_PAGE_BIT_FILE - _PAGE_BIT_PRESENT - 1) | 139 | #define SWP_TYPE_BITS (_PAGE_BIT_FILE - _PAGE_BIT_PRESENT - 1) |
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 4cc9f2b7cdc3..81bb91b49a88 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h | |||
@@ -179,6 +179,9 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp) | |||
179 | /* | 179 | /* |
180 | * Bits 0, 6 and 7 are taken in the low part of the pte, | 180 | * Bits 0, 6 and 7 are taken in the low part of the pte, |
181 | * put the 32 bits of offset into the high part. | 181 | * put the 32 bits of offset into the high part. |
182 | * | ||
183 | * For soft-dirty tracking 11 bit is taken from | ||
184 | * the low part of pte as well. | ||
182 | */ | 185 | */ |
183 | #define pte_to_pgoff(pte) ((pte).pte_high) | 186 | #define pte_to_pgoff(pte) ((pte).pte_high) |
184 | #define pgoff_to_pte(off) \ | 187 | #define pgoff_to_pte(off) \ |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 7dc305a46058..8d16befdec88 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -22,7 +22,8 @@ | |||
22 | * ZERO_PAGE is a global shared page that is always zero: used | 22 | * ZERO_PAGE is a global shared page that is always zero: used |
23 | * for zero-mapped memory areas etc.. | 23 | * for zero-mapped memory areas etc.. |
24 | */ | 24 | */ |
25 | extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; | 25 | extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] |
26 | __visible; | ||
26 | #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) | 27 | #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) |
27 | 28 | ||
28 | extern spinlock_t pgd_lock; | 29 | extern spinlock_t pgd_lock; |
@@ -314,6 +315,36 @@ static inline pmd_t pmd_mksoft_dirty(pmd_t pmd) | |||
314 | return pmd_set_flags(pmd, _PAGE_SOFT_DIRTY); | 315 | return pmd_set_flags(pmd, _PAGE_SOFT_DIRTY); |
315 | } | 316 | } |
316 | 317 | ||
318 | static inline pte_t pte_swp_mksoft_dirty(pte_t pte) | ||
319 | { | ||
320 | return pte_set_flags(pte, _PAGE_SWP_SOFT_DIRTY); | ||
321 | } | ||
322 | |||
323 | static inline int pte_swp_soft_dirty(pte_t pte) | ||
324 | { | ||
325 | return pte_flags(pte) & _PAGE_SWP_SOFT_DIRTY; | ||
326 | } | ||
327 | |||
328 | static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) | ||
329 | { | ||
330 | return pte_clear_flags(pte, _PAGE_SWP_SOFT_DIRTY); | ||
331 | } | ||
332 | |||
333 | static inline pte_t pte_file_clear_soft_dirty(pte_t pte) | ||
334 | { | ||
335 | return pte_clear_flags(pte, _PAGE_SOFT_DIRTY); | ||
336 | } | ||
337 | |||
338 | static inline pte_t pte_file_mksoft_dirty(pte_t pte) | ||
339 | { | ||
340 | return pte_set_flags(pte, _PAGE_SOFT_DIRTY); | ||
341 | } | ||
342 | |||
343 | static inline int pte_file_soft_dirty(pte_t pte) | ||
344 | { | ||
345 | return pte_flags(pte) & _PAGE_SOFT_DIRTY; | ||
346 | } | ||
347 | |||
317 | /* | 348 | /* |
318 | * Mask out unsupported bits in a present pgprot. Non-present pgprots | 349 | * Mask out unsupported bits in a present pgprot. Non-present pgprots |
319 | * can use those bits for other purposes, so leave them be. | 350 | * can use those bits for other purposes, so leave them be. |
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index c98ac63aae48..f4843e031131 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h | |||
@@ -61,12 +61,27 @@ | |||
61 | * they do not conflict with each other. | 61 | * they do not conflict with each other. |
62 | */ | 62 | */ |
63 | 63 | ||
64 | #define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_HIDDEN | ||
65 | |||
64 | #ifdef CONFIG_MEM_SOFT_DIRTY | 66 | #ifdef CONFIG_MEM_SOFT_DIRTY |
65 | #define _PAGE_SOFT_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN) | 67 | #define _PAGE_SOFT_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_SOFT_DIRTY) |
66 | #else | 68 | #else |
67 | #define _PAGE_SOFT_DIRTY (_AT(pteval_t, 0)) | 69 | #define _PAGE_SOFT_DIRTY (_AT(pteval_t, 0)) |
68 | #endif | 70 | #endif |
69 | 71 | ||
72 | /* | ||
73 | * Tracking soft dirty bit when a page goes to a swap is tricky. | ||
74 | * We need a bit which can be stored in pte _and_ not conflict | ||
75 | * with swap entry format. On x86 bits 6 and 7 are *not* involved | ||
76 | * into swap entry computation, but bit 6 is used for nonlinear | ||
77 | * file mapping, so we borrow bit 7 for soft dirty tracking. | ||
78 | */ | ||
79 | #ifdef CONFIG_MEM_SOFT_DIRTY | ||
80 | #define _PAGE_SWP_SOFT_DIRTY _PAGE_PSE | ||
81 | #else | ||
82 | #define _PAGE_SWP_SOFT_DIRTY (_AT(pteval_t, 0)) | ||
83 | #endif | ||
84 | |||
70 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) | 85 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) |
71 | #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) | 86 | #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) |
72 | #else | 87 | #else |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 24cf5aefb704..987c75ecc334 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -412,7 +412,7 @@ union irq_stack_union { | |||
412 | }; | 412 | }; |
413 | }; | 413 | }; |
414 | 414 | ||
415 | DECLARE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union); | 415 | DECLARE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union) __visible; |
416 | DECLARE_INIT_PER_CPU(irq_stack_union); | 416 | DECLARE_INIT_PER_CPU(irq_stack_union); |
417 | 417 | ||
418 | DECLARE_PER_CPU(char *, irq_stack_ptr); | 418 | DECLARE_PER_CPU(char *, irq_stack_ptr); |
@@ -942,33 +942,19 @@ extern int set_tsc_mode(unsigned int val); | |||
942 | 942 | ||
943 | extern u16 amd_get_nb_id(int cpu); | 943 | extern u16 amd_get_nb_id(int cpu); |
944 | 944 | ||
945 | struct aperfmperf { | 945 | static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves) |
946 | u64 aperf, mperf; | ||
947 | }; | ||
948 | |||
949 | static inline void get_aperfmperf(struct aperfmperf *am) | ||
950 | { | 946 | { |
951 | WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_APERFMPERF)); | 947 | uint32_t base, eax, signature[3]; |
952 | |||
953 | rdmsrl(MSR_IA32_APERF, am->aperf); | ||
954 | rdmsrl(MSR_IA32_MPERF, am->mperf); | ||
955 | } | ||
956 | 948 | ||
957 | #define APERFMPERF_SHIFT 10 | 949 | for (base = 0x40000000; base < 0x40010000; base += 0x100) { |
950 | cpuid(base, &eax, &signature[0], &signature[1], &signature[2]); | ||
958 | 951 | ||
959 | static inline | 952 | if (!memcmp(sig, signature, 12) && |
960 | unsigned long calc_aperfmperf_ratio(struct aperfmperf *old, | 953 | (leaves == 0 || ((eax - base) >= leaves))) |
961 | struct aperfmperf *new) | 954 | return base; |
962 | { | 955 | } |
963 | u64 aperf = new->aperf - old->aperf; | ||
964 | u64 mperf = new->mperf - old->mperf; | ||
965 | unsigned long ratio = aperf; | ||
966 | |||
967 | mperf >>= APERFMPERF_SHIFT; | ||
968 | if (mperf) | ||
969 | ratio = div64_u64(aperf, mperf); | ||
970 | 956 | ||
971 | return ratio; | 957 | return 0; |
972 | } | 958 | } |
973 | 959 | ||
974 | extern unsigned long arch_align_stack(unsigned long sp); | 960 | extern unsigned long arch_align_stack(unsigned long sp); |
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index 109a9dd5d454..be8269b00e2a 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h | |||
@@ -93,7 +93,6 @@ unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, | |||
93 | 93 | ||
94 | struct pvclock_vsyscall_time_info { | 94 | struct pvclock_vsyscall_time_info { |
95 | struct pvclock_vcpu_time_info pvti; | 95 | struct pvclock_vcpu_time_info pvti; |
96 | u32 migrate_count; | ||
97 | } __attribute__((__aligned__(SMP_CACHE_BYTES))); | 96 | } __attribute__((__aligned__(SMP_CACHE_BYTES))); |
98 | 97 | ||
99 | #define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info) | 98 | #define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info) |
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index b7bf3505e1ec..347555492dad 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h | |||
@@ -6,6 +6,8 @@ | |||
6 | 6 | ||
7 | #define COMMAND_LINE_SIZE 2048 | 7 | #define COMMAND_LINE_SIZE 2048 |
8 | 8 | ||
9 | #include <linux/linkage.h> | ||
10 | |||
9 | #ifdef __i386__ | 11 | #ifdef __i386__ |
10 | 12 | ||
11 | #include <linux/pfn.h> | 13 | #include <linux/pfn.h> |
@@ -108,11 +110,11 @@ void *extend_brk(size_t size, size_t align); | |||
108 | extern void probe_roms(void); | 110 | extern void probe_roms(void); |
109 | #ifdef __i386__ | 111 | #ifdef __i386__ |
110 | 112 | ||
111 | void __init i386_start_kernel(void); | 113 | asmlinkage void __init i386_start_kernel(void); |
112 | 114 | ||
113 | #else | 115 | #else |
114 | void __init x86_64_start_kernel(char *real_mode); | 116 | asmlinkage void __init x86_64_start_kernel(char *real_mode); |
115 | void __init x86_64_start_reservations(char *real_mode_data); | 117 | asmlinkage void __init x86_64_start_reservations(char *real_mode_data); |
116 | 118 | ||
117 | #endif /* __i386__ */ | 119 | #endif /* __i386__ */ |
118 | #endif /* _SETUP */ | 120 | #endif /* _SETUP */ |
diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 2f4d924fe6c9..645cad2c95ff 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h | |||
@@ -101,7 +101,7 @@ static inline void native_wbinvd(void) | |||
101 | asm volatile("wbinvd": : :"memory"); | 101 | asm volatile("wbinvd": : :"memory"); |
102 | } | 102 | } |
103 | 103 | ||
104 | extern void native_load_gs_index(unsigned); | 104 | extern asmlinkage void native_load_gs_index(unsigned); |
105 | 105 | ||
106 | #ifdef CONFIG_PARAVIRT | 106 | #ifdef CONFIG_PARAVIRT |
107 | #include <asm/paravirt.h> | 107 | #include <asm/paravirt.h> |
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index 33692eaabab5..bf156ded74b5 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h | |||
@@ -1,11 +1,14 @@ | |||
1 | #ifndef _ASM_X86_SPINLOCK_H | 1 | #ifndef _ASM_X86_SPINLOCK_H |
2 | #define _ASM_X86_SPINLOCK_H | 2 | #define _ASM_X86_SPINLOCK_H |
3 | 3 | ||
4 | #include <linux/jump_label.h> | ||
4 | #include <linux/atomic.h> | 5 | #include <linux/atomic.h> |
5 | #include <asm/page.h> | 6 | #include <asm/page.h> |
6 | #include <asm/processor.h> | 7 | #include <asm/processor.h> |
7 | #include <linux/compiler.h> | 8 | #include <linux/compiler.h> |
8 | #include <asm/paravirt.h> | 9 | #include <asm/paravirt.h> |
10 | #include <asm/bitops.h> | ||
11 | |||
9 | /* | 12 | /* |
10 | * Your basic SMP spinlocks, allowing only a single CPU anywhere | 13 | * Your basic SMP spinlocks, allowing only a single CPU anywhere |
11 | * | 14 | * |
@@ -34,6 +37,36 @@ | |||
34 | # define UNLOCK_LOCK_PREFIX | 37 | # define UNLOCK_LOCK_PREFIX |
35 | #endif | 38 | #endif |
36 | 39 | ||
40 | /* How long a lock should spin before we consider blocking */ | ||
41 | #define SPIN_THRESHOLD (1 << 15) | ||
42 | |||
43 | extern struct static_key paravirt_ticketlocks_enabled; | ||
44 | static __always_inline bool static_key_false(struct static_key *key); | ||
45 | |||
46 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | ||
47 | |||
48 | static inline void __ticket_enter_slowpath(arch_spinlock_t *lock) | ||
49 | { | ||
50 | set_bit(0, (volatile unsigned long *)&lock->tickets.tail); | ||
51 | } | ||
52 | |||
53 | #else /* !CONFIG_PARAVIRT_SPINLOCKS */ | ||
54 | static __always_inline void __ticket_lock_spinning(arch_spinlock_t *lock, | ||
55 | __ticket_t ticket) | ||
56 | { | ||
57 | } | ||
58 | static inline void __ticket_unlock_kick(arch_spinlock_t *lock, | ||
59 | __ticket_t ticket) | ||
60 | { | ||
61 | } | ||
62 | |||
63 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ | ||
64 | |||
65 | static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock) | ||
66 | { | ||
67 | return lock.tickets.head == lock.tickets.tail; | ||
68 | } | ||
69 | |||
37 | /* | 70 | /* |
38 | * Ticket locks are conceptually two parts, one indicating the current head of | 71 | * Ticket locks are conceptually two parts, one indicating the current head of |
39 | * the queue, and the other indicating the current tail. The lock is acquired | 72 | * the queue, and the other indicating the current tail. The lock is acquired |
@@ -47,81 +80,101 @@ | |||
47 | * in the high part, because a wide xadd increment of the low part would carry | 80 | * in the high part, because a wide xadd increment of the low part would carry |
48 | * up and contaminate the high part. | 81 | * up and contaminate the high part. |
49 | */ | 82 | */ |
50 | static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock) | 83 | static __always_inline void arch_spin_lock(arch_spinlock_t *lock) |
51 | { | 84 | { |
52 | register struct __raw_tickets inc = { .tail = 1 }; | 85 | register struct __raw_tickets inc = { .tail = TICKET_LOCK_INC }; |
53 | 86 | ||
54 | inc = xadd(&lock->tickets, inc); | 87 | inc = xadd(&lock->tickets, inc); |
88 | if (likely(inc.head == inc.tail)) | ||
89 | goto out; | ||
55 | 90 | ||
91 | inc.tail &= ~TICKET_SLOWPATH_FLAG; | ||
56 | for (;;) { | 92 | for (;;) { |
57 | if (inc.head == inc.tail) | 93 | unsigned count = SPIN_THRESHOLD; |
58 | break; | 94 | |
59 | cpu_relax(); | 95 | do { |
60 | inc.head = ACCESS_ONCE(lock->tickets.head); | 96 | if (ACCESS_ONCE(lock->tickets.head) == inc.tail) |
97 | goto out; | ||
98 | cpu_relax(); | ||
99 | } while (--count); | ||
100 | __ticket_lock_spinning(lock, inc.tail); | ||
61 | } | 101 | } |
62 | barrier(); /* make sure nothing creeps before the lock is taken */ | 102 | out: barrier(); /* make sure nothing creeps before the lock is taken */ |
63 | } | 103 | } |
64 | 104 | ||
65 | static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock) | 105 | static __always_inline int arch_spin_trylock(arch_spinlock_t *lock) |
66 | { | 106 | { |
67 | arch_spinlock_t old, new; | 107 | arch_spinlock_t old, new; |
68 | 108 | ||
69 | old.tickets = ACCESS_ONCE(lock->tickets); | 109 | old.tickets = ACCESS_ONCE(lock->tickets); |
70 | if (old.tickets.head != old.tickets.tail) | 110 | if (old.tickets.head != (old.tickets.tail & ~TICKET_SLOWPATH_FLAG)) |
71 | return 0; | 111 | return 0; |
72 | 112 | ||
73 | new.head_tail = old.head_tail + (1 << TICKET_SHIFT); | 113 | new.head_tail = old.head_tail + (TICKET_LOCK_INC << TICKET_SHIFT); |
74 | 114 | ||
75 | /* cmpxchg is a full barrier, so nothing can move before it */ | 115 | /* cmpxchg is a full barrier, so nothing can move before it */ |
76 | return cmpxchg(&lock->head_tail, old.head_tail, new.head_tail) == old.head_tail; | 116 | return cmpxchg(&lock->head_tail, old.head_tail, new.head_tail) == old.head_tail; |
77 | } | 117 | } |
78 | 118 | ||
79 | static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock) | 119 | static inline void __ticket_unlock_slowpath(arch_spinlock_t *lock, |
120 | arch_spinlock_t old) | ||
80 | { | 121 | { |
81 | __add(&lock->tickets.head, 1, UNLOCK_LOCK_PREFIX); | 122 | arch_spinlock_t new; |
123 | |||
124 | BUILD_BUG_ON(((__ticket_t)NR_CPUS) != NR_CPUS); | ||
125 | |||
126 | /* Perform the unlock on the "before" copy */ | ||
127 | old.tickets.head += TICKET_LOCK_INC; | ||
128 | |||
129 | /* Clear the slowpath flag */ | ||
130 | new.head_tail = old.head_tail & ~(TICKET_SLOWPATH_FLAG << TICKET_SHIFT); | ||
131 | |||
132 | /* | ||
133 | * If the lock is uncontended, clear the flag - use cmpxchg in | ||
134 | * case it changes behind our back though. | ||
135 | */ | ||
136 | if (new.tickets.head != new.tickets.tail || | ||
137 | cmpxchg(&lock->head_tail, old.head_tail, | ||
138 | new.head_tail) != old.head_tail) { | ||
139 | /* | ||
140 | * Lock still has someone queued for it, so wake up an | ||
141 | * appropriate waiter. | ||
142 | */ | ||
143 | __ticket_unlock_kick(lock, old.tickets.head); | ||
144 | } | ||
82 | } | 145 | } |
83 | 146 | ||
84 | static inline int __ticket_spin_is_locked(arch_spinlock_t *lock) | 147 | static __always_inline void arch_spin_unlock(arch_spinlock_t *lock) |
85 | { | 148 | { |
86 | struct __raw_tickets tmp = ACCESS_ONCE(lock->tickets); | 149 | if (TICKET_SLOWPATH_FLAG && |
150 | static_key_false(¶virt_ticketlocks_enabled)) { | ||
151 | arch_spinlock_t prev; | ||
87 | 152 | ||
88 | return tmp.tail != tmp.head; | 153 | prev = *lock; |
89 | } | 154 | add_smp(&lock->tickets.head, TICKET_LOCK_INC); |
90 | 155 | ||
91 | static inline int __ticket_spin_is_contended(arch_spinlock_t *lock) | 156 | /* add_smp() is a full mb() */ |
92 | { | ||
93 | struct __raw_tickets tmp = ACCESS_ONCE(lock->tickets); | ||
94 | 157 | ||
95 | return (__ticket_t)(tmp.tail - tmp.head) > 1; | 158 | if (unlikely(lock->tickets.tail & TICKET_SLOWPATH_FLAG)) |
159 | __ticket_unlock_slowpath(lock, prev); | ||
160 | } else | ||
161 | __add(&lock->tickets.head, TICKET_LOCK_INC, UNLOCK_LOCK_PREFIX); | ||
96 | } | 162 | } |
97 | 163 | ||
98 | #ifndef CONFIG_PARAVIRT_SPINLOCKS | ||
99 | |||
100 | static inline int arch_spin_is_locked(arch_spinlock_t *lock) | 164 | static inline int arch_spin_is_locked(arch_spinlock_t *lock) |
101 | { | 165 | { |
102 | return __ticket_spin_is_locked(lock); | 166 | struct __raw_tickets tmp = ACCESS_ONCE(lock->tickets); |
103 | } | ||
104 | |||
105 | static inline int arch_spin_is_contended(arch_spinlock_t *lock) | ||
106 | { | ||
107 | return __ticket_spin_is_contended(lock); | ||
108 | } | ||
109 | #define arch_spin_is_contended arch_spin_is_contended | ||
110 | 167 | ||
111 | static __always_inline void arch_spin_lock(arch_spinlock_t *lock) | 168 | return tmp.tail != tmp.head; |
112 | { | ||
113 | __ticket_spin_lock(lock); | ||
114 | } | 169 | } |
115 | 170 | ||
116 | static __always_inline int arch_spin_trylock(arch_spinlock_t *lock) | 171 | static inline int arch_spin_is_contended(arch_spinlock_t *lock) |
117 | { | 172 | { |
118 | return __ticket_spin_trylock(lock); | 173 | struct __raw_tickets tmp = ACCESS_ONCE(lock->tickets); |
119 | } | ||
120 | 174 | ||
121 | static __always_inline void arch_spin_unlock(arch_spinlock_t *lock) | 175 | return (__ticket_t)(tmp.tail - tmp.head) > TICKET_LOCK_INC; |
122 | { | ||
123 | __ticket_spin_unlock(lock); | ||
124 | } | 176 | } |
177 | #define arch_spin_is_contended arch_spin_is_contended | ||
125 | 178 | ||
126 | static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock, | 179 | static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock, |
127 | unsigned long flags) | 180 | unsigned long flags) |
@@ -129,8 +182,6 @@ static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock, | |||
129 | arch_spin_lock(lock); | 182 | arch_spin_lock(lock); |
130 | } | 183 | } |
131 | 184 | ||
132 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ | ||
133 | |||
134 | static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) | 185 | static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) |
135 | { | 186 | { |
136 | while (arch_spin_is_locked(lock)) | 187 | while (arch_spin_is_locked(lock)) |
@@ -233,8 +284,4 @@ static inline void arch_write_unlock(arch_rwlock_t *rw) | |||
233 | #define arch_read_relax(lock) cpu_relax() | 284 | #define arch_read_relax(lock) cpu_relax() |
234 | #define arch_write_relax(lock) cpu_relax() | 285 | #define arch_write_relax(lock) cpu_relax() |
235 | 286 | ||
236 | /* The {read|write|spin}_lock() on x86 are full memory barriers. */ | ||
237 | static inline void smp_mb__after_lock(void) { } | ||
238 | #define ARCH_HAS_SMP_MB_AFTER_LOCK | ||
239 | |||
240 | #endif /* _ASM_X86_SPINLOCK_H */ | 287 | #endif /* _ASM_X86_SPINLOCK_H */ |
diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h index ad0ad07fc006..4f1bea19945b 100644 --- a/arch/x86/include/asm/spinlock_types.h +++ b/arch/x86/include/asm/spinlock_types.h | |||
@@ -1,13 +1,17 @@ | |||
1 | #ifndef _ASM_X86_SPINLOCK_TYPES_H | 1 | #ifndef _ASM_X86_SPINLOCK_TYPES_H |
2 | #define _ASM_X86_SPINLOCK_TYPES_H | 2 | #define _ASM_X86_SPINLOCK_TYPES_H |
3 | 3 | ||
4 | #ifndef __LINUX_SPINLOCK_TYPES_H | ||
5 | # error "please don't include this file directly" | ||
6 | #endif | ||
7 | |||
8 | #include <linux/types.h> | 4 | #include <linux/types.h> |
9 | 5 | ||
10 | #if (CONFIG_NR_CPUS < 256) | 6 | #ifdef CONFIG_PARAVIRT_SPINLOCKS |
7 | #define __TICKET_LOCK_INC 2 | ||
8 | #define TICKET_SLOWPATH_FLAG ((__ticket_t)1) | ||
9 | #else | ||
10 | #define __TICKET_LOCK_INC 1 | ||
11 | #define TICKET_SLOWPATH_FLAG ((__ticket_t)0) | ||
12 | #endif | ||
13 | |||
14 | #if (CONFIG_NR_CPUS < (256 / __TICKET_LOCK_INC)) | ||
11 | typedef u8 __ticket_t; | 15 | typedef u8 __ticket_t; |
12 | typedef u16 __ticketpair_t; | 16 | typedef u16 __ticketpair_t; |
13 | #else | 17 | #else |
@@ -15,6 +19,8 @@ typedef u16 __ticket_t; | |||
15 | typedef u32 __ticketpair_t; | 19 | typedef u32 __ticketpair_t; |
16 | #endif | 20 | #endif |
17 | 21 | ||
22 | #define TICKET_LOCK_INC ((__ticket_t)__TICKET_LOCK_INC) | ||
23 | |||
18 | #define TICKET_SHIFT (sizeof(__ticket_t) * 8) | 24 | #define TICKET_SHIFT (sizeof(__ticket_t) * 8) |
19 | 25 | ||
20 | typedef struct arch_spinlock { | 26 | typedef struct arch_spinlock { |
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h index 4ec45b3abba1..d7f3b3b78ac3 100644 --- a/arch/x86/include/asm/switch_to.h +++ b/arch/x86/include/asm/switch_to.h | |||
@@ -2,8 +2,8 @@ | |||
2 | #define _ASM_X86_SWITCH_TO_H | 2 | #define _ASM_X86_SWITCH_TO_H |
3 | 3 | ||
4 | struct task_struct; /* one of the stranger aspects of C forward declarations */ | 4 | struct task_struct; /* one of the stranger aspects of C forward declarations */ |
5 | struct task_struct *__switch_to(struct task_struct *prev, | 5 | __visible struct task_struct *__switch_to(struct task_struct *prev, |
6 | struct task_struct *next); | 6 | struct task_struct *next); |
7 | struct tss_struct; | 7 | struct tss_struct; |
8 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | 8 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, |
9 | struct tss_struct *tss); | 9 | struct tss_struct *tss); |
diff --git a/arch/x86/include/asm/sync_bitops.h b/arch/x86/include/asm/sync_bitops.h index 9d09b4073b60..05af3b31d522 100644 --- a/arch/x86/include/asm/sync_bitops.h +++ b/arch/x86/include/asm/sync_bitops.h | |||
@@ -26,9 +26,9 @@ | |||
26 | * Note that @nr may be almost arbitrarily large; this function is not | 26 | * Note that @nr may be almost arbitrarily large; this function is not |
27 | * restricted to acting on a single-word quantity. | 27 | * restricted to acting on a single-word quantity. |
28 | */ | 28 | */ |
29 | static inline void sync_set_bit(int nr, volatile unsigned long *addr) | 29 | static inline void sync_set_bit(long nr, volatile unsigned long *addr) |
30 | { | 30 | { |
31 | asm volatile("lock; btsl %1,%0" | 31 | asm volatile("lock; bts %1,%0" |
32 | : "+m" (ADDR) | 32 | : "+m" (ADDR) |
33 | : "Ir" (nr) | 33 | : "Ir" (nr) |
34 | : "memory"); | 34 | : "memory"); |
@@ -44,9 +44,9 @@ static inline void sync_set_bit(int nr, volatile unsigned long *addr) | |||
44 | * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() | 44 | * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() |
45 | * in order to ensure changes are visible on other processors. | 45 | * in order to ensure changes are visible on other processors. |
46 | */ | 46 | */ |
47 | static inline void sync_clear_bit(int nr, volatile unsigned long *addr) | 47 | static inline void sync_clear_bit(long nr, volatile unsigned long *addr) |
48 | { | 48 | { |
49 | asm volatile("lock; btrl %1,%0" | 49 | asm volatile("lock; btr %1,%0" |
50 | : "+m" (ADDR) | 50 | : "+m" (ADDR) |
51 | : "Ir" (nr) | 51 | : "Ir" (nr) |
52 | : "memory"); | 52 | : "memory"); |
@@ -61,9 +61,9 @@ static inline void sync_clear_bit(int nr, volatile unsigned long *addr) | |||
61 | * Note that @nr may be almost arbitrarily large; this function is not | 61 | * Note that @nr may be almost arbitrarily large; this function is not |
62 | * restricted to acting on a single-word quantity. | 62 | * restricted to acting on a single-word quantity. |
63 | */ | 63 | */ |
64 | static inline void sync_change_bit(int nr, volatile unsigned long *addr) | 64 | static inline void sync_change_bit(long nr, volatile unsigned long *addr) |
65 | { | 65 | { |
66 | asm volatile("lock; btcl %1,%0" | 66 | asm volatile("lock; btc %1,%0" |
67 | : "+m" (ADDR) | 67 | : "+m" (ADDR) |
68 | : "Ir" (nr) | 68 | : "Ir" (nr) |
69 | : "memory"); | 69 | : "memory"); |
@@ -77,11 +77,11 @@ static inline void sync_change_bit(int nr, volatile unsigned long *addr) | |||
77 | * This operation is atomic and cannot be reordered. | 77 | * This operation is atomic and cannot be reordered. |
78 | * It also implies a memory barrier. | 78 | * It also implies a memory barrier. |
79 | */ | 79 | */ |
80 | static inline int sync_test_and_set_bit(int nr, volatile unsigned long *addr) | 80 | static inline int sync_test_and_set_bit(long nr, volatile unsigned long *addr) |
81 | { | 81 | { |
82 | int oldbit; | 82 | int oldbit; |
83 | 83 | ||
84 | asm volatile("lock; btsl %2,%1\n\tsbbl %0,%0" | 84 | asm volatile("lock; bts %2,%1\n\tsbbl %0,%0" |
85 | : "=r" (oldbit), "+m" (ADDR) | 85 | : "=r" (oldbit), "+m" (ADDR) |
86 | : "Ir" (nr) : "memory"); | 86 | : "Ir" (nr) : "memory"); |
87 | return oldbit; | 87 | return oldbit; |
@@ -95,11 +95,11 @@ static inline int sync_test_and_set_bit(int nr, volatile unsigned long *addr) | |||
95 | * This operation is atomic and cannot be reordered. | 95 | * This operation is atomic and cannot be reordered. |
96 | * It also implies a memory barrier. | 96 | * It also implies a memory barrier. |
97 | */ | 97 | */ |
98 | static inline int sync_test_and_clear_bit(int nr, volatile unsigned long *addr) | 98 | static inline int sync_test_and_clear_bit(long nr, volatile unsigned long *addr) |
99 | { | 99 | { |
100 | int oldbit; | 100 | int oldbit; |
101 | 101 | ||
102 | asm volatile("lock; btrl %2,%1\n\tsbbl %0,%0" | 102 | asm volatile("lock; btr %2,%1\n\tsbbl %0,%0" |
103 | : "=r" (oldbit), "+m" (ADDR) | 103 | : "=r" (oldbit), "+m" (ADDR) |
104 | : "Ir" (nr) : "memory"); | 104 | : "Ir" (nr) : "memory"); |
105 | return oldbit; | 105 | return oldbit; |
@@ -113,11 +113,11 @@ static inline int sync_test_and_clear_bit(int nr, volatile unsigned long *addr) | |||
113 | * This operation is atomic and cannot be reordered. | 113 | * This operation is atomic and cannot be reordered. |
114 | * It also implies a memory barrier. | 114 | * It also implies a memory barrier. |
115 | */ | 115 | */ |
116 | static inline int sync_test_and_change_bit(int nr, volatile unsigned long *addr) | 116 | static inline int sync_test_and_change_bit(long nr, volatile unsigned long *addr) |
117 | { | 117 | { |
118 | int oldbit; | 118 | int oldbit; |
119 | 119 | ||
120 | asm volatile("lock; btcl %2,%1\n\tsbbl %0,%0" | 120 | asm volatile("lock; btc %2,%1\n\tsbbl %0,%0" |
121 | : "=r" (oldbit), "+m" (ADDR) | 121 | : "=r" (oldbit), "+m" (ADDR) |
122 | : "Ir" (nr) : "memory"); | 122 | : "Ir" (nr) : "memory"); |
123 | return oldbit; | 123 | return oldbit; |
diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h index 2e188d68397c..aea284b41312 100644 --- a/arch/x86/include/asm/syscall.h +++ b/arch/x86/include/asm/syscall.h | |||
@@ -20,7 +20,8 @@ | |||
20 | #include <asm/thread_info.h> /* for TS_COMPAT */ | 20 | #include <asm/thread_info.h> /* for TS_COMPAT */ |
21 | #include <asm/unistd.h> | 21 | #include <asm/unistd.h> |
22 | 22 | ||
23 | extern const unsigned long sys_call_table[]; | 23 | typedef void (*sys_call_ptr_t)(void); |
24 | extern const sys_call_ptr_t sys_call_table[]; | ||
24 | 25 | ||
25 | /* | 26 | /* |
26 | * Only the low 32 bits of orig_ax are meaningful, so we return int. | 27 | * Only the low 32 bits of orig_ax are meaningful, so we return int. |
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 2917a6452c49..592a6a672e07 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h | |||
@@ -24,7 +24,7 @@ asmlinkage long sys_iopl(unsigned int); | |||
24 | asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); | 24 | asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); |
25 | 25 | ||
26 | /* kernel/signal.c */ | 26 | /* kernel/signal.c */ |
27 | long sys_rt_sigreturn(void); | 27 | asmlinkage long sys_rt_sigreturn(void); |
28 | 28 | ||
29 | /* kernel/tls.c */ | 29 | /* kernel/tls.c */ |
30 | asmlinkage long sys_set_thread_area(struct user_desc __user *); | 30 | asmlinkage long sys_set_thread_area(struct user_desc __user *); |
@@ -34,7 +34,7 @@ asmlinkage long sys_get_thread_area(struct user_desc __user *); | |||
34 | #ifdef CONFIG_X86_32 | 34 | #ifdef CONFIG_X86_32 |
35 | 35 | ||
36 | /* kernel/signal.c */ | 36 | /* kernel/signal.c */ |
37 | unsigned long sys_sigreturn(void); | 37 | asmlinkage unsigned long sys_sigreturn(void); |
38 | 38 | ||
39 | /* kernel/vm86_32.c */ | 39 | /* kernel/vm86_32.c */ |
40 | asmlinkage long sys_vm86old(struct vm86_struct __user *); | 40 | asmlinkage long sys_vm86old(struct vm86_struct __user *); |
@@ -44,7 +44,7 @@ asmlinkage long sys_vm86(unsigned long, unsigned long); | |||
44 | 44 | ||
45 | /* X86_64 only */ | 45 | /* X86_64 only */ |
46 | /* kernel/process_64.c */ | 46 | /* kernel/process_64.c */ |
47 | long sys_arch_prctl(int, unsigned long); | 47 | asmlinkage long sys_arch_prctl(int, unsigned long); |
48 | 48 | ||
49 | /* kernel/sys_x86_64.c */ | 49 | /* kernel/sys_x86_64.c */ |
50 | asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long, | 50 | asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long, |
diff --git a/arch/x86/include/asm/sysfb.h b/arch/x86/include/asm/sysfb.h new file mode 100644 index 000000000000..2aeb3e25579c --- /dev/null +++ b/arch/x86/include/asm/sysfb.h | |||
@@ -0,0 +1,98 @@ | |||
1 | #ifndef _ARCH_X86_KERNEL_SYSFB_H | ||
2 | #define _ARCH_X86_KERNEL_SYSFB_H | ||
3 | |||
4 | /* | ||
5 | * Generic System Framebuffers on x86 | ||
6 | * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/platform_data/simplefb.h> | ||
16 | #include <linux/screen_info.h> | ||
17 | |||
18 | enum { | ||
19 | M_I17, /* 17-Inch iMac */ | ||
20 | M_I20, /* 20-Inch iMac */ | ||
21 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ | ||
22 | M_I24, /* 24-Inch iMac */ | ||
23 | M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ | ||
24 | M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ | ||
25 | M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ | ||
26 | M_MINI, /* Mac Mini */ | ||
27 | M_MINI_3_1, /* Mac Mini, 3,1th gen */ | ||
28 | M_MINI_4_1, /* Mac Mini, 4,1th gen */ | ||
29 | M_MB, /* MacBook */ | ||
30 | M_MB_2, /* MacBook, 2nd rev. */ | ||
31 | M_MB_3, /* MacBook, 3rd rev. */ | ||
32 | M_MB_5_1, /* MacBook, 5th rev. */ | ||
33 | M_MB_6_1, /* MacBook, 6th rev. */ | ||
34 | M_MB_7_1, /* MacBook, 7th rev. */ | ||
35 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ | ||
36 | M_MBA, /* MacBook Air */ | ||
37 | M_MBA_3, /* Macbook Air, 3rd rev */ | ||
38 | M_MBP, /* MacBook Pro */ | ||
39 | M_MBP_2, /* MacBook Pro 2nd gen */ | ||
40 | M_MBP_2_2, /* MacBook Pro 2,2nd gen */ | ||
41 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ | ||
42 | M_MBP_4, /* MacBook Pro, 4th gen */ | ||
43 | M_MBP_5_1, /* MacBook Pro, 5,1th gen */ | ||
44 | M_MBP_5_2, /* MacBook Pro, 5,2th gen */ | ||
45 | M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ | ||
46 | M_MBP_6_1, /* MacBook Pro, 6,1th gen */ | ||
47 | M_MBP_6_2, /* MacBook Pro, 6,2th gen */ | ||
48 | M_MBP_7_1, /* MacBook Pro, 7,1th gen */ | ||
49 | M_MBP_8_2, /* MacBook Pro, 8,2nd gen */ | ||
50 | M_UNKNOWN /* placeholder */ | ||
51 | }; | ||
52 | |||
53 | struct efifb_dmi_info { | ||
54 | char *optname; | ||
55 | unsigned long base; | ||
56 | int stride; | ||
57 | int width; | ||
58 | int height; | ||
59 | int flags; | ||
60 | }; | ||
61 | |||
62 | #ifdef CONFIG_EFI | ||
63 | |||
64 | extern struct efifb_dmi_info efifb_dmi_list[]; | ||
65 | void sysfb_apply_efi_quirks(void); | ||
66 | |||
67 | #else /* CONFIG_EFI */ | ||
68 | |||
69 | static inline void sysfb_apply_efi_quirks(void) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | #endif /* CONFIG_EFI */ | ||
74 | |||
75 | #ifdef CONFIG_X86_SYSFB | ||
76 | |||
77 | bool parse_mode(const struct screen_info *si, | ||
78 | struct simplefb_platform_data *mode); | ||
79 | int create_simplefb(const struct screen_info *si, | ||
80 | const struct simplefb_platform_data *mode); | ||
81 | |||
82 | #else /* CONFIG_X86_SYSFB */ | ||
83 | |||
84 | static inline bool parse_mode(const struct screen_info *si, | ||
85 | struct simplefb_platform_data *mode) | ||
86 | { | ||
87 | return false; | ||
88 | } | ||
89 | |||
90 | static inline int create_simplefb(const struct screen_info *si, | ||
91 | const struct simplefb_platform_data *mode) | ||
92 | { | ||
93 | return -EINVAL; | ||
94 | } | ||
95 | |||
96 | #endif /* CONFIG_X86_SYSFB */ | ||
97 | |||
98 | #endif /* _ARCH_X86_KERNEL_SYSFB_H */ | ||
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 095b21507b6a..d35f24e231cd 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
@@ -124,9 +124,6 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu); | |||
124 | #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) | 124 | #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) |
125 | #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) | 125 | #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) |
126 | #define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) | 126 | #define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) |
127 | |||
128 | /* indicates that pointers to the topology cpumask_t maps are valid */ | ||
129 | #define arch_provides_topology_pointers yes | ||
130 | #endif | 127 | #endif |
131 | 128 | ||
132 | static inline void arch_fix_phys_package_id(int num, u32 slot) | 129 | static inline void arch_fix_phys_package_id(int num, u32 slot) |
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 88eae2aec619..7036cb60cd87 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h | |||
@@ -6,11 +6,7 @@ | |||
6 | #include <asm/debugreg.h> | 6 | #include <asm/debugreg.h> |
7 | #include <asm/siginfo.h> /* TRAP_TRACE, ... */ | 7 | #include <asm/siginfo.h> /* TRAP_TRACE, ... */ |
8 | 8 | ||
9 | #ifdef CONFIG_X86_32 | 9 | #define dotraplinkage __visible |
10 | #define dotraplinkage | ||
11 | #else | ||
12 | #define dotraplinkage asmlinkage | ||
13 | #endif | ||
14 | 10 | ||
15 | asmlinkage void divide_error(void); | 11 | asmlinkage void divide_error(void); |
16 | asmlinkage void debug(void); | 12 | asmlinkage void debug(void); |
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index c91e8b9d588b..235be70d5bb4 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h | |||
@@ -49,6 +49,7 @@ extern void tsc_init(void); | |||
49 | extern void mark_tsc_unstable(char *reason); | 49 | extern void mark_tsc_unstable(char *reason); |
50 | extern int unsynchronized_tsc(void); | 50 | extern int unsynchronized_tsc(void); |
51 | extern int check_tsc_unstable(void); | 51 | extern int check_tsc_unstable(void); |
52 | extern int check_tsc_disabled(void); | ||
52 | extern unsigned long native_calibrate_tsc(void); | 53 | extern unsigned long native_calibrate_tsc(void); |
53 | 54 | ||
54 | extern int tsc_clocksource_reliable; | 55 | extern int tsc_clocksource_reliable; |
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 5ee26875baea..5838fa911aa0 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h | |||
@@ -153,16 +153,19 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) | |||
153 | * Careful: we have to cast the result to the type of the pointer | 153 | * Careful: we have to cast the result to the type of the pointer |
154 | * for sign reasons. | 154 | * for sign reasons. |
155 | * | 155 | * |
156 | * The use of %edx as the register specifier is a bit of a | 156 | * The use of _ASM_DX as the register specifier is a bit of a |
157 | * simplification, as gcc only cares about it as the starting point | 157 | * simplification, as gcc only cares about it as the starting point |
158 | * and not size: for a 64-bit value it will use %ecx:%edx on 32 bits | 158 | * and not size: for a 64-bit value it will use %ecx:%edx on 32 bits |
159 | * (%ecx being the next register in gcc's x86 register sequence), and | 159 | * (%ecx being the next register in gcc's x86 register sequence), and |
160 | * %rdx on 64 bits. | 160 | * %rdx on 64 bits. |
161 | * | ||
162 | * Clang/LLVM cares about the size of the register, but still wants | ||
163 | * the base register for something that ends up being a pair. | ||
161 | */ | 164 | */ |
162 | #define get_user(x, ptr) \ | 165 | #define get_user(x, ptr) \ |
163 | ({ \ | 166 | ({ \ |
164 | int __ret_gu; \ | 167 | int __ret_gu; \ |
165 | register __inttype(*(ptr)) __val_gu asm("%edx"); \ | 168 | register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ |
166 | __chk_user_ptr(ptr); \ | 169 | __chk_user_ptr(ptr); \ |
167 | might_fault(); \ | 170 | might_fault(); \ |
168 | asm volatile("call __get_user_%P3" \ | 171 | asm volatile("call __get_user_%P3" \ |
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index f3e01a2cbaa1..966502d4682e 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h | |||
@@ -387,6 +387,7 @@ enum vmcs_field { | |||
387 | #define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0 | 387 | #define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0 |
388 | #define VMX_EPT_EXTENT_CONTEXT 1 | 388 | #define VMX_EPT_EXTENT_CONTEXT 1 |
389 | #define VMX_EPT_EXTENT_GLOBAL 2 | 389 | #define VMX_EPT_EXTENT_GLOBAL 2 |
390 | #define VMX_EPT_EXTENT_SHIFT 24 | ||
390 | 391 | ||
391 | #define VMX_EPT_EXECUTE_ONLY_BIT (1ull) | 392 | #define VMX_EPT_EXECUTE_ONLY_BIT (1ull) |
392 | #define VMX_EPT_PAGE_WALK_4_BIT (1ull << 6) | 393 | #define VMX_EPT_PAGE_WALK_4_BIT (1ull << 6) |
@@ -394,6 +395,7 @@ enum vmcs_field { | |||
394 | #define VMX_EPTP_WB_BIT (1ull << 14) | 395 | #define VMX_EPTP_WB_BIT (1ull << 14) |
395 | #define VMX_EPT_2MB_PAGE_BIT (1ull << 16) | 396 | #define VMX_EPT_2MB_PAGE_BIT (1ull << 16) |
396 | #define VMX_EPT_1GB_PAGE_BIT (1ull << 17) | 397 | #define VMX_EPT_1GB_PAGE_BIT (1ull << 17) |
398 | #define VMX_EPT_INVEPT_BIT (1ull << 20) | ||
397 | #define VMX_EPT_AD_BIT (1ull << 21) | 399 | #define VMX_EPT_AD_BIT (1ull << 21) |
398 | #define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) | 400 | #define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) |
399 | #define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) | 401 | #define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) |
diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h index de656ac2af41..d76ac40da206 100644 --- a/arch/x86/include/asm/vvar.h +++ b/arch/x86/include/asm/vvar.h | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #define DEFINE_VVAR(type, name) \ | 36 | #define DEFINE_VVAR(type, name) \ |
37 | type name \ | 37 | type name \ |
38 | __attribute__((section(".vvar_" #name), aligned(16))) | 38 | __attribute__((section(".vvar_" #name), aligned(16))) __visible |
39 | 39 | ||
40 | #define VVAR(name) (*vvaraddr_ ## name) | 40 | #define VVAR(name) (*vvaraddr_ ## name) |
41 | 41 | ||
diff --git a/arch/x86/include/asm/xen/events.h b/arch/x86/include/asm/xen/events.h index ca842f2769ef..608a79d5a466 100644 --- a/arch/x86/include/asm/xen/events.h +++ b/arch/x86/include/asm/xen/events.h | |||
@@ -7,6 +7,7 @@ enum ipi_vector { | |||
7 | XEN_CALL_FUNCTION_SINGLE_VECTOR, | 7 | XEN_CALL_FUNCTION_SINGLE_VECTOR, |
8 | XEN_SPIN_UNLOCK_VECTOR, | 8 | XEN_SPIN_UNLOCK_VECTOR, |
9 | XEN_IRQ_WORK_VECTOR, | 9 | XEN_IRQ_WORK_VECTOR, |
10 | XEN_NMI_VECTOR, | ||
10 | 11 | ||
11 | XEN_NR_IPIS, | 12 | XEN_NR_IPIS, |
12 | }; | 13 | }; |
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index 125f344f06a9..d866959e5685 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h | |||
@@ -40,21 +40,7 @@ extern struct start_info *xen_start_info; | |||
40 | 40 | ||
41 | static inline uint32_t xen_cpuid_base(void) | 41 | static inline uint32_t xen_cpuid_base(void) |
42 | { | 42 | { |
43 | uint32_t base, eax, ebx, ecx, edx; | 43 | return hypervisor_cpuid_base("XenVMMXenVMM", 2); |
44 | char signature[13]; | ||
45 | |||
46 | for (base = 0x40000000; base < 0x40010000; base += 0x100) { | ||
47 | cpuid(base, &eax, &ebx, &ecx, &edx); | ||
48 | *(uint32_t *)(signature + 0) = ebx; | ||
49 | *(uint32_t *)(signature + 4) = ecx; | ||
50 | *(uint32_t *)(signature + 8) = edx; | ||
51 | signature[12] = 0; | ||
52 | |||
53 | if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2)) | ||
54 | return base; | ||
55 | } | ||
56 | |||
57 | return 0; | ||
58 | } | 44 | } |
59 | 45 | ||
60 | #ifdef CONFIG_XEN | 46 | #ifdef CONFIG_XEN |
diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 06fdbd987e97..94dc8ca434e0 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #define KVM_FEATURE_ASYNC_PF 4 | 23 | #define KVM_FEATURE_ASYNC_PF 4 |
24 | #define KVM_FEATURE_STEAL_TIME 5 | 24 | #define KVM_FEATURE_STEAL_TIME 5 |
25 | #define KVM_FEATURE_PV_EOI 6 | 25 | #define KVM_FEATURE_PV_EOI 6 |
26 | #define KVM_FEATURE_PV_UNHALT 7 | ||
26 | 27 | ||
27 | /* The last 8 bits are used to indicate how to interpret the flags field | 28 | /* The last 8 bits are used to indicate how to interpret the flags field |
28 | * in pvclock structure. If no bits are set, all flags are ignored. | 29 | * in pvclock structure. If no bits are set, all flags are ignored. |
diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index d651082c7cf7..0e79420376eb 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h | |||
@@ -65,6 +65,7 @@ | |||
65 | #define EXIT_REASON_EOI_INDUCED 45 | 65 | #define EXIT_REASON_EOI_INDUCED 45 |
66 | #define EXIT_REASON_EPT_VIOLATION 48 | 66 | #define EXIT_REASON_EPT_VIOLATION 48 |
67 | #define EXIT_REASON_EPT_MISCONFIG 49 | 67 | #define EXIT_REASON_EPT_MISCONFIG 49 |
68 | #define EXIT_REASON_INVEPT 50 | ||
68 | #define EXIT_REASON_PREEMPTION_TIMER 52 | 69 | #define EXIT_REASON_PREEMPTION_TIMER 52 |
69 | #define EXIT_REASON_WBINVD 54 | 70 | #define EXIT_REASON_WBINVD 54 |
70 | #define EXIT_REASON_XSETBV 55 | 71 | #define EXIT_REASON_XSETBV 55 |
@@ -106,12 +107,13 @@ | |||
106 | { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \ | 107 | { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \ |
107 | { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \ | 108 | { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \ |
108 | { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \ | 109 | { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \ |
110 | { EXIT_REASON_INVEPT, "INVEPT" }, \ | ||
111 | { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, \ | ||
109 | { EXIT_REASON_WBINVD, "WBINVD" }, \ | 112 | { EXIT_REASON_WBINVD, "WBINVD" }, \ |
110 | { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, \ | 113 | { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, \ |
111 | { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \ | 114 | { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \ |
112 | { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ | 115 | { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ |
113 | { EXIT_REASON_INVD, "INVD" }, \ | 116 | { EXIT_REASON_INVD, "INVD" }, \ |
114 | { EXIT_REASON_INVPCID, "INVPCID" }, \ | 117 | { EXIT_REASON_INVPCID, "INVPCID" } |
115 | { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" } | ||
116 | 118 | ||
117 | #endif /* _UAPIVMX_H */ | 119 | #endif /* _UAPIVMX_H */ |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 88d99ea77723..a5408b965c9d 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -103,6 +103,9 @@ obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o | |||
103 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o | 103 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o |
104 | obj-$(CONFIG_OF) += devicetree.o | 104 | obj-$(CONFIG_OF) += devicetree.o |
105 | obj-$(CONFIG_UPROBES) += uprobes.o | 105 | obj-$(CONFIG_UPROBES) += uprobes.o |
106 | obj-y += sysfb.o | ||
107 | obj-$(CONFIG_X86_SYSFB) += sysfb_simplefb.o | ||
108 | obj-$(CONFIG_EFI) += sysfb_efi.o | ||
106 | 109 | ||
107 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o | 110 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o |
108 | obj-$(CONFIG_TRACING) += tracepoint.o | 111 | obj-$(CONFIG_TRACING) += tracepoint.o |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 2627a81253ee..40c76604199f 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -67,6 +67,7 @@ EXPORT_SYMBOL(acpi_pci_disabled); | |||
67 | int acpi_lapic; | 67 | int acpi_lapic; |
68 | int acpi_ioapic; | 68 | int acpi_ioapic; |
69 | int acpi_strict; | 69 | int acpi_strict; |
70 | int acpi_disable_cmcff; | ||
70 | 71 | ||
71 | u8 acpi_sci_flags __initdata; | 72 | u8 acpi_sci_flags __initdata; |
72 | int acpi_sci_override_gsi __initdata; | 73 | int acpi_sci_override_gsi __initdata; |
@@ -141,16 +142,8 @@ static u32 irq_to_gsi(int irq) | |||
141 | } | 142 | } |
142 | 143 | ||
143 | /* | 144 | /* |
144 | * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, | 145 | * This is just a simple wrapper around early_ioremap(), |
145 | * to map the target physical address. The problem is that set_fixmap() | 146 | * with sanity checks for phys == 0 and size == 0. |
146 | * provides a single page, and it is possible that the page is not | ||
147 | * sufficient. | ||
148 | * By using this area, we can map up to MAX_IO_APICS pages temporarily, | ||
149 | * i.e. until the next __va_range() call. | ||
150 | * | ||
151 | * Important Safety Note: The fixed I/O APIC page numbers are *subtracted* | ||
152 | * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and | ||
153 | * count idx down while incrementing the phys address. | ||
154 | */ | 147 | */ |
155 | char *__init __acpi_map_table(unsigned long phys, unsigned long size) | 148 | char *__init __acpi_map_table(unsigned long phys, unsigned long size) |
156 | { | 149 | { |
@@ -160,6 +153,7 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size) | |||
160 | 153 | ||
161 | return early_ioremap(phys, size); | 154 | return early_ioremap(phys, size); |
162 | } | 155 | } |
156 | |||
163 | void __init __acpi_unmap_table(char *map, unsigned long size) | 157 | void __init __acpi_unmap_table(char *map, unsigned long size) |
164 | { | 158 | { |
165 | if (!map || !size) | 159 | if (!map || !size) |
@@ -199,7 +193,7 @@ static void acpi_register_lapic(int id, u8 enabled) | |||
199 | { | 193 | { |
200 | unsigned int ver = 0; | 194 | unsigned int ver = 0; |
201 | 195 | ||
202 | if (id >= (MAX_LOCAL_APIC-1)) { | 196 | if (id >= MAX_LOCAL_APIC) { |
203 | printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); | 197 | printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); |
204 | return; | 198 | return; |
205 | } | 199 | } |
@@ -1120,6 +1114,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | |||
1120 | int ioapic; | 1114 | int ioapic; |
1121 | int ioapic_pin; | 1115 | int ioapic_pin; |
1122 | struct io_apic_irq_attr irq_attr; | 1116 | struct io_apic_irq_attr irq_attr; |
1117 | int ret; | ||
1123 | 1118 | ||
1124 | if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) | 1119 | if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) |
1125 | return gsi; | 1120 | return gsi; |
@@ -1149,7 +1144,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | |||
1149 | set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, | 1144 | set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, |
1150 | trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, | 1145 | trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, |
1151 | polarity == ACPI_ACTIVE_HIGH ? 0 : 1); | 1146 | polarity == ACPI_ACTIVE_HIGH ? 0 : 1); |
1152 | io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); | 1147 | ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); |
1148 | if (ret < 0) | ||
1149 | gsi = INT_MIN; | ||
1153 | 1150 | ||
1154 | return gsi; | 1151 | return gsi; |
1155 | } | 1152 | } |
@@ -1626,6 +1623,10 @@ static int __init parse_acpi(char *arg) | |||
1626 | /* "acpi=copy_dsdt" copys DSDT */ | 1623 | /* "acpi=copy_dsdt" copys DSDT */ |
1627 | else if (strcmp(arg, "copy_dsdt") == 0) { | 1624 | else if (strcmp(arg, "copy_dsdt") == 0) { |
1628 | acpi_gbl_copy_dsdt_locally = 1; | 1625 | acpi_gbl_copy_dsdt_locally = 1; |
1626 | } | ||
1627 | /* "acpi=nocmcff" disables FF mode for corrected errors */ | ||
1628 | else if (strcmp(arg, "nocmcff") == 0) { | ||
1629 | acpi_disable_cmcff = 1; | ||
1629 | } else { | 1630 | } else { |
1630 | /* Core will printk when we return error. */ | 1631 | /* Core will printk when we return error. */ |
1631 | return -EINVAL; | 1632 | return -EINVAL; |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index c15cf9a25e27..15e8563e5c24 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/memory.h> | 11 | #include <linux/memory.h> |
12 | #include <linux/stop_machine.h> | 12 | #include <linux/stop_machine.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/kdebug.h> | ||
14 | #include <asm/alternative.h> | 15 | #include <asm/alternative.h> |
15 | #include <asm/sections.h> | 16 | #include <asm/sections.h> |
16 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
@@ -596,97 +597,93 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len) | |||
596 | return addr; | 597 | return addr; |
597 | } | 598 | } |
598 | 599 | ||
599 | /* | 600 | static void do_sync_core(void *info) |
600 | * Cross-modifying kernel text with stop_machine(). | 601 | { |
601 | * This code originally comes from immediate value. | 602 | sync_core(); |
602 | */ | 603 | } |
603 | static atomic_t stop_machine_first; | ||
604 | static int wrote_text; | ||
605 | 604 | ||
606 | struct text_poke_params { | 605 | static bool bp_patching_in_progress; |
607 | struct text_poke_param *params; | 606 | static void *bp_int3_handler, *bp_int3_addr; |
608 | int nparams; | ||
609 | }; | ||
610 | 607 | ||
611 | static int __kprobes stop_machine_text_poke(void *data) | 608 | int poke_int3_handler(struct pt_regs *regs) |
612 | { | 609 | { |
613 | struct text_poke_params *tpp = data; | 610 | /* bp_patching_in_progress */ |
614 | struct text_poke_param *p; | 611 | smp_rmb(); |
615 | int i; | ||
616 | 612 | ||
617 | if (atomic_xchg(&stop_machine_first, 0)) { | 613 | if (likely(!bp_patching_in_progress)) |
618 | for (i = 0; i < tpp->nparams; i++) { | 614 | return 0; |
619 | p = &tpp->params[i]; | ||
620 | text_poke(p->addr, p->opcode, p->len); | ||
621 | } | ||
622 | smp_wmb(); /* Make sure other cpus see that this has run */ | ||
623 | wrote_text = 1; | ||
624 | } else { | ||
625 | while (!wrote_text) | ||
626 | cpu_relax(); | ||
627 | smp_mb(); /* Load wrote_text before following execution */ | ||
628 | } | ||
629 | 615 | ||
630 | for (i = 0; i < tpp->nparams; i++) { | 616 | if (user_mode_vm(regs) || regs->ip != (unsigned long)bp_int3_addr) |
631 | p = &tpp->params[i]; | 617 | return 0; |
632 | flush_icache_range((unsigned long)p->addr, | 618 | |
633 | (unsigned long)p->addr + p->len); | 619 | /* set up the specified breakpoint handler */ |
634 | } | 620 | regs->ip = (unsigned long) bp_int3_handler; |
635 | /* | 621 | |
636 | * Intel Archiecture Software Developer's Manual section 7.1.3 specifies | 622 | return 1; |
637 | * that a core serializing instruction such as "cpuid" should be | ||
638 | * executed on _each_ core before the new instruction is made visible. | ||
639 | */ | ||
640 | sync_core(); | ||
641 | return 0; | ||
642 | } | ||
643 | 623 | ||
644 | /** | ||
645 | * text_poke_smp - Update instructions on a live kernel on SMP | ||
646 | * @addr: address to modify | ||
647 | * @opcode: source of the copy | ||
648 | * @len: length to copy | ||
649 | * | ||
650 | * Modify multi-byte instruction by using stop_machine() on SMP. This allows | ||
651 | * user to poke/set multi-byte text on SMP. Only non-NMI/MCE code modifying | ||
652 | * should be allowed, since stop_machine() does _not_ protect code against | ||
653 | * NMI and MCE. | ||
654 | * | ||
655 | * Note: Must be called under get_online_cpus() and text_mutex. | ||
656 | */ | ||
657 | void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len) | ||
658 | { | ||
659 | struct text_poke_params tpp; | ||
660 | struct text_poke_param p; | ||
661 | |||
662 | p.addr = addr; | ||
663 | p.opcode = opcode; | ||
664 | p.len = len; | ||
665 | tpp.params = &p; | ||
666 | tpp.nparams = 1; | ||
667 | atomic_set(&stop_machine_first, 1); | ||
668 | wrote_text = 0; | ||
669 | /* Use __stop_machine() because the caller already got online_cpus. */ | ||
670 | __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask); | ||
671 | return addr; | ||
672 | } | 624 | } |
673 | 625 | ||
674 | /** | 626 | /** |
675 | * text_poke_smp_batch - Update instructions on a live kernel on SMP | 627 | * text_poke_bp() -- update instructions on live kernel on SMP |
676 | * @params: an array of text_poke parameters | 628 | * @addr: address to patch |
677 | * @n: the number of elements in params. | 629 | * @opcode: opcode of new instruction |
630 | * @len: length to copy | ||
631 | * @handler: address to jump to when the temporary breakpoint is hit | ||
678 | * | 632 | * |
679 | * Modify multi-byte instruction by using stop_machine() on SMP. Since the | 633 | * Modify multi-byte instruction by using int3 breakpoint on SMP. |
680 | * stop_machine() is heavy task, it is better to aggregate text_poke requests | 634 | * We completely avoid stop_machine() here, and achieve the |
681 | * and do it once if possible. | 635 | * synchronization using int3 breakpoint. |
682 | * | 636 | * |
683 | * Note: Must be called under get_online_cpus() and text_mutex. | 637 | * The way it is done: |
638 | * - add a int3 trap to the address that will be patched | ||
639 | * - sync cores | ||
640 | * - update all but the first byte of the patched range | ||
641 | * - sync cores | ||
642 | * - replace the first byte (int3) by the first byte of | ||
643 | * replacing opcode | ||
644 | * - sync cores | ||
645 | * | ||
646 | * Note: must be called under text_mutex. | ||
684 | */ | 647 | */ |
685 | void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n) | 648 | void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler) |
686 | { | 649 | { |
687 | struct text_poke_params tpp = {.params = params, .nparams = n}; | 650 | unsigned char int3 = 0xcc; |
651 | |||
652 | bp_int3_handler = handler; | ||
653 | bp_int3_addr = (u8 *)addr + sizeof(int3); | ||
654 | bp_patching_in_progress = true; | ||
655 | /* | ||
656 | * Corresponding read barrier in int3 notifier for | ||
657 | * making sure the in_progress flags is correctly ordered wrt. | ||
658 | * patching | ||
659 | */ | ||
660 | smp_wmb(); | ||
661 | |||
662 | text_poke(addr, &int3, sizeof(int3)); | ||
688 | 663 | ||
689 | atomic_set(&stop_machine_first, 1); | 664 | on_each_cpu(do_sync_core, NULL, 1); |
690 | wrote_text = 0; | 665 | |
691 | __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask); | 666 | if (len - sizeof(int3) > 0) { |
667 | /* patch all but the first byte */ | ||
668 | text_poke((char *)addr + sizeof(int3), | ||
669 | (const char *) opcode + sizeof(int3), | ||
670 | len - sizeof(int3)); | ||
671 | /* | ||
672 | * According to Intel, this core syncing is very likely | ||
673 | * not necessary and we'd be safe even without it. But | ||
674 | * better safe than sorry (plus there's not only Intel). | ||
675 | */ | ||
676 | on_each_cpu(do_sync_core, NULL, 1); | ||
677 | } | ||
678 | |||
679 | /* patch the first byte */ | ||
680 | text_poke(addr, opcode, sizeof(int3)); | ||
681 | |||
682 | on_each_cpu(do_sync_core, NULL, 1); | ||
683 | |||
684 | bp_patching_in_progress = false; | ||
685 | smp_wmb(); | ||
686 | |||
687 | return addr; | ||
692 | } | 688 | } |
689 | |||
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 3048ded1b598..59554dca96ec 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c | |||
@@ -20,6 +20,7 @@ const struct pci_device_id amd_nb_misc_ids[] = { | |||
20 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, | 20 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, |
21 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, | 21 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, |
22 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) }, | 22 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) }, |
23 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) }, | ||
23 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, | 24 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, |
24 | {} | 25 | {} |
25 | }; | 26 | }; |
@@ -27,6 +28,7 @@ EXPORT_SYMBOL(amd_nb_misc_ids); | |||
27 | 28 | ||
28 | static const struct pci_device_id amd_nb_link_ids[] = { | 29 | static const struct pci_device_id amd_nb_link_ids[] = { |
29 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, | 30 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, |
31 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) }, | ||
30 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, | 32 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, |
31 | {} | 33 | {} |
32 | }; | 34 | }; |
@@ -81,13 +83,20 @@ int amd_cache_northbridges(void) | |||
81 | next_northbridge(misc, amd_nb_misc_ids); | 83 | next_northbridge(misc, amd_nb_misc_ids); |
82 | node_to_amd_nb(i)->link = link = | 84 | node_to_amd_nb(i)->link = link = |
83 | next_northbridge(link, amd_nb_link_ids); | 85 | next_northbridge(link, amd_nb_link_ids); |
84 | } | 86 | } |
85 | 87 | ||
88 | /* GART present only on Fam15h upto model 0fh */ | ||
86 | if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 || | 89 | if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 || |
87 | boot_cpu_data.x86 == 0x15) | 90 | (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model < 0x10)) |
88 | amd_northbridges.flags |= AMD_NB_GART; | 91 | amd_northbridges.flags |= AMD_NB_GART; |
89 | 92 | ||
90 | /* | 93 | /* |
94 | * Check for L3 cache presence. | ||
95 | */ | ||
96 | if (!cpuid_edx(0x80000006)) | ||
97 | return 0; | ||
98 | |||
99 | /* | ||
91 | * Some CPU families support L3 Cache Index Disable. There are some | 100 | * Some CPU families support L3 Cache Index Disable. There are some |
92 | * limitations because of E382 and E388 on family 0x10. | 101 | * limitations because of E382 and E388 on family 0x10. |
93 | */ | 102 | */ |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index eca89c53a7f5..a7eb82d9b012 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -913,7 +913,7 @@ static void local_apic_timer_interrupt(void) | |||
913 | * [ if a single-CPU system runs an SMP kernel then we call the local | 913 | * [ if a single-CPU system runs an SMP kernel then we call the local |
914 | * interrupt as well. Thus we cannot inline the local irq ... ] | 914 | * interrupt as well. Thus we cannot inline the local irq ... ] |
915 | */ | 915 | */ |
916 | void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) | 916 | __visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) |
917 | { | 917 | { |
918 | struct pt_regs *old_regs = set_irq_regs(regs); | 918 | struct pt_regs *old_regs = set_irq_regs(regs); |
919 | 919 | ||
@@ -932,7 +932,7 @@ void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) | |||
932 | set_irq_regs(old_regs); | 932 | set_irq_regs(old_regs); |
933 | } | 933 | } |
934 | 934 | ||
935 | void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs) | 935 | __visible void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs) |
936 | { | 936 | { |
937 | struct pt_regs *old_regs = set_irq_regs(regs); | 937 | struct pt_regs *old_regs = set_irq_regs(regs); |
938 | 938 | ||
@@ -1946,14 +1946,14 @@ static inline void __smp_spurious_interrupt(void) | |||
1946 | "should never happen.\n", smp_processor_id()); | 1946 | "should never happen.\n", smp_processor_id()); |
1947 | } | 1947 | } |
1948 | 1948 | ||
1949 | void smp_spurious_interrupt(struct pt_regs *regs) | 1949 | __visible void smp_spurious_interrupt(struct pt_regs *regs) |
1950 | { | 1950 | { |
1951 | entering_irq(); | 1951 | entering_irq(); |
1952 | __smp_spurious_interrupt(); | 1952 | __smp_spurious_interrupt(); |
1953 | exiting_irq(); | 1953 | exiting_irq(); |
1954 | } | 1954 | } |
1955 | 1955 | ||
1956 | void smp_trace_spurious_interrupt(struct pt_regs *regs) | 1956 | __visible void smp_trace_spurious_interrupt(struct pt_regs *regs) |
1957 | { | 1957 | { |
1958 | entering_irq(); | 1958 | entering_irq(); |
1959 | trace_spurious_apic_entry(SPURIOUS_APIC_VECTOR); | 1959 | trace_spurious_apic_entry(SPURIOUS_APIC_VECTOR); |
@@ -2002,14 +2002,14 @@ static inline void __smp_error_interrupt(struct pt_regs *regs) | |||
2002 | 2002 | ||
2003 | } | 2003 | } |
2004 | 2004 | ||
2005 | void smp_error_interrupt(struct pt_regs *regs) | 2005 | __visible void smp_error_interrupt(struct pt_regs *regs) |
2006 | { | 2006 | { |
2007 | entering_irq(); | 2007 | entering_irq(); |
2008 | __smp_error_interrupt(regs); | 2008 | __smp_error_interrupt(regs); |
2009 | exiting_irq(); | 2009 | exiting_irq(); |
2010 | } | 2010 | } |
2011 | 2011 | ||
2012 | void smp_trace_error_interrupt(struct pt_regs *regs) | 2012 | __visible void smp_trace_error_interrupt(struct pt_regs *regs) |
2013 | { | 2013 | { |
2014 | entering_irq(); | 2014 | entering_irq(); |
2015 | trace_error_apic_entry(ERROR_APIC_VECTOR); | 2015 | trace_error_apic_entry(ERROR_APIC_VECTOR); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 9ed796ccc32c..e63a5bd2a78f 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1534,6 +1534,11 @@ void intel_ir_io_apic_print_entries(unsigned int apic, | |||
1534 | } | 1534 | } |
1535 | } | 1535 | } |
1536 | 1536 | ||
1537 | void ioapic_zap_locks(void) | ||
1538 | { | ||
1539 | raw_spin_lock_init(&ioapic_lock); | ||
1540 | } | ||
1541 | |||
1537 | __apicdebuginit(void) print_IO_APIC(int ioapic_idx) | 1542 | __apicdebuginit(void) print_IO_APIC(int ioapic_idx) |
1538 | { | 1543 | { |
1539 | union IO_APIC_reg_00 reg_00; | 1544 | union IO_APIC_reg_00 reg_00; |
@@ -3375,12 +3380,15 @@ int io_apic_setup_irq_pin_once(unsigned int irq, int node, | |||
3375 | { | 3380 | { |
3376 | unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin; | 3381 | unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin; |
3377 | int ret; | 3382 | int ret; |
3383 | struct IO_APIC_route_entry orig_entry; | ||
3378 | 3384 | ||
3379 | /* Avoid redundant programming */ | 3385 | /* Avoid redundant programming */ |
3380 | if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) { | 3386 | if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) { |
3381 | pr_debug("Pin %d-%d already programmed\n", | 3387 | pr_debug("Pin %d-%d already programmed\n", mpc_ioapic_id(ioapic_idx), pin); |
3382 | mpc_ioapic_id(ioapic_idx), pin); | 3388 | orig_entry = ioapic_read_entry(attr->ioapic, pin); |
3383 | return 0; | 3389 | if (attr->trigger == orig_entry.trigger && attr->polarity == orig_entry.polarity) |
3390 | return 0; | ||
3391 | return -EBUSY; | ||
3384 | } | 3392 | } |
3385 | ret = io_apic_setup_irq_pin(irq, node, attr); | 3393 | ret = io_apic_setup_irq_pin(irq, node, attr); |
3386 | if (!ret) | 3394 | if (!ret) |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 53a4e2744846..3ab03430211d 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
@@ -392,7 +392,7 @@ static struct cpuidle_device apm_cpuidle_device; | |||
392 | /* | 392 | /* |
393 | * Local variables | 393 | * Local variables |
394 | */ | 394 | */ |
395 | static struct { | 395 | __visible struct { |
396 | unsigned long offset; | 396 | unsigned long offset; |
397 | unsigned short segment; | 397 | unsigned short segment; |
398 | } apm_bios_entry; | 398 | } apm_bios_entry; |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f654ecefea5b..903a264af981 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -66,8 +66,8 @@ static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | |||
66 | * performance at the same time.. | 66 | * performance at the same time.. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | extern void vide(void); | 69 | extern __visible void vide(void); |
70 | __asm__(".align 4\nvide: ret"); | 70 | __asm__(".globl vide\n\t.align 4\nvide: ret"); |
71 | 71 | ||
72 | static void init_amd_k5(struct cpuinfo_x86 *c) | 72 | static void init_amd_k5(struct cpuinfo_x86 *c) |
73 | { | 73 | { |
@@ -512,7 +512,7 @@ static void early_init_amd(struct cpuinfo_x86 *c) | |||
512 | 512 | ||
513 | static const int amd_erratum_383[]; | 513 | static const int amd_erratum_383[]; |
514 | static const int amd_erratum_400[]; | 514 | static const int amd_erratum_400[]; |
515 | static bool cpu_has_amd_erratum(const int *erratum); | 515 | static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); |
516 | 516 | ||
517 | static void init_amd(struct cpuinfo_x86 *c) | 517 | static void init_amd(struct cpuinfo_x86 *c) |
518 | { | 518 | { |
@@ -729,11 +729,11 @@ static void init_amd(struct cpuinfo_x86 *c) | |||
729 | value &= ~(1ULL << 24); | 729 | value &= ~(1ULL << 24); |
730 | wrmsrl_safe(MSR_AMD64_BU_CFG2, value); | 730 | wrmsrl_safe(MSR_AMD64_BU_CFG2, value); |
731 | 731 | ||
732 | if (cpu_has_amd_erratum(amd_erratum_383)) | 732 | if (cpu_has_amd_erratum(c, amd_erratum_383)) |
733 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); | 733 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); |
734 | } | 734 | } |
735 | 735 | ||
736 | if (cpu_has_amd_erratum(amd_erratum_400)) | 736 | if (cpu_has_amd_erratum(c, amd_erratum_400)) |
737 | set_cpu_bug(c, X86_BUG_AMD_APIC_C1E); | 737 | set_cpu_bug(c, X86_BUG_AMD_APIC_C1E); |
738 | 738 | ||
739 | rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); | 739 | rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); |
@@ -878,23 +878,13 @@ static const int amd_erratum_400[] = | |||
878 | static const int amd_erratum_383[] = | 878 | static const int amd_erratum_383[] = |
879 | AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); | 879 | AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); |
880 | 880 | ||
881 | static bool cpu_has_amd_erratum(const int *erratum) | 881 | |
882 | static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) | ||
882 | { | 883 | { |
883 | struct cpuinfo_x86 *cpu = __this_cpu_ptr(&cpu_info); | ||
884 | int osvw_id = *erratum++; | 884 | int osvw_id = *erratum++; |
885 | u32 range; | 885 | u32 range; |
886 | u32 ms; | 886 | u32 ms; |
887 | 887 | ||
888 | /* | ||
889 | * If called early enough that current_cpu_data hasn't been initialized | ||
890 | * yet, fall back to boot_cpu_data. | ||
891 | */ | ||
892 | if (cpu->x86 == 0) | ||
893 | cpu = &boot_cpu_data; | ||
894 | |||
895 | if (cpu->x86_vendor != X86_VENDOR_AMD) | ||
896 | return false; | ||
897 | |||
898 | if (osvw_id >= 0 && osvw_id < 65536 && | 888 | if (osvw_id >= 0 && osvw_id < 65536 && |
899 | cpu_has(cpu, X86_FEATURE_OSVW)) { | 889 | cpu_has(cpu, X86_FEATURE_OSVW)) { |
900 | u64 osvw_len; | 890 | u64 osvw_len; |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 25eb2747b063..2793d1f095a2 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -1076,7 +1076,7 @@ struct desc_ptr debug_idt_descr = { NR_VECTORS * 16 - 1, | |||
1076 | (unsigned long) debug_idt_table }; | 1076 | (unsigned long) debug_idt_table }; |
1077 | 1077 | ||
1078 | DEFINE_PER_CPU_FIRST(union irq_stack_union, | 1078 | DEFINE_PER_CPU_FIRST(union irq_stack_union, |
1079 | irq_stack_union) __aligned(PAGE_SIZE); | 1079 | irq_stack_union) __aligned(PAGE_SIZE) __visible; |
1080 | 1080 | ||
1081 | /* | 1081 | /* |
1082 | * The following four percpu variables are hot. Align current_task to | 1082 | * The following four percpu variables are hot. Align current_task to |
@@ -1093,7 +1093,7 @@ EXPORT_PER_CPU_SYMBOL(kernel_stack); | |||
1093 | DEFINE_PER_CPU(char *, irq_stack_ptr) = | 1093 | DEFINE_PER_CPU(char *, irq_stack_ptr) = |
1094 | init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; | 1094 | init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; |
1095 | 1095 | ||
1096 | DEFINE_PER_CPU(unsigned int, irq_count) = -1; | 1096 | DEFINE_PER_CPU(unsigned int, irq_count) __visible = -1; |
1097 | 1097 | ||
1098 | DEFINE_PER_CPU(struct task_struct *, fpu_owner_task); | 1098 | DEFINE_PER_CPU(struct task_struct *, fpu_owner_task); |
1099 | 1099 | ||
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index 87279212d318..36ce402a3fa5 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c | |||
@@ -25,11 +25,6 @@ | |||
25 | #include <asm/processor.h> | 25 | #include <asm/processor.h> |
26 | #include <asm/hypervisor.h> | 26 | #include <asm/hypervisor.h> |
27 | 27 | ||
28 | /* | ||
29 | * Hypervisor detect order. This is specified explicitly here because | ||
30 | * some hypervisors might implement compatibility modes for other | ||
31 | * hypervisors and therefore need to be detected in specific sequence. | ||
32 | */ | ||
33 | static const __initconst struct hypervisor_x86 * const hypervisors[] = | 28 | static const __initconst struct hypervisor_x86 * const hypervisors[] = |
34 | { | 29 | { |
35 | #ifdef CONFIG_XEN_PVHVM | 30 | #ifdef CONFIG_XEN_PVHVM |
@@ -49,15 +44,19 @@ static inline void __init | |||
49 | detect_hypervisor_vendor(void) | 44 | detect_hypervisor_vendor(void) |
50 | { | 45 | { |
51 | const struct hypervisor_x86 *h, * const *p; | 46 | const struct hypervisor_x86 *h, * const *p; |
47 | uint32_t pri, max_pri = 0; | ||
52 | 48 | ||
53 | for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) { | 49 | for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) { |
54 | h = *p; | 50 | h = *p; |
55 | if (h->detect()) { | 51 | pri = h->detect(); |
52 | if (pri != 0 && pri > max_pri) { | ||
53 | max_pri = pri; | ||
56 | x86_hyper = h; | 54 | x86_hyper = h; |
57 | printk(KERN_INFO "Hypervisor detected: %s\n", h->name); | ||
58 | break; | ||
59 | } | 55 | } |
60 | } | 56 | } |
57 | |||
58 | if (max_pri) | ||
59 | printk(KERN_INFO "Hypervisor detected: %s\n", x86_hyper->name); | ||
61 | } | 60 | } |
62 | 61 | ||
63 | void init_hypervisor(struct cpuinfo_x86 *c) | 62 | void init_hypervisor(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h index 5b7d4fa5d3b7..09edd0b65fef 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-internal.h +++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h | |||
@@ -25,15 +25,18 @@ int mce_severity(struct mce *a, int tolerant, char **msg); | |||
25 | struct dentry *mce_get_debugfs_dir(void); | 25 | struct dentry *mce_get_debugfs_dir(void); |
26 | 26 | ||
27 | extern struct mce_bank *mce_banks; | 27 | extern struct mce_bank *mce_banks; |
28 | extern mce_banks_t mce_banks_ce_disabled; | ||
28 | 29 | ||
29 | #ifdef CONFIG_X86_MCE_INTEL | 30 | #ifdef CONFIG_X86_MCE_INTEL |
30 | unsigned long mce_intel_adjust_timer(unsigned long interval); | 31 | unsigned long mce_intel_adjust_timer(unsigned long interval); |
31 | void mce_intel_cmci_poll(void); | 32 | void mce_intel_cmci_poll(void); |
32 | void mce_intel_hcpu_update(unsigned long cpu); | 33 | void mce_intel_hcpu_update(unsigned long cpu); |
34 | void cmci_disable_bank(int bank); | ||
33 | #else | 35 | #else |
34 | # define mce_intel_adjust_timer mce_adjust_timer_default | 36 | # define mce_intel_adjust_timer mce_adjust_timer_default |
35 | static inline void mce_intel_cmci_poll(void) { } | 37 | static inline void mce_intel_cmci_poll(void) { } |
36 | static inline void mce_intel_hcpu_update(unsigned long cpu) { } | 38 | static inline void mce_intel_hcpu_update(unsigned long cpu) { } |
39 | static inline void cmci_disable_bank(int bank) { } | ||
37 | #endif | 40 | #endif |
38 | 41 | ||
39 | void mce_timer_kick(unsigned long interval); | 42 | void mce_timer_kick(unsigned long interval); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 87a65c939bcd..b3218cdee95f 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -97,6 +97,15 @@ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { | |||
97 | [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL | 97 | [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL |
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* | ||
101 | * MCA banks controlled through firmware first for corrected errors. | ||
102 | * This is a global list of banks for which we won't enable CMCI and we | ||
103 | * won't poll. Firmware controls these banks and is responsible for | ||
104 | * reporting corrected errors through GHES. Uncorrected/recoverable | ||
105 | * errors are still notified through a machine check. | ||
106 | */ | ||
107 | mce_banks_t mce_banks_ce_disabled; | ||
108 | |||
100 | static DEFINE_PER_CPU(struct work_struct, mce_work); | 109 | static DEFINE_PER_CPU(struct work_struct, mce_work); |
101 | 110 | ||
102 | static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs); | 111 | static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs); |
@@ -1935,6 +1944,25 @@ static struct miscdevice mce_chrdev_device = { | |||
1935 | &mce_chrdev_ops, | 1944 | &mce_chrdev_ops, |
1936 | }; | 1945 | }; |
1937 | 1946 | ||
1947 | static void __mce_disable_bank(void *arg) | ||
1948 | { | ||
1949 | int bank = *((int *)arg); | ||
1950 | __clear_bit(bank, __get_cpu_var(mce_poll_banks)); | ||
1951 | cmci_disable_bank(bank); | ||
1952 | } | ||
1953 | |||
1954 | void mce_disable_bank(int bank) | ||
1955 | { | ||
1956 | if (bank >= mca_cfg.banks) { | ||
1957 | pr_warn(FW_BUG | ||
1958 | "Ignoring request to disable invalid MCA bank %d.\n", | ||
1959 | bank); | ||
1960 | return; | ||
1961 | } | ||
1962 | set_bit(bank, mce_banks_ce_disabled); | ||
1963 | on_each_cpu(__mce_disable_bank, &bank, 1); | ||
1964 | } | ||
1965 | |||
1938 | /* | 1966 | /* |
1939 | * mce=off Disables machine check | 1967 | * mce=off Disables machine check |
1940 | * mce=no_cmci Disables CMCI | 1968 | * mce=no_cmci Disables CMCI |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index d56405309dc1..4cfe0458ca66 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c | |||
@@ -203,6 +203,10 @@ static void cmci_discover(int banks) | |||
203 | if (test_bit(i, owned)) | 203 | if (test_bit(i, owned)) |
204 | continue; | 204 | continue; |
205 | 205 | ||
206 | /* Skip banks in firmware first mode */ | ||
207 | if (test_bit(i, mce_banks_ce_disabled)) | ||
208 | continue; | ||
209 | |||
206 | rdmsrl(MSR_IA32_MCx_CTL2(i), val); | 210 | rdmsrl(MSR_IA32_MCx_CTL2(i), val); |
207 | 211 | ||
208 | /* Already owned by someone else? */ | 212 | /* Already owned by someone else? */ |
@@ -271,6 +275,19 @@ void cmci_recheck(void) | |||
271 | local_irq_restore(flags); | 275 | local_irq_restore(flags); |
272 | } | 276 | } |
273 | 277 | ||
278 | /* Caller must hold the lock on cmci_discover_lock */ | ||
279 | static void __cmci_disable_bank(int bank) | ||
280 | { | ||
281 | u64 val; | ||
282 | |||
283 | if (!test_bit(bank, __get_cpu_var(mce_banks_owned))) | ||
284 | return; | ||
285 | rdmsrl(MSR_IA32_MCx_CTL2(bank), val); | ||
286 | val &= ~MCI_CTL2_CMCI_EN; | ||
287 | wrmsrl(MSR_IA32_MCx_CTL2(bank), val); | ||
288 | __clear_bit(bank, __get_cpu_var(mce_banks_owned)); | ||
289 | } | ||
290 | |||
274 | /* | 291 | /* |
275 | * Disable CMCI on this CPU for all banks it owns when it goes down. | 292 | * Disable CMCI on this CPU for all banks it owns when it goes down. |
276 | * This allows other CPUs to claim the banks on rediscovery. | 293 | * This allows other CPUs to claim the banks on rediscovery. |
@@ -280,20 +297,12 @@ void cmci_clear(void) | |||
280 | unsigned long flags; | 297 | unsigned long flags; |
281 | int i; | 298 | int i; |
282 | int banks; | 299 | int banks; |
283 | u64 val; | ||
284 | 300 | ||
285 | if (!cmci_supported(&banks)) | 301 | if (!cmci_supported(&banks)) |
286 | return; | 302 | return; |
287 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | 303 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); |
288 | for (i = 0; i < banks; i++) { | 304 | for (i = 0; i < banks; i++) |
289 | if (!test_bit(i, __get_cpu_var(mce_banks_owned))) | 305 | __cmci_disable_bank(i); |
290 | continue; | ||
291 | /* Disable CMCI */ | ||
292 | rdmsrl(MSR_IA32_MCx_CTL2(i), val); | ||
293 | val &= ~MCI_CTL2_CMCI_EN; | ||
294 | wrmsrl(MSR_IA32_MCx_CTL2(i), val); | ||
295 | __clear_bit(i, __get_cpu_var(mce_banks_owned)); | ||
296 | } | ||
297 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | 306 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); |
298 | } | 307 | } |
299 | 308 | ||
@@ -327,6 +336,19 @@ void cmci_reenable(void) | |||
327 | cmci_discover(banks); | 336 | cmci_discover(banks); |
328 | } | 337 | } |
329 | 338 | ||
339 | void cmci_disable_bank(int bank) | ||
340 | { | ||
341 | int banks; | ||
342 | unsigned long flags; | ||
343 | |||
344 | if (!cmci_supported(&banks)) | ||
345 | return; | ||
346 | |||
347 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | ||
348 | __cmci_disable_bank(bank); | ||
349 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | ||
350 | } | ||
351 | |||
330 | static void intel_init_cmci(void) | 352 | static void intel_init_cmci(void) |
331 | { | 353 | { |
332 | int banks; | 354 | int banks; |
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 8f4be53ea04b..71a39f3621ba 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
@@ -27,20 +27,23 @@ | |||
27 | struct ms_hyperv_info ms_hyperv; | 27 | struct ms_hyperv_info ms_hyperv; |
28 | EXPORT_SYMBOL_GPL(ms_hyperv); | 28 | EXPORT_SYMBOL_GPL(ms_hyperv); |
29 | 29 | ||
30 | static bool __init ms_hyperv_platform(void) | 30 | static uint32_t __init ms_hyperv_platform(void) |
31 | { | 31 | { |
32 | u32 eax; | 32 | u32 eax; |
33 | u32 hyp_signature[3]; | 33 | u32 hyp_signature[3]; |
34 | 34 | ||
35 | if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) | 35 | if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) |
36 | return false; | 36 | return 0; |
37 | 37 | ||
38 | cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, | 38 | cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, |
39 | &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); | 39 | &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); |
40 | 40 | ||
41 | return eax >= HYPERV_CPUID_MIN && | 41 | if (eax >= HYPERV_CPUID_MIN && |
42 | eax <= HYPERV_CPUID_MAX && | 42 | eax <= HYPERV_CPUID_MAX && |
43 | !memcmp("Microsoft Hv", hyp_signature, 12); | 43 | !memcmp("Microsoft Hv", hyp_signature, 12)) |
44 | return HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS; | ||
45 | |||
46 | return 0; | ||
44 | } | 47 | } |
45 | 48 | ||
46 | static cycle_t read_hv_clock(struct clocksource *arg) | 49 | static cycle_t read_hv_clock(struct clocksource *arg) |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index a7c7305030cc..8355c84b9729 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -1884,6 +1884,7 @@ static struct pmu pmu = { | |||
1884 | void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) | 1884 | void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) |
1885 | { | 1885 | { |
1886 | userpg->cap_usr_time = 0; | 1886 | userpg->cap_usr_time = 0; |
1887 | userpg->cap_usr_time_zero = 0; | ||
1887 | userpg->cap_usr_rdpmc = x86_pmu.attr_rdpmc; | 1888 | userpg->cap_usr_rdpmc = x86_pmu.attr_rdpmc; |
1888 | userpg->pmc_width = x86_pmu.cntval_bits; | 1889 | userpg->pmc_width = x86_pmu.cntval_bits; |
1889 | 1890 | ||
@@ -1897,6 +1898,11 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) | |||
1897 | userpg->time_mult = this_cpu_read(cyc2ns); | 1898 | userpg->time_mult = this_cpu_read(cyc2ns); |
1898 | userpg->time_shift = CYC2NS_SCALE_FACTOR; | 1899 | userpg->time_shift = CYC2NS_SCALE_FACTOR; |
1899 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; | 1900 | userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; |
1901 | |||
1902 | if (sched_clock_stable && !check_tsc_disabled()) { | ||
1903 | userpg->cap_usr_time_zero = 1; | ||
1904 | userpg->time_zero = this_cpu_read(cyc2ns_offset); | ||
1905 | } | ||
1900 | } | 1906 | } |
1901 | 1907 | ||
1902 | /* | 1908 | /* |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 97e557bc4c91..cc16faae0538 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -641,6 +641,8 @@ extern struct event_constraint intel_core2_pebs_event_constraints[]; | |||
641 | 641 | ||
642 | extern struct event_constraint intel_atom_pebs_event_constraints[]; | 642 | extern struct event_constraint intel_atom_pebs_event_constraints[]; |
643 | 643 | ||
644 | extern struct event_constraint intel_slm_pebs_event_constraints[]; | ||
645 | |||
644 | extern struct event_constraint intel_nehalem_pebs_event_constraints[]; | 646 | extern struct event_constraint intel_nehalem_pebs_event_constraints[]; |
645 | 647 | ||
646 | extern struct event_constraint intel_westmere_pebs_event_constraints[]; | 648 | extern struct event_constraint intel_westmere_pebs_event_constraints[]; |
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 4cbe03287b08..beeb7cc07044 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c | |||
@@ -347,8 +347,7 @@ static struct amd_nb *amd_alloc_nb(int cpu) | |||
347 | struct amd_nb *nb; | 347 | struct amd_nb *nb; |
348 | int i; | 348 | int i; |
349 | 349 | ||
350 | nb = kmalloc_node(sizeof(struct amd_nb), GFP_KERNEL | __GFP_ZERO, | 350 | nb = kzalloc_node(sizeof(struct amd_nb), GFP_KERNEL, cpu_to_node(cpu)); |
351 | cpu_to_node(cpu)); | ||
352 | if (!nb) | 351 | if (!nb) |
353 | return NULL; | 352 | return NULL; |
354 | 353 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index fbc9210b45bc..0abf6742a8b0 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -81,7 +81,8 @@ static struct event_constraint intel_nehalem_event_constraints[] __read_mostly = | |||
81 | 81 | ||
82 | static struct extra_reg intel_nehalem_extra_regs[] __read_mostly = | 82 | static struct extra_reg intel_nehalem_extra_regs[] __read_mostly = |
83 | { | 83 | { |
84 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), | 84 | /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ |
85 | INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), | ||
85 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b), | 86 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b), |
86 | EVENT_EXTRA_END | 87 | EVENT_EXTRA_END |
87 | }; | 88 | }; |
@@ -143,8 +144,9 @@ static struct event_constraint intel_ivb_event_constraints[] __read_mostly = | |||
143 | 144 | ||
144 | static struct extra_reg intel_westmere_extra_regs[] __read_mostly = | 145 | static struct extra_reg intel_westmere_extra_regs[] __read_mostly = |
145 | { | 146 | { |
146 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), | 147 | /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ |
147 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1), | 148 | INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), |
149 | INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1), | ||
148 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b), | 150 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b), |
149 | EVENT_EXTRA_END | 151 | EVENT_EXTRA_END |
150 | }; | 152 | }; |
@@ -162,16 +164,27 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly = | |||
162 | EVENT_CONSTRAINT_END | 164 | EVENT_CONSTRAINT_END |
163 | }; | 165 | }; |
164 | 166 | ||
167 | static struct event_constraint intel_slm_event_constraints[] __read_mostly = | ||
168 | { | ||
169 | FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ | ||
170 | FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ | ||
171 | FIXED_EVENT_CONSTRAINT(0x013c, 2), /* CPU_CLK_UNHALTED.REF */ | ||
172 | FIXED_EVENT_CONSTRAINT(0x0300, 2), /* pseudo CPU_CLK_UNHALTED.REF */ | ||
173 | EVENT_CONSTRAINT_END | ||
174 | }; | ||
175 | |||
165 | static struct extra_reg intel_snb_extra_regs[] __read_mostly = { | 176 | static struct extra_reg intel_snb_extra_regs[] __read_mostly = { |
166 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), | 177 | /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ |
167 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), | 178 | INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), |
179 | INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), | ||
168 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), | 180 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), |
169 | EVENT_EXTRA_END | 181 | EVENT_EXTRA_END |
170 | }; | 182 | }; |
171 | 183 | ||
172 | static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { | 184 | static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { |
173 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), | 185 | /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ |
174 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), | 186 | INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), |
187 | INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), | ||
175 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), | 188 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), |
176 | EVENT_EXTRA_END | 189 | EVENT_EXTRA_END |
177 | }; | 190 | }; |
@@ -882,6 +895,140 @@ static __initconst const u64 atom_hw_cache_event_ids | |||
882 | }, | 895 | }, |
883 | }; | 896 | }; |
884 | 897 | ||
898 | static struct extra_reg intel_slm_extra_regs[] __read_mostly = | ||
899 | { | ||
900 | /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ | ||
901 | INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x768005ffff, RSP_0), | ||
902 | INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x768005ffff, RSP_1), | ||
903 | EVENT_EXTRA_END | ||
904 | }; | ||
905 | |||
906 | #define SLM_DMND_READ SNB_DMND_DATA_RD | ||
907 | #define SLM_DMND_WRITE SNB_DMND_RFO | ||
908 | #define SLM_DMND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO) | ||
909 | |||
910 | #define SLM_SNP_ANY (SNB_SNP_NONE|SNB_SNP_MISS|SNB_NO_FWD|SNB_HITM) | ||
911 | #define SLM_LLC_ACCESS SNB_RESP_ANY | ||
912 | #define SLM_LLC_MISS (SLM_SNP_ANY|SNB_NON_DRAM) | ||
913 | |||
914 | static __initconst const u64 slm_hw_cache_extra_regs | ||
915 | [PERF_COUNT_HW_CACHE_MAX] | ||
916 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
917 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = | ||
918 | { | ||
919 | [ C(LL ) ] = { | ||
920 | [ C(OP_READ) ] = { | ||
921 | [ C(RESULT_ACCESS) ] = SLM_DMND_READ|SLM_LLC_ACCESS, | ||
922 | [ C(RESULT_MISS) ] = SLM_DMND_READ|SLM_LLC_MISS, | ||
923 | }, | ||
924 | [ C(OP_WRITE) ] = { | ||
925 | [ C(RESULT_ACCESS) ] = SLM_DMND_WRITE|SLM_LLC_ACCESS, | ||
926 | [ C(RESULT_MISS) ] = SLM_DMND_WRITE|SLM_LLC_MISS, | ||
927 | }, | ||
928 | [ C(OP_PREFETCH) ] = { | ||
929 | [ C(RESULT_ACCESS) ] = SLM_DMND_PREFETCH|SLM_LLC_ACCESS, | ||
930 | [ C(RESULT_MISS) ] = SLM_DMND_PREFETCH|SLM_LLC_MISS, | ||
931 | }, | ||
932 | }, | ||
933 | }; | ||
934 | |||
935 | static __initconst const u64 slm_hw_cache_event_ids | ||
936 | [PERF_COUNT_HW_CACHE_MAX] | ||
937 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
938 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = | ||
939 | { | ||
940 | [ C(L1D) ] = { | ||
941 | [ C(OP_READ) ] = { | ||
942 | [ C(RESULT_ACCESS) ] = 0, | ||
943 | [ C(RESULT_MISS) ] = 0x0104, /* LD_DCU_MISS */ | ||
944 | }, | ||
945 | [ C(OP_WRITE) ] = { | ||
946 | [ C(RESULT_ACCESS) ] = 0, | ||
947 | [ C(RESULT_MISS) ] = 0, | ||
948 | }, | ||
949 | [ C(OP_PREFETCH) ] = { | ||
950 | [ C(RESULT_ACCESS) ] = 0, | ||
951 | [ C(RESULT_MISS) ] = 0, | ||
952 | }, | ||
953 | }, | ||
954 | [ C(L1I ) ] = { | ||
955 | [ C(OP_READ) ] = { | ||
956 | [ C(RESULT_ACCESS) ] = 0x0380, /* ICACHE.ACCESSES */ | ||
957 | [ C(RESULT_MISS) ] = 0x0280, /* ICACGE.MISSES */ | ||
958 | }, | ||
959 | [ C(OP_WRITE) ] = { | ||
960 | [ C(RESULT_ACCESS) ] = -1, | ||
961 | [ C(RESULT_MISS) ] = -1, | ||
962 | }, | ||
963 | [ C(OP_PREFETCH) ] = { | ||
964 | [ C(RESULT_ACCESS) ] = 0, | ||
965 | [ C(RESULT_MISS) ] = 0, | ||
966 | }, | ||
967 | }, | ||
968 | [ C(LL ) ] = { | ||
969 | [ C(OP_READ) ] = { | ||
970 | /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */ | ||
971 | [ C(RESULT_ACCESS) ] = 0x01b7, | ||
972 | /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */ | ||
973 | [ C(RESULT_MISS) ] = 0x01b7, | ||
974 | }, | ||
975 | [ C(OP_WRITE) ] = { | ||
976 | /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */ | ||
977 | [ C(RESULT_ACCESS) ] = 0x01b7, | ||
978 | /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */ | ||
979 | [ C(RESULT_MISS) ] = 0x01b7, | ||
980 | }, | ||
981 | [ C(OP_PREFETCH) ] = { | ||
982 | /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */ | ||
983 | [ C(RESULT_ACCESS) ] = 0x01b7, | ||
984 | /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */ | ||
985 | [ C(RESULT_MISS) ] = 0x01b7, | ||
986 | }, | ||
987 | }, | ||
988 | [ C(DTLB) ] = { | ||
989 | [ C(OP_READ) ] = { | ||
990 | [ C(RESULT_ACCESS) ] = 0, | ||
991 | [ C(RESULT_MISS) ] = 0x0804, /* LD_DTLB_MISS */ | ||
992 | }, | ||
993 | [ C(OP_WRITE) ] = { | ||
994 | [ C(RESULT_ACCESS) ] = 0, | ||
995 | [ C(RESULT_MISS) ] = 0, | ||
996 | }, | ||
997 | [ C(OP_PREFETCH) ] = { | ||
998 | [ C(RESULT_ACCESS) ] = 0, | ||
999 | [ C(RESULT_MISS) ] = 0, | ||
1000 | }, | ||
1001 | }, | ||
1002 | [ C(ITLB) ] = { | ||
1003 | [ C(OP_READ) ] = { | ||
1004 | [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */ | ||
1005 | [ C(RESULT_MISS) ] = 0x0282, /* ITLB.MISSES */ | ||
1006 | }, | ||
1007 | [ C(OP_WRITE) ] = { | ||
1008 | [ C(RESULT_ACCESS) ] = -1, | ||
1009 | [ C(RESULT_MISS) ] = -1, | ||
1010 | }, | ||
1011 | [ C(OP_PREFETCH) ] = { | ||
1012 | [ C(RESULT_ACCESS) ] = -1, | ||
1013 | [ C(RESULT_MISS) ] = -1, | ||
1014 | }, | ||
1015 | }, | ||
1016 | [ C(BPU ) ] = { | ||
1017 | [ C(OP_READ) ] = { | ||
1018 | [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */ | ||
1019 | [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */ | ||
1020 | }, | ||
1021 | [ C(OP_WRITE) ] = { | ||
1022 | [ C(RESULT_ACCESS) ] = -1, | ||
1023 | [ C(RESULT_MISS) ] = -1, | ||
1024 | }, | ||
1025 | [ C(OP_PREFETCH) ] = { | ||
1026 | [ C(RESULT_ACCESS) ] = -1, | ||
1027 | [ C(RESULT_MISS) ] = -1, | ||
1028 | }, | ||
1029 | }, | ||
1030 | }; | ||
1031 | |||
885 | static inline bool intel_pmu_needs_lbr_smpl(struct perf_event *event) | 1032 | static inline bool intel_pmu_needs_lbr_smpl(struct perf_event *event) |
886 | { | 1033 | { |
887 | /* user explicitly requested branch sampling */ | 1034 | /* user explicitly requested branch sampling */ |
@@ -1301,11 +1448,11 @@ static void intel_fixup_er(struct perf_event *event, int idx) | |||
1301 | 1448 | ||
1302 | if (idx == EXTRA_REG_RSP_0) { | 1449 | if (idx == EXTRA_REG_RSP_0) { |
1303 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; | 1450 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; |
1304 | event->hw.config |= 0x01b7; | 1451 | event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_0].event; |
1305 | event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; | 1452 | event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; |
1306 | } else if (idx == EXTRA_REG_RSP_1) { | 1453 | } else if (idx == EXTRA_REG_RSP_1) { |
1307 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; | 1454 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; |
1308 | event->hw.config |= 0x01bb; | 1455 | event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_1].event; |
1309 | event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; | 1456 | event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; |
1310 | } | 1457 | } |
1311 | } | 1458 | } |
@@ -2176,6 +2323,21 @@ __init int intel_pmu_init(void) | |||
2176 | pr_cont("Atom events, "); | 2323 | pr_cont("Atom events, "); |
2177 | break; | 2324 | break; |
2178 | 2325 | ||
2326 | case 55: /* Atom 22nm "Silvermont" */ | ||
2327 | memcpy(hw_cache_event_ids, slm_hw_cache_event_ids, | ||
2328 | sizeof(hw_cache_event_ids)); | ||
2329 | memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs, | ||
2330 | sizeof(hw_cache_extra_regs)); | ||
2331 | |||
2332 | intel_pmu_lbr_init_atom(); | ||
2333 | |||
2334 | x86_pmu.event_constraints = intel_slm_event_constraints; | ||
2335 | x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints; | ||
2336 | x86_pmu.extra_regs = intel_slm_extra_regs; | ||
2337 | x86_pmu.er_flags |= ERF_HAS_RSP_1; | ||
2338 | pr_cont("Silvermont events, "); | ||
2339 | break; | ||
2340 | |||
2179 | case 37: /* 32 nm nehalem, "Clarkdale" */ | 2341 | case 37: /* 32 nm nehalem, "Clarkdale" */ |
2180 | case 44: /* 32 nm nehalem, "Gulftown" */ | 2342 | case 44: /* 32 nm nehalem, "Gulftown" */ |
2181 | case 47: /* 32 nm Xeon E7 */ | 2343 | case 47: /* 32 nm Xeon E7 */ |
@@ -2270,6 +2432,7 @@ __init int intel_pmu_init(void) | |||
2270 | case 70: | 2432 | case 70: |
2271 | case 71: | 2433 | case 71: |
2272 | case 63: | 2434 | case 63: |
2435 | case 69: | ||
2273 | x86_pmu.late_ack = true; | 2436 | x86_pmu.late_ack = true; |
2274 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); | 2437 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
2275 | memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); | 2438 | memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 3065c57a63c1..63438aad177f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -224,7 +224,7 @@ static int alloc_pebs_buffer(int cpu) | |||
224 | if (!x86_pmu.pebs) | 224 | if (!x86_pmu.pebs) |
225 | return 0; | 225 | return 0; |
226 | 226 | ||
227 | buffer = kmalloc_node(PEBS_BUFFER_SIZE, GFP_KERNEL | __GFP_ZERO, node); | 227 | buffer = kzalloc_node(PEBS_BUFFER_SIZE, GFP_KERNEL, node); |
228 | if (unlikely(!buffer)) | 228 | if (unlikely(!buffer)) |
229 | return -ENOMEM; | 229 | return -ENOMEM; |
230 | 230 | ||
@@ -262,7 +262,7 @@ static int alloc_bts_buffer(int cpu) | |||
262 | if (!x86_pmu.bts) | 262 | if (!x86_pmu.bts) |
263 | return 0; | 263 | return 0; |
264 | 264 | ||
265 | buffer = kmalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_ZERO, node); | 265 | buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL, node); |
266 | if (unlikely(!buffer)) | 266 | if (unlikely(!buffer)) |
267 | return -ENOMEM; | 267 | return -ENOMEM; |
268 | 268 | ||
@@ -295,7 +295,7 @@ static int alloc_ds_buffer(int cpu) | |||
295 | int node = cpu_to_node(cpu); | 295 | int node = cpu_to_node(cpu); |
296 | struct debug_store *ds; | 296 | struct debug_store *ds; |
297 | 297 | ||
298 | ds = kmalloc_node(sizeof(*ds), GFP_KERNEL | __GFP_ZERO, node); | 298 | ds = kzalloc_node(sizeof(*ds), GFP_KERNEL, node); |
299 | if (unlikely(!ds)) | 299 | if (unlikely(!ds)) |
300 | return -ENOMEM; | 300 | return -ENOMEM; |
301 | 301 | ||
@@ -517,6 +517,32 @@ struct event_constraint intel_atom_pebs_event_constraints[] = { | |||
517 | EVENT_CONSTRAINT_END | 517 | EVENT_CONSTRAINT_END |
518 | }; | 518 | }; |
519 | 519 | ||
520 | struct event_constraint intel_slm_pebs_event_constraints[] = { | ||
521 | INTEL_UEVENT_CONSTRAINT(0x0103, 0x1), /* REHABQ.LD_BLOCK_ST_FORWARD_PS */ | ||
522 | INTEL_UEVENT_CONSTRAINT(0x0803, 0x1), /* REHABQ.LD_SPLITS_PS */ | ||
523 | INTEL_UEVENT_CONSTRAINT(0x0204, 0x1), /* MEM_UOPS_RETIRED.L2_HIT_LOADS_PS */ | ||
524 | INTEL_UEVENT_CONSTRAINT(0x0404, 0x1), /* MEM_UOPS_RETIRED.L2_MISS_LOADS_PS */ | ||
525 | INTEL_UEVENT_CONSTRAINT(0x0804, 0x1), /* MEM_UOPS_RETIRED.DTLB_MISS_LOADS_PS */ | ||
526 | INTEL_UEVENT_CONSTRAINT(0x2004, 0x1), /* MEM_UOPS_RETIRED.HITM_PS */ | ||
527 | INTEL_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY_PS */ | ||
528 | INTEL_UEVENT_CONSTRAINT(0x00c4, 0x1), /* BR_INST_RETIRED.ALL_BRANCHES_PS */ | ||
529 | INTEL_UEVENT_CONSTRAINT(0x7ec4, 0x1), /* BR_INST_RETIRED.JCC_PS */ | ||
530 | INTEL_UEVENT_CONSTRAINT(0xbfc4, 0x1), /* BR_INST_RETIRED.FAR_BRANCH_PS */ | ||
531 | INTEL_UEVENT_CONSTRAINT(0xebc4, 0x1), /* BR_INST_RETIRED.NON_RETURN_IND_PS */ | ||
532 | INTEL_UEVENT_CONSTRAINT(0xf7c4, 0x1), /* BR_INST_RETIRED.RETURN_PS */ | ||
533 | INTEL_UEVENT_CONSTRAINT(0xf9c4, 0x1), /* BR_INST_RETIRED.CALL_PS */ | ||
534 | INTEL_UEVENT_CONSTRAINT(0xfbc4, 0x1), /* BR_INST_RETIRED.IND_CALL_PS */ | ||
535 | INTEL_UEVENT_CONSTRAINT(0xfdc4, 0x1), /* BR_INST_RETIRED.REL_CALL_PS */ | ||
536 | INTEL_UEVENT_CONSTRAINT(0xfec4, 0x1), /* BR_INST_RETIRED.TAKEN_JCC_PS */ | ||
537 | INTEL_UEVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_MISP_RETIRED.ALL_BRANCHES_PS */ | ||
538 | INTEL_UEVENT_CONSTRAINT(0x7ec5, 0x1), /* BR_INST_MISP_RETIRED.JCC_PS */ | ||
539 | INTEL_UEVENT_CONSTRAINT(0xebc5, 0x1), /* BR_INST_MISP_RETIRED.NON_RETURN_IND_PS */ | ||
540 | INTEL_UEVENT_CONSTRAINT(0xf7c5, 0x1), /* BR_INST_MISP_RETIRED.RETURN_PS */ | ||
541 | INTEL_UEVENT_CONSTRAINT(0xfbc5, 0x1), /* BR_INST_MISP_RETIRED.IND_CALL_PS */ | ||
542 | INTEL_UEVENT_CONSTRAINT(0xfec5, 0x1), /* BR_INST_MISP_RETIRED.TAKEN_JCC_PS */ | ||
543 | EVENT_CONSTRAINT_END | ||
544 | }; | ||
545 | |||
520 | struct event_constraint intel_nehalem_pebs_event_constraints[] = { | 546 | struct event_constraint intel_nehalem_pebs_event_constraints[] = { |
521 | INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */ | 547 | INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */ |
522 | INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ | 548 | INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index cad791dbde95..fd8011ed4dcd 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -6,6 +6,8 @@ static struct intel_uncore_type **pci_uncores = empty_uncore; | |||
6 | /* pci bus to socket mapping */ | 6 | /* pci bus to socket mapping */ |
7 | static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; | 7 | static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; |
8 | 8 | ||
9 | static struct pci_dev *extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX]; | ||
10 | |||
9 | static DEFINE_RAW_SPINLOCK(uncore_box_lock); | 11 | static DEFINE_RAW_SPINLOCK(uncore_box_lock); |
10 | 12 | ||
11 | /* mask of cpus that collect uncore events */ | 13 | /* mask of cpus that collect uncore events */ |
@@ -45,6 +47,24 @@ DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7"); | |||
45 | DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); | 47 | DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); |
46 | DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); | 48 | DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); |
47 | DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31"); | 49 | DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31"); |
50 | DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51"); | ||
51 | DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35"); | ||
52 | DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31"); | ||
53 | DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17"); | ||
54 | DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12"); | ||
55 | DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8"); | ||
56 | DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4"); | ||
57 | DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31"); | ||
58 | DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63"); | ||
59 | DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51"); | ||
60 | DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35"); | ||
61 | DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31"); | ||
62 | DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17"); | ||
63 | DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12"); | ||
64 | DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8"); | ||
65 | DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4"); | ||
66 | DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31"); | ||
67 | DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63"); | ||
48 | 68 | ||
49 | static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) | 69 | static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) |
50 | { | 70 | { |
@@ -281,7 +301,7 @@ static struct attribute *snbep_uncore_cbox_formats_attr[] = { | |||
281 | }; | 301 | }; |
282 | 302 | ||
283 | static struct attribute *snbep_uncore_pcu_formats_attr[] = { | 303 | static struct attribute *snbep_uncore_pcu_formats_attr[] = { |
284 | &format_attr_event.attr, | 304 | &format_attr_event_ext.attr, |
285 | &format_attr_occ_sel.attr, | 305 | &format_attr_occ_sel.attr, |
286 | &format_attr_edge.attr, | 306 | &format_attr_edge.attr, |
287 | &format_attr_inv.attr, | 307 | &format_attr_inv.attr, |
@@ -301,6 +321,24 @@ static struct attribute *snbep_uncore_qpi_formats_attr[] = { | |||
301 | &format_attr_edge.attr, | 321 | &format_attr_edge.attr, |
302 | &format_attr_inv.attr, | 322 | &format_attr_inv.attr, |
303 | &format_attr_thresh8.attr, | 323 | &format_attr_thresh8.attr, |
324 | &format_attr_match_rds.attr, | ||
325 | &format_attr_match_rnid30.attr, | ||
326 | &format_attr_match_rnid4.attr, | ||
327 | &format_attr_match_dnid.attr, | ||
328 | &format_attr_match_mc.attr, | ||
329 | &format_attr_match_opc.attr, | ||
330 | &format_attr_match_vnw.attr, | ||
331 | &format_attr_match0.attr, | ||
332 | &format_attr_match1.attr, | ||
333 | &format_attr_mask_rds.attr, | ||
334 | &format_attr_mask_rnid30.attr, | ||
335 | &format_attr_mask_rnid4.attr, | ||
336 | &format_attr_mask_dnid.attr, | ||
337 | &format_attr_mask_mc.attr, | ||
338 | &format_attr_mask_opc.attr, | ||
339 | &format_attr_mask_vnw.attr, | ||
340 | &format_attr_mask0.attr, | ||
341 | &format_attr_mask1.attr, | ||
304 | NULL, | 342 | NULL, |
305 | }; | 343 | }; |
306 | 344 | ||
@@ -314,8 +352,8 @@ static struct uncore_event_desc snbep_uncore_imc_events[] = { | |||
314 | static struct uncore_event_desc snbep_uncore_qpi_events[] = { | 352 | static struct uncore_event_desc snbep_uncore_qpi_events[] = { |
315 | INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), | 353 | INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), |
316 | INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), | 354 | INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), |
317 | INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x02,umask=0x08"), | 355 | INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x102,umask=0x08"), |
318 | INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x03,umask=0x04"), | 356 | INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x103,umask=0x04"), |
319 | { /* end: all zeroes */ }, | 357 | { /* end: all zeroes */ }, |
320 | }; | 358 | }; |
321 | 359 | ||
@@ -356,13 +394,16 @@ static struct intel_uncore_ops snbep_uncore_msr_ops = { | |||
356 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), | 394 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), |
357 | }; | 395 | }; |
358 | 396 | ||
397 | #define SNBEP_UNCORE_PCI_OPS_COMMON_INIT() \ | ||
398 | .init_box = snbep_uncore_pci_init_box, \ | ||
399 | .disable_box = snbep_uncore_pci_disable_box, \ | ||
400 | .enable_box = snbep_uncore_pci_enable_box, \ | ||
401 | .disable_event = snbep_uncore_pci_disable_event, \ | ||
402 | .read_counter = snbep_uncore_pci_read_counter | ||
403 | |||
359 | static struct intel_uncore_ops snbep_uncore_pci_ops = { | 404 | static struct intel_uncore_ops snbep_uncore_pci_ops = { |
360 | .init_box = snbep_uncore_pci_init_box, | 405 | SNBEP_UNCORE_PCI_OPS_COMMON_INIT(), |
361 | .disable_box = snbep_uncore_pci_disable_box, | 406 | .enable_event = snbep_uncore_pci_enable_event, \ |
362 | .enable_box = snbep_uncore_pci_enable_box, | ||
363 | .disable_event = snbep_uncore_pci_disable_event, | ||
364 | .enable_event = snbep_uncore_pci_enable_event, | ||
365 | .read_counter = snbep_uncore_pci_read_counter, | ||
366 | }; | 407 | }; |
367 | 408 | ||
368 | static struct event_constraint snbep_uncore_cbox_constraints[] = { | 409 | static struct event_constraint snbep_uncore_cbox_constraints[] = { |
@@ -726,6 +767,61 @@ static struct intel_uncore_type *snbep_msr_uncores[] = { | |||
726 | NULL, | 767 | NULL, |
727 | }; | 768 | }; |
728 | 769 | ||
770 | enum { | ||
771 | SNBEP_PCI_QPI_PORT0_FILTER, | ||
772 | SNBEP_PCI_QPI_PORT1_FILTER, | ||
773 | }; | ||
774 | |||
775 | static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
776 | { | ||
777 | struct hw_perf_event *hwc = &event->hw; | ||
778 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
779 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
780 | |||
781 | if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) { | ||
782 | reg1->idx = 0; | ||
783 | reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0; | ||
784 | reg1->config = event->attr.config1; | ||
785 | reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0; | ||
786 | reg2->config = event->attr.config2; | ||
787 | } | ||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
792 | { | ||
793 | struct pci_dev *pdev = box->pci_dev; | ||
794 | struct hw_perf_event *hwc = &event->hw; | ||
795 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
796 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
797 | |||
798 | if (reg1->idx != EXTRA_REG_NONE) { | ||
799 | int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER; | ||
800 | struct pci_dev *filter_pdev = extra_pci_dev[box->phys_id][idx]; | ||
801 | WARN_ON_ONCE(!filter_pdev); | ||
802 | if (filter_pdev) { | ||
803 | pci_write_config_dword(filter_pdev, reg1->reg, | ||
804 | (u32)reg1->config); | ||
805 | pci_write_config_dword(filter_pdev, reg1->reg + 4, | ||
806 | (u32)(reg1->config >> 32)); | ||
807 | pci_write_config_dword(filter_pdev, reg2->reg, | ||
808 | (u32)reg2->config); | ||
809 | pci_write_config_dword(filter_pdev, reg2->reg + 4, | ||
810 | (u32)(reg2->config >> 32)); | ||
811 | } | ||
812 | } | ||
813 | |||
814 | pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); | ||
815 | } | ||
816 | |||
817 | static struct intel_uncore_ops snbep_uncore_qpi_ops = { | ||
818 | SNBEP_UNCORE_PCI_OPS_COMMON_INIT(), | ||
819 | .enable_event = snbep_qpi_enable_event, | ||
820 | .hw_config = snbep_qpi_hw_config, | ||
821 | .get_constraint = uncore_get_constraint, | ||
822 | .put_constraint = uncore_put_constraint, | ||
823 | }; | ||
824 | |||
729 | #define SNBEP_UNCORE_PCI_COMMON_INIT() \ | 825 | #define SNBEP_UNCORE_PCI_COMMON_INIT() \ |
730 | .perf_ctr = SNBEP_PCI_PMON_CTR0, \ | 826 | .perf_ctr = SNBEP_PCI_PMON_CTR0, \ |
731 | .event_ctl = SNBEP_PCI_PMON_CTL0, \ | 827 | .event_ctl = SNBEP_PCI_PMON_CTL0, \ |
@@ -755,17 +851,18 @@ static struct intel_uncore_type snbep_uncore_imc = { | |||
755 | }; | 851 | }; |
756 | 852 | ||
757 | static struct intel_uncore_type snbep_uncore_qpi = { | 853 | static struct intel_uncore_type snbep_uncore_qpi = { |
758 | .name = "qpi", | 854 | .name = "qpi", |
759 | .num_counters = 4, | 855 | .num_counters = 4, |
760 | .num_boxes = 2, | 856 | .num_boxes = 2, |
761 | .perf_ctr_bits = 48, | 857 | .perf_ctr_bits = 48, |
762 | .perf_ctr = SNBEP_PCI_PMON_CTR0, | 858 | .perf_ctr = SNBEP_PCI_PMON_CTR0, |
763 | .event_ctl = SNBEP_PCI_PMON_CTL0, | 859 | .event_ctl = SNBEP_PCI_PMON_CTL0, |
764 | .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, | 860 | .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, |
765 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | 861 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, |
766 | .ops = &snbep_uncore_pci_ops, | 862 | .num_shared_regs = 1, |
767 | .event_descs = snbep_uncore_qpi_events, | 863 | .ops = &snbep_uncore_qpi_ops, |
768 | .format_group = &snbep_uncore_qpi_format_group, | 864 | .event_descs = snbep_uncore_qpi_events, |
865 | .format_group = &snbep_uncore_qpi_format_group, | ||
769 | }; | 866 | }; |
770 | 867 | ||
771 | 868 | ||
@@ -807,43 +904,53 @@ static struct intel_uncore_type *snbep_pci_uncores[] = { | |||
807 | static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { | 904 | static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { |
808 | { /* Home Agent */ | 905 | { /* Home Agent */ |
809 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), | 906 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), |
810 | .driver_data = SNBEP_PCI_UNCORE_HA, | 907 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0), |
811 | }, | 908 | }, |
812 | { /* MC Channel 0 */ | 909 | { /* MC Channel 0 */ |
813 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), | 910 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), |
814 | .driver_data = SNBEP_PCI_UNCORE_IMC, | 911 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0), |
815 | }, | 912 | }, |
816 | { /* MC Channel 1 */ | 913 | { /* MC Channel 1 */ |
817 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), | 914 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), |
818 | .driver_data = SNBEP_PCI_UNCORE_IMC, | 915 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1), |
819 | }, | 916 | }, |
820 | { /* MC Channel 2 */ | 917 | { /* MC Channel 2 */ |
821 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), | 918 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), |
822 | .driver_data = SNBEP_PCI_UNCORE_IMC, | 919 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2), |
823 | }, | 920 | }, |
824 | { /* MC Channel 3 */ | 921 | { /* MC Channel 3 */ |
825 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), | 922 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), |
826 | .driver_data = SNBEP_PCI_UNCORE_IMC, | 923 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3), |
827 | }, | 924 | }, |
828 | { /* QPI Port 0 */ | 925 | { /* QPI Port 0 */ |
829 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), | 926 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), |
830 | .driver_data = SNBEP_PCI_UNCORE_QPI, | 927 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0), |
831 | }, | 928 | }, |
832 | { /* QPI Port 1 */ | 929 | { /* QPI Port 1 */ |
833 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), | 930 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), |
834 | .driver_data = SNBEP_PCI_UNCORE_QPI, | 931 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1), |
835 | }, | 932 | }, |
836 | { /* R2PCIe */ | 933 | { /* R2PCIe */ |
837 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), | 934 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), |
838 | .driver_data = SNBEP_PCI_UNCORE_R2PCIE, | 935 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0), |
839 | }, | 936 | }, |
840 | { /* R3QPI Link 0 */ | 937 | { /* R3QPI Link 0 */ |
841 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), | 938 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), |
842 | .driver_data = SNBEP_PCI_UNCORE_R3QPI, | 939 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0), |
843 | }, | 940 | }, |
844 | { /* R3QPI Link 1 */ | 941 | { /* R3QPI Link 1 */ |
845 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), | 942 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), |
846 | .driver_data = SNBEP_PCI_UNCORE_R3QPI, | 943 | .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1), |
944 | }, | ||
945 | { /* QPI Port 0 filter */ | ||
946 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86), | ||
947 | .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, | ||
948 | SNBEP_PCI_QPI_PORT0_FILTER), | ||
949 | }, | ||
950 | { /* QPI Port 0 filter */ | ||
951 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96), | ||
952 | .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, | ||
953 | SNBEP_PCI_QPI_PORT1_FILTER), | ||
847 | }, | 954 | }, |
848 | { /* end: all zeroes */ } | 955 | { /* end: all zeroes */ } |
849 | }; | 956 | }; |
@@ -1256,71 +1363,71 @@ static struct intel_uncore_type *ivt_pci_uncores[] = { | |||
1256 | static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { | 1363 | static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { |
1257 | { /* Home Agent 0 */ | 1364 | { /* Home Agent 0 */ |
1258 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30), | 1365 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30), |
1259 | .driver_data = IVT_PCI_UNCORE_HA, | 1366 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 0), |
1260 | }, | 1367 | }, |
1261 | { /* Home Agent 1 */ | 1368 | { /* Home Agent 1 */ |
1262 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38), | 1369 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38), |
1263 | .driver_data = IVT_PCI_UNCORE_HA, | 1370 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 1), |
1264 | }, | 1371 | }, |
1265 | { /* MC0 Channel 0 */ | 1372 | { /* MC0 Channel 0 */ |
1266 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4), | 1373 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4), |
1267 | .driver_data = IVT_PCI_UNCORE_IMC, | 1374 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 0), |
1268 | }, | 1375 | }, |
1269 | { /* MC0 Channel 1 */ | 1376 | { /* MC0 Channel 1 */ |
1270 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5), | 1377 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5), |
1271 | .driver_data = IVT_PCI_UNCORE_IMC, | 1378 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 1), |
1272 | }, | 1379 | }, |
1273 | { /* MC0 Channel 3 */ | 1380 | { /* MC0 Channel 3 */ |
1274 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0), | 1381 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0), |
1275 | .driver_data = IVT_PCI_UNCORE_IMC, | 1382 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 2), |
1276 | }, | 1383 | }, |
1277 | { /* MC0 Channel 4 */ | 1384 | { /* MC0 Channel 4 */ |
1278 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1), | 1385 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1), |
1279 | .driver_data = IVT_PCI_UNCORE_IMC, | 1386 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 3), |
1280 | }, | 1387 | }, |
1281 | { /* MC1 Channel 0 */ | 1388 | { /* MC1 Channel 0 */ |
1282 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4), | 1389 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4), |
1283 | .driver_data = IVT_PCI_UNCORE_IMC, | 1390 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 4), |
1284 | }, | 1391 | }, |
1285 | { /* MC1 Channel 1 */ | 1392 | { /* MC1 Channel 1 */ |
1286 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5), | 1393 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5), |
1287 | .driver_data = IVT_PCI_UNCORE_IMC, | 1394 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 5), |
1288 | }, | 1395 | }, |
1289 | { /* MC1 Channel 3 */ | 1396 | { /* MC1 Channel 3 */ |
1290 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0), | 1397 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0), |
1291 | .driver_data = IVT_PCI_UNCORE_IMC, | 1398 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 6), |
1292 | }, | 1399 | }, |
1293 | { /* MC1 Channel 4 */ | 1400 | { /* MC1 Channel 4 */ |
1294 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), | 1401 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), |
1295 | .driver_data = IVT_PCI_UNCORE_IMC, | 1402 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7), |
1296 | }, | 1403 | }, |
1297 | { /* QPI0 Port 0 */ | 1404 | { /* QPI0 Port 0 */ |
1298 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), | 1405 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), |
1299 | .driver_data = IVT_PCI_UNCORE_QPI, | 1406 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0), |
1300 | }, | 1407 | }, |
1301 | { /* QPI0 Port 1 */ | 1408 | { /* QPI0 Port 1 */ |
1302 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33), | 1409 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33), |
1303 | .driver_data = IVT_PCI_UNCORE_QPI, | 1410 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 1), |
1304 | }, | 1411 | }, |
1305 | { /* QPI1 Port 2 */ | 1412 | { /* QPI1 Port 2 */ |
1306 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a), | 1413 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a), |
1307 | .driver_data = IVT_PCI_UNCORE_QPI, | 1414 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 2), |
1308 | }, | 1415 | }, |
1309 | { /* R2PCIe */ | 1416 | { /* R2PCIe */ |
1310 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34), | 1417 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34), |
1311 | .driver_data = IVT_PCI_UNCORE_R2PCIE, | 1418 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R2PCIE, 0), |
1312 | }, | 1419 | }, |
1313 | { /* R3QPI0 Link 0 */ | 1420 | { /* R3QPI0 Link 0 */ |
1314 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36), | 1421 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36), |
1315 | .driver_data = IVT_PCI_UNCORE_R3QPI, | 1422 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 0), |
1316 | }, | 1423 | }, |
1317 | { /* R3QPI0 Link 1 */ | 1424 | { /* R3QPI0 Link 1 */ |
1318 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37), | 1425 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37), |
1319 | .driver_data = IVT_PCI_UNCORE_R3QPI, | 1426 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 1), |
1320 | }, | 1427 | }, |
1321 | { /* R3QPI1 Link 2 */ | 1428 | { /* R3QPI1 Link 2 */ |
1322 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), | 1429 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), |
1323 | .driver_data = IVT_PCI_UNCORE_R3QPI, | 1430 | .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2), |
1324 | }, | 1431 | }, |
1325 | { /* end: all zeroes */ } | 1432 | { /* end: all zeroes */ } |
1326 | }; | 1433 | }; |
@@ -2606,7 +2713,7 @@ struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int cp | |||
2606 | 2713 | ||
2607 | size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg); | 2714 | size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg); |
2608 | 2715 | ||
2609 | box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu)); | 2716 | box = kzalloc_node(size, GFP_KERNEL, cpu_to_node(cpu)); |
2610 | if (!box) | 2717 | if (!box) |
2611 | return NULL; | 2718 | return NULL; |
2612 | 2719 | ||
@@ -3167,16 +3274,24 @@ static bool pcidrv_registered; | |||
3167 | /* | 3274 | /* |
3168 | * add a pci uncore device | 3275 | * add a pci uncore device |
3169 | */ | 3276 | */ |
3170 | static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) | 3277 | static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
3171 | { | 3278 | { |
3172 | struct intel_uncore_pmu *pmu; | 3279 | struct intel_uncore_pmu *pmu; |
3173 | struct intel_uncore_box *box; | 3280 | struct intel_uncore_box *box; |
3174 | int i, phys_id; | 3281 | struct intel_uncore_type *type; |
3282 | int phys_id; | ||
3175 | 3283 | ||
3176 | phys_id = pcibus_to_physid[pdev->bus->number]; | 3284 | phys_id = pcibus_to_physid[pdev->bus->number]; |
3177 | if (phys_id < 0) | 3285 | if (phys_id < 0) |
3178 | return -ENODEV; | 3286 | return -ENODEV; |
3179 | 3287 | ||
3288 | if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) { | ||
3289 | extra_pci_dev[phys_id][UNCORE_PCI_DEV_IDX(id->driver_data)] = pdev; | ||
3290 | pci_set_drvdata(pdev, NULL); | ||
3291 | return 0; | ||
3292 | } | ||
3293 | |||
3294 | type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)]; | ||
3180 | box = uncore_alloc_box(type, 0); | 3295 | box = uncore_alloc_box(type, 0); |
3181 | if (!box) | 3296 | if (!box) |
3182 | return -ENOMEM; | 3297 | return -ENOMEM; |
@@ -3185,21 +3300,11 @@ static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) | |||
3185 | * for performance monitoring unit with multiple boxes, | 3300 | * for performance monitoring unit with multiple boxes, |
3186 | * each box has a different function id. | 3301 | * each box has a different function id. |
3187 | */ | 3302 | */ |
3188 | for (i = 0; i < type->num_boxes; i++) { | 3303 | pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)]; |
3189 | pmu = &type->pmus[i]; | 3304 | if (pmu->func_id < 0) |
3190 | if (pmu->func_id == pdev->devfn) | 3305 | pmu->func_id = pdev->devfn; |
3191 | break; | 3306 | else |
3192 | if (pmu->func_id < 0) { | 3307 | WARN_ON_ONCE(pmu->func_id != pdev->devfn); |
3193 | pmu->func_id = pdev->devfn; | ||
3194 | break; | ||
3195 | } | ||
3196 | pmu = NULL; | ||
3197 | } | ||
3198 | |||
3199 | if (!pmu) { | ||
3200 | kfree(box); | ||
3201 | return -EINVAL; | ||
3202 | } | ||
3203 | 3308 | ||
3204 | box->phys_id = phys_id; | 3309 | box->phys_id = phys_id; |
3205 | box->pci_dev = pdev; | 3310 | box->pci_dev = pdev; |
@@ -3217,9 +3322,22 @@ static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) | |||
3217 | static void uncore_pci_remove(struct pci_dev *pdev) | 3322 | static void uncore_pci_remove(struct pci_dev *pdev) |
3218 | { | 3323 | { |
3219 | struct intel_uncore_box *box = pci_get_drvdata(pdev); | 3324 | struct intel_uncore_box *box = pci_get_drvdata(pdev); |
3220 | struct intel_uncore_pmu *pmu = box->pmu; | 3325 | struct intel_uncore_pmu *pmu; |
3221 | int cpu, phys_id = pcibus_to_physid[pdev->bus->number]; | 3326 | int i, cpu, phys_id = pcibus_to_physid[pdev->bus->number]; |
3222 | 3327 | ||
3328 | box = pci_get_drvdata(pdev); | ||
3329 | if (!box) { | ||
3330 | for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) { | ||
3331 | if (extra_pci_dev[phys_id][i] == pdev) { | ||
3332 | extra_pci_dev[phys_id][i] = NULL; | ||
3333 | break; | ||
3334 | } | ||
3335 | } | ||
3336 | WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX); | ||
3337 | return; | ||
3338 | } | ||
3339 | |||
3340 | pmu = box->pmu; | ||
3223 | if (WARN_ON_ONCE(phys_id != box->phys_id)) | 3341 | if (WARN_ON_ONCE(phys_id != box->phys_id)) |
3224 | return; | 3342 | return; |
3225 | 3343 | ||
@@ -3240,12 +3358,6 @@ static void uncore_pci_remove(struct pci_dev *pdev) | |||
3240 | kfree(box); | 3358 | kfree(box); |
3241 | } | 3359 | } |
3242 | 3360 | ||
3243 | static int uncore_pci_probe(struct pci_dev *pdev, | ||
3244 | const struct pci_device_id *id) | ||
3245 | { | ||
3246 | return uncore_pci_add(pci_uncores[id->driver_data], pdev); | ||
3247 | } | ||
3248 | |||
3249 | static int __init uncore_pci_init(void) | 3361 | static int __init uncore_pci_init(void) |
3250 | { | 3362 | { |
3251 | int ret; | 3363 | int ret; |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 47b3d00c9d89..a80ab71a883d 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
@@ -12,6 +12,15 @@ | |||
12 | #define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC | 12 | #define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC |
13 | #define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1) | 13 | #define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1) |
14 | 14 | ||
15 | #define UNCORE_PCI_DEV_DATA(type, idx) ((type << 8) | idx) | ||
16 | #define UNCORE_PCI_DEV_TYPE(data) ((data >> 8) & 0xff) | ||
17 | #define UNCORE_PCI_DEV_IDX(data) (data & 0xff) | ||
18 | #define UNCORE_EXTRA_PCI_DEV 0xff | ||
19 | #define UNCORE_EXTRA_PCI_DEV_MAX 2 | ||
20 | |||
21 | /* support up to 8 sockets */ | ||
22 | #define UNCORE_SOCKET_MAX 8 | ||
23 | |||
15 | #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) | 24 | #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) |
16 | 25 | ||
17 | /* SNB event control */ | 26 | /* SNB event control */ |
@@ -108,6 +117,7 @@ | |||
108 | (SNBEP_PMON_CTL_EV_SEL_MASK | \ | 117 | (SNBEP_PMON_CTL_EV_SEL_MASK | \ |
109 | SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ | 118 | SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ |
110 | SNBEP_PMON_CTL_EDGE_DET | \ | 119 | SNBEP_PMON_CTL_EDGE_DET | \ |
120 | SNBEP_PMON_CTL_EV_SEL_EXT | \ | ||
111 | SNBEP_PMON_CTL_INVERT | \ | 121 | SNBEP_PMON_CTL_INVERT | \ |
112 | SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ | 122 | SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ |
113 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ | 123 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ |
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 7076878404ec..628a059a9a06 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
@@ -93,7 +93,7 @@ static void __init vmware_platform_setup(void) | |||
93 | * serial key should be enough, as this will always have a VMware | 93 | * serial key should be enough, as this will always have a VMware |
94 | * specific string when running under VMware hypervisor. | 94 | * specific string when running under VMware hypervisor. |
95 | */ | 95 | */ |
96 | static bool __init vmware_platform(void) | 96 | static uint32_t __init vmware_platform(void) |
97 | { | 97 | { |
98 | if (cpu_has_hypervisor) { | 98 | if (cpu_has_hypervisor) { |
99 | unsigned int eax; | 99 | unsigned int eax; |
@@ -102,12 +102,12 @@ static bool __init vmware_platform(void) | |||
102 | cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &hyper_vendor_id[0], | 102 | cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &hyper_vendor_id[0], |
103 | &hyper_vendor_id[1], &hyper_vendor_id[2]); | 103 | &hyper_vendor_id[1], &hyper_vendor_id[2]); |
104 | if (!memcmp(hyper_vendor_id, "VMwareVMware", 12)) | 104 | if (!memcmp(hyper_vendor_id, "VMwareVMware", 12)) |
105 | return true; | 105 | return CPUID_VMWARE_INFO_LEAF; |
106 | } else if (dmi_available && dmi_name_in_serial("VMware") && | 106 | } else if (dmi_available && dmi_name_in_serial("VMware") && |
107 | __vmware_platform()) | 107 | __vmware_platform()) |
108 | return true; | 108 | return 1; |
109 | 109 | ||
110 | return false; | 110 | return 0; |
111 | } | 111 | } |
112 | 112 | ||
113 | /* | 113 | /* |
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 74467feb4dc5..e0e0841eef45 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c | |||
@@ -128,7 +128,9 @@ void native_machine_crash_shutdown(struct pt_regs *regs) | |||
128 | cpu_emergency_svm_disable(); | 128 | cpu_emergency_svm_disable(); |
129 | 129 | ||
130 | lapic_shutdown(); | 130 | lapic_shutdown(); |
131 | #if defined(CONFIG_X86_IO_APIC) | 131 | #ifdef CONFIG_X86_IO_APIC |
132 | /* Prevent crash_kexec() from deadlocking on ioapic_lock. */ | ||
133 | ioapic_zap_locks(); | ||
132 | disable_IO_APIC(); | 134 | disable_IO_APIC(); |
133 | #endif | 135 | #endif |
134 | #ifdef CONFIG_HPET_TIMER | 136 | #ifdef CONFIG_HPET_TIMER |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index d32abeabbda5..174da5fc5a7b 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -658,15 +658,18 @@ __init void e820_setup_gap(void) | |||
658 | * boot_params.e820_map, others are passed via SETUP_E820_EXT node of | 658 | * boot_params.e820_map, others are passed via SETUP_E820_EXT node of |
659 | * linked list of struct setup_data, which is parsed here. | 659 | * linked list of struct setup_data, which is parsed here. |
660 | */ | 660 | */ |
661 | void __init parse_e820_ext(struct setup_data *sdata) | 661 | void __init parse_e820_ext(u64 phys_addr, u32 data_len) |
662 | { | 662 | { |
663 | int entries; | 663 | int entries; |
664 | struct e820entry *extmap; | 664 | struct e820entry *extmap; |
665 | struct setup_data *sdata; | ||
665 | 666 | ||
667 | sdata = early_memremap(phys_addr, data_len); | ||
666 | entries = sdata->len / sizeof(struct e820entry); | 668 | entries = sdata->len / sizeof(struct e820entry); |
667 | extmap = (struct e820entry *)(sdata->data); | 669 | extmap = (struct e820entry *)(sdata->data); |
668 | __append_e820_map(extmap, entries); | 670 | __append_e820_map(extmap, entries); |
669 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); | 671 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); |
672 | early_iounmap(sdata, data_len); | ||
670 | printk(KERN_INFO "e820: extended physical RAM map:\n"); | 673 | printk(KERN_INFO "e820: extended physical RAM map:\n"); |
671 | e820_print_map("extended"); | 674 | e820_print_map("extended"); |
672 | } | 675 | } |
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 138463a24877..06f87bece92a 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
@@ -29,7 +29,7 @@ static void __init i386_default_early_setup(void) | |||
29 | reserve_ebda_region(); | 29 | reserve_ebda_region(); |
30 | } | 30 | } |
31 | 31 | ||
32 | void __init i386_start_kernel(void) | 32 | asmlinkage void __init i386_start_kernel(void) |
33 | { | 33 | { |
34 | sanitize_boot_params(&boot_params); | 34 | sanitize_boot_params(&boot_params); |
35 | 35 | ||
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 55b67614ed94..1be8e43b669e 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -137,7 +137,7 @@ static void __init copy_bootdata(char *real_mode_data) | |||
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | void __init x86_64_start_kernel(char * real_mode_data) | 140 | asmlinkage void __init x86_64_start_kernel(char * real_mode_data) |
141 | { | 141 | { |
142 | int i; | 142 | int i; |
143 | 143 | ||
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 5dd87a89f011..81ba27679f18 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -409,6 +409,7 @@ enable_paging: | |||
409 | /* | 409 | /* |
410 | * Check if it is 486 | 410 | * Check if it is 486 |
411 | */ | 411 | */ |
412 | movb $4,X86 # at least 486 | ||
412 | cmpl $-1,X86_CPUID | 413 | cmpl $-1,X86_CPUID |
413 | je is486 | 414 | je is486 |
414 | 415 | ||
@@ -436,7 +437,6 @@ enable_paging: | |||
436 | movl %edx,X86_CAPABILITY | 437 | movl %edx,X86_CAPABILITY |
437 | 438 | ||
438 | is486: | 439 | is486: |
439 | movb $4,X86 | ||
440 | movl $0x50022,%ecx # set AM, WP, NE and MP | 440 | movl $0x50022,%ecx # set AM, WP, NE and MP |
441 | movl %cr0,%eax | 441 | movl %cr0,%eax |
442 | andl $0x80000011,%eax # Save PG,PE,ET | 442 | andl $0x80000011,%eax # Save PG,PE,ET |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 3a8185c042a2..22d0687e7fda 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -177,7 +177,7 @@ u64 arch_irq_stat(void) | |||
177 | * SMP cross-CPU interrupts have their own specific | 177 | * SMP cross-CPU interrupts have their own specific |
178 | * handlers). | 178 | * handlers). |
179 | */ | 179 | */ |
180 | unsigned int __irq_entry do_IRQ(struct pt_regs *regs) | 180 | __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs) |
181 | { | 181 | { |
182 | struct pt_regs *old_regs = set_irq_regs(regs); | 182 | struct pt_regs *old_regs = set_irq_regs(regs); |
183 | 183 | ||
@@ -215,7 +215,7 @@ void __smp_x86_platform_ipi(void) | |||
215 | x86_platform_ipi_callback(); | 215 | x86_platform_ipi_callback(); |
216 | } | 216 | } |
217 | 217 | ||
218 | void smp_x86_platform_ipi(struct pt_regs *regs) | 218 | __visible void smp_x86_platform_ipi(struct pt_regs *regs) |
219 | { | 219 | { |
220 | struct pt_regs *old_regs = set_irq_regs(regs); | 220 | struct pt_regs *old_regs = set_irq_regs(regs); |
221 | 221 | ||
@@ -229,7 +229,7 @@ void smp_x86_platform_ipi(struct pt_regs *regs) | |||
229 | /* | 229 | /* |
230 | * Handler for POSTED_INTERRUPT_VECTOR. | 230 | * Handler for POSTED_INTERRUPT_VECTOR. |
231 | */ | 231 | */ |
232 | void smp_kvm_posted_intr_ipi(struct pt_regs *regs) | 232 | __visible void smp_kvm_posted_intr_ipi(struct pt_regs *regs) |
233 | { | 233 | { |
234 | struct pt_regs *old_regs = set_irq_regs(regs); | 234 | struct pt_regs *old_regs = set_irq_regs(regs); |
235 | 235 | ||
@@ -247,7 +247,7 @@ void smp_kvm_posted_intr_ipi(struct pt_regs *regs) | |||
247 | } | 247 | } |
248 | #endif | 248 | #endif |
249 | 249 | ||
250 | void smp_trace_x86_platform_ipi(struct pt_regs *regs) | 250 | __visible void smp_trace_x86_platform_ipi(struct pt_regs *regs) |
251 | { | 251 | { |
252 | struct pt_regs *old_regs = set_irq_regs(regs); | 252 | struct pt_regs *old_regs = set_irq_regs(regs); |
253 | 253 | ||
diff --git a/arch/x86/kernel/irq_work.c b/arch/x86/kernel/irq_work.c index 636a55e4a13c..1de84e3ab4e0 100644 --- a/arch/x86/kernel/irq_work.c +++ b/arch/x86/kernel/irq_work.c | |||
@@ -22,14 +22,14 @@ static inline void __smp_irq_work_interrupt(void) | |||
22 | irq_work_run(); | 22 | irq_work_run(); |
23 | } | 23 | } |
24 | 24 | ||
25 | void smp_irq_work_interrupt(struct pt_regs *regs) | 25 | __visible void smp_irq_work_interrupt(struct pt_regs *regs) |
26 | { | 26 | { |
27 | irq_work_entering_irq(); | 27 | irq_work_entering_irq(); |
28 | __smp_irq_work_interrupt(); | 28 | __smp_irq_work_interrupt(); |
29 | exiting_irq(); | 29 | exiting_irq(); |
30 | } | 30 | } |
31 | 31 | ||
32 | void smp_trace_irq_work_interrupt(struct pt_regs *regs) | 32 | __visible void smp_trace_irq_work_interrupt(struct pt_regs *regs) |
33 | { | 33 | { |
34 | irq_work_entering_irq(); | 34 | irq_work_entering_irq(); |
35 | trace_irq_work_entry(IRQ_WORK_VECTOR); | 35 | trace_irq_work_entry(IRQ_WORK_VECTOR); |
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c index 2889b3d43882..460f5d9ceebb 100644 --- a/arch/x86/kernel/jump_label.c +++ b/arch/x86/kernel/jump_label.c | |||
@@ -37,7 +37,19 @@ static void __jump_label_transform(struct jump_entry *entry, | |||
37 | } else | 37 | } else |
38 | memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE); | 38 | memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE); |
39 | 39 | ||
40 | (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE); | 40 | /* |
41 | * Make text_poke_bp() a default fallback poker. | ||
42 | * | ||
43 | * At the time the change is being done, just ignore whether we | ||
44 | * are doing nop -> jump or jump -> nop transition, and assume | ||
45 | * always nop being the 'currently valid' instruction | ||
46 | * | ||
47 | */ | ||
48 | if (poker) | ||
49 | (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE); | ||
50 | else | ||
51 | text_poke_bp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE, | ||
52 | (void *)entry->code + JUMP_LABEL_NOP_SIZE); | ||
41 | } | 53 | } |
42 | 54 | ||
43 | void arch_jump_label_transform(struct jump_entry *entry, | 55 | void arch_jump_label_transform(struct jump_entry *entry, |
@@ -45,7 +57,7 @@ void arch_jump_label_transform(struct jump_entry *entry, | |||
45 | { | 57 | { |
46 | get_online_cpus(); | 58 | get_online_cpus(); |
47 | mutex_lock(&text_mutex); | 59 | mutex_lock(&text_mutex); |
48 | __jump_label_transform(entry, type, text_poke_smp); | 60 | __jump_label_transform(entry, type, NULL); |
49 | mutex_unlock(&text_mutex); | 61 | mutex_unlock(&text_mutex); |
50 | put_online_cpus(); | 62 | put_online_cpus(); |
51 | } | 63 | } |
diff --git a/arch/x86/kernel/kprobes/common.h b/arch/x86/kernel/kprobes/common.h index 2e9d4b5af036..c6ee63f927ab 100644 --- a/arch/x86/kernel/kprobes/common.h +++ b/arch/x86/kernel/kprobes/common.h | |||
@@ -82,14 +82,9 @@ extern void synthesize_reljump(void *from, void *to); | |||
82 | extern void synthesize_relcall(void *from, void *to); | 82 | extern void synthesize_relcall(void *from, void *to); |
83 | 83 | ||
84 | #ifdef CONFIG_OPTPROBES | 84 | #ifdef CONFIG_OPTPROBES |
85 | extern int arch_init_optprobes(void); | ||
86 | extern int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter); | 85 | extern int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter); |
87 | extern unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr); | 86 | extern unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr); |
88 | #else /* !CONFIG_OPTPROBES */ | 87 | #else /* !CONFIG_OPTPROBES */ |
89 | static inline int arch_init_optprobes(void) | ||
90 | { | ||
91 | return 0; | ||
92 | } | ||
93 | static inline int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter) | 88 | static inline int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter) |
94 | { | 89 | { |
95 | return 0; | 90 | return 0; |
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 211bce445522..79a3f9682871 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
@@ -661,7 +661,7 @@ static void __used __kprobes kretprobe_trampoline_holder(void) | |||
661 | /* | 661 | /* |
662 | * Called from kretprobe_trampoline | 662 | * Called from kretprobe_trampoline |
663 | */ | 663 | */ |
664 | static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | 664 | __visible __used __kprobes void *trampoline_handler(struct pt_regs *regs) |
665 | { | 665 | { |
666 | struct kretprobe_instance *ri = NULL; | 666 | struct kretprobe_instance *ri = NULL; |
667 | struct hlist_head *head, empty_rp; | 667 | struct hlist_head *head, empty_rp; |
@@ -1068,7 +1068,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
1068 | 1068 | ||
1069 | int __init arch_init_kprobes(void) | 1069 | int __init arch_init_kprobes(void) |
1070 | { | 1070 | { |
1071 | return arch_init_optprobes(); | 1071 | return 0; |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | int __kprobes arch_trampoline_kprobe(struct kprobe *p) | 1074 | int __kprobes arch_trampoline_kprobe(struct kprobe *p) |
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 76dc6f095724..898160b42e43 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c | |||
@@ -88,9 +88,7 @@ static void __kprobes synthesize_set_arg1(kprobe_opcode_t *addr, unsigned long v | |||
88 | *(unsigned long *)addr = val; | 88 | *(unsigned long *)addr = val; |
89 | } | 89 | } |
90 | 90 | ||
91 | static void __used __kprobes kprobes_optinsn_template_holder(void) | 91 | asm ( |
92 | { | ||
93 | asm volatile ( | ||
94 | ".global optprobe_template_entry\n" | 92 | ".global optprobe_template_entry\n" |
95 | "optprobe_template_entry:\n" | 93 | "optprobe_template_entry:\n" |
96 | #ifdef CONFIG_X86_64 | 94 | #ifdef CONFIG_X86_64 |
@@ -129,7 +127,6 @@ static void __used __kprobes kprobes_optinsn_template_holder(void) | |||
129 | #endif | 127 | #endif |
130 | ".global optprobe_template_end\n" | 128 | ".global optprobe_template_end\n" |
131 | "optprobe_template_end:\n"); | 129 | "optprobe_template_end:\n"); |
132 | } | ||
133 | 130 | ||
134 | #define TMPL_MOVE_IDX \ | 131 | #define TMPL_MOVE_IDX \ |
135 | ((long)&optprobe_template_val - (long)&optprobe_template_entry) | 132 | ((long)&optprobe_template_val - (long)&optprobe_template_entry) |
@@ -371,31 +368,6 @@ int __kprobes arch_prepare_optimized_kprobe(struct optimized_kprobe *op) | |||
371 | return 0; | 368 | return 0; |
372 | } | 369 | } |
373 | 370 | ||
374 | #define MAX_OPTIMIZE_PROBES 256 | ||
375 | static struct text_poke_param *jump_poke_params; | ||
376 | static struct jump_poke_buffer { | ||
377 | u8 buf[RELATIVEJUMP_SIZE]; | ||
378 | } *jump_poke_bufs; | ||
379 | |||
380 | static void __kprobes setup_optimize_kprobe(struct text_poke_param *tprm, | ||
381 | u8 *insn_buf, | ||
382 | struct optimized_kprobe *op) | ||
383 | { | ||
384 | s32 rel = (s32)((long)op->optinsn.insn - | ||
385 | ((long)op->kp.addr + RELATIVEJUMP_SIZE)); | ||
386 | |||
387 | /* Backup instructions which will be replaced by jump address */ | ||
388 | memcpy(op->optinsn.copied_insn, op->kp.addr + INT3_SIZE, | ||
389 | RELATIVE_ADDR_SIZE); | ||
390 | |||
391 | insn_buf[0] = RELATIVEJUMP_OPCODE; | ||
392 | *(s32 *)(&insn_buf[1]) = rel; | ||
393 | |||
394 | tprm->addr = op->kp.addr; | ||
395 | tprm->opcode = insn_buf; | ||
396 | tprm->len = RELATIVEJUMP_SIZE; | ||
397 | } | ||
398 | |||
399 | /* | 371 | /* |
400 | * Replace breakpoints (int3) with relative jumps. | 372 | * Replace breakpoints (int3) with relative jumps. |
401 | * Caller must call with locking kprobe_mutex and text_mutex. | 373 | * Caller must call with locking kprobe_mutex and text_mutex. |
@@ -403,37 +375,38 @@ static void __kprobes setup_optimize_kprobe(struct text_poke_param *tprm, | |||
403 | void __kprobes arch_optimize_kprobes(struct list_head *oplist) | 375 | void __kprobes arch_optimize_kprobes(struct list_head *oplist) |
404 | { | 376 | { |
405 | struct optimized_kprobe *op, *tmp; | 377 | struct optimized_kprobe *op, *tmp; |
406 | int c = 0; | 378 | u8 insn_buf[RELATIVEJUMP_SIZE]; |
407 | 379 | ||
408 | list_for_each_entry_safe(op, tmp, oplist, list) { | 380 | list_for_each_entry_safe(op, tmp, oplist, list) { |
381 | s32 rel = (s32)((long)op->optinsn.insn - | ||
382 | ((long)op->kp.addr + RELATIVEJUMP_SIZE)); | ||
383 | |||
409 | WARN_ON(kprobe_disabled(&op->kp)); | 384 | WARN_ON(kprobe_disabled(&op->kp)); |
410 | /* Setup param */ | 385 | |
411 | setup_optimize_kprobe(&jump_poke_params[c], | 386 | /* Backup instructions which will be replaced by jump address */ |
412 | jump_poke_bufs[c].buf, op); | 387 | memcpy(op->optinsn.copied_insn, op->kp.addr + INT3_SIZE, |
388 | RELATIVE_ADDR_SIZE); | ||
389 | |||
390 | insn_buf[0] = RELATIVEJUMP_OPCODE; | ||
391 | *(s32 *)(&insn_buf[1]) = rel; | ||
392 | |||
393 | text_poke_bp(op->kp.addr, insn_buf, RELATIVEJUMP_SIZE, | ||
394 | op->optinsn.insn); | ||
395 | |||
413 | list_del_init(&op->list); | 396 | list_del_init(&op->list); |
414 | if (++c >= MAX_OPTIMIZE_PROBES) | ||
415 | break; | ||
416 | } | 397 | } |
417 | |||
418 | /* | ||
419 | * text_poke_smp doesn't support NMI/MCE code modifying. | ||
420 | * However, since kprobes itself also doesn't support NMI/MCE | ||
421 | * code probing, it's not a problem. | ||
422 | */ | ||
423 | text_poke_smp_batch(jump_poke_params, c); | ||
424 | } | 398 | } |
425 | 399 | ||
426 | static void __kprobes setup_unoptimize_kprobe(struct text_poke_param *tprm, | 400 | /* Replace a relative jump with a breakpoint (int3). */ |
427 | u8 *insn_buf, | 401 | void __kprobes arch_unoptimize_kprobe(struct optimized_kprobe *op) |
428 | struct optimized_kprobe *op) | ||
429 | { | 402 | { |
403 | u8 insn_buf[RELATIVEJUMP_SIZE]; | ||
404 | |||
430 | /* Set int3 to first byte for kprobes */ | 405 | /* Set int3 to first byte for kprobes */ |
431 | insn_buf[0] = BREAKPOINT_INSTRUCTION; | 406 | insn_buf[0] = BREAKPOINT_INSTRUCTION; |
432 | memcpy(insn_buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE); | 407 | memcpy(insn_buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE); |
433 | 408 | text_poke_bp(op->kp.addr, insn_buf, RELATIVEJUMP_SIZE, | |
434 | tprm->addr = op->kp.addr; | 409 | op->optinsn.insn); |
435 | tprm->opcode = insn_buf; | ||
436 | tprm->len = RELATIVEJUMP_SIZE; | ||
437 | } | 410 | } |
438 | 411 | ||
439 | /* | 412 | /* |
@@ -444,34 +417,11 @@ extern void arch_unoptimize_kprobes(struct list_head *oplist, | |||
444 | struct list_head *done_list) | 417 | struct list_head *done_list) |
445 | { | 418 | { |
446 | struct optimized_kprobe *op, *tmp; | 419 | struct optimized_kprobe *op, *tmp; |
447 | int c = 0; | ||
448 | 420 | ||
449 | list_for_each_entry_safe(op, tmp, oplist, list) { | 421 | list_for_each_entry_safe(op, tmp, oplist, list) { |
450 | /* Setup param */ | 422 | arch_unoptimize_kprobe(op); |
451 | setup_unoptimize_kprobe(&jump_poke_params[c], | ||
452 | jump_poke_bufs[c].buf, op); | ||
453 | list_move(&op->list, done_list); | 423 | list_move(&op->list, done_list); |
454 | if (++c >= MAX_OPTIMIZE_PROBES) | ||
455 | break; | ||
456 | } | 424 | } |
457 | |||
458 | /* | ||
459 | * text_poke_smp doesn't support NMI/MCE code modifying. | ||
460 | * However, since kprobes itself also doesn't support NMI/MCE | ||
461 | * code probing, it's not a problem. | ||
462 | */ | ||
463 | text_poke_smp_batch(jump_poke_params, c); | ||
464 | } | ||
465 | |||
466 | /* Replace a relative jump with a breakpoint (int3). */ | ||
467 | void __kprobes arch_unoptimize_kprobe(struct optimized_kprobe *op) | ||
468 | { | ||
469 | u8 buf[RELATIVEJUMP_SIZE]; | ||
470 | |||
471 | /* Set int3 to first byte for kprobes */ | ||
472 | buf[0] = BREAKPOINT_INSTRUCTION; | ||
473 | memcpy(buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE); | ||
474 | text_poke_smp(op->kp.addr, buf, RELATIVEJUMP_SIZE); | ||
475 | } | 425 | } |
476 | 426 | ||
477 | int __kprobes | 427 | int __kprobes |
@@ -491,22 +441,3 @@ setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter) | |||
491 | } | 441 | } |
492 | return 0; | 442 | return 0; |
493 | } | 443 | } |
494 | |||
495 | int __kprobes arch_init_optprobes(void) | ||
496 | { | ||
497 | /* Allocate code buffer and parameter array */ | ||
498 | jump_poke_bufs = kmalloc(sizeof(struct jump_poke_buffer) * | ||
499 | MAX_OPTIMIZE_PROBES, GFP_KERNEL); | ||
500 | if (!jump_poke_bufs) | ||
501 | return -ENOMEM; | ||
502 | |||
503 | jump_poke_params = kmalloc(sizeof(struct text_poke_param) * | ||
504 | MAX_OPTIMIZE_PROBES, GFP_KERNEL); | ||
505 | if (!jump_poke_params) { | ||
506 | kfree(jump_poke_bufs); | ||
507 | jump_poke_bufs = NULL; | ||
508 | return -ENOMEM; | ||
509 | } | ||
510 | |||
511 | return 0; | ||
512 | } | ||
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index a96d32cc55b8..697b93af02dd 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/kprobes.h> | 36 | #include <linux/kprobes.h> |
37 | #include <linux/debugfs.h> | ||
37 | #include <asm/timer.h> | 38 | #include <asm/timer.h> |
38 | #include <asm/cpu.h> | 39 | #include <asm/cpu.h> |
39 | #include <asm/traps.h> | 40 | #include <asm/traps.h> |
@@ -419,6 +420,7 @@ static void __init kvm_smp_prepare_boot_cpu(void) | |||
419 | WARN_ON(kvm_register_clock("primary cpu clock")); | 420 | WARN_ON(kvm_register_clock("primary cpu clock")); |
420 | kvm_guest_cpu_init(); | 421 | kvm_guest_cpu_init(); |
421 | native_smp_prepare_boot_cpu(); | 422 | native_smp_prepare_boot_cpu(); |
423 | kvm_spinlock_init(); | ||
422 | } | 424 | } |
423 | 425 | ||
424 | static void kvm_guest_cpu_online(void *dummy) | 426 | static void kvm_guest_cpu_online(void *dummy) |
@@ -498,11 +500,9 @@ void __init kvm_guest_init(void) | |||
498 | #endif | 500 | #endif |
499 | } | 501 | } |
500 | 502 | ||
501 | static bool __init kvm_detect(void) | 503 | static uint32_t __init kvm_detect(void) |
502 | { | 504 | { |
503 | if (!kvm_para_available()) | 505 | return kvm_cpuid_base(); |
504 | return false; | ||
505 | return true; | ||
506 | } | 506 | } |
507 | 507 | ||
508 | const struct hypervisor_x86 x86_hyper_kvm __refconst = { | 508 | const struct hypervisor_x86 x86_hyper_kvm __refconst = { |
@@ -523,3 +523,263 @@ static __init int activate_jump_labels(void) | |||
523 | return 0; | 523 | return 0; |
524 | } | 524 | } |
525 | arch_initcall(activate_jump_labels); | 525 | arch_initcall(activate_jump_labels); |
526 | |||
527 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | ||
528 | |||
529 | /* Kick a cpu by its apicid. Used to wake up a halted vcpu */ | ||
530 | static void kvm_kick_cpu(int cpu) | ||
531 | { | ||
532 | int apicid; | ||
533 | unsigned long flags = 0; | ||
534 | |||
535 | apicid = per_cpu(x86_cpu_to_apicid, cpu); | ||
536 | kvm_hypercall2(KVM_HC_KICK_CPU, flags, apicid); | ||
537 | } | ||
538 | |||
539 | enum kvm_contention_stat { | ||
540 | TAKEN_SLOW, | ||
541 | TAKEN_SLOW_PICKUP, | ||
542 | RELEASED_SLOW, | ||
543 | RELEASED_SLOW_KICKED, | ||
544 | NR_CONTENTION_STATS | ||
545 | }; | ||
546 | |||
547 | #ifdef CONFIG_KVM_DEBUG_FS | ||
548 | #define HISTO_BUCKETS 30 | ||
549 | |||
550 | static struct kvm_spinlock_stats | ||
551 | { | ||
552 | u32 contention_stats[NR_CONTENTION_STATS]; | ||
553 | u32 histo_spin_blocked[HISTO_BUCKETS+1]; | ||
554 | u64 time_blocked; | ||
555 | } spinlock_stats; | ||
556 | |||
557 | static u8 zero_stats; | ||
558 | |||
559 | static inline void check_zero(void) | ||
560 | { | ||
561 | u8 ret; | ||
562 | u8 old; | ||
563 | |||
564 | old = ACCESS_ONCE(zero_stats); | ||
565 | if (unlikely(old)) { | ||
566 | ret = cmpxchg(&zero_stats, old, 0); | ||
567 | /* This ensures only one fellow resets the stat */ | ||
568 | if (ret == old) | ||
569 | memset(&spinlock_stats, 0, sizeof(spinlock_stats)); | ||
570 | } | ||
571 | } | ||
572 | |||
573 | static inline void add_stats(enum kvm_contention_stat var, u32 val) | ||
574 | { | ||
575 | check_zero(); | ||
576 | spinlock_stats.contention_stats[var] += val; | ||
577 | } | ||
578 | |||
579 | |||
580 | static inline u64 spin_time_start(void) | ||
581 | { | ||
582 | return sched_clock(); | ||
583 | } | ||
584 | |||
585 | static void __spin_time_accum(u64 delta, u32 *array) | ||
586 | { | ||
587 | unsigned index; | ||
588 | |||
589 | index = ilog2(delta); | ||
590 | check_zero(); | ||
591 | |||
592 | if (index < HISTO_BUCKETS) | ||
593 | array[index]++; | ||
594 | else | ||
595 | array[HISTO_BUCKETS]++; | ||
596 | } | ||
597 | |||
598 | static inline void spin_time_accum_blocked(u64 start) | ||
599 | { | ||
600 | u32 delta; | ||
601 | |||
602 | delta = sched_clock() - start; | ||
603 | __spin_time_accum(delta, spinlock_stats.histo_spin_blocked); | ||
604 | spinlock_stats.time_blocked += delta; | ||
605 | } | ||
606 | |||
607 | static struct dentry *d_spin_debug; | ||
608 | static struct dentry *d_kvm_debug; | ||
609 | |||
610 | struct dentry *kvm_init_debugfs(void) | ||
611 | { | ||
612 | d_kvm_debug = debugfs_create_dir("kvm", NULL); | ||
613 | if (!d_kvm_debug) | ||
614 | printk(KERN_WARNING "Could not create 'kvm' debugfs directory\n"); | ||
615 | |||
616 | return d_kvm_debug; | ||
617 | } | ||
618 | |||
619 | static int __init kvm_spinlock_debugfs(void) | ||
620 | { | ||
621 | struct dentry *d_kvm; | ||
622 | |||
623 | d_kvm = kvm_init_debugfs(); | ||
624 | if (d_kvm == NULL) | ||
625 | return -ENOMEM; | ||
626 | |||
627 | d_spin_debug = debugfs_create_dir("spinlocks", d_kvm); | ||
628 | |||
629 | debugfs_create_u8("zero_stats", 0644, d_spin_debug, &zero_stats); | ||
630 | |||
631 | debugfs_create_u32("taken_slow", 0444, d_spin_debug, | ||
632 | &spinlock_stats.contention_stats[TAKEN_SLOW]); | ||
633 | debugfs_create_u32("taken_slow_pickup", 0444, d_spin_debug, | ||
634 | &spinlock_stats.contention_stats[TAKEN_SLOW_PICKUP]); | ||
635 | |||
636 | debugfs_create_u32("released_slow", 0444, d_spin_debug, | ||
637 | &spinlock_stats.contention_stats[RELEASED_SLOW]); | ||
638 | debugfs_create_u32("released_slow_kicked", 0444, d_spin_debug, | ||
639 | &spinlock_stats.contention_stats[RELEASED_SLOW_KICKED]); | ||
640 | |||
641 | debugfs_create_u64("time_blocked", 0444, d_spin_debug, | ||
642 | &spinlock_stats.time_blocked); | ||
643 | |||
644 | debugfs_create_u32_array("histo_blocked", 0444, d_spin_debug, | ||
645 | spinlock_stats.histo_spin_blocked, HISTO_BUCKETS + 1); | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | fs_initcall(kvm_spinlock_debugfs); | ||
650 | #else /* !CONFIG_KVM_DEBUG_FS */ | ||
651 | static inline void add_stats(enum kvm_contention_stat var, u32 val) | ||
652 | { | ||
653 | } | ||
654 | |||
655 | static inline u64 spin_time_start(void) | ||
656 | { | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static inline void spin_time_accum_blocked(u64 start) | ||
661 | { | ||
662 | } | ||
663 | #endif /* CONFIG_KVM_DEBUG_FS */ | ||
664 | |||
665 | struct kvm_lock_waiting { | ||
666 | struct arch_spinlock *lock; | ||
667 | __ticket_t want; | ||
668 | }; | ||
669 | |||
670 | /* cpus 'waiting' on a spinlock to become available */ | ||
671 | static cpumask_t waiting_cpus; | ||
672 | |||
673 | /* Track spinlock on which a cpu is waiting */ | ||
674 | static DEFINE_PER_CPU(struct kvm_lock_waiting, klock_waiting); | ||
675 | |||
676 | static void kvm_lock_spinning(struct arch_spinlock *lock, __ticket_t want) | ||
677 | { | ||
678 | struct kvm_lock_waiting *w; | ||
679 | int cpu; | ||
680 | u64 start; | ||
681 | unsigned long flags; | ||
682 | |||
683 | if (in_nmi()) | ||
684 | return; | ||
685 | |||
686 | w = &__get_cpu_var(klock_waiting); | ||
687 | cpu = smp_processor_id(); | ||
688 | start = spin_time_start(); | ||
689 | |||
690 | /* | ||
691 | * Make sure an interrupt handler can't upset things in a | ||
692 | * partially setup state. | ||
693 | */ | ||
694 | local_irq_save(flags); | ||
695 | |||
696 | /* | ||
697 | * The ordering protocol on this is that the "lock" pointer | ||
698 | * may only be set non-NULL if the "want" ticket is correct. | ||
699 | * If we're updating "want", we must first clear "lock". | ||
700 | */ | ||
701 | w->lock = NULL; | ||
702 | smp_wmb(); | ||
703 | w->want = want; | ||
704 | smp_wmb(); | ||
705 | w->lock = lock; | ||
706 | |||
707 | add_stats(TAKEN_SLOW, 1); | ||
708 | |||
709 | /* | ||
710 | * This uses set_bit, which is atomic but we should not rely on its | ||
711 | * reordering gurantees. So barrier is needed after this call. | ||
712 | */ | ||
713 | cpumask_set_cpu(cpu, &waiting_cpus); | ||
714 | |||
715 | barrier(); | ||
716 | |||
717 | /* | ||
718 | * Mark entry to slowpath before doing the pickup test to make | ||
719 | * sure we don't deadlock with an unlocker. | ||
720 | */ | ||
721 | __ticket_enter_slowpath(lock); | ||
722 | |||
723 | /* | ||
724 | * check again make sure it didn't become free while | ||
725 | * we weren't looking. | ||
726 | */ | ||
727 | if (ACCESS_ONCE(lock->tickets.head) == want) { | ||
728 | add_stats(TAKEN_SLOW_PICKUP, 1); | ||
729 | goto out; | ||
730 | } | ||
731 | |||
732 | /* | ||
733 | * halt until it's our turn and kicked. Note that we do safe halt | ||
734 | * for irq enabled case to avoid hang when lock info is overwritten | ||
735 | * in irq spinlock slowpath and no spurious interrupt occur to save us. | ||
736 | */ | ||
737 | if (arch_irqs_disabled_flags(flags)) | ||
738 | halt(); | ||
739 | else | ||
740 | safe_halt(); | ||
741 | |||
742 | out: | ||
743 | cpumask_clear_cpu(cpu, &waiting_cpus); | ||
744 | w->lock = NULL; | ||
745 | local_irq_restore(flags); | ||
746 | spin_time_accum_blocked(start); | ||
747 | } | ||
748 | PV_CALLEE_SAVE_REGS_THUNK(kvm_lock_spinning); | ||
749 | |||
750 | /* Kick vcpu waiting on @lock->head to reach value @ticket */ | ||
751 | static void kvm_unlock_kick(struct arch_spinlock *lock, __ticket_t ticket) | ||
752 | { | ||
753 | int cpu; | ||
754 | |||
755 | add_stats(RELEASED_SLOW, 1); | ||
756 | for_each_cpu(cpu, &waiting_cpus) { | ||
757 | const struct kvm_lock_waiting *w = &per_cpu(klock_waiting, cpu); | ||
758 | if (ACCESS_ONCE(w->lock) == lock && | ||
759 | ACCESS_ONCE(w->want) == ticket) { | ||
760 | add_stats(RELEASED_SLOW_KICKED, 1); | ||
761 | kvm_kick_cpu(cpu); | ||
762 | break; | ||
763 | } | ||
764 | } | ||
765 | } | ||
766 | |||
767 | /* | ||
768 | * Setup pv_lock_ops to exploit KVM_FEATURE_PV_UNHALT if present. | ||
769 | */ | ||
770 | void __init kvm_spinlock_init(void) | ||
771 | { | ||
772 | if (!kvm_para_available()) | ||
773 | return; | ||
774 | /* Does host kernel support KVM_FEATURE_PV_UNHALT? */ | ||
775 | if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT)) | ||
776 | return; | ||
777 | |||
778 | printk(KERN_INFO "KVM setup paravirtual spinlock\n"); | ||
779 | |||
780 | static_key_slow_inc(¶virt_ticketlocks_enabled); | ||
781 | |||
782 | pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(kvm_lock_spinning); | ||
783 | pv_lock_ops.unlock_kick = kvm_unlock_kick; | ||
784 | } | ||
785 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ | ||
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 7a0adb7ee433..7123b5df479d 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
@@ -145,10 +145,9 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static unsigned int verify_patch_size(int cpu, u32 patch_size, | 148 | static unsigned int verify_patch_size(u8 family, u32 patch_size, |
149 | unsigned int size) | 149 | unsigned int size) |
150 | { | 150 | { |
151 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
152 | u32 max_size; | 151 | u32 max_size; |
153 | 152 | ||
154 | #define F1XH_MPB_MAX_SIZE 2048 | 153 | #define F1XH_MPB_MAX_SIZE 2048 |
@@ -156,7 +155,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, | |||
156 | #define F15H_MPB_MAX_SIZE 4096 | 155 | #define F15H_MPB_MAX_SIZE 4096 |
157 | #define F16H_MPB_MAX_SIZE 3458 | 156 | #define F16H_MPB_MAX_SIZE 3458 |
158 | 157 | ||
159 | switch (c->x86) { | 158 | switch (family) { |
160 | case 0x14: | 159 | case 0x14: |
161 | max_size = F14H_MPB_MAX_SIZE; | 160 | max_size = F14H_MPB_MAX_SIZE; |
162 | break; | 161 | break; |
@@ -277,9 +276,8 @@ static void cleanup(void) | |||
277 | * driver cannot continue functioning normally. In such cases, we tear | 276 | * driver cannot continue functioning normally. In such cases, we tear |
278 | * down everything we've used up so far and exit. | 277 | * down everything we've used up so far and exit. |
279 | */ | 278 | */ |
280 | static int verify_and_add_patch(unsigned int cpu, u8 *fw, unsigned int leftover) | 279 | static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover) |
281 | { | 280 | { |
282 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
283 | struct microcode_header_amd *mc_hdr; | 281 | struct microcode_header_amd *mc_hdr; |
284 | struct ucode_patch *patch; | 282 | struct ucode_patch *patch; |
285 | unsigned int patch_size, crnt_size, ret; | 283 | unsigned int patch_size, crnt_size, ret; |
@@ -299,7 +297,7 @@ static int verify_and_add_patch(unsigned int cpu, u8 *fw, unsigned int leftover) | |||
299 | 297 | ||
300 | /* check if patch is for the current family */ | 298 | /* check if patch is for the current family */ |
301 | proc_fam = ((proc_fam >> 8) & 0xf) + ((proc_fam >> 20) & 0xff); | 299 | proc_fam = ((proc_fam >> 8) & 0xf) + ((proc_fam >> 20) & 0xff); |
302 | if (proc_fam != c->x86) | 300 | if (proc_fam != family) |
303 | return crnt_size; | 301 | return crnt_size; |
304 | 302 | ||
305 | if (mc_hdr->nb_dev_id || mc_hdr->sb_dev_id) { | 303 | if (mc_hdr->nb_dev_id || mc_hdr->sb_dev_id) { |
@@ -308,7 +306,7 @@ static int verify_and_add_patch(unsigned int cpu, u8 *fw, unsigned int leftover) | |||
308 | return crnt_size; | 306 | return crnt_size; |
309 | } | 307 | } |
310 | 308 | ||
311 | ret = verify_patch_size(cpu, patch_size, leftover); | 309 | ret = verify_patch_size(family, patch_size, leftover); |
312 | if (!ret) { | 310 | if (!ret) { |
313 | pr_err("Patch-ID 0x%08x: size mismatch.\n", mc_hdr->patch_id); | 311 | pr_err("Patch-ID 0x%08x: size mismatch.\n", mc_hdr->patch_id); |
314 | return crnt_size; | 312 | return crnt_size; |
@@ -339,7 +337,8 @@ static int verify_and_add_patch(unsigned int cpu, u8 *fw, unsigned int leftover) | |||
339 | return crnt_size; | 337 | return crnt_size; |
340 | } | 338 | } |
341 | 339 | ||
342 | static enum ucode_state __load_microcode_amd(int cpu, const u8 *data, size_t size) | 340 | static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, |
341 | size_t size) | ||
343 | { | 342 | { |
344 | enum ucode_state ret = UCODE_ERROR; | 343 | enum ucode_state ret = UCODE_ERROR; |
345 | unsigned int leftover; | 344 | unsigned int leftover; |
@@ -362,7 +361,7 @@ static enum ucode_state __load_microcode_amd(int cpu, const u8 *data, size_t siz | |||
362 | } | 361 | } |
363 | 362 | ||
364 | while (leftover) { | 363 | while (leftover) { |
365 | crnt_size = verify_and_add_patch(cpu, fw, leftover); | 364 | crnt_size = verify_and_add_patch(family, fw, leftover); |
366 | if (crnt_size < 0) | 365 | if (crnt_size < 0) |
367 | return ret; | 366 | return ret; |
368 | 367 | ||
@@ -373,22 +372,22 @@ static enum ucode_state __load_microcode_amd(int cpu, const u8 *data, size_t siz | |||
373 | return UCODE_OK; | 372 | return UCODE_OK; |
374 | } | 373 | } |
375 | 374 | ||
376 | enum ucode_state load_microcode_amd(int cpu, const u8 *data, size_t size) | 375 | enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) |
377 | { | 376 | { |
378 | enum ucode_state ret; | 377 | enum ucode_state ret; |
379 | 378 | ||
380 | /* free old equiv table */ | 379 | /* free old equiv table */ |
381 | free_equiv_cpu_table(); | 380 | free_equiv_cpu_table(); |
382 | 381 | ||
383 | ret = __load_microcode_amd(cpu, data, size); | 382 | ret = __load_microcode_amd(family, data, size); |
384 | 383 | ||
385 | if (ret != UCODE_OK) | 384 | if (ret != UCODE_OK) |
386 | cleanup(); | 385 | cleanup(); |
387 | 386 | ||
388 | #if defined(CONFIG_MICROCODE_AMD_EARLY) && defined(CONFIG_X86_32) | 387 | #if defined(CONFIG_MICROCODE_AMD_EARLY) && defined(CONFIG_X86_32) |
389 | /* save BSP's matching patch for early load */ | 388 | /* save BSP's matching patch for early load */ |
390 | if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) { | 389 | if (cpu_data(smp_processor_id()).cpu_index == boot_cpu_data.cpu_index) { |
391 | struct ucode_patch *p = find_patch(cpu); | 390 | struct ucode_patch *p = find_patch(smp_processor_id()); |
392 | if (p) { | 391 | if (p) { |
393 | memset(amd_bsp_mpb, 0, MPB_MAX_SIZE); | 392 | memset(amd_bsp_mpb, 0, MPB_MAX_SIZE); |
394 | memcpy(amd_bsp_mpb, p->data, min_t(u32, ksize(p->data), | 393 | memcpy(amd_bsp_mpb, p->data, min_t(u32, ksize(p->data), |
@@ -441,7 +440,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device, | |||
441 | goto fw_release; | 440 | goto fw_release; |
442 | } | 441 | } |
443 | 442 | ||
444 | ret = load_microcode_amd(cpu, fw->data, fw->size); | 443 | ret = load_microcode_amd(c->x86, fw->data, fw->size); |
445 | 444 | ||
446 | fw_release: | 445 | fw_release: |
447 | release_firmware(fw); | 446 | release_firmware(fw); |
diff --git a/arch/x86/kernel/microcode_amd_early.c b/arch/x86/kernel/microcode_amd_early.c index 1d14ffee5749..6073104ccaa3 100644 --- a/arch/x86/kernel/microcode_amd_early.c +++ b/arch/x86/kernel/microcode_amd_early.c | |||
@@ -238,25 +238,17 @@ static void __init collect_cpu_sig_on_bsp(void *arg) | |||
238 | uci->cpu_sig.sig = cpuid_eax(0x00000001); | 238 | uci->cpu_sig.sig = cpuid_eax(0x00000001); |
239 | } | 239 | } |
240 | #else | 240 | #else |
241 | static void collect_cpu_info_amd_early(struct cpuinfo_x86 *c, | 241 | void load_ucode_amd_ap(void) |
242 | struct ucode_cpu_info *uci) | ||
243 | { | 242 | { |
243 | unsigned int cpu = smp_processor_id(); | ||
244 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
244 | u32 rev, eax; | 245 | u32 rev, eax; |
245 | 246 | ||
246 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax); | 247 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax); |
247 | eax = cpuid_eax(0x00000001); | 248 | eax = cpuid_eax(0x00000001); |
248 | 249 | ||
249 | uci->cpu_sig.sig = eax; | ||
250 | uci->cpu_sig.rev = rev; | 250 | uci->cpu_sig.rev = rev; |
251 | c->microcode = rev; | 251 | uci->cpu_sig.sig = eax; |
252 | c->x86 = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | ||
253 | } | ||
254 | |||
255 | void load_ucode_amd_ap(void) | ||
256 | { | ||
257 | unsigned int cpu = smp_processor_id(); | ||
258 | |||
259 | collect_cpu_info_amd_early(&cpu_data(cpu), ucode_cpu_info + cpu); | ||
260 | 252 | ||
261 | if (cpu && !ucode_loaded) { | 253 | if (cpu && !ucode_loaded) { |
262 | void *ucode; | 254 | void *ucode; |
@@ -265,8 +257,10 @@ void load_ucode_amd_ap(void) | |||
265 | return; | 257 | return; |
266 | 258 | ||
267 | ucode = (void *)(initrd_start + ucode_offset); | 259 | ucode = (void *)(initrd_start + ucode_offset); |
268 | if (load_microcode_amd(0, ucode, ucode_size) != UCODE_OK) | 260 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); |
261 | if (load_microcode_amd(eax, ucode, ucode_size) != UCODE_OK) | ||
269 | return; | 262 | return; |
263 | |||
270 | ucode_loaded = true; | 264 | ucode_loaded = true; |
271 | } | 265 | } |
272 | 266 | ||
@@ -278,6 +272,8 @@ int __init save_microcode_in_initrd_amd(void) | |||
278 | { | 272 | { |
279 | enum ucode_state ret; | 273 | enum ucode_state ret; |
280 | void *ucode; | 274 | void *ucode; |
275 | u32 eax; | ||
276 | |||
281 | #ifdef CONFIG_X86_32 | 277 | #ifdef CONFIG_X86_32 |
282 | unsigned int bsp = boot_cpu_data.cpu_index; | 278 | unsigned int bsp = boot_cpu_data.cpu_index; |
283 | struct ucode_cpu_info *uci = ucode_cpu_info + bsp; | 279 | struct ucode_cpu_info *uci = ucode_cpu_info + bsp; |
@@ -293,7 +289,10 @@ int __init save_microcode_in_initrd_amd(void) | |||
293 | return 0; | 289 | return 0; |
294 | 290 | ||
295 | ucode = (void *)(initrd_start + ucode_offset); | 291 | ucode = (void *)(initrd_start + ucode_offset); |
296 | ret = load_microcode_amd(0, ucode, ucode_size); | 292 | eax = cpuid_eax(0x00000001); |
293 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | ||
294 | |||
295 | ret = load_microcode_amd(eax, ucode, ucode_size); | ||
297 | if (ret != UCODE_OK) | 296 | if (ret != UCODE_OK) |
298 | return -EINVAL; | 297 | return -EINVAL; |
299 | 298 | ||
diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 676b8c77a976..bbb6c7316341 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c | |||
@@ -4,25 +4,17 @@ | |||
4 | */ | 4 | */ |
5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/jump_label.h> | ||
7 | 8 | ||
8 | #include <asm/paravirt.h> | 9 | #include <asm/paravirt.h> |
9 | 10 | ||
10 | static inline void | ||
11 | default_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) | ||
12 | { | ||
13 | arch_spin_lock(lock); | ||
14 | } | ||
15 | |||
16 | struct pv_lock_ops pv_lock_ops = { | 11 | struct pv_lock_ops pv_lock_ops = { |
17 | #ifdef CONFIG_SMP | 12 | #ifdef CONFIG_SMP |
18 | .spin_is_locked = __ticket_spin_is_locked, | 13 | .lock_spinning = __PV_IS_CALLEE_SAVE(paravirt_nop), |
19 | .spin_is_contended = __ticket_spin_is_contended, | 14 | .unlock_kick = paravirt_nop, |
20 | |||
21 | .spin_lock = __ticket_spin_lock, | ||
22 | .spin_lock_flags = default_spin_lock_flags, | ||
23 | .spin_trylock = __ticket_spin_trylock, | ||
24 | .spin_unlock = __ticket_spin_unlock, | ||
25 | #endif | 15 | #endif |
26 | }; | 16 | }; |
27 | EXPORT_SYMBOL(pv_lock_ops); | 17 | EXPORT_SYMBOL(pv_lock_ops); |
28 | 18 | ||
19 | struct static_key paravirt_ticketlocks_enabled = STATIC_KEY_INIT_FALSE; | ||
20 | EXPORT_SYMBOL(paravirt_ticketlocks_enabled); | ||
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index cd6de64cc480..1b10af835c31 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -62,11 +62,6 @@ void __init default_banner(void) | |||
62 | pv_info.name); | 62 | pv_info.name); |
63 | } | 63 | } |
64 | 64 | ||
65 | /* Simple instruction patching code. */ | ||
66 | #define DEF_NATIVE(ops, name, code) \ | ||
67 | extern const char start_##ops##_##name[], end_##ops##_##name[]; \ | ||
68 | asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") | ||
69 | |||
70 | /* Undefined instruction for dealing with missing ops pointers. */ | 65 | /* Undefined instruction for dealing with missing ops pointers. */ |
71 | static const unsigned char ud2a[] = { 0x0f, 0x0b }; | 66 | static const unsigned char ud2a[] = { 0x0f, 0x0b }; |
72 | 67 | ||
@@ -324,7 +319,7 @@ struct pv_time_ops pv_time_ops = { | |||
324 | .steal_clock = native_steal_clock, | 319 | .steal_clock = native_steal_clock, |
325 | }; | 320 | }; |
326 | 321 | ||
327 | struct pv_irq_ops pv_irq_ops = { | 322 | __visible struct pv_irq_ops pv_irq_ops = { |
328 | .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), | 323 | .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), |
329 | .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl), | 324 | .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl), |
330 | .irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), | 325 | .irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), |
@@ -336,7 +331,7 @@ struct pv_irq_ops pv_irq_ops = { | |||
336 | #endif | 331 | #endif |
337 | }; | 332 | }; |
338 | 333 | ||
339 | struct pv_cpu_ops pv_cpu_ops = { | 334 | __visible struct pv_cpu_ops pv_cpu_ops = { |
340 | .cpuid = native_cpuid, | 335 | .cpuid = native_cpuid, |
341 | .get_debugreg = native_get_debugreg, | 336 | .get_debugreg = native_get_debugreg, |
342 | .set_debugreg = native_set_debugreg, | 337 | .set_debugreg = native_set_debugreg, |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 83369e5a1d27..c83516be1052 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -36,7 +36,7 @@ | |||
36 | * section. Since TSS's are completely CPU-local, we want them | 36 | * section. Since TSS's are completely CPU-local, we want them |
37 | * on exact cacheline boundaries, to eliminate cacheline ping-pong. | 37 | * on exact cacheline boundaries, to eliminate cacheline ping-pong. |
38 | */ | 38 | */ |
39 | DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; | 39 | __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; |
40 | 40 | ||
41 | #ifdef CONFIG_X86_64 | 41 | #ifdef CONFIG_X86_64 |
42 | static DEFINE_PER_CPU(unsigned char, is_idle); | 42 | static DEFINE_PER_CPU(unsigned char, is_idle); |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index f8adefca71dc..884f98f69354 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -247,7 +247,7 @@ EXPORT_SYMBOL_GPL(start_thread); | |||
247 | * the task-switch, and shows up in ret_from_fork in entry.S, | 247 | * the task-switch, and shows up in ret_from_fork in entry.S, |
248 | * for example. | 248 | * for example. |
249 | */ | 249 | */ |
250 | __notrace_funcgraph struct task_struct * | 250 | __visible __notrace_funcgraph struct task_struct * |
251 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | 251 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) |
252 | { | 252 | { |
253 | struct thread_struct *prev = &prev_p->thread, | 253 | struct thread_struct *prev = &prev_p->thread, |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 05646bab4ca6..bb1dc51bab05 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -52,7 +52,7 @@ | |||
52 | 52 | ||
53 | asmlinkage extern void ret_from_fork(void); | 53 | asmlinkage extern void ret_from_fork(void); |
54 | 54 | ||
55 | DEFINE_PER_CPU(unsigned long, old_rsp); | 55 | asmlinkage DEFINE_PER_CPU(unsigned long, old_rsp); |
56 | 56 | ||
57 | /* Prints also some state that isn't saved in the pt_regs */ | 57 | /* Prints also some state that isn't saved in the pt_regs */ |
58 | void __show_regs(struct pt_regs *regs, int all) | 58 | void __show_regs(struct pt_regs *regs, int all) |
@@ -274,7 +274,7 @@ void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp) | |||
274 | * Kprobes not supported here. Set the probe on schedule instead. | 274 | * Kprobes not supported here. Set the probe on schedule instead. |
275 | * Function graph tracer not supported too. | 275 | * Function graph tracer not supported too. |
276 | */ | 276 | */ |
277 | __notrace_funcgraph struct task_struct * | 277 | __visible __notrace_funcgraph struct task_struct * |
278 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | 278 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) |
279 | { | 279 | { |
280 | struct thread_struct *prev = &prev_p->thread; | 280 | struct thread_struct *prev = &prev_p->thread; |
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 2cb9470ea85b..a16bae3f83b3 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c | |||
@@ -128,46 +128,7 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock, | |||
128 | set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); | 128 | set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); |
129 | } | 129 | } |
130 | 130 | ||
131 | static struct pvclock_vsyscall_time_info *pvclock_vdso_info; | ||
132 | |||
133 | static struct pvclock_vsyscall_time_info * | ||
134 | pvclock_get_vsyscall_user_time_info(int cpu) | ||
135 | { | ||
136 | if (!pvclock_vdso_info) { | ||
137 | BUG(); | ||
138 | return NULL; | ||
139 | } | ||
140 | |||
141 | return &pvclock_vdso_info[cpu]; | ||
142 | } | ||
143 | |||
144 | struct pvclock_vcpu_time_info *pvclock_get_vsyscall_time_info(int cpu) | ||
145 | { | ||
146 | return &pvclock_get_vsyscall_user_time_info(cpu)->pvti; | ||
147 | } | ||
148 | |||
149 | #ifdef CONFIG_X86_64 | 131 | #ifdef CONFIG_X86_64 |
150 | static int pvclock_task_migrate(struct notifier_block *nb, unsigned long l, | ||
151 | void *v) | ||
152 | { | ||
153 | struct task_migration_notifier *mn = v; | ||
154 | struct pvclock_vsyscall_time_info *pvti; | ||
155 | |||
156 | pvti = pvclock_get_vsyscall_user_time_info(mn->from_cpu); | ||
157 | |||
158 | /* this is NULL when pvclock vsyscall is not initialized */ | ||
159 | if (unlikely(pvti == NULL)) | ||
160 | return NOTIFY_DONE; | ||
161 | |||
162 | pvti->migrate_count++; | ||
163 | |||
164 | return NOTIFY_DONE; | ||
165 | } | ||
166 | |||
167 | static struct notifier_block pvclock_migrate = { | ||
168 | .notifier_call = pvclock_task_migrate, | ||
169 | }; | ||
170 | |||
171 | /* | 132 | /* |
172 | * Initialize the generic pvclock vsyscall state. This will allocate | 133 | * Initialize the generic pvclock vsyscall state. This will allocate |
173 | * a/some page(s) for the per-vcpu pvclock information, set up a | 134 | * a/some page(s) for the per-vcpu pvclock information, set up a |
@@ -181,17 +142,12 @@ int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i, | |||
181 | 142 | ||
182 | WARN_ON (size != PVCLOCK_VSYSCALL_NR_PAGES*PAGE_SIZE); | 143 | WARN_ON (size != PVCLOCK_VSYSCALL_NR_PAGES*PAGE_SIZE); |
183 | 144 | ||
184 | pvclock_vdso_info = i; | ||
185 | |||
186 | for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { | 145 | for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { |
187 | __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx, | 146 | __set_fixmap(PVCLOCK_FIXMAP_BEGIN + idx, |
188 | __pa(i) + (idx*PAGE_SIZE), | 147 | __pa(i) + (idx*PAGE_SIZE), |
189 | PAGE_KERNEL_VVAR); | 148 | PAGE_KERNEL_VVAR); |
190 | } | 149 | } |
191 | 150 | ||
192 | |||
193 | register_task_migration_notifier(&pvclock_migrate); | ||
194 | |||
195 | return 0; | 151 | return 0; |
196 | } | 152 | } |
197 | #endif | 153 | #endif |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index f8ec57815c05..f0de6294b955 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -206,9 +206,9 @@ EXPORT_SYMBOL(boot_cpu_data); | |||
206 | 206 | ||
207 | 207 | ||
208 | #if !defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64) | 208 | #if !defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64) |
209 | unsigned long mmu_cr4_features; | 209 | __visible unsigned long mmu_cr4_features; |
210 | #else | 210 | #else |
211 | unsigned long mmu_cr4_features = X86_CR4_PAE; | 211 | __visible unsigned long mmu_cr4_features = X86_CR4_PAE; |
212 | #endif | 212 | #endif |
213 | 213 | ||
214 | /* Boot loader ID and version as integers, for the benefit of proc_dointvec */ | 214 | /* Boot loader ID and version as integers, for the benefit of proc_dointvec */ |
@@ -426,25 +426,23 @@ static void __init reserve_initrd(void) | |||
426 | static void __init parse_setup_data(void) | 426 | static void __init parse_setup_data(void) |
427 | { | 427 | { |
428 | struct setup_data *data; | 428 | struct setup_data *data; |
429 | u64 pa_data; | 429 | u64 pa_data, pa_next; |
430 | 430 | ||
431 | pa_data = boot_params.hdr.setup_data; | 431 | pa_data = boot_params.hdr.setup_data; |
432 | while (pa_data) { | 432 | while (pa_data) { |
433 | u32 data_len, map_len; | 433 | u32 data_len, map_len, data_type; |
434 | 434 | ||
435 | map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK), | 435 | map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK), |
436 | (u64)sizeof(struct setup_data)); | 436 | (u64)sizeof(struct setup_data)); |
437 | data = early_memremap(pa_data, map_len); | 437 | data = early_memremap(pa_data, map_len); |
438 | data_len = data->len + sizeof(struct setup_data); | 438 | data_len = data->len + sizeof(struct setup_data); |
439 | if (data_len > map_len) { | 439 | data_type = data->type; |
440 | early_iounmap(data, map_len); | 440 | pa_next = data->next; |
441 | data = early_memremap(pa_data, data_len); | 441 | early_iounmap(data, map_len); |
442 | map_len = data_len; | ||
443 | } | ||
444 | 442 | ||
445 | switch (data->type) { | 443 | switch (data_type) { |
446 | case SETUP_E820_EXT: | 444 | case SETUP_E820_EXT: |
447 | parse_e820_ext(data); | 445 | parse_e820_ext(pa_data, data_len); |
448 | break; | 446 | break; |
449 | case SETUP_DTB: | 447 | case SETUP_DTB: |
450 | add_dtb(pa_data); | 448 | add_dtb(pa_data); |
@@ -452,8 +450,7 @@ static void __init parse_setup_data(void) | |||
452 | default: | 450 | default: |
453 | break; | 451 | break; |
454 | } | 452 | } |
455 | pa_data = data->next; | 453 | pa_data = pa_next; |
456 | early_iounmap(data, map_len); | ||
457 | } | 454 | } |
458 | } | 455 | } |
459 | 456 | ||
@@ -1070,7 +1067,7 @@ void __init setup_arch(char **cmdline_p) | |||
1070 | 1067 | ||
1071 | cleanup_highmap(); | 1068 | cleanup_highmap(); |
1072 | 1069 | ||
1073 | memblock.current_limit = ISA_END_ADDRESS; | 1070 | memblock_set_current_limit(ISA_END_ADDRESS); |
1074 | memblock_x86_fill(); | 1071 | memblock_x86_fill(); |
1075 | 1072 | ||
1076 | /* | 1073 | /* |
@@ -1103,7 +1100,7 @@ void __init setup_arch(char **cmdline_p) | |||
1103 | 1100 | ||
1104 | setup_real_mode(); | 1101 | setup_real_mode(); |
1105 | 1102 | ||
1106 | memblock.current_limit = get_max_mapped(); | 1103 | memblock_set_current_limit(get_max_mapped()); |
1107 | dma_contiguous_reserve(0); | 1104 | dma_contiguous_reserve(0); |
1108 | 1105 | ||
1109 | /* | 1106 | /* |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index cf913587d4dd..9e5de6813e1f 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -358,7 +358,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, | |||
358 | else | 358 | else |
359 | put_user_ex(0, &frame->uc.uc_flags); | 359 | put_user_ex(0, &frame->uc.uc_flags); |
360 | put_user_ex(0, &frame->uc.uc_link); | 360 | put_user_ex(0, &frame->uc.uc_link); |
361 | err |= __save_altstack(&frame->uc.uc_stack, regs->sp); | 361 | save_altstack_ex(&frame->uc.uc_stack, regs->sp); |
362 | 362 | ||
363 | /* Set up to return from userspace. */ | 363 | /* Set up to return from userspace. */ |
364 | restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); | 364 | restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); |
@@ -423,7 +423,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, | |||
423 | else | 423 | else |
424 | put_user_ex(0, &frame->uc.uc_flags); | 424 | put_user_ex(0, &frame->uc.uc_flags); |
425 | put_user_ex(0, &frame->uc.uc_link); | 425 | put_user_ex(0, &frame->uc.uc_link); |
426 | err |= __save_altstack(&frame->uc.uc_stack, regs->sp); | 426 | save_altstack_ex(&frame->uc.uc_stack, regs->sp); |
427 | 427 | ||
428 | /* Set up to return from userspace. If provided, use a stub | 428 | /* Set up to return from userspace. If provided, use a stub |
429 | already in userspace. */ | 429 | already in userspace. */ |
@@ -490,7 +490,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig, | |||
490 | else | 490 | else |
491 | put_user_ex(0, &frame->uc.uc_flags); | 491 | put_user_ex(0, &frame->uc.uc_flags); |
492 | put_user_ex(0, &frame->uc.uc_link); | 492 | put_user_ex(0, &frame->uc.uc_link); |
493 | err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp); | 493 | compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); |
494 | put_user_ex(0, &frame->uc.uc__pad0); | 494 | put_user_ex(0, &frame->uc.uc__pad0); |
495 | 495 | ||
496 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { | 496 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
@@ -533,7 +533,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig, | |||
533 | * Do a signal return; undo the signal stack. | 533 | * Do a signal return; undo the signal stack. |
534 | */ | 534 | */ |
535 | #ifdef CONFIG_X86_32 | 535 | #ifdef CONFIG_X86_32 |
536 | unsigned long sys_sigreturn(void) | 536 | asmlinkage unsigned long sys_sigreturn(void) |
537 | { | 537 | { |
538 | struct pt_regs *regs = current_pt_regs(); | 538 | struct pt_regs *regs = current_pt_regs(); |
539 | struct sigframe __user *frame; | 539 | struct sigframe __user *frame; |
@@ -562,7 +562,7 @@ badframe: | |||
562 | } | 562 | } |
563 | #endif /* CONFIG_X86_32 */ | 563 | #endif /* CONFIG_X86_32 */ |
564 | 564 | ||
565 | long sys_rt_sigreturn(void) | 565 | asmlinkage long sys_rt_sigreturn(void) |
566 | { | 566 | { |
567 | struct pt_regs *regs = current_pt_regs(); | 567 | struct pt_regs *regs = current_pt_regs(); |
568 | struct rt_sigframe __user *frame; | 568 | struct rt_sigframe __user *frame; |
@@ -728,7 +728,7 @@ static void do_signal(struct pt_regs *regs) | |||
728 | * notification of userspace execution resumption | 728 | * notification of userspace execution resumption |
729 | * - triggered by the TIF_WORK_MASK flags | 729 | * - triggered by the TIF_WORK_MASK flags |
730 | */ | 730 | */ |
731 | void | 731 | __visible void |
732 | do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | 732 | do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) |
733 | { | 733 | { |
734 | user_exit(); | 734 | user_exit(); |
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index cdaa347dfcad..7c3a5a61f2e4 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
@@ -256,7 +256,7 @@ static inline void __smp_reschedule_interrupt(void) | |||
256 | scheduler_ipi(); | 256 | scheduler_ipi(); |
257 | } | 257 | } |
258 | 258 | ||
259 | void smp_reschedule_interrupt(struct pt_regs *regs) | 259 | __visible void smp_reschedule_interrupt(struct pt_regs *regs) |
260 | { | 260 | { |
261 | ack_APIC_irq(); | 261 | ack_APIC_irq(); |
262 | __smp_reschedule_interrupt(); | 262 | __smp_reschedule_interrupt(); |
@@ -271,7 +271,7 @@ static inline void smp_entering_irq(void) | |||
271 | irq_enter(); | 271 | irq_enter(); |
272 | } | 272 | } |
273 | 273 | ||
274 | void smp_trace_reschedule_interrupt(struct pt_regs *regs) | 274 | __visible void smp_trace_reschedule_interrupt(struct pt_regs *regs) |
275 | { | 275 | { |
276 | /* | 276 | /* |
277 | * Need to call irq_enter() before calling the trace point. | 277 | * Need to call irq_enter() before calling the trace point. |
@@ -295,14 +295,14 @@ static inline void __smp_call_function_interrupt(void) | |||
295 | inc_irq_stat(irq_call_count); | 295 | inc_irq_stat(irq_call_count); |
296 | } | 296 | } |
297 | 297 | ||
298 | void smp_call_function_interrupt(struct pt_regs *regs) | 298 | __visible void smp_call_function_interrupt(struct pt_regs *regs) |
299 | { | 299 | { |
300 | smp_entering_irq(); | 300 | smp_entering_irq(); |
301 | __smp_call_function_interrupt(); | 301 | __smp_call_function_interrupt(); |
302 | exiting_irq(); | 302 | exiting_irq(); |
303 | } | 303 | } |
304 | 304 | ||
305 | void smp_trace_call_function_interrupt(struct pt_regs *regs) | 305 | __visible void smp_trace_call_function_interrupt(struct pt_regs *regs) |
306 | { | 306 | { |
307 | smp_entering_irq(); | 307 | smp_entering_irq(); |
308 | trace_call_function_entry(CALL_FUNCTION_VECTOR); | 308 | trace_call_function_entry(CALL_FUNCTION_VECTOR); |
@@ -317,14 +317,14 @@ static inline void __smp_call_function_single_interrupt(void) | |||
317 | inc_irq_stat(irq_call_count); | 317 | inc_irq_stat(irq_call_count); |
318 | } | 318 | } |
319 | 319 | ||
320 | void smp_call_function_single_interrupt(struct pt_regs *regs) | 320 | __visible void smp_call_function_single_interrupt(struct pt_regs *regs) |
321 | { | 321 | { |
322 | smp_entering_irq(); | 322 | smp_entering_irq(); |
323 | __smp_call_function_single_interrupt(); | 323 | __smp_call_function_single_interrupt(); |
324 | exiting_irq(); | 324 | exiting_irq(); |
325 | } | 325 | } |
326 | 326 | ||
327 | void smp_trace_call_function_single_interrupt(struct pt_regs *regs) | 327 | __visible void smp_trace_call_function_single_interrupt(struct pt_regs *regs) |
328 | { | 328 | { |
329 | smp_entering_irq(); | 329 | smp_entering_irq(); |
330 | trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR); | 330 | trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR); |
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index dbded5aedb81..30277e27431a 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c | |||
@@ -101,7 +101,7 @@ static void find_start_end(unsigned long flags, unsigned long *begin, | |||
101 | *begin = new_begin; | 101 | *begin = new_begin; |
102 | } | 102 | } |
103 | } else { | 103 | } else { |
104 | *begin = TASK_UNMAPPED_BASE; | 104 | *begin = current->mm->mmap_legacy_base; |
105 | *end = TASK_SIZE; | 105 | *end = TASK_SIZE; |
106 | } | 106 | } |
107 | } | 107 | } |
diff --git a/arch/x86/kernel/syscall_32.c b/arch/x86/kernel/syscall_32.c index 147fcd4941c4..e9bcd57d8a9e 100644 --- a/arch/x86/kernel/syscall_32.c +++ b/arch/x86/kernel/syscall_32.c | |||
@@ -15,7 +15,7 @@ typedef asmlinkage void (*sys_call_ptr_t)(void); | |||
15 | 15 | ||
16 | extern asmlinkage void sys_ni_syscall(void); | 16 | extern asmlinkage void sys_ni_syscall(void); |
17 | 17 | ||
18 | const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { | 18 | __visible const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { |
19 | /* | 19 | /* |
20 | * Smells like a compiler bug -- it doesn't work | 20 | * Smells like a compiler bug -- it doesn't work |
21 | * when the & below is removed. | 21 | * when the & below is removed. |
diff --git a/arch/x86/kernel/syscall_64.c b/arch/x86/kernel/syscall_64.c index 5c7f8c20da74..4ac730b37f0b 100644 --- a/arch/x86/kernel/syscall_64.c +++ b/arch/x86/kernel/syscall_64.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/sys.h> | 4 | #include <linux/sys.h> |
5 | #include <linux/cache.h> | 5 | #include <linux/cache.h> |
6 | #include <asm/asm-offsets.h> | 6 | #include <asm/asm-offsets.h> |
7 | #include <asm/syscall.h> | ||
7 | 8 | ||
8 | #define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat) | 9 | #define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat) |
9 | 10 | ||
@@ -19,11 +20,9 @@ | |||
19 | 20 | ||
20 | #define __SYSCALL_64(nr, sym, compat) [nr] = sym, | 21 | #define __SYSCALL_64(nr, sym, compat) [nr] = sym, |
21 | 22 | ||
22 | typedef void (*sys_call_ptr_t)(void); | ||
23 | |||
24 | extern void sys_ni_syscall(void); | 23 | extern void sys_ni_syscall(void); |
25 | 24 | ||
26 | const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { | 25 | asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { |
27 | /* | 26 | /* |
28 | * Smells like a compiler bug -- it doesn't work | 27 | * Smells like a compiler bug -- it doesn't work |
29 | * when the & below is removed. | 28 | * when the & below is removed. |
diff --git a/arch/x86/kernel/sysfb.c b/arch/x86/kernel/sysfb.c new file mode 100644 index 000000000000..193ec2ce46c7 --- /dev/null +++ b/arch/x86/kernel/sysfb.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Generic System Framebuffers on x86 | ||
3 | * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the Free | ||
7 | * Software Foundation; either version 2 of the License, or (at your option) | ||
8 | * any later version. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * Simple-Framebuffer support for x86 systems | ||
13 | * Create a platform-device for any available boot framebuffer. The | ||
14 | * simple-framebuffer platform device is already available on DT systems, so | ||
15 | * this module parses the global "screen_info" object and creates a suitable | ||
16 | * platform device compatible with the "simple-framebuffer" DT object. If | ||
17 | * the framebuffer is incompatible, we instead create a legacy | ||
18 | * "vesa-framebuffer", "efi-framebuffer" or "platform-framebuffer" device and | ||
19 | * pass the screen_info as platform_data. This allows legacy drivers | ||
20 | * to pick these devices up without messing with simple-framebuffer drivers. | ||
21 | * The global "screen_info" is still valid at all times. | ||
22 | * | ||
23 | * If CONFIG_X86_SYSFB is not selected, we never register "simple-framebuffer" | ||
24 | * platform devices, but only use legacy framebuffer devices for | ||
25 | * backwards compatibility. | ||
26 | * | ||
27 | * TODO: We set the dev_id field of all platform-devices to 0. This allows | ||
28 | * other x86 OF/DT parsers to create such devices, too. However, they must | ||
29 | * start at offset 1 for this to work. | ||
30 | */ | ||
31 | |||
32 | #include <linux/err.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/kernel.h> | ||
35 | #include <linux/mm.h> | ||
36 | #include <linux/platform_data/simplefb.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/screen_info.h> | ||
39 | #include <asm/sysfb.h> | ||
40 | |||
41 | static __init int sysfb_init(void) | ||
42 | { | ||
43 | struct screen_info *si = &screen_info; | ||
44 | struct simplefb_platform_data mode; | ||
45 | struct platform_device *pd; | ||
46 | const char *name; | ||
47 | bool compatible; | ||
48 | int ret; | ||
49 | |||
50 | sysfb_apply_efi_quirks(); | ||
51 | |||
52 | /* try to create a simple-framebuffer device */ | ||
53 | compatible = parse_mode(si, &mode); | ||
54 | if (compatible) { | ||
55 | ret = create_simplefb(si, &mode); | ||
56 | if (!ret) | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | /* if the FB is incompatible, create a legacy framebuffer device */ | ||
61 | if (si->orig_video_isVGA == VIDEO_TYPE_EFI) | ||
62 | name = "efi-framebuffer"; | ||
63 | else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB) | ||
64 | name = "vesa-framebuffer"; | ||
65 | else | ||
66 | name = "platform-framebuffer"; | ||
67 | |||
68 | pd = platform_device_register_resndata(NULL, name, 0, | ||
69 | NULL, 0, si, sizeof(*si)); | ||
70 | return IS_ERR(pd) ? PTR_ERR(pd) : 0; | ||
71 | } | ||
72 | |||
73 | /* must execute after PCI subsystem for EFI quirks */ | ||
74 | device_initcall(sysfb_init); | ||
diff --git a/arch/x86/kernel/sysfb_efi.c b/arch/x86/kernel/sysfb_efi.c new file mode 100644 index 000000000000..b285d4e8c68e --- /dev/null +++ b/arch/x86/kernel/sysfb_efi.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * Generic System Framebuffers on x86 | ||
3 | * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> | ||
4 | * | ||
5 | * EFI Quirks Copyright (c) 2006 Edgar Hucek <gimli@dark-green.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the Free | ||
9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
10 | * any later version. | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * EFI Quirks | ||
15 | * Several EFI systems do not correctly advertise their boot framebuffers. | ||
16 | * Hence, we use this static table of known broken machines and fix up the | ||
17 | * information so framebuffer drivers can load corectly. | ||
18 | */ | ||
19 | |||
20 | #include <linux/dmi.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <linux/screen_info.h> | ||
27 | #include <video/vga.h> | ||
28 | #include <asm/sysfb.h> | ||
29 | |||
30 | enum { | ||
31 | OVERRIDE_NONE = 0x0, | ||
32 | OVERRIDE_BASE = 0x1, | ||
33 | OVERRIDE_STRIDE = 0x2, | ||
34 | OVERRIDE_HEIGHT = 0x4, | ||
35 | OVERRIDE_WIDTH = 0x8, | ||
36 | }; | ||
37 | |||
38 | struct efifb_dmi_info efifb_dmi_list[] = { | ||
39 | [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
40 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */ | ||
41 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, | ||
42 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */ | ||
43 | [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
44 | [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE }, | ||
45 | [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE }, | ||
46 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE }, | ||
47 | [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE }, | ||
48 | [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
49 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
50 | [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
51 | [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
52 | [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
53 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
54 | /* 11" Macbook Air 3,1 passes the wrong stride */ | ||
55 | [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE }, | ||
56 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
57 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */ | ||
58 | [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
59 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
60 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
61 | [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
62 | [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
63 | [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
64 | [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
65 | [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE }, | ||
66 | [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
67 | [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
68 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE } | ||
69 | }; | ||
70 | |||
71 | #define choose_value(dmivalue, fwvalue, field, flags) ({ \ | ||
72 | typeof(fwvalue) _ret_ = fwvalue; \ | ||
73 | if ((flags) & (field)) \ | ||
74 | _ret_ = dmivalue; \ | ||
75 | else if ((fwvalue) == 0) \ | ||
76 | _ret_ = dmivalue; \ | ||
77 | _ret_; \ | ||
78 | }) | ||
79 | |||
80 | static int __init efifb_set_system(const struct dmi_system_id *id) | ||
81 | { | ||
82 | struct efifb_dmi_info *info = id->driver_data; | ||
83 | |||
84 | if (info->base == 0 && info->height == 0 && info->width == 0 && | ||
85 | info->stride == 0) | ||
86 | return 0; | ||
87 | |||
88 | /* Trust the bootloader over the DMI tables */ | ||
89 | if (screen_info.lfb_base == 0) { | ||
90 | #if defined(CONFIG_PCI) | ||
91 | struct pci_dev *dev = NULL; | ||
92 | int found_bar = 0; | ||
93 | #endif | ||
94 | if (info->base) { | ||
95 | screen_info.lfb_base = choose_value(info->base, | ||
96 | screen_info.lfb_base, OVERRIDE_BASE, | ||
97 | info->flags); | ||
98 | |||
99 | #if defined(CONFIG_PCI) | ||
100 | /* make sure that the address in the table is actually | ||
101 | * on a VGA device's PCI BAR */ | ||
102 | |||
103 | for_each_pci_dev(dev) { | ||
104 | int i; | ||
105 | if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
106 | continue; | ||
107 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
108 | resource_size_t start, end; | ||
109 | |||
110 | start = pci_resource_start(dev, i); | ||
111 | if (start == 0) | ||
112 | break; | ||
113 | end = pci_resource_end(dev, i); | ||
114 | if (screen_info.lfb_base >= start && | ||
115 | screen_info.lfb_base < end) { | ||
116 | found_bar = 1; | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | if (!found_bar) | ||
121 | screen_info.lfb_base = 0; | ||
122 | #endif | ||
123 | } | ||
124 | } | ||
125 | if (screen_info.lfb_base) { | ||
126 | screen_info.lfb_linelength = choose_value(info->stride, | ||
127 | screen_info.lfb_linelength, OVERRIDE_STRIDE, | ||
128 | info->flags); | ||
129 | screen_info.lfb_width = choose_value(info->width, | ||
130 | screen_info.lfb_width, OVERRIDE_WIDTH, | ||
131 | info->flags); | ||
132 | screen_info.lfb_height = choose_value(info->height, | ||
133 | screen_info.lfb_height, OVERRIDE_HEIGHT, | ||
134 | info->flags); | ||
135 | if (screen_info.orig_video_isVGA == 0) | ||
136 | screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; | ||
137 | } else { | ||
138 | screen_info.lfb_linelength = 0; | ||
139 | screen_info.lfb_width = 0; | ||
140 | screen_info.lfb_height = 0; | ||
141 | screen_info.orig_video_isVGA = 0; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " | ||
146 | "(%dx%d, stride %d)\n", id->ident, | ||
147 | screen_info.lfb_base, screen_info.lfb_width, | ||
148 | screen_info.lfb_height, screen_info.lfb_linelength); | ||
149 | |||
150 | return 1; | ||
151 | } | ||
152 | |||
153 | #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ | ||
154 | { \ | ||
155 | efifb_set_system, \ | ||
156 | name, \ | ||
157 | { \ | ||
158 | DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ | ||
159 | DMI_MATCH(DMI_PRODUCT_NAME, name) \ | ||
160 | }, \ | ||
161 | &efifb_dmi_list[enumid] \ | ||
162 | } | ||
163 | |||
164 | static const struct dmi_system_id efifb_dmi_system_table[] __initconst = { | ||
165 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), | ||
166 | /* At least one of these two will be right; maybe both? */ | ||
167 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), | ||
168 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20), | ||
169 | /* At least one of these two will be right; maybe both? */ | ||
170 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), | ||
171 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), | ||
172 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), | ||
173 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), | ||
174 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), | ||
175 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), | ||
176 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), | ||
177 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), | ||
178 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), | ||
179 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), | ||
180 | /* At least one of these two will be right; maybe both? */ | ||
181 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), | ||
182 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB), | ||
183 | /* At least one of these two will be right; maybe both? */ | ||
184 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), | ||
185 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), | ||
186 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), | ||
187 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), | ||
188 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), | ||
189 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), | ||
190 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), | ||
191 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3), | ||
192 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), | ||
193 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), | ||
194 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), | ||
195 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), | ||
196 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), | ||
197 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), | ||
198 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), | ||
199 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), | ||
200 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), | ||
201 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), | ||
202 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), | ||
203 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), | ||
204 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), | ||
205 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2), | ||
206 | {}, | ||
207 | }; | ||
208 | |||
209 | __init void sysfb_apply_efi_quirks(void) | ||
210 | { | ||
211 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || | ||
212 | !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) | ||
213 | dmi_check_system(efifb_dmi_system_table); | ||
214 | } | ||
diff --git a/arch/x86/kernel/sysfb_simplefb.c b/arch/x86/kernel/sysfb_simplefb.c new file mode 100644 index 000000000000..22513e96b012 --- /dev/null +++ b/arch/x86/kernel/sysfb_simplefb.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Generic System Framebuffers on x86 | ||
3 | * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the Free | ||
7 | * Software Foundation; either version 2 of the License, or (at your option) | ||
8 | * any later version. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * simple-framebuffer probing | ||
13 | * Try to convert "screen_info" into a "simple-framebuffer" compatible mode. | ||
14 | * If the mode is incompatible, we return "false" and let the caller create | ||
15 | * legacy nodes instead. | ||
16 | */ | ||
17 | |||
18 | #include <linux/err.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/mm.h> | ||
22 | #include <linux/platform_data/simplefb.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/screen_info.h> | ||
25 | #include <asm/sysfb.h> | ||
26 | |||
27 | static const char simplefb_resname[] = "BOOTFB"; | ||
28 | static const struct simplefb_format formats[] = SIMPLEFB_FORMATS; | ||
29 | |||
30 | /* try parsing x86 screen_info into a simple-framebuffer mode struct */ | ||
31 | __init bool parse_mode(const struct screen_info *si, | ||
32 | struct simplefb_platform_data *mode) | ||
33 | { | ||
34 | const struct simplefb_format *f; | ||
35 | __u8 type; | ||
36 | unsigned int i; | ||
37 | |||
38 | type = si->orig_video_isVGA; | ||
39 | if (type != VIDEO_TYPE_VLFB && type != VIDEO_TYPE_EFI) | ||
40 | return false; | ||
41 | |||
42 | for (i = 0; i < ARRAY_SIZE(formats); ++i) { | ||
43 | f = &formats[i]; | ||
44 | if (si->lfb_depth == f->bits_per_pixel && | ||
45 | si->red_size == f->red.length && | ||
46 | si->red_pos == f->red.offset && | ||
47 | si->green_size == f->green.length && | ||
48 | si->green_pos == f->green.offset && | ||
49 | si->blue_size == f->blue.length && | ||
50 | si->blue_pos == f->blue.offset && | ||
51 | si->rsvd_size == f->transp.length && | ||
52 | si->rsvd_pos == f->transp.offset) { | ||
53 | mode->format = f->name; | ||
54 | mode->width = si->lfb_width; | ||
55 | mode->height = si->lfb_height; | ||
56 | mode->stride = si->lfb_linelength; | ||
57 | return true; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | return false; | ||
62 | } | ||
63 | |||
64 | __init int create_simplefb(const struct screen_info *si, | ||
65 | const struct simplefb_platform_data *mode) | ||
66 | { | ||
67 | struct platform_device *pd; | ||
68 | struct resource res; | ||
69 | unsigned long len; | ||
70 | |||
71 | /* don't use lfb_size as it may contain the whole VMEM instead of only | ||
72 | * the part that is occupied by the framebuffer */ | ||
73 | len = mode->height * mode->stride; | ||
74 | len = PAGE_ALIGN(len); | ||
75 | if (len > si->lfb_size << 16) { | ||
76 | printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | |||
80 | /* setup IORESOURCE_MEM as framebuffer memory */ | ||
81 | memset(&res, 0, sizeof(res)); | ||
82 | res.flags = IORESOURCE_MEM; | ||
83 | res.name = simplefb_resname; | ||
84 | res.start = si->lfb_base; | ||
85 | res.end = si->lfb_base + len - 1; | ||
86 | if (res.end <= res.start) | ||
87 | return -EINVAL; | ||
88 | |||
89 | pd = platform_device_register_resndata(NULL, "simple-framebuffer", 0, | ||
90 | &res, 1, mode, sizeof(*mode)); | ||
91 | if (IS_ERR(pd)) | ||
92 | return PTR_ERR(pd); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index addf7b58f4e8..91a4496db434 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c | |||
@@ -301,6 +301,15 @@ static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) | |||
301 | return 0; | 301 | return 0; |
302 | } | 302 | } |
303 | 303 | ||
304 | static int tboot_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b) | ||
305 | { | ||
306 | if (!tboot_enabled()) | ||
307 | return 0; | ||
308 | |||
309 | pr_warning("tboot is not able to suspend on platforms with reduced hardware sleep (ACPIv5)"); | ||
310 | return -ENODEV; | ||
311 | } | ||
312 | |||
304 | static atomic_t ap_wfs_count; | 313 | static atomic_t ap_wfs_count; |
305 | 314 | ||
306 | static int tboot_wait_for_aps(int num_aps) | 315 | static int tboot_wait_for_aps(int num_aps) |
@@ -422,6 +431,7 @@ static __init int tboot_late_init(void) | |||
422 | #endif | 431 | #endif |
423 | 432 | ||
424 | acpi_os_set_prepare_sleep(&tboot_sleep); | 433 | acpi_os_set_prepare_sleep(&tboot_sleep); |
434 | acpi_os_set_prepare_extended_sleep(&tboot_extended_sleep); | ||
425 | return 0; | 435 | return 0; |
426 | } | 436 | } |
427 | 437 | ||
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 1b23a1c92746..8c8093b146ca 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <asm/mce.h> | 58 | #include <asm/mce.h> |
59 | #include <asm/fixmap.h> | 59 | #include <asm/fixmap.h> |
60 | #include <asm/mach_traps.h> | 60 | #include <asm/mach_traps.h> |
61 | #include <asm/alternative.h> | ||
61 | 62 | ||
62 | #ifdef CONFIG_X86_64 | 63 | #ifdef CONFIG_X86_64 |
63 | #include <asm/x86_init.h> | 64 | #include <asm/x86_init.h> |
@@ -327,6 +328,9 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co | |||
327 | ftrace_int3_handler(regs)) | 328 | ftrace_int3_handler(regs)) |
328 | return; | 329 | return; |
329 | #endif | 330 | #endif |
331 | if (poke_int3_handler(regs)) | ||
332 | return; | ||
333 | |||
330 | prev_state = exception_enter(); | 334 | prev_state = exception_enter(); |
331 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP | 335 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP |
332 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, | 336 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 6ff49247edf8..930e5d48f560 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -89,6 +89,12 @@ int check_tsc_unstable(void) | |||
89 | } | 89 | } |
90 | EXPORT_SYMBOL_GPL(check_tsc_unstable); | 90 | EXPORT_SYMBOL_GPL(check_tsc_unstable); |
91 | 91 | ||
92 | int check_tsc_disabled(void) | ||
93 | { | ||
94 | return tsc_disabled; | ||
95 | } | ||
96 | EXPORT_SYMBOL_GPL(check_tsc_disabled); | ||
97 | |||
92 | #ifdef CONFIG_X86_TSC | 98 | #ifdef CONFIG_X86_TSC |
93 | int __init notsc_setup(char *str) | 99 | int __init notsc_setup(char *str) |
94 | { | 100 | { |
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index a20ecb5b6cbf..b110fe6c03d4 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
@@ -413,7 +413,8 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
413 | (1 << KVM_FEATURE_CLOCKSOURCE2) | | 413 | (1 << KVM_FEATURE_CLOCKSOURCE2) | |
414 | (1 << KVM_FEATURE_ASYNC_PF) | | 414 | (1 << KVM_FEATURE_ASYNC_PF) | |
415 | (1 << KVM_FEATURE_PV_EOI) | | 415 | (1 << KVM_FEATURE_PV_EOI) | |
416 | (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT); | 416 | (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) | |
417 | (1 << KVM_FEATURE_PV_UNHALT); | ||
417 | 418 | ||
418 | if (sched_info_on()) | 419 | if (sched_info_on()) |
419 | entry->eax |= (1 << KVM_FEATURE_STEAL_TIME); | 420 | entry->eax |= (1 << KVM_FEATURE_STEAL_TIME); |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index afc11245827c..5439117d5c4c 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -79,16 +79,6 @@ static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val) | |||
79 | *((u32 *) (apic->regs + reg_off)) = val; | 79 | *((u32 *) (apic->regs + reg_off)) = val; |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline int apic_test_and_set_vector(int vec, void *bitmap) | ||
83 | { | ||
84 | return test_and_set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); | ||
85 | } | ||
86 | |||
87 | static inline int apic_test_and_clear_vector(int vec, void *bitmap) | ||
88 | { | ||
89 | return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); | ||
90 | } | ||
91 | |||
92 | static inline int apic_test_vector(int vec, void *bitmap) | 82 | static inline int apic_test_vector(int vec, void *bitmap) |
93 | { | 83 | { |
94 | return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); | 84 | return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); |
@@ -331,10 +321,10 @@ void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir) | |||
331 | } | 321 | } |
332 | EXPORT_SYMBOL_GPL(kvm_apic_update_irr); | 322 | EXPORT_SYMBOL_GPL(kvm_apic_update_irr); |
333 | 323 | ||
334 | static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic) | 324 | static inline void apic_set_irr(int vec, struct kvm_lapic *apic) |
335 | { | 325 | { |
336 | apic->irr_pending = true; | 326 | apic->irr_pending = true; |
337 | return apic_test_and_set_vector(vec, apic->regs + APIC_IRR); | 327 | apic_set_vector(vec, apic->regs + APIC_IRR); |
338 | } | 328 | } |
339 | 329 | ||
340 | static inline int apic_search_irr(struct kvm_lapic *apic) | 330 | static inline int apic_search_irr(struct kvm_lapic *apic) |
@@ -681,32 +671,28 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
681 | if (unlikely(!apic_enabled(apic))) | 671 | if (unlikely(!apic_enabled(apic))) |
682 | break; | 672 | break; |
683 | 673 | ||
674 | result = 1; | ||
675 | |||
684 | if (dest_map) | 676 | if (dest_map) |
685 | __set_bit(vcpu->vcpu_id, dest_map); | 677 | __set_bit(vcpu->vcpu_id, dest_map); |
686 | 678 | ||
687 | if (kvm_x86_ops->deliver_posted_interrupt) { | 679 | if (kvm_x86_ops->deliver_posted_interrupt) |
688 | result = 1; | ||
689 | kvm_x86_ops->deliver_posted_interrupt(vcpu, vector); | 680 | kvm_x86_ops->deliver_posted_interrupt(vcpu, vector); |
690 | } else { | 681 | else { |
691 | result = !apic_test_and_set_irr(vector, apic); | 682 | apic_set_irr(vector, apic); |
692 | |||
693 | if (!result) { | ||
694 | if (trig_mode) | ||
695 | apic_debug("level trig mode repeatedly " | ||
696 | "for vector %d", vector); | ||
697 | goto out; | ||
698 | } | ||
699 | 683 | ||
700 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 684 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
701 | kvm_vcpu_kick(vcpu); | 685 | kvm_vcpu_kick(vcpu); |
702 | } | 686 | } |
703 | out: | ||
704 | trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode, | 687 | trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode, |
705 | trig_mode, vector, !result); | 688 | trig_mode, vector, false); |
706 | break; | 689 | break; |
707 | 690 | ||
708 | case APIC_DM_REMRD: | 691 | case APIC_DM_REMRD: |
709 | apic_debug("Ignoring delivery mode 3\n"); | 692 | result = 1; |
693 | vcpu->arch.pv.pv_unhalted = 1; | ||
694 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
695 | kvm_vcpu_kick(vcpu); | ||
710 | break; | 696 | break; |
711 | 697 | ||
712 | case APIC_DM_SMI: | 698 | case APIC_DM_SMI: |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 9e9285ae9b94..6e2d2c8f230b 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -132,8 +132,8 @@ module_param(dbg, bool, 0644); | |||
132 | (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ | 132 | (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ |
133 | * PT32_LEVEL_BITS))) - 1)) | 133 | * PT32_LEVEL_BITS))) - 1)) |
134 | 134 | ||
135 | #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \ | 135 | #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | shadow_user_mask \ |
136 | | PT64_NX_MASK) | 136 | | shadow_x_mask | shadow_nx_mask) |
137 | 137 | ||
138 | #define ACC_EXEC_MASK 1 | 138 | #define ACC_EXEC_MASK 1 |
139 | #define ACC_WRITE_MASK PT_WRITABLE_MASK | 139 | #define ACC_WRITE_MASK PT_WRITABLE_MASK |
@@ -331,11 +331,6 @@ static int is_large_pte(u64 pte) | |||
331 | return pte & PT_PAGE_SIZE_MASK; | 331 | return pte & PT_PAGE_SIZE_MASK; |
332 | } | 332 | } |
333 | 333 | ||
334 | static int is_dirty_gpte(unsigned long pte) | ||
335 | { | ||
336 | return pte & PT_DIRTY_MASK; | ||
337 | } | ||
338 | |||
339 | static int is_rmap_spte(u64 pte) | 334 | static int is_rmap_spte(u64 pte) |
340 | { | 335 | { |
341 | return is_shadow_present_pte(pte); | 336 | return is_shadow_present_pte(pte); |
@@ -2052,12 +2047,18 @@ static void shadow_walk_next(struct kvm_shadow_walk_iterator *iterator) | |||
2052 | return __shadow_walk_next(iterator, *iterator->sptep); | 2047 | return __shadow_walk_next(iterator, *iterator->sptep); |
2053 | } | 2048 | } |
2054 | 2049 | ||
2055 | static void link_shadow_page(u64 *sptep, struct kvm_mmu_page *sp) | 2050 | static void link_shadow_page(u64 *sptep, struct kvm_mmu_page *sp, bool accessed) |
2056 | { | 2051 | { |
2057 | u64 spte; | 2052 | u64 spte; |
2058 | 2053 | ||
2054 | BUILD_BUG_ON(VMX_EPT_READABLE_MASK != PT_PRESENT_MASK || | ||
2055 | VMX_EPT_WRITABLE_MASK != PT_WRITABLE_MASK); | ||
2056 | |||
2059 | spte = __pa(sp->spt) | PT_PRESENT_MASK | PT_WRITABLE_MASK | | 2057 | spte = __pa(sp->spt) | PT_PRESENT_MASK | PT_WRITABLE_MASK | |
2060 | shadow_user_mask | shadow_x_mask | shadow_accessed_mask; | 2058 | shadow_user_mask | shadow_x_mask; |
2059 | |||
2060 | if (accessed) | ||
2061 | spte |= shadow_accessed_mask; | ||
2061 | 2062 | ||
2062 | mmu_spte_set(sptep, spte); | 2063 | mmu_spte_set(sptep, spte); |
2063 | } | 2064 | } |
@@ -2574,14 +2575,6 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) | |||
2574 | mmu_free_roots(vcpu); | 2575 | mmu_free_roots(vcpu); |
2575 | } | 2576 | } |
2576 | 2577 | ||
2577 | static bool is_rsvd_bits_set(struct kvm_mmu *mmu, u64 gpte, int level) | ||
2578 | { | ||
2579 | int bit7; | ||
2580 | |||
2581 | bit7 = (gpte >> 7) & 1; | ||
2582 | return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0; | ||
2583 | } | ||
2584 | |||
2585 | static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, | 2578 | static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, |
2586 | bool no_dirty_log) | 2579 | bool no_dirty_log) |
2587 | { | 2580 | { |
@@ -2594,26 +2587,6 @@ static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, | |||
2594 | return gfn_to_pfn_memslot_atomic(slot, gfn); | 2587 | return gfn_to_pfn_memslot_atomic(slot, gfn); |
2595 | } | 2588 | } |
2596 | 2589 | ||
2597 | static bool prefetch_invalid_gpte(struct kvm_vcpu *vcpu, | ||
2598 | struct kvm_mmu_page *sp, u64 *spte, | ||
2599 | u64 gpte) | ||
2600 | { | ||
2601 | if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)) | ||
2602 | goto no_present; | ||
2603 | |||
2604 | if (!is_present_gpte(gpte)) | ||
2605 | goto no_present; | ||
2606 | |||
2607 | if (!(gpte & PT_ACCESSED_MASK)) | ||
2608 | goto no_present; | ||
2609 | |||
2610 | return false; | ||
2611 | |||
2612 | no_present: | ||
2613 | drop_spte(vcpu->kvm, spte); | ||
2614 | return true; | ||
2615 | } | ||
2616 | |||
2617 | static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu, | 2590 | static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu, |
2618 | struct kvm_mmu_page *sp, | 2591 | struct kvm_mmu_page *sp, |
2619 | u64 *start, u64 *end) | 2592 | u64 *start, u64 *end) |
@@ -2710,7 +2683,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | |||
2710 | iterator.level - 1, | 2683 | iterator.level - 1, |
2711 | 1, ACC_ALL, iterator.sptep); | 2684 | 1, ACC_ALL, iterator.sptep); |
2712 | 2685 | ||
2713 | link_shadow_page(iterator.sptep, sp); | 2686 | link_shadow_page(iterator.sptep, sp, true); |
2714 | } | 2687 | } |
2715 | } | 2688 | } |
2716 | return emulate; | 2689 | return emulate; |
@@ -2808,7 +2781,7 @@ exit: | |||
2808 | return ret; | 2781 | return ret; |
2809 | } | 2782 | } |
2810 | 2783 | ||
2811 | static bool page_fault_can_be_fast(struct kvm_vcpu *vcpu, u32 error_code) | 2784 | static bool page_fault_can_be_fast(u32 error_code) |
2812 | { | 2785 | { |
2813 | /* | 2786 | /* |
2814 | * Do not fix the mmio spte with invalid generation number which | 2787 | * Do not fix the mmio spte with invalid generation number which |
@@ -2861,7 +2834,7 @@ static bool fast_page_fault(struct kvm_vcpu *vcpu, gva_t gva, int level, | |||
2861 | bool ret = false; | 2834 | bool ret = false; |
2862 | u64 spte = 0ull; | 2835 | u64 spte = 0ull; |
2863 | 2836 | ||
2864 | if (!page_fault_can_be_fast(vcpu, error_code)) | 2837 | if (!page_fault_can_be_fast(error_code)) |
2865 | return false; | 2838 | return false; |
2866 | 2839 | ||
2867 | walk_shadow_page_lockless_begin(vcpu); | 2840 | walk_shadow_page_lockless_begin(vcpu); |
@@ -3209,6 +3182,7 @@ void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu) | |||
3209 | mmu_sync_roots(vcpu); | 3182 | mmu_sync_roots(vcpu); |
3210 | spin_unlock(&vcpu->kvm->mmu_lock); | 3183 | spin_unlock(&vcpu->kvm->mmu_lock); |
3211 | } | 3184 | } |
3185 | EXPORT_SYMBOL_GPL(kvm_mmu_sync_roots); | ||
3212 | 3186 | ||
3213 | static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr, | 3187 | static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr, |
3214 | u32 access, struct x86_exception *exception) | 3188 | u32 access, struct x86_exception *exception) |
@@ -3478,6 +3452,7 @@ void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) | |||
3478 | ++vcpu->stat.tlb_flush; | 3452 | ++vcpu->stat.tlb_flush; |
3479 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); | 3453 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); |
3480 | } | 3454 | } |
3455 | EXPORT_SYMBOL_GPL(kvm_mmu_flush_tlb); | ||
3481 | 3456 | ||
3482 | static void paging_new_cr3(struct kvm_vcpu *vcpu) | 3457 | static void paging_new_cr3(struct kvm_vcpu *vcpu) |
3483 | { | 3458 | { |
@@ -3501,18 +3476,6 @@ static void paging_free(struct kvm_vcpu *vcpu) | |||
3501 | nonpaging_free(vcpu); | 3476 | nonpaging_free(vcpu); |
3502 | } | 3477 | } |
3503 | 3478 | ||
3504 | static inline void protect_clean_gpte(unsigned *access, unsigned gpte) | ||
3505 | { | ||
3506 | unsigned mask; | ||
3507 | |||
3508 | BUILD_BUG_ON(PT_WRITABLE_MASK != ACC_WRITE_MASK); | ||
3509 | |||
3510 | mask = (unsigned)~ACC_WRITE_MASK; | ||
3511 | /* Allow write access to dirty gptes */ | ||
3512 | mask |= (gpte >> (PT_DIRTY_SHIFT - PT_WRITABLE_SHIFT)) & PT_WRITABLE_MASK; | ||
3513 | *access &= mask; | ||
3514 | } | ||
3515 | |||
3516 | static bool sync_mmio_spte(struct kvm *kvm, u64 *sptep, gfn_t gfn, | 3479 | static bool sync_mmio_spte(struct kvm *kvm, u64 *sptep, gfn_t gfn, |
3517 | unsigned access, int *nr_present) | 3480 | unsigned access, int *nr_present) |
3518 | { | 3481 | { |
@@ -3530,16 +3493,6 @@ static bool sync_mmio_spte(struct kvm *kvm, u64 *sptep, gfn_t gfn, | |||
3530 | return false; | 3493 | return false; |
3531 | } | 3494 | } |
3532 | 3495 | ||
3533 | static inline unsigned gpte_access(struct kvm_vcpu *vcpu, u64 gpte) | ||
3534 | { | ||
3535 | unsigned access; | ||
3536 | |||
3537 | access = (gpte & (PT_WRITABLE_MASK | PT_USER_MASK)) | ACC_EXEC_MASK; | ||
3538 | access &= ~(gpte >> PT64_NX_SHIFT); | ||
3539 | |||
3540 | return access; | ||
3541 | } | ||
3542 | |||
3543 | static inline bool is_last_gpte(struct kvm_mmu *mmu, unsigned level, unsigned gpte) | 3496 | static inline bool is_last_gpte(struct kvm_mmu *mmu, unsigned level, unsigned gpte) |
3544 | { | 3497 | { |
3545 | unsigned index; | 3498 | unsigned index; |
@@ -3549,6 +3502,11 @@ static inline bool is_last_gpte(struct kvm_mmu *mmu, unsigned level, unsigned gp | |||
3549 | return mmu->last_pte_bitmap & (1 << index); | 3502 | return mmu->last_pte_bitmap & (1 << index); |
3550 | } | 3503 | } |
3551 | 3504 | ||
3505 | #define PTTYPE_EPT 18 /* arbitrary */ | ||
3506 | #define PTTYPE PTTYPE_EPT | ||
3507 | #include "paging_tmpl.h" | ||
3508 | #undef PTTYPE | ||
3509 | |||
3552 | #define PTTYPE 64 | 3510 | #define PTTYPE 64 |
3553 | #include "paging_tmpl.h" | 3511 | #include "paging_tmpl.h" |
3554 | #undef PTTYPE | 3512 | #undef PTTYPE |
@@ -3563,6 +3521,8 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, | |||
3563 | int maxphyaddr = cpuid_maxphyaddr(vcpu); | 3521 | int maxphyaddr = cpuid_maxphyaddr(vcpu); |
3564 | u64 exb_bit_rsvd = 0; | 3522 | u64 exb_bit_rsvd = 0; |
3565 | 3523 | ||
3524 | context->bad_mt_xwr = 0; | ||
3525 | |||
3566 | if (!context->nx) | 3526 | if (!context->nx) |
3567 | exb_bit_rsvd = rsvd_bits(63, 63); | 3527 | exb_bit_rsvd = rsvd_bits(63, 63); |
3568 | switch (context->root_level) { | 3528 | switch (context->root_level) { |
@@ -3618,7 +3578,40 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, | |||
3618 | } | 3578 | } |
3619 | } | 3579 | } |
3620 | 3580 | ||
3621 | static void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu) | 3581 | static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu, |
3582 | struct kvm_mmu *context, bool execonly) | ||
3583 | { | ||
3584 | int maxphyaddr = cpuid_maxphyaddr(vcpu); | ||
3585 | int pte; | ||
3586 | |||
3587 | context->rsvd_bits_mask[0][3] = | ||
3588 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(3, 7); | ||
3589 | context->rsvd_bits_mask[0][2] = | ||
3590 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(3, 6); | ||
3591 | context->rsvd_bits_mask[0][1] = | ||
3592 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(3, 6); | ||
3593 | context->rsvd_bits_mask[0][0] = rsvd_bits(maxphyaddr, 51); | ||
3594 | |||
3595 | /* large page */ | ||
3596 | context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3]; | ||
3597 | context->rsvd_bits_mask[1][2] = | ||
3598 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(12, 29); | ||
3599 | context->rsvd_bits_mask[1][1] = | ||
3600 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(12, 20); | ||
3601 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[0][0]; | ||
3602 | |||
3603 | for (pte = 0; pte < 64; pte++) { | ||
3604 | int rwx_bits = pte & 7; | ||
3605 | int mt = pte >> 3; | ||
3606 | if (mt == 0x2 || mt == 0x3 || mt == 0x7 || | ||
3607 | rwx_bits == 0x2 || rwx_bits == 0x6 || | ||
3608 | (rwx_bits == 0x4 && !execonly)) | ||
3609 | context->bad_mt_xwr |= (1ull << pte); | ||
3610 | } | ||
3611 | } | ||
3612 | |||
3613 | static void update_permission_bitmask(struct kvm_vcpu *vcpu, | ||
3614 | struct kvm_mmu *mmu, bool ept) | ||
3622 | { | 3615 | { |
3623 | unsigned bit, byte, pfec; | 3616 | unsigned bit, byte, pfec; |
3624 | u8 map; | 3617 | u8 map; |
@@ -3636,12 +3629,16 @@ static void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu | |||
3636 | w = bit & ACC_WRITE_MASK; | 3629 | w = bit & ACC_WRITE_MASK; |
3637 | u = bit & ACC_USER_MASK; | 3630 | u = bit & ACC_USER_MASK; |
3638 | 3631 | ||
3639 | /* Not really needed: !nx will cause pte.nx to fault */ | 3632 | if (!ept) { |
3640 | x |= !mmu->nx; | 3633 | /* Not really needed: !nx will cause pte.nx to fault */ |
3641 | /* Allow supervisor writes if !cr0.wp */ | 3634 | x |= !mmu->nx; |
3642 | w |= !is_write_protection(vcpu) && !uf; | 3635 | /* Allow supervisor writes if !cr0.wp */ |
3643 | /* Disallow supervisor fetches of user code if cr4.smep */ | 3636 | w |= !is_write_protection(vcpu) && !uf; |
3644 | x &= !(smep && u && !uf); | 3637 | /* Disallow supervisor fetches of user code if cr4.smep */ |
3638 | x &= !(smep && u && !uf); | ||
3639 | } else | ||
3640 | /* Not really needed: no U/S accesses on ept */ | ||
3641 | u = 1; | ||
3645 | 3642 | ||
3646 | fault = (ff && !x) || (uf && !u) || (wf && !w); | 3643 | fault = (ff && !x) || (uf && !u) || (wf && !w); |
3647 | map |= fault << bit; | 3644 | map |= fault << bit; |
@@ -3676,7 +3673,7 @@ static int paging64_init_context_common(struct kvm_vcpu *vcpu, | |||
3676 | context->root_level = level; | 3673 | context->root_level = level; |
3677 | 3674 | ||
3678 | reset_rsvds_bits_mask(vcpu, context); | 3675 | reset_rsvds_bits_mask(vcpu, context); |
3679 | update_permission_bitmask(vcpu, context); | 3676 | update_permission_bitmask(vcpu, context, false); |
3680 | update_last_pte_bitmap(vcpu, context); | 3677 | update_last_pte_bitmap(vcpu, context); |
3681 | 3678 | ||
3682 | ASSERT(is_pae(vcpu)); | 3679 | ASSERT(is_pae(vcpu)); |
@@ -3706,7 +3703,7 @@ static int paging32_init_context(struct kvm_vcpu *vcpu, | |||
3706 | context->root_level = PT32_ROOT_LEVEL; | 3703 | context->root_level = PT32_ROOT_LEVEL; |
3707 | 3704 | ||
3708 | reset_rsvds_bits_mask(vcpu, context); | 3705 | reset_rsvds_bits_mask(vcpu, context); |
3709 | update_permission_bitmask(vcpu, context); | 3706 | update_permission_bitmask(vcpu, context, false); |
3710 | update_last_pte_bitmap(vcpu, context); | 3707 | update_last_pte_bitmap(vcpu, context); |
3711 | 3708 | ||
3712 | context->new_cr3 = paging_new_cr3; | 3709 | context->new_cr3 = paging_new_cr3; |
@@ -3768,7 +3765,7 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) | |||
3768 | context->gva_to_gpa = paging32_gva_to_gpa; | 3765 | context->gva_to_gpa = paging32_gva_to_gpa; |
3769 | } | 3766 | } |
3770 | 3767 | ||
3771 | update_permission_bitmask(vcpu, context); | 3768 | update_permission_bitmask(vcpu, context, false); |
3772 | update_last_pte_bitmap(vcpu, context); | 3769 | update_last_pte_bitmap(vcpu, context); |
3773 | 3770 | ||
3774 | return 0; | 3771 | return 0; |
@@ -3800,6 +3797,33 @@ int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context) | |||
3800 | } | 3797 | } |
3801 | EXPORT_SYMBOL_GPL(kvm_init_shadow_mmu); | 3798 | EXPORT_SYMBOL_GPL(kvm_init_shadow_mmu); |
3802 | 3799 | ||
3800 | int kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, | ||
3801 | bool execonly) | ||
3802 | { | ||
3803 | ASSERT(vcpu); | ||
3804 | ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa)); | ||
3805 | |||
3806 | context->shadow_root_level = kvm_x86_ops->get_tdp_level(); | ||
3807 | |||
3808 | context->nx = true; | ||
3809 | context->new_cr3 = paging_new_cr3; | ||
3810 | context->page_fault = ept_page_fault; | ||
3811 | context->gva_to_gpa = ept_gva_to_gpa; | ||
3812 | context->sync_page = ept_sync_page; | ||
3813 | context->invlpg = ept_invlpg; | ||
3814 | context->update_pte = ept_update_pte; | ||
3815 | context->free = paging_free; | ||
3816 | context->root_level = context->shadow_root_level; | ||
3817 | context->root_hpa = INVALID_PAGE; | ||
3818 | context->direct_map = false; | ||
3819 | |||
3820 | update_permission_bitmask(vcpu, context, true); | ||
3821 | reset_rsvds_bits_mask_ept(vcpu, context, execonly); | ||
3822 | |||
3823 | return 0; | ||
3824 | } | ||
3825 | EXPORT_SYMBOL_GPL(kvm_init_shadow_ept_mmu); | ||
3826 | |||
3803 | static int init_kvm_softmmu(struct kvm_vcpu *vcpu) | 3827 | static int init_kvm_softmmu(struct kvm_vcpu *vcpu) |
3804 | { | 3828 | { |
3805 | int r = kvm_init_shadow_mmu(vcpu, vcpu->arch.walk_mmu); | 3829 | int r = kvm_init_shadow_mmu(vcpu, vcpu->arch.walk_mmu); |
@@ -3847,7 +3871,7 @@ static int init_kvm_nested_mmu(struct kvm_vcpu *vcpu) | |||
3847 | g_context->gva_to_gpa = paging32_gva_to_gpa_nested; | 3871 | g_context->gva_to_gpa = paging32_gva_to_gpa_nested; |
3848 | } | 3872 | } |
3849 | 3873 | ||
3850 | update_permission_bitmask(vcpu, g_context); | 3874 | update_permission_bitmask(vcpu, g_context, false); |
3851 | update_last_pte_bitmap(vcpu, g_context); | 3875 | update_last_pte_bitmap(vcpu, g_context); |
3852 | 3876 | ||
3853 | return 0; | 3877 | return 0; |
@@ -3923,8 +3947,8 @@ static bool need_remote_flush(u64 old, u64 new) | |||
3923 | return true; | 3947 | return true; |
3924 | if ((old ^ new) & PT64_BASE_ADDR_MASK) | 3948 | if ((old ^ new) & PT64_BASE_ADDR_MASK) |
3925 | return true; | 3949 | return true; |
3926 | old ^= PT64_NX_MASK; | 3950 | old ^= shadow_nx_mask; |
3927 | new ^= PT64_NX_MASK; | 3951 | new ^= shadow_nx_mask; |
3928 | return (old & ~new & PT64_PERM_MASK) != 0; | 3952 | return (old & ~new & PT64_PERM_MASK) != 0; |
3929 | } | 3953 | } |
3930 | 3954 | ||
@@ -4182,7 +4206,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code, | |||
4182 | switch (er) { | 4206 | switch (er) { |
4183 | case EMULATE_DONE: | 4207 | case EMULATE_DONE: |
4184 | return 1; | 4208 | return 1; |
4185 | case EMULATE_DO_MMIO: | 4209 | case EMULATE_USER_EXIT: |
4186 | ++vcpu->stat.mmio_exits; | 4210 | ++vcpu->stat.mmio_exits; |
4187 | /* fall through */ | 4211 | /* fall through */ |
4188 | case EMULATE_FAIL: | 4212 | case EMULATE_FAIL: |
@@ -4390,11 +4414,8 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm) | |||
4390 | /* | 4414 | /* |
4391 | * The very rare case: if the generation-number is round, | 4415 | * The very rare case: if the generation-number is round, |
4392 | * zap all shadow pages. | 4416 | * zap all shadow pages. |
4393 | * | ||
4394 | * The max value is MMIO_MAX_GEN - 1 since it is not called | ||
4395 | * when mark memslot invalid. | ||
4396 | */ | 4417 | */ |
4397 | if (unlikely(kvm_current_mmio_generation(kvm) >= (MMIO_MAX_GEN - 1))) { | 4418 | if (unlikely(kvm_current_mmio_generation(kvm) >= MMIO_MAX_GEN)) { |
4398 | printk_ratelimited(KERN_INFO "kvm: zapping shadow pages for mmio generation wraparound\n"); | 4419 | printk_ratelimited(KERN_INFO "kvm: zapping shadow pages for mmio generation wraparound\n"); |
4399 | kvm_mmu_invalidate_zap_all_pages(kvm); | 4420 | kvm_mmu_invalidate_zap_all_pages(kvm); |
4400 | } | 4421 | } |
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 5b59c573aba7..77e044a0f5f7 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h | |||
@@ -71,6 +71,8 @@ enum { | |||
71 | 71 | ||
72 | int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct); | 72 | int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct); |
73 | int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context); | 73 | int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context); |
74 | int kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, | ||
75 | bool execonly); | ||
74 | 76 | ||
75 | static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm) | 77 | static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm) |
76 | { | 78 | { |
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 7769699d48a8..043330159179 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
@@ -23,6 +23,13 @@ | |||
23 | * so the code in this file is compiled twice, once per pte size. | 23 | * so the code in this file is compiled twice, once per pte size. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | /* | ||
27 | * This is used to catch non optimized PT_GUEST_(DIRTY|ACCESS)_SHIFT macro | ||
28 | * uses for EPT without A/D paging type. | ||
29 | */ | ||
30 | extern u64 __pure __using_nonexistent_pte_bit(void) | ||
31 | __compiletime_error("wrong use of PT_GUEST_(DIRTY|ACCESS)_SHIFT"); | ||
32 | |||
26 | #if PTTYPE == 64 | 33 | #if PTTYPE == 64 |
27 | #define pt_element_t u64 | 34 | #define pt_element_t u64 |
28 | #define guest_walker guest_walker64 | 35 | #define guest_walker guest_walker64 |
@@ -32,6 +39,10 @@ | |||
32 | #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl) | 39 | #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl) |
33 | #define PT_INDEX(addr, level) PT64_INDEX(addr, level) | 40 | #define PT_INDEX(addr, level) PT64_INDEX(addr, level) |
34 | #define PT_LEVEL_BITS PT64_LEVEL_BITS | 41 | #define PT_LEVEL_BITS PT64_LEVEL_BITS |
42 | #define PT_GUEST_ACCESSED_MASK PT_ACCESSED_MASK | ||
43 | #define PT_GUEST_DIRTY_MASK PT_DIRTY_MASK | ||
44 | #define PT_GUEST_DIRTY_SHIFT PT_DIRTY_SHIFT | ||
45 | #define PT_GUEST_ACCESSED_SHIFT PT_ACCESSED_SHIFT | ||
35 | #ifdef CONFIG_X86_64 | 46 | #ifdef CONFIG_X86_64 |
36 | #define PT_MAX_FULL_LEVELS 4 | 47 | #define PT_MAX_FULL_LEVELS 4 |
37 | #define CMPXCHG cmpxchg | 48 | #define CMPXCHG cmpxchg |
@@ -49,7 +60,26 @@ | |||
49 | #define PT_INDEX(addr, level) PT32_INDEX(addr, level) | 60 | #define PT_INDEX(addr, level) PT32_INDEX(addr, level) |
50 | #define PT_LEVEL_BITS PT32_LEVEL_BITS | 61 | #define PT_LEVEL_BITS PT32_LEVEL_BITS |
51 | #define PT_MAX_FULL_LEVELS 2 | 62 | #define PT_MAX_FULL_LEVELS 2 |
63 | #define PT_GUEST_ACCESSED_MASK PT_ACCESSED_MASK | ||
64 | #define PT_GUEST_DIRTY_MASK PT_DIRTY_MASK | ||
65 | #define PT_GUEST_DIRTY_SHIFT PT_DIRTY_SHIFT | ||
66 | #define PT_GUEST_ACCESSED_SHIFT PT_ACCESSED_SHIFT | ||
52 | #define CMPXCHG cmpxchg | 67 | #define CMPXCHG cmpxchg |
68 | #elif PTTYPE == PTTYPE_EPT | ||
69 | #define pt_element_t u64 | ||
70 | #define guest_walker guest_walkerEPT | ||
71 | #define FNAME(name) ept_##name | ||
72 | #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK | ||
73 | #define PT_LVL_ADDR_MASK(lvl) PT64_LVL_ADDR_MASK(lvl) | ||
74 | #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl) | ||
75 | #define PT_INDEX(addr, level) PT64_INDEX(addr, level) | ||
76 | #define PT_LEVEL_BITS PT64_LEVEL_BITS | ||
77 | #define PT_GUEST_ACCESSED_MASK 0 | ||
78 | #define PT_GUEST_DIRTY_MASK 0 | ||
79 | #define PT_GUEST_DIRTY_SHIFT __using_nonexistent_pte_bit() | ||
80 | #define PT_GUEST_ACCESSED_SHIFT __using_nonexistent_pte_bit() | ||
81 | #define CMPXCHG cmpxchg64 | ||
82 | #define PT_MAX_FULL_LEVELS 4 | ||
53 | #else | 83 | #else |
54 | #error Invalid PTTYPE value | 84 | #error Invalid PTTYPE value |
55 | #endif | 85 | #endif |
@@ -80,6 +110,40 @@ static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl) | |||
80 | return (gpte & PT_LVL_ADDR_MASK(lvl)) >> PAGE_SHIFT; | 110 | return (gpte & PT_LVL_ADDR_MASK(lvl)) >> PAGE_SHIFT; |
81 | } | 111 | } |
82 | 112 | ||
113 | static inline void FNAME(protect_clean_gpte)(unsigned *access, unsigned gpte) | ||
114 | { | ||
115 | unsigned mask; | ||
116 | |||
117 | /* dirty bit is not supported, so no need to track it */ | ||
118 | if (!PT_GUEST_DIRTY_MASK) | ||
119 | return; | ||
120 | |||
121 | BUILD_BUG_ON(PT_WRITABLE_MASK != ACC_WRITE_MASK); | ||
122 | |||
123 | mask = (unsigned)~ACC_WRITE_MASK; | ||
124 | /* Allow write access to dirty gptes */ | ||
125 | mask |= (gpte >> (PT_GUEST_DIRTY_SHIFT - PT_WRITABLE_SHIFT)) & | ||
126 | PT_WRITABLE_MASK; | ||
127 | *access &= mask; | ||
128 | } | ||
129 | |||
130 | static bool FNAME(is_rsvd_bits_set)(struct kvm_mmu *mmu, u64 gpte, int level) | ||
131 | { | ||
132 | int bit7 = (gpte >> 7) & 1, low6 = gpte & 0x3f; | ||
133 | |||
134 | return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) | | ||
135 | ((mmu->bad_mt_xwr & (1ull << low6)) != 0); | ||
136 | } | ||
137 | |||
138 | static inline int FNAME(is_present_gpte)(unsigned long pte) | ||
139 | { | ||
140 | #if PTTYPE != PTTYPE_EPT | ||
141 | return is_present_gpte(pte); | ||
142 | #else | ||
143 | return pte & 7; | ||
144 | #endif | ||
145 | } | ||
146 | |||
83 | static int FNAME(cmpxchg_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, | 147 | static int FNAME(cmpxchg_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, |
84 | pt_element_t __user *ptep_user, unsigned index, | 148 | pt_element_t __user *ptep_user, unsigned index, |
85 | pt_element_t orig_pte, pt_element_t new_pte) | 149 | pt_element_t orig_pte, pt_element_t new_pte) |
@@ -103,6 +167,42 @@ static int FNAME(cmpxchg_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, | |||
103 | return (ret != orig_pte); | 167 | return (ret != orig_pte); |
104 | } | 168 | } |
105 | 169 | ||
170 | static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcpu *vcpu, | ||
171 | struct kvm_mmu_page *sp, u64 *spte, | ||
172 | u64 gpte) | ||
173 | { | ||
174 | if (FNAME(is_rsvd_bits_set)(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)) | ||
175 | goto no_present; | ||
176 | |||
177 | if (!FNAME(is_present_gpte)(gpte)) | ||
178 | goto no_present; | ||
179 | |||
180 | /* if accessed bit is not supported prefetch non accessed gpte */ | ||
181 | if (PT_GUEST_ACCESSED_MASK && !(gpte & PT_GUEST_ACCESSED_MASK)) | ||
182 | goto no_present; | ||
183 | |||
184 | return false; | ||
185 | |||
186 | no_present: | ||
187 | drop_spte(vcpu->kvm, spte); | ||
188 | return true; | ||
189 | } | ||
190 | |||
191 | static inline unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, u64 gpte) | ||
192 | { | ||
193 | unsigned access; | ||
194 | #if PTTYPE == PTTYPE_EPT | ||
195 | access = ((gpte & VMX_EPT_WRITABLE_MASK) ? ACC_WRITE_MASK : 0) | | ||
196 | ((gpte & VMX_EPT_EXECUTABLE_MASK) ? ACC_EXEC_MASK : 0) | | ||
197 | ACC_USER_MASK; | ||
198 | #else | ||
199 | access = (gpte & (PT_WRITABLE_MASK | PT_USER_MASK)) | ACC_EXEC_MASK; | ||
200 | access &= ~(gpte >> PT64_NX_SHIFT); | ||
201 | #endif | ||
202 | |||
203 | return access; | ||
204 | } | ||
205 | |||
106 | static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu, | 206 | static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu, |
107 | struct kvm_mmu *mmu, | 207 | struct kvm_mmu *mmu, |
108 | struct guest_walker *walker, | 208 | struct guest_walker *walker, |
@@ -114,18 +214,23 @@ static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu, | |||
114 | gfn_t table_gfn; | 214 | gfn_t table_gfn; |
115 | int ret; | 215 | int ret; |
116 | 216 | ||
217 | /* dirty/accessed bits are not supported, so no need to update them */ | ||
218 | if (!PT_GUEST_DIRTY_MASK) | ||
219 | return 0; | ||
220 | |||
117 | for (level = walker->max_level; level >= walker->level; --level) { | 221 | for (level = walker->max_level; level >= walker->level; --level) { |
118 | pte = orig_pte = walker->ptes[level - 1]; | 222 | pte = orig_pte = walker->ptes[level - 1]; |
119 | table_gfn = walker->table_gfn[level - 1]; | 223 | table_gfn = walker->table_gfn[level - 1]; |
120 | ptep_user = walker->ptep_user[level - 1]; | 224 | ptep_user = walker->ptep_user[level - 1]; |
121 | index = offset_in_page(ptep_user) / sizeof(pt_element_t); | 225 | index = offset_in_page(ptep_user) / sizeof(pt_element_t); |
122 | if (!(pte & PT_ACCESSED_MASK)) { | 226 | if (!(pte & PT_GUEST_ACCESSED_MASK)) { |
123 | trace_kvm_mmu_set_accessed_bit(table_gfn, index, sizeof(pte)); | 227 | trace_kvm_mmu_set_accessed_bit(table_gfn, index, sizeof(pte)); |
124 | pte |= PT_ACCESSED_MASK; | 228 | pte |= PT_GUEST_ACCESSED_MASK; |
125 | } | 229 | } |
126 | if (level == walker->level && write_fault && !is_dirty_gpte(pte)) { | 230 | if (level == walker->level && write_fault && |
231 | !(pte & PT_GUEST_DIRTY_MASK)) { | ||
127 | trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte)); | 232 | trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte)); |
128 | pte |= PT_DIRTY_MASK; | 233 | pte |= PT_GUEST_DIRTY_MASK; |
129 | } | 234 | } |
130 | if (pte == orig_pte) | 235 | if (pte == orig_pte) |
131 | continue; | 236 | continue; |
@@ -170,7 +275,7 @@ retry_walk: | |||
170 | if (walker->level == PT32E_ROOT_LEVEL) { | 275 | if (walker->level == PT32E_ROOT_LEVEL) { |
171 | pte = mmu->get_pdptr(vcpu, (addr >> 30) & 3); | 276 | pte = mmu->get_pdptr(vcpu, (addr >> 30) & 3); |
172 | trace_kvm_mmu_paging_element(pte, walker->level); | 277 | trace_kvm_mmu_paging_element(pte, walker->level); |
173 | if (!is_present_gpte(pte)) | 278 | if (!FNAME(is_present_gpte)(pte)) |
174 | goto error; | 279 | goto error; |
175 | --walker->level; | 280 | --walker->level; |
176 | } | 281 | } |
@@ -179,7 +284,7 @@ retry_walk: | |||
179 | ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) || | 284 | ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) || |
180 | (mmu->get_cr3(vcpu) & CR3_NONPAE_RESERVED_BITS) == 0); | 285 | (mmu->get_cr3(vcpu) & CR3_NONPAE_RESERVED_BITS) == 0); |
181 | 286 | ||
182 | accessed_dirty = PT_ACCESSED_MASK; | 287 | accessed_dirty = PT_GUEST_ACCESSED_MASK; |
183 | pt_access = pte_access = ACC_ALL; | 288 | pt_access = pte_access = ACC_ALL; |
184 | ++walker->level; | 289 | ++walker->level; |
185 | 290 | ||
@@ -215,17 +320,17 @@ retry_walk: | |||
215 | 320 | ||
216 | trace_kvm_mmu_paging_element(pte, walker->level); | 321 | trace_kvm_mmu_paging_element(pte, walker->level); |
217 | 322 | ||
218 | if (unlikely(!is_present_gpte(pte))) | 323 | if (unlikely(!FNAME(is_present_gpte)(pte))) |
219 | goto error; | 324 | goto error; |
220 | 325 | ||
221 | if (unlikely(is_rsvd_bits_set(&vcpu->arch.mmu, pte, | 326 | if (unlikely(FNAME(is_rsvd_bits_set)(mmu, pte, |
222 | walker->level))) { | 327 | walker->level))) { |
223 | errcode |= PFERR_RSVD_MASK | PFERR_PRESENT_MASK; | 328 | errcode |= PFERR_RSVD_MASK | PFERR_PRESENT_MASK; |
224 | goto error; | 329 | goto error; |
225 | } | 330 | } |
226 | 331 | ||
227 | accessed_dirty &= pte; | 332 | accessed_dirty &= pte; |
228 | pte_access = pt_access & gpte_access(vcpu, pte); | 333 | pte_access = pt_access & FNAME(gpte_access)(vcpu, pte); |
229 | 334 | ||
230 | walker->ptes[walker->level - 1] = pte; | 335 | walker->ptes[walker->level - 1] = pte; |
231 | } while (!is_last_gpte(mmu, walker->level, pte)); | 336 | } while (!is_last_gpte(mmu, walker->level, pte)); |
@@ -248,13 +353,15 @@ retry_walk: | |||
248 | walker->gfn = real_gpa >> PAGE_SHIFT; | 353 | walker->gfn = real_gpa >> PAGE_SHIFT; |
249 | 354 | ||
250 | if (!write_fault) | 355 | if (!write_fault) |
251 | protect_clean_gpte(&pte_access, pte); | 356 | FNAME(protect_clean_gpte)(&pte_access, pte); |
252 | else | 357 | else |
253 | /* | 358 | /* |
254 | * On a write fault, fold the dirty bit into accessed_dirty by | 359 | * On a write fault, fold the dirty bit into accessed_dirty. |
255 | * shifting it one place right. | 360 | * For modes without A/D bits support accessed_dirty will be |
361 | * always clear. | ||
256 | */ | 362 | */ |
257 | accessed_dirty &= pte >> (PT_DIRTY_SHIFT - PT_ACCESSED_SHIFT); | 363 | accessed_dirty &= pte >> |
364 | (PT_GUEST_DIRTY_SHIFT - PT_GUEST_ACCESSED_SHIFT); | ||
258 | 365 | ||
259 | if (unlikely(!accessed_dirty)) { | 366 | if (unlikely(!accessed_dirty)) { |
260 | ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, write_fault); | 367 | ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, write_fault); |
@@ -279,6 +386,25 @@ error: | |||
279 | walker->fault.vector = PF_VECTOR; | 386 | walker->fault.vector = PF_VECTOR; |
280 | walker->fault.error_code_valid = true; | 387 | walker->fault.error_code_valid = true; |
281 | walker->fault.error_code = errcode; | 388 | walker->fault.error_code = errcode; |
389 | |||
390 | #if PTTYPE == PTTYPE_EPT | ||
391 | /* | ||
392 | * Use PFERR_RSVD_MASK in error_code to to tell if EPT | ||
393 | * misconfiguration requires to be injected. The detection is | ||
394 | * done by is_rsvd_bits_set() above. | ||
395 | * | ||
396 | * We set up the value of exit_qualification to inject: | ||
397 | * [2:0] - Derive from [2:0] of real exit_qualification at EPT violation | ||
398 | * [5:3] - Calculated by the page walk of the guest EPT page tables | ||
399 | * [7:8] - Derived from [7:8] of real exit_qualification | ||
400 | * | ||
401 | * The other bits are set to 0. | ||
402 | */ | ||
403 | if (!(errcode & PFERR_RSVD_MASK)) { | ||
404 | vcpu->arch.exit_qualification &= 0x187; | ||
405 | vcpu->arch.exit_qualification |= ((pt_access & pte) & 0x7) << 3; | ||
406 | } | ||
407 | #endif | ||
282 | walker->fault.address = addr; | 408 | walker->fault.address = addr; |
283 | walker->fault.nested_page_fault = mmu != vcpu->arch.walk_mmu; | 409 | walker->fault.nested_page_fault = mmu != vcpu->arch.walk_mmu; |
284 | 410 | ||
@@ -293,6 +419,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker, | |||
293 | access); | 419 | access); |
294 | } | 420 | } |
295 | 421 | ||
422 | #if PTTYPE != PTTYPE_EPT | ||
296 | static int FNAME(walk_addr_nested)(struct guest_walker *walker, | 423 | static int FNAME(walk_addr_nested)(struct guest_walker *walker, |
297 | struct kvm_vcpu *vcpu, gva_t addr, | 424 | struct kvm_vcpu *vcpu, gva_t addr, |
298 | u32 access) | 425 | u32 access) |
@@ -300,6 +427,7 @@ static int FNAME(walk_addr_nested)(struct guest_walker *walker, | |||
300 | return FNAME(walk_addr_generic)(walker, vcpu, &vcpu->arch.nested_mmu, | 427 | return FNAME(walk_addr_generic)(walker, vcpu, &vcpu->arch.nested_mmu, |
301 | addr, access); | 428 | addr, access); |
302 | } | 429 | } |
430 | #endif | ||
303 | 431 | ||
304 | static bool | 432 | static bool |
305 | FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | 433 | FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, |
@@ -309,14 +437,14 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | |||
309 | gfn_t gfn; | 437 | gfn_t gfn; |
310 | pfn_t pfn; | 438 | pfn_t pfn; |
311 | 439 | ||
312 | if (prefetch_invalid_gpte(vcpu, sp, spte, gpte)) | 440 | if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte)) |
313 | return false; | 441 | return false; |
314 | 442 | ||
315 | pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); | 443 | pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); |
316 | 444 | ||
317 | gfn = gpte_to_gfn(gpte); | 445 | gfn = gpte_to_gfn(gpte); |
318 | pte_access = sp->role.access & gpte_access(vcpu, gpte); | 446 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); |
319 | protect_clean_gpte(&pte_access, gpte); | 447 | FNAME(protect_clean_gpte)(&pte_access, gpte); |
320 | pfn = pte_prefetch_gfn_to_pfn(vcpu, gfn, | 448 | pfn = pte_prefetch_gfn_to_pfn(vcpu, gfn, |
321 | no_dirty_log && (pte_access & ACC_WRITE_MASK)); | 449 | no_dirty_log && (pte_access & ACC_WRITE_MASK)); |
322 | if (is_error_pfn(pfn)) | 450 | if (is_error_pfn(pfn)) |
@@ -446,7 +574,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | |||
446 | goto out_gpte_changed; | 574 | goto out_gpte_changed; |
447 | 575 | ||
448 | if (sp) | 576 | if (sp) |
449 | link_shadow_page(it.sptep, sp); | 577 | link_shadow_page(it.sptep, sp, PT_GUEST_ACCESSED_MASK); |
450 | } | 578 | } |
451 | 579 | ||
452 | for (; | 580 | for (; |
@@ -466,7 +594,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | |||
466 | 594 | ||
467 | sp = kvm_mmu_get_page(vcpu, direct_gfn, addr, it.level-1, | 595 | sp = kvm_mmu_get_page(vcpu, direct_gfn, addr, it.level-1, |
468 | true, direct_access, it.sptep); | 596 | true, direct_access, it.sptep); |
469 | link_shadow_page(it.sptep, sp); | 597 | link_shadow_page(it.sptep, sp, PT_GUEST_ACCESSED_MASK); |
470 | } | 598 | } |
471 | 599 | ||
472 | clear_sp_write_flooding_count(it.sptep); | 600 | clear_sp_write_flooding_count(it.sptep); |
@@ -727,6 +855,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, | |||
727 | return gpa; | 855 | return gpa; |
728 | } | 856 | } |
729 | 857 | ||
858 | #if PTTYPE != PTTYPE_EPT | ||
730 | static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr, | 859 | static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr, |
731 | u32 access, | 860 | u32 access, |
732 | struct x86_exception *exception) | 861 | struct x86_exception *exception) |
@@ -745,6 +874,7 @@ static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr, | |||
745 | 874 | ||
746 | return gpa; | 875 | return gpa; |
747 | } | 876 | } |
877 | #endif | ||
748 | 878 | ||
749 | /* | 879 | /* |
750 | * Using the cached information from sp->gfns is safe because: | 880 | * Using the cached information from sp->gfns is safe because: |
@@ -785,15 +915,15 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | |||
785 | sizeof(pt_element_t))) | 915 | sizeof(pt_element_t))) |
786 | return -EINVAL; | 916 | return -EINVAL; |
787 | 917 | ||
788 | if (prefetch_invalid_gpte(vcpu, sp, &sp->spt[i], gpte)) { | 918 | if (FNAME(prefetch_invalid_gpte)(vcpu, sp, &sp->spt[i], gpte)) { |
789 | vcpu->kvm->tlbs_dirty++; | 919 | vcpu->kvm->tlbs_dirty++; |
790 | continue; | 920 | continue; |
791 | } | 921 | } |
792 | 922 | ||
793 | gfn = gpte_to_gfn(gpte); | 923 | gfn = gpte_to_gfn(gpte); |
794 | pte_access = sp->role.access; | 924 | pte_access = sp->role.access; |
795 | pte_access &= gpte_access(vcpu, gpte); | 925 | pte_access &= FNAME(gpte_access)(vcpu, gpte); |
796 | protect_clean_gpte(&pte_access, gpte); | 926 | FNAME(protect_clean_gpte)(&pte_access, gpte); |
797 | 927 | ||
798 | if (sync_mmio_spte(vcpu->kvm, &sp->spt[i], gfn, pte_access, | 928 | if (sync_mmio_spte(vcpu->kvm, &sp->spt[i], gfn, pte_access, |
799 | &nr_present)) | 929 | &nr_present)) |
@@ -830,3 +960,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | |||
830 | #undef gpte_to_gfn | 960 | #undef gpte_to_gfn |
831 | #undef gpte_to_gfn_lvl | 961 | #undef gpte_to_gfn_lvl |
832 | #undef CMPXCHG | 962 | #undef CMPXCHG |
963 | #undef PT_GUEST_ACCESSED_MASK | ||
964 | #undef PT_GUEST_DIRTY_MASK | ||
965 | #undef PT_GUEST_DIRTY_SHIFT | ||
966 | #undef PT_GUEST_ACCESSED_SHIFT | ||
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index c53e797e7369..5c4f63151b4d 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c | |||
@@ -160,7 +160,7 @@ static void stop_counter(struct kvm_pmc *pmc) | |||
160 | 160 | ||
161 | static void reprogram_counter(struct kvm_pmc *pmc, u32 type, | 161 | static void reprogram_counter(struct kvm_pmc *pmc, u32 type, |
162 | unsigned config, bool exclude_user, bool exclude_kernel, | 162 | unsigned config, bool exclude_user, bool exclude_kernel, |
163 | bool intr) | 163 | bool intr, bool in_tx, bool in_tx_cp) |
164 | { | 164 | { |
165 | struct perf_event *event; | 165 | struct perf_event *event; |
166 | struct perf_event_attr attr = { | 166 | struct perf_event_attr attr = { |
@@ -173,6 +173,10 @@ static void reprogram_counter(struct kvm_pmc *pmc, u32 type, | |||
173 | .exclude_kernel = exclude_kernel, | 173 | .exclude_kernel = exclude_kernel, |
174 | .config = config, | 174 | .config = config, |
175 | }; | 175 | }; |
176 | if (in_tx) | ||
177 | attr.config |= HSW_IN_TX; | ||
178 | if (in_tx_cp) | ||
179 | attr.config |= HSW_IN_TX_CHECKPOINTED; | ||
176 | 180 | ||
177 | attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc); | 181 | attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc); |
178 | 182 | ||
@@ -226,7 +230,9 @@ static void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) | |||
226 | 230 | ||
227 | if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE | | 231 | if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE | |
228 | ARCH_PERFMON_EVENTSEL_INV | | 232 | ARCH_PERFMON_EVENTSEL_INV | |
229 | ARCH_PERFMON_EVENTSEL_CMASK))) { | 233 | ARCH_PERFMON_EVENTSEL_CMASK | |
234 | HSW_IN_TX | | ||
235 | HSW_IN_TX_CHECKPOINTED))) { | ||
230 | config = find_arch_event(&pmc->vcpu->arch.pmu, event_select, | 236 | config = find_arch_event(&pmc->vcpu->arch.pmu, event_select, |
231 | unit_mask); | 237 | unit_mask); |
232 | if (config != PERF_COUNT_HW_MAX) | 238 | if (config != PERF_COUNT_HW_MAX) |
@@ -239,7 +245,9 @@ static void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) | |||
239 | reprogram_counter(pmc, type, config, | 245 | reprogram_counter(pmc, type, config, |
240 | !(eventsel & ARCH_PERFMON_EVENTSEL_USR), | 246 | !(eventsel & ARCH_PERFMON_EVENTSEL_USR), |
241 | !(eventsel & ARCH_PERFMON_EVENTSEL_OS), | 247 | !(eventsel & ARCH_PERFMON_EVENTSEL_OS), |
242 | eventsel & ARCH_PERFMON_EVENTSEL_INT); | 248 | eventsel & ARCH_PERFMON_EVENTSEL_INT, |
249 | (eventsel & HSW_IN_TX), | ||
250 | (eventsel & HSW_IN_TX_CHECKPOINTED)); | ||
243 | } | 251 | } |
244 | 252 | ||
245 | static void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 en_pmi, int idx) | 253 | static void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 en_pmi, int idx) |
@@ -256,7 +264,7 @@ static void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 en_pmi, int idx) | |||
256 | arch_events[fixed_pmc_events[idx]].event_type, | 264 | arch_events[fixed_pmc_events[idx]].event_type, |
257 | !(en & 0x2), /* exclude user */ | 265 | !(en & 0x2), /* exclude user */ |
258 | !(en & 0x1), /* exclude kernel */ | 266 | !(en & 0x1), /* exclude kernel */ |
259 | pmi); | 267 | pmi, false, false); |
260 | } | 268 | } |
261 | 269 | ||
262 | static inline u8 fixed_en_pmi(u64 ctrl, int idx) | 270 | static inline u8 fixed_en_pmi(u64 ctrl, int idx) |
@@ -408,7 +416,7 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
408 | } else if ((pmc = get_gp_pmc(pmu, index, MSR_P6_EVNTSEL0))) { | 416 | } else if ((pmc = get_gp_pmc(pmu, index, MSR_P6_EVNTSEL0))) { |
409 | if (data == pmc->eventsel) | 417 | if (data == pmc->eventsel) |
410 | return 0; | 418 | return 0; |
411 | if (!(data & 0xffffffff00200000ull)) { | 419 | if (!(data & pmu->reserved_bits)) { |
412 | reprogram_gp_counter(pmc, data); | 420 | reprogram_gp_counter(pmc, data); |
413 | return 0; | 421 | return 0; |
414 | } | 422 | } |
@@ -450,6 +458,7 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) | |||
450 | pmu->counter_bitmask[KVM_PMC_GP] = 0; | 458 | pmu->counter_bitmask[KVM_PMC_GP] = 0; |
451 | pmu->counter_bitmask[KVM_PMC_FIXED] = 0; | 459 | pmu->counter_bitmask[KVM_PMC_FIXED] = 0; |
452 | pmu->version = 0; | 460 | pmu->version = 0; |
461 | pmu->reserved_bits = 0xffffffff00200000ull; | ||
453 | 462 | ||
454 | entry = kvm_find_cpuid_entry(vcpu, 0xa, 0); | 463 | entry = kvm_find_cpuid_entry(vcpu, 0xa, 0); |
455 | if (!entry) | 464 | if (!entry) |
@@ -478,6 +487,12 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) | |||
478 | pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | | 487 | pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | |
479 | (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED); | 488 | (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED); |
480 | pmu->global_ctrl_mask = ~pmu->global_ctrl; | 489 | pmu->global_ctrl_mask = ~pmu->global_ctrl; |
490 | |||
491 | entry = kvm_find_cpuid_entry(vcpu, 7, 0); | ||
492 | if (entry && | ||
493 | (boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) && | ||
494 | (entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM))) | ||
495 | pmu->reserved_bits ^= HSW_IN_TX|HSW_IN_TX_CHECKPOINTED; | ||
481 | } | 496 | } |
482 | 497 | ||
483 | void kvm_pmu_init(struct kvm_vcpu *vcpu) | 498 | void kvm_pmu_init(struct kvm_vcpu *vcpu) |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 064d0be67ecc..1f1da43ff2a2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -373,6 +373,7 @@ struct nested_vmx { | |||
373 | * we must keep them pinned while L2 runs. | 373 | * we must keep them pinned while L2 runs. |
374 | */ | 374 | */ |
375 | struct page *apic_access_page; | 375 | struct page *apic_access_page; |
376 | u64 msr_ia32_feature_control; | ||
376 | }; | 377 | }; |
377 | 378 | ||
378 | #define POSTED_INTR_ON 0 | 379 | #define POSTED_INTR_ON 0 |
@@ -711,10 +712,10 @@ static void nested_release_page_clean(struct page *page) | |||
711 | kvm_release_page_clean(page); | 712 | kvm_release_page_clean(page); |
712 | } | 713 | } |
713 | 714 | ||
715 | static unsigned long nested_ept_get_cr3(struct kvm_vcpu *vcpu); | ||
714 | static u64 construct_eptp(unsigned long root_hpa); | 716 | static u64 construct_eptp(unsigned long root_hpa); |
715 | static void kvm_cpu_vmxon(u64 addr); | 717 | static void kvm_cpu_vmxon(u64 addr); |
716 | static void kvm_cpu_vmxoff(void); | 718 | static void kvm_cpu_vmxoff(void); |
717 | static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); | ||
718 | static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr); | 719 | static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr); |
719 | static void vmx_set_segment(struct kvm_vcpu *vcpu, | 720 | static void vmx_set_segment(struct kvm_vcpu *vcpu, |
720 | struct kvm_segment *var, int seg); | 721 | struct kvm_segment *var, int seg); |
@@ -1039,12 +1040,16 @@ static inline bool nested_cpu_has2(struct vmcs12 *vmcs12, u32 bit) | |||
1039 | (vmcs12->secondary_vm_exec_control & bit); | 1040 | (vmcs12->secondary_vm_exec_control & bit); |
1040 | } | 1041 | } |
1041 | 1042 | ||
1042 | static inline bool nested_cpu_has_virtual_nmis(struct vmcs12 *vmcs12, | 1043 | static inline bool nested_cpu_has_virtual_nmis(struct vmcs12 *vmcs12) |
1043 | struct kvm_vcpu *vcpu) | ||
1044 | { | 1044 | { |
1045 | return vmcs12->pin_based_vm_exec_control & PIN_BASED_VIRTUAL_NMIS; | 1045 | return vmcs12->pin_based_vm_exec_control & PIN_BASED_VIRTUAL_NMIS; |
1046 | } | 1046 | } |
1047 | 1047 | ||
1048 | static inline int nested_cpu_has_ept(struct vmcs12 *vmcs12) | ||
1049 | { | ||
1050 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT); | ||
1051 | } | ||
1052 | |||
1048 | static inline bool is_exception(u32 intr_info) | 1053 | static inline bool is_exception(u32 intr_info) |
1049 | { | 1054 | { |
1050 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) | 1055 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) |
@@ -2155,6 +2160,7 @@ static u32 nested_vmx_pinbased_ctls_low, nested_vmx_pinbased_ctls_high; | |||
2155 | static u32 nested_vmx_exit_ctls_low, nested_vmx_exit_ctls_high; | 2160 | static u32 nested_vmx_exit_ctls_low, nested_vmx_exit_ctls_high; |
2156 | static u32 nested_vmx_entry_ctls_low, nested_vmx_entry_ctls_high; | 2161 | static u32 nested_vmx_entry_ctls_low, nested_vmx_entry_ctls_high; |
2157 | static u32 nested_vmx_misc_low, nested_vmx_misc_high; | 2162 | static u32 nested_vmx_misc_low, nested_vmx_misc_high; |
2163 | static u32 nested_vmx_ept_caps; | ||
2158 | static __init void nested_vmx_setup_ctls_msrs(void) | 2164 | static __init void nested_vmx_setup_ctls_msrs(void) |
2159 | { | 2165 | { |
2160 | /* | 2166 | /* |
@@ -2190,14 +2196,17 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2190 | * If bit 55 of VMX_BASIC is off, bits 0-8 and 10, 11, 13, 14, 16 and | 2196 | * If bit 55 of VMX_BASIC is off, bits 0-8 and 10, 11, 13, 14, 16 and |
2191 | * 17 must be 1. | 2197 | * 17 must be 1. |
2192 | */ | 2198 | */ |
2199 | rdmsr(MSR_IA32_VMX_EXIT_CTLS, | ||
2200 | nested_vmx_exit_ctls_low, nested_vmx_exit_ctls_high); | ||
2193 | nested_vmx_exit_ctls_low = VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; | 2201 | nested_vmx_exit_ctls_low = VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; |
2194 | /* Note that guest use of VM_EXIT_ACK_INTR_ON_EXIT is not supported. */ | 2202 | /* Note that guest use of VM_EXIT_ACK_INTR_ON_EXIT is not supported. */ |
2203 | nested_vmx_exit_ctls_high &= | ||
2195 | #ifdef CONFIG_X86_64 | 2204 | #ifdef CONFIG_X86_64 |
2196 | nested_vmx_exit_ctls_high = VM_EXIT_HOST_ADDR_SPACE_SIZE; | 2205 | VM_EXIT_HOST_ADDR_SPACE_SIZE | |
2197 | #else | ||
2198 | nested_vmx_exit_ctls_high = 0; | ||
2199 | #endif | 2206 | #endif |
2200 | nested_vmx_exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; | 2207 | VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT; |
2208 | nested_vmx_exit_ctls_high |= (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | | ||
2209 | VM_EXIT_LOAD_IA32_EFER); | ||
2201 | 2210 | ||
2202 | /* entry controls */ | 2211 | /* entry controls */ |
2203 | rdmsr(MSR_IA32_VMX_ENTRY_CTLS, | 2212 | rdmsr(MSR_IA32_VMX_ENTRY_CTLS, |
@@ -2205,8 +2214,12 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2205 | /* If bit 55 of VMX_BASIC is off, bits 0-8 and 12 must be 1. */ | 2214 | /* If bit 55 of VMX_BASIC is off, bits 0-8 and 12 must be 1. */ |
2206 | nested_vmx_entry_ctls_low = VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR; | 2215 | nested_vmx_entry_ctls_low = VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR; |
2207 | nested_vmx_entry_ctls_high &= | 2216 | nested_vmx_entry_ctls_high &= |
2208 | VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_IA32E_MODE; | 2217 | #ifdef CONFIG_X86_64 |
2209 | nested_vmx_entry_ctls_high |= VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR; | 2218 | VM_ENTRY_IA32E_MODE | |
2219 | #endif | ||
2220 | VM_ENTRY_LOAD_IA32_PAT; | ||
2221 | nested_vmx_entry_ctls_high |= (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | | ||
2222 | VM_ENTRY_LOAD_IA32_EFER); | ||
2210 | 2223 | ||
2211 | /* cpu-based controls */ | 2224 | /* cpu-based controls */ |
2212 | rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, | 2225 | rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, |
@@ -2241,6 +2254,22 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2241 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | | 2254 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
2242 | SECONDARY_EXEC_WBINVD_EXITING; | 2255 | SECONDARY_EXEC_WBINVD_EXITING; |
2243 | 2256 | ||
2257 | if (enable_ept) { | ||
2258 | /* nested EPT: emulate EPT also to L1 */ | ||
2259 | nested_vmx_secondary_ctls_high |= SECONDARY_EXEC_ENABLE_EPT; | ||
2260 | nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | | ||
2261 | VMX_EPTP_WB_BIT | VMX_EPT_INVEPT_BIT; | ||
2262 | nested_vmx_ept_caps &= vmx_capability.ept; | ||
2263 | /* | ||
2264 | * Since invept is completely emulated we support both global | ||
2265 | * and context invalidation independent of what host cpu | ||
2266 | * supports | ||
2267 | */ | ||
2268 | nested_vmx_ept_caps |= VMX_EPT_EXTENT_GLOBAL_BIT | | ||
2269 | VMX_EPT_EXTENT_CONTEXT_BIT; | ||
2270 | } else | ||
2271 | nested_vmx_ept_caps = 0; | ||
2272 | |||
2244 | /* miscellaneous data */ | 2273 | /* miscellaneous data */ |
2245 | rdmsr(MSR_IA32_VMX_MISC, nested_vmx_misc_low, nested_vmx_misc_high); | 2274 | rdmsr(MSR_IA32_VMX_MISC, nested_vmx_misc_low, nested_vmx_misc_high); |
2246 | nested_vmx_misc_low &= VMX_MISC_PREEMPTION_TIMER_RATE_MASK | | 2275 | nested_vmx_misc_low &= VMX_MISC_PREEMPTION_TIMER_RATE_MASK | |
@@ -2282,8 +2311,11 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
2282 | 2311 | ||
2283 | switch (msr_index) { | 2312 | switch (msr_index) { |
2284 | case MSR_IA32_FEATURE_CONTROL: | 2313 | case MSR_IA32_FEATURE_CONTROL: |
2285 | *pdata = 0; | 2314 | if (nested_vmx_allowed(vcpu)) { |
2286 | break; | 2315 | *pdata = to_vmx(vcpu)->nested.msr_ia32_feature_control; |
2316 | break; | ||
2317 | } | ||
2318 | return 0; | ||
2287 | case MSR_IA32_VMX_BASIC: | 2319 | case MSR_IA32_VMX_BASIC: |
2288 | /* | 2320 | /* |
2289 | * This MSR reports some information about VMX support. We | 2321 | * This MSR reports some information about VMX support. We |
@@ -2346,8 +2378,8 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
2346 | nested_vmx_secondary_ctls_high); | 2378 | nested_vmx_secondary_ctls_high); |
2347 | break; | 2379 | break; |
2348 | case MSR_IA32_VMX_EPT_VPID_CAP: | 2380 | case MSR_IA32_VMX_EPT_VPID_CAP: |
2349 | /* Currently, no nested ept or nested vpid */ | 2381 | /* Currently, no nested vpid support */ |
2350 | *pdata = 0; | 2382 | *pdata = nested_vmx_ept_caps; |
2351 | break; | 2383 | break; |
2352 | default: | 2384 | default: |
2353 | return 0; | 2385 | return 0; |
@@ -2356,14 +2388,24 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
2356 | return 1; | 2388 | return 1; |
2357 | } | 2389 | } |
2358 | 2390 | ||
2359 | static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) | 2391 | static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
2360 | { | 2392 | { |
2393 | u32 msr_index = msr_info->index; | ||
2394 | u64 data = msr_info->data; | ||
2395 | bool host_initialized = msr_info->host_initiated; | ||
2396 | |||
2361 | if (!nested_vmx_allowed(vcpu)) | 2397 | if (!nested_vmx_allowed(vcpu)) |
2362 | return 0; | 2398 | return 0; |
2363 | 2399 | ||
2364 | if (msr_index == MSR_IA32_FEATURE_CONTROL) | 2400 | if (msr_index == MSR_IA32_FEATURE_CONTROL) { |
2365 | /* TODO: the right thing. */ | 2401 | if (!host_initialized && |
2402 | to_vmx(vcpu)->nested.msr_ia32_feature_control | ||
2403 | & FEATURE_CONTROL_LOCKED) | ||
2404 | return 0; | ||
2405 | to_vmx(vcpu)->nested.msr_ia32_feature_control = data; | ||
2366 | return 1; | 2406 | return 1; |
2407 | } | ||
2408 | |||
2367 | /* | 2409 | /* |
2368 | * No need to treat VMX capability MSRs specially: If we don't handle | 2410 | * No need to treat VMX capability MSRs specially: If we don't handle |
2369 | * them, handle_wrmsr will #GP(0), which is correct (they are readonly) | 2411 | * them, handle_wrmsr will #GP(0), which is correct (they are readonly) |
@@ -2494,7 +2536,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
2494 | return 1; | 2536 | return 1; |
2495 | /* Otherwise falls through */ | 2537 | /* Otherwise falls through */ |
2496 | default: | 2538 | default: |
2497 | if (vmx_set_vmx_msr(vcpu, msr_index, data)) | 2539 | if (vmx_set_vmx_msr(vcpu, msr_info)) |
2498 | break; | 2540 | break; |
2499 | msr = find_msr_entry(vmx, msr_index); | 2541 | msr = find_msr_entry(vmx, msr_index); |
2500 | if (msr) { | 2542 | if (msr) { |
@@ -5302,9 +5344,13 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu) | |||
5302 | 5344 | ||
5303 | /* It is a write fault? */ | 5345 | /* It is a write fault? */ |
5304 | error_code = exit_qualification & (1U << 1); | 5346 | error_code = exit_qualification & (1U << 1); |
5347 | /* It is a fetch fault? */ | ||
5348 | error_code |= (exit_qualification & (1U << 2)) << 2; | ||
5305 | /* ept page table is present? */ | 5349 | /* ept page table is present? */ |
5306 | error_code |= (exit_qualification >> 3) & 0x1; | 5350 | error_code |= (exit_qualification >> 3) & 0x1; |
5307 | 5351 | ||
5352 | vcpu->arch.exit_qualification = exit_qualification; | ||
5353 | |||
5308 | return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0); | 5354 | return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0); |
5309 | } | 5355 | } |
5310 | 5356 | ||
@@ -5438,7 +5484,8 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) | |||
5438 | 5484 | ||
5439 | err = emulate_instruction(vcpu, EMULTYPE_NO_REEXECUTE); | 5485 | err = emulate_instruction(vcpu, EMULTYPE_NO_REEXECUTE); |
5440 | 5486 | ||
5441 | if (err == EMULATE_DO_MMIO) { | 5487 | if (err == EMULATE_USER_EXIT) { |
5488 | ++vcpu->stat.mmio_exits; | ||
5442 | ret = 0; | 5489 | ret = 0; |
5443 | goto out; | 5490 | goto out; |
5444 | } | 5491 | } |
@@ -5567,8 +5614,47 @@ static void nested_free_all_saved_vmcss(struct vcpu_vmx *vmx) | |||
5567 | free_loaded_vmcs(&vmx->vmcs01); | 5614 | free_loaded_vmcs(&vmx->vmcs01); |
5568 | } | 5615 | } |
5569 | 5616 | ||
5617 | /* | ||
5618 | * The following 3 functions, nested_vmx_succeed()/failValid()/failInvalid(), | ||
5619 | * set the success or error code of an emulated VMX instruction, as specified | ||
5620 | * by Vol 2B, VMX Instruction Reference, "Conventions". | ||
5621 | */ | ||
5622 | static void nested_vmx_succeed(struct kvm_vcpu *vcpu) | ||
5623 | { | ||
5624 | vmx_set_rflags(vcpu, vmx_get_rflags(vcpu) | ||
5625 | & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | | ||
5626 | X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF)); | ||
5627 | } | ||
5628 | |||
5629 | static void nested_vmx_failInvalid(struct kvm_vcpu *vcpu) | ||
5630 | { | ||
5631 | vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu) | ||
5632 | & ~(X86_EFLAGS_PF | X86_EFLAGS_AF | X86_EFLAGS_ZF | | ||
5633 | X86_EFLAGS_SF | X86_EFLAGS_OF)) | ||
5634 | | X86_EFLAGS_CF); | ||
5635 | } | ||
5636 | |||
5570 | static void nested_vmx_failValid(struct kvm_vcpu *vcpu, | 5637 | static void nested_vmx_failValid(struct kvm_vcpu *vcpu, |
5571 | u32 vm_instruction_error); | 5638 | u32 vm_instruction_error) |
5639 | { | ||
5640 | if (to_vmx(vcpu)->nested.current_vmptr == -1ull) { | ||
5641 | /* | ||
5642 | * failValid writes the error number to the current VMCS, which | ||
5643 | * can't be done there isn't a current VMCS. | ||
5644 | */ | ||
5645 | nested_vmx_failInvalid(vcpu); | ||
5646 | return; | ||
5647 | } | ||
5648 | vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu) | ||
5649 | & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | | ||
5650 | X86_EFLAGS_SF | X86_EFLAGS_OF)) | ||
5651 | | X86_EFLAGS_ZF); | ||
5652 | get_vmcs12(vcpu)->vm_instruction_error = vm_instruction_error; | ||
5653 | /* | ||
5654 | * We don't need to force a shadow sync because | ||
5655 | * VM_INSTRUCTION_ERROR is not shadowed | ||
5656 | */ | ||
5657 | } | ||
5572 | 5658 | ||
5573 | /* | 5659 | /* |
5574 | * Emulate the VMXON instruction. | 5660 | * Emulate the VMXON instruction. |
@@ -5583,6 +5669,8 @@ static int handle_vmon(struct kvm_vcpu *vcpu) | |||
5583 | struct kvm_segment cs; | 5669 | struct kvm_segment cs; |
5584 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 5670 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
5585 | struct vmcs *shadow_vmcs; | 5671 | struct vmcs *shadow_vmcs; |
5672 | const u64 VMXON_NEEDED_FEATURES = FEATURE_CONTROL_LOCKED | ||
5673 | | FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX; | ||
5586 | 5674 | ||
5587 | /* The Intel VMX Instruction Reference lists a bunch of bits that | 5675 | /* The Intel VMX Instruction Reference lists a bunch of bits that |
5588 | * are prerequisite to running VMXON, most notably cr4.VMXE must be | 5676 | * are prerequisite to running VMXON, most notably cr4.VMXE must be |
@@ -5611,6 +5699,13 @@ static int handle_vmon(struct kvm_vcpu *vcpu) | |||
5611 | skip_emulated_instruction(vcpu); | 5699 | skip_emulated_instruction(vcpu); |
5612 | return 1; | 5700 | return 1; |
5613 | } | 5701 | } |
5702 | |||
5703 | if ((vmx->nested.msr_ia32_feature_control & VMXON_NEEDED_FEATURES) | ||
5704 | != VMXON_NEEDED_FEATURES) { | ||
5705 | kvm_inject_gp(vcpu, 0); | ||
5706 | return 1; | ||
5707 | } | ||
5708 | |||
5614 | if (enable_shadow_vmcs) { | 5709 | if (enable_shadow_vmcs) { |
5615 | shadow_vmcs = alloc_vmcs(); | 5710 | shadow_vmcs = alloc_vmcs(); |
5616 | if (!shadow_vmcs) | 5711 | if (!shadow_vmcs) |
@@ -5628,6 +5723,7 @@ static int handle_vmon(struct kvm_vcpu *vcpu) | |||
5628 | vmx->nested.vmxon = true; | 5723 | vmx->nested.vmxon = true; |
5629 | 5724 | ||
5630 | skip_emulated_instruction(vcpu); | 5725 | skip_emulated_instruction(vcpu); |
5726 | nested_vmx_succeed(vcpu); | ||
5631 | return 1; | 5727 | return 1; |
5632 | } | 5728 | } |
5633 | 5729 | ||
@@ -5712,6 +5808,7 @@ static int handle_vmoff(struct kvm_vcpu *vcpu) | |||
5712 | return 1; | 5808 | return 1; |
5713 | free_nested(to_vmx(vcpu)); | 5809 | free_nested(to_vmx(vcpu)); |
5714 | skip_emulated_instruction(vcpu); | 5810 | skip_emulated_instruction(vcpu); |
5811 | nested_vmx_succeed(vcpu); | ||
5715 | return 1; | 5812 | return 1; |
5716 | } | 5813 | } |
5717 | 5814 | ||
@@ -5768,48 +5865,6 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu, | |||
5768 | return 0; | 5865 | return 0; |
5769 | } | 5866 | } |
5770 | 5867 | ||
5771 | /* | ||
5772 | * The following 3 functions, nested_vmx_succeed()/failValid()/failInvalid(), | ||
5773 | * set the success or error code of an emulated VMX instruction, as specified | ||
5774 | * by Vol 2B, VMX Instruction Reference, "Conventions". | ||
5775 | */ | ||
5776 | static void nested_vmx_succeed(struct kvm_vcpu *vcpu) | ||
5777 | { | ||
5778 | vmx_set_rflags(vcpu, vmx_get_rflags(vcpu) | ||
5779 | & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | | ||
5780 | X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF)); | ||
5781 | } | ||
5782 | |||
5783 | static void nested_vmx_failInvalid(struct kvm_vcpu *vcpu) | ||
5784 | { | ||
5785 | vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu) | ||
5786 | & ~(X86_EFLAGS_PF | X86_EFLAGS_AF | X86_EFLAGS_ZF | | ||
5787 | X86_EFLAGS_SF | X86_EFLAGS_OF)) | ||
5788 | | X86_EFLAGS_CF); | ||
5789 | } | ||
5790 | |||
5791 | static void nested_vmx_failValid(struct kvm_vcpu *vcpu, | ||
5792 | u32 vm_instruction_error) | ||
5793 | { | ||
5794 | if (to_vmx(vcpu)->nested.current_vmptr == -1ull) { | ||
5795 | /* | ||
5796 | * failValid writes the error number to the current VMCS, which | ||
5797 | * can't be done there isn't a current VMCS. | ||
5798 | */ | ||
5799 | nested_vmx_failInvalid(vcpu); | ||
5800 | return; | ||
5801 | } | ||
5802 | vmx_set_rflags(vcpu, (vmx_get_rflags(vcpu) | ||
5803 | & ~(X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | | ||
5804 | X86_EFLAGS_SF | X86_EFLAGS_OF)) | ||
5805 | | X86_EFLAGS_ZF); | ||
5806 | get_vmcs12(vcpu)->vm_instruction_error = vm_instruction_error; | ||
5807 | /* | ||
5808 | * We don't need to force a shadow sync because | ||
5809 | * VM_INSTRUCTION_ERROR is not shadowed | ||
5810 | */ | ||
5811 | } | ||
5812 | |||
5813 | /* Emulate the VMCLEAR instruction */ | 5868 | /* Emulate the VMCLEAR instruction */ |
5814 | static int handle_vmclear(struct kvm_vcpu *vcpu) | 5869 | static int handle_vmclear(struct kvm_vcpu *vcpu) |
5815 | { | 5870 | { |
@@ -5972,8 +6027,8 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) | |||
5972 | unsigned long field; | 6027 | unsigned long field; |
5973 | u64 field_value; | 6028 | u64 field_value; |
5974 | struct vmcs *shadow_vmcs = vmx->nested.current_shadow_vmcs; | 6029 | struct vmcs *shadow_vmcs = vmx->nested.current_shadow_vmcs; |
5975 | unsigned long *fields = (unsigned long *)shadow_read_write_fields; | 6030 | const unsigned long *fields = shadow_read_write_fields; |
5976 | int num_fields = max_shadow_read_write_fields; | 6031 | const int num_fields = max_shadow_read_write_fields; |
5977 | 6032 | ||
5978 | vmcs_load(shadow_vmcs); | 6033 | vmcs_load(shadow_vmcs); |
5979 | 6034 | ||
@@ -6002,12 +6057,11 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) | |||
6002 | 6057 | ||
6003 | static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) | 6058 | static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) |
6004 | { | 6059 | { |
6005 | unsigned long *fields[] = { | 6060 | const unsigned long *fields[] = { |
6006 | (unsigned long *)shadow_read_write_fields, | 6061 | shadow_read_write_fields, |
6007 | (unsigned long *)shadow_read_only_fields | 6062 | shadow_read_only_fields |
6008 | }; | 6063 | }; |
6009 | int num_lists = ARRAY_SIZE(fields); | 6064 | const int max_fields[] = { |
6010 | int max_fields[] = { | ||
6011 | max_shadow_read_write_fields, | 6065 | max_shadow_read_write_fields, |
6012 | max_shadow_read_only_fields | 6066 | max_shadow_read_only_fields |
6013 | }; | 6067 | }; |
@@ -6018,7 +6072,7 @@ static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) | |||
6018 | 6072 | ||
6019 | vmcs_load(shadow_vmcs); | 6073 | vmcs_load(shadow_vmcs); |
6020 | 6074 | ||
6021 | for (q = 0; q < num_lists; q++) { | 6075 | for (q = 0; q < ARRAY_SIZE(fields); q++) { |
6022 | for (i = 0; i < max_fields[q]; i++) { | 6076 | for (i = 0; i < max_fields[q]; i++) { |
6023 | field = fields[q][i]; | 6077 | field = fields[q][i]; |
6024 | vmcs12_read_any(&vmx->vcpu, field, &field_value); | 6078 | vmcs12_read_any(&vmx->vcpu, field, &field_value); |
@@ -6248,6 +6302,74 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu) | |||
6248 | return 1; | 6302 | return 1; |
6249 | } | 6303 | } |
6250 | 6304 | ||
6305 | /* Emulate the INVEPT instruction */ | ||
6306 | static int handle_invept(struct kvm_vcpu *vcpu) | ||
6307 | { | ||
6308 | u32 vmx_instruction_info, types; | ||
6309 | unsigned long type; | ||
6310 | gva_t gva; | ||
6311 | struct x86_exception e; | ||
6312 | struct { | ||
6313 | u64 eptp, gpa; | ||
6314 | } operand; | ||
6315 | u64 eptp_mask = ((1ull << 51) - 1) & PAGE_MASK; | ||
6316 | |||
6317 | if (!(nested_vmx_secondary_ctls_high & SECONDARY_EXEC_ENABLE_EPT) || | ||
6318 | !(nested_vmx_ept_caps & VMX_EPT_INVEPT_BIT)) { | ||
6319 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
6320 | return 1; | ||
6321 | } | ||
6322 | |||
6323 | if (!nested_vmx_check_permission(vcpu)) | ||
6324 | return 1; | ||
6325 | |||
6326 | if (!kvm_read_cr0_bits(vcpu, X86_CR0_PE)) { | ||
6327 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
6328 | return 1; | ||
6329 | } | ||
6330 | |||
6331 | vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); | ||
6332 | type = kvm_register_read(vcpu, (vmx_instruction_info >> 28) & 0xf); | ||
6333 | |||
6334 | types = (nested_vmx_ept_caps >> VMX_EPT_EXTENT_SHIFT) & 6; | ||
6335 | |||
6336 | if (!(types & (1UL << type))) { | ||
6337 | nested_vmx_failValid(vcpu, | ||
6338 | VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); | ||
6339 | return 1; | ||
6340 | } | ||
6341 | |||
6342 | /* According to the Intel VMX instruction reference, the memory | ||
6343 | * operand is read even if it isn't needed (e.g., for type==global) | ||
6344 | */ | ||
6345 | if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), | ||
6346 | vmx_instruction_info, &gva)) | ||
6347 | return 1; | ||
6348 | if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &operand, | ||
6349 | sizeof(operand), &e)) { | ||
6350 | kvm_inject_page_fault(vcpu, &e); | ||
6351 | return 1; | ||
6352 | } | ||
6353 | |||
6354 | switch (type) { | ||
6355 | case VMX_EPT_EXTENT_CONTEXT: | ||
6356 | if ((operand.eptp & eptp_mask) != | ||
6357 | (nested_ept_get_cr3(vcpu) & eptp_mask)) | ||
6358 | break; | ||
6359 | case VMX_EPT_EXTENT_GLOBAL: | ||
6360 | kvm_mmu_sync_roots(vcpu); | ||
6361 | kvm_mmu_flush_tlb(vcpu); | ||
6362 | nested_vmx_succeed(vcpu); | ||
6363 | break; | ||
6364 | default: | ||
6365 | BUG_ON(1); | ||
6366 | break; | ||
6367 | } | ||
6368 | |||
6369 | skip_emulated_instruction(vcpu); | ||
6370 | return 1; | ||
6371 | } | ||
6372 | |||
6251 | /* | 6373 | /* |
6252 | * The exit handlers return 1 if the exit was handled fully and guest execution | 6374 | * The exit handlers return 1 if the exit was handled fully and guest execution |
6253 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs | 6375 | * may resume. Otherwise they set the kvm_run parameter to indicate what needs |
@@ -6292,6 +6414,7 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { | |||
6292 | [EXIT_REASON_PAUSE_INSTRUCTION] = handle_pause, | 6414 | [EXIT_REASON_PAUSE_INSTRUCTION] = handle_pause, |
6293 | [EXIT_REASON_MWAIT_INSTRUCTION] = handle_invalid_op, | 6415 | [EXIT_REASON_MWAIT_INSTRUCTION] = handle_invalid_op, |
6294 | [EXIT_REASON_MONITOR_INSTRUCTION] = handle_invalid_op, | 6416 | [EXIT_REASON_MONITOR_INSTRUCTION] = handle_invalid_op, |
6417 | [EXIT_REASON_INVEPT] = handle_invept, | ||
6295 | }; | 6418 | }; |
6296 | 6419 | ||
6297 | static const int kvm_vmx_max_exit_handlers = | 6420 | static const int kvm_vmx_max_exit_handlers = |
@@ -6518,6 +6641,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
6518 | case EXIT_REASON_VMPTRST: case EXIT_REASON_VMREAD: | 6641 | case EXIT_REASON_VMPTRST: case EXIT_REASON_VMREAD: |
6519 | case EXIT_REASON_VMRESUME: case EXIT_REASON_VMWRITE: | 6642 | case EXIT_REASON_VMRESUME: case EXIT_REASON_VMWRITE: |
6520 | case EXIT_REASON_VMOFF: case EXIT_REASON_VMON: | 6643 | case EXIT_REASON_VMOFF: case EXIT_REASON_VMON: |
6644 | case EXIT_REASON_INVEPT: | ||
6521 | /* | 6645 | /* |
6522 | * VMX instructions trap unconditionally. This allows L1 to | 6646 | * VMX instructions trap unconditionally. This allows L1 to |
6523 | * emulate them for its L2 guest, i.e., allows 3-level nesting! | 6647 | * emulate them for its L2 guest, i.e., allows 3-level nesting! |
@@ -6550,7 +6674,20 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
6550 | return nested_cpu_has2(vmcs12, | 6674 | return nested_cpu_has2(vmcs12, |
6551 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES); | 6675 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES); |
6552 | case EXIT_REASON_EPT_VIOLATION: | 6676 | case EXIT_REASON_EPT_VIOLATION: |
6677 | /* | ||
6678 | * L0 always deals with the EPT violation. If nested EPT is | ||
6679 | * used, and the nested mmu code discovers that the address is | ||
6680 | * missing in the guest EPT table (EPT12), the EPT violation | ||
6681 | * will be injected with nested_ept_inject_page_fault() | ||
6682 | */ | ||
6683 | return 0; | ||
6553 | case EXIT_REASON_EPT_MISCONFIG: | 6684 | case EXIT_REASON_EPT_MISCONFIG: |
6685 | /* | ||
6686 | * L2 never uses directly L1's EPT, but rather L0's own EPT | ||
6687 | * table (shadow on EPT) or a merged EPT table that L0 built | ||
6688 | * (EPT on EPT). So any problems with the structure of the | ||
6689 | * table is L0's fault. | ||
6690 | */ | ||
6554 | return 0; | 6691 | return 0; |
6555 | case EXIT_REASON_PREEMPTION_TIMER: | 6692 | case EXIT_REASON_PREEMPTION_TIMER: |
6556 | return vmcs12->pin_based_vm_exec_control & | 6693 | return vmcs12->pin_based_vm_exec_control & |
@@ -6638,7 +6775,7 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) | |||
6638 | 6775 | ||
6639 | if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked && | 6776 | if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked && |
6640 | !(is_guest_mode(vcpu) && nested_cpu_has_virtual_nmis( | 6777 | !(is_guest_mode(vcpu) && nested_cpu_has_virtual_nmis( |
6641 | get_vmcs12(vcpu), vcpu)))) { | 6778 | get_vmcs12(vcpu))))) { |
6642 | if (vmx_interrupt_allowed(vcpu)) { | 6779 | if (vmx_interrupt_allowed(vcpu)) { |
6643 | vmx->soft_vnmi_blocked = 0; | 6780 | vmx->soft_vnmi_blocked = 0; |
6644 | } else if (vmx->vnmi_blocked_time > 1000000000LL && | 6781 | } else if (vmx->vnmi_blocked_time > 1000000000LL && |
@@ -7326,6 +7463,48 @@ static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) | |||
7326 | entry->ecx |= bit(X86_FEATURE_VMX); | 7463 | entry->ecx |= bit(X86_FEATURE_VMX); |
7327 | } | 7464 | } |
7328 | 7465 | ||
7466 | static void nested_ept_inject_page_fault(struct kvm_vcpu *vcpu, | ||
7467 | struct x86_exception *fault) | ||
7468 | { | ||
7469 | struct vmcs12 *vmcs12; | ||
7470 | nested_vmx_vmexit(vcpu); | ||
7471 | vmcs12 = get_vmcs12(vcpu); | ||
7472 | |||
7473 | if (fault->error_code & PFERR_RSVD_MASK) | ||
7474 | vmcs12->vm_exit_reason = EXIT_REASON_EPT_MISCONFIG; | ||
7475 | else | ||
7476 | vmcs12->vm_exit_reason = EXIT_REASON_EPT_VIOLATION; | ||
7477 | vmcs12->exit_qualification = vcpu->arch.exit_qualification; | ||
7478 | vmcs12->guest_physical_address = fault->address; | ||
7479 | } | ||
7480 | |||
7481 | /* Callbacks for nested_ept_init_mmu_context: */ | ||
7482 | |||
7483 | static unsigned long nested_ept_get_cr3(struct kvm_vcpu *vcpu) | ||
7484 | { | ||
7485 | /* return the page table to be shadowed - in our case, EPT12 */ | ||
7486 | return get_vmcs12(vcpu)->ept_pointer; | ||
7487 | } | ||
7488 | |||
7489 | static int nested_ept_init_mmu_context(struct kvm_vcpu *vcpu) | ||
7490 | { | ||
7491 | int r = kvm_init_shadow_ept_mmu(vcpu, &vcpu->arch.mmu, | ||
7492 | nested_vmx_ept_caps & VMX_EPT_EXECUTE_ONLY_BIT); | ||
7493 | |||
7494 | vcpu->arch.mmu.set_cr3 = vmx_set_cr3; | ||
7495 | vcpu->arch.mmu.get_cr3 = nested_ept_get_cr3; | ||
7496 | vcpu->arch.mmu.inject_page_fault = nested_ept_inject_page_fault; | ||
7497 | |||
7498 | vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu; | ||
7499 | |||
7500 | return r; | ||
7501 | } | ||
7502 | |||
7503 | static void nested_ept_uninit_mmu_context(struct kvm_vcpu *vcpu) | ||
7504 | { | ||
7505 | vcpu->arch.walk_mmu = &vcpu->arch.mmu; | ||
7506 | } | ||
7507 | |||
7329 | /* | 7508 | /* |
7330 | * prepare_vmcs02 is called when the L1 guest hypervisor runs its nested | 7509 | * prepare_vmcs02 is called when the L1 guest hypervisor runs its nested |
7331 | * L2 guest. L1 has a vmcs for L2 (vmcs12), and this function "merges" it | 7510 | * L2 guest. L1 has a vmcs for L2 (vmcs12), and this function "merges" it |
@@ -7388,7 +7567,7 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7388 | vmcs12->guest_interruptibility_info); | 7567 | vmcs12->guest_interruptibility_info); |
7389 | vmcs_write32(GUEST_SYSENTER_CS, vmcs12->guest_sysenter_cs); | 7568 | vmcs_write32(GUEST_SYSENTER_CS, vmcs12->guest_sysenter_cs); |
7390 | kvm_set_dr(vcpu, 7, vmcs12->guest_dr7); | 7569 | kvm_set_dr(vcpu, 7, vmcs12->guest_dr7); |
7391 | vmcs_writel(GUEST_RFLAGS, vmcs12->guest_rflags); | 7570 | vmx_set_rflags(vcpu, vmcs12->guest_rflags); |
7392 | vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, | 7571 | vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, |
7393 | vmcs12->guest_pending_dbg_exceptions); | 7572 | vmcs12->guest_pending_dbg_exceptions); |
7394 | vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->guest_sysenter_esp); | 7573 | vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->guest_sysenter_esp); |
@@ -7508,15 +7687,24 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7508 | vcpu->arch.cr0_guest_owned_bits &= ~vmcs12->cr0_guest_host_mask; | 7687 | vcpu->arch.cr0_guest_owned_bits &= ~vmcs12->cr0_guest_host_mask; |
7509 | vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits); | 7688 | vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits); |
7510 | 7689 | ||
7511 | /* Note: IA32_MODE, LOAD_IA32_EFER are modified by vmx_set_efer below */ | 7690 | /* L2->L1 exit controls are emulated - the hardware exit is to L0 so |
7512 | vmcs_write32(VM_EXIT_CONTROLS, | 7691 | * we should use its exit controls. Note that VM_EXIT_LOAD_IA32_EFER |
7513 | vmcs12->vm_exit_controls | vmcs_config.vmexit_ctrl); | 7692 | * bits are further modified by vmx_set_efer() below. |
7514 | vmcs_write32(VM_ENTRY_CONTROLS, vmcs12->vm_entry_controls | | 7693 | */ |
7694 | vmcs_write32(VM_EXIT_CONTROLS, vmcs_config.vmexit_ctrl); | ||
7695 | |||
7696 | /* vmcs12's VM_ENTRY_LOAD_IA32_EFER and VM_ENTRY_IA32E_MODE are | ||
7697 | * emulated by vmx_set_efer(), below. | ||
7698 | */ | ||
7699 | vmcs_write32(VM_ENTRY_CONTROLS, | ||
7700 | (vmcs12->vm_entry_controls & ~VM_ENTRY_LOAD_IA32_EFER & | ||
7701 | ~VM_ENTRY_IA32E_MODE) | | ||
7515 | (vmcs_config.vmentry_ctrl & ~VM_ENTRY_IA32E_MODE)); | 7702 | (vmcs_config.vmentry_ctrl & ~VM_ENTRY_IA32E_MODE)); |
7516 | 7703 | ||
7517 | if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PAT) | 7704 | if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PAT) { |
7518 | vmcs_write64(GUEST_IA32_PAT, vmcs12->guest_ia32_pat); | 7705 | vmcs_write64(GUEST_IA32_PAT, vmcs12->guest_ia32_pat); |
7519 | else if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) | 7706 | vcpu->arch.pat = vmcs12->guest_ia32_pat; |
7707 | } else if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) | ||
7520 | vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat); | 7708 | vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat); |
7521 | 7709 | ||
7522 | 7710 | ||
@@ -7538,6 +7726,11 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7538 | vmx_flush_tlb(vcpu); | 7726 | vmx_flush_tlb(vcpu); |
7539 | } | 7727 | } |
7540 | 7728 | ||
7729 | if (nested_cpu_has_ept(vmcs12)) { | ||
7730 | kvm_mmu_unload(vcpu); | ||
7731 | nested_ept_init_mmu_context(vcpu); | ||
7732 | } | ||
7733 | |||
7541 | if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER) | 7734 | if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER) |
7542 | vcpu->arch.efer = vmcs12->guest_ia32_efer; | 7735 | vcpu->arch.efer = vmcs12->guest_ia32_efer; |
7543 | else if (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) | 7736 | else if (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) |
@@ -7565,6 +7758,16 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7565 | kvm_set_cr3(vcpu, vmcs12->guest_cr3); | 7758 | kvm_set_cr3(vcpu, vmcs12->guest_cr3); |
7566 | kvm_mmu_reset_context(vcpu); | 7759 | kvm_mmu_reset_context(vcpu); |
7567 | 7760 | ||
7761 | /* | ||
7762 | * L1 may access the L2's PDPTR, so save them to construct vmcs12 | ||
7763 | */ | ||
7764 | if (enable_ept) { | ||
7765 | vmcs_write64(GUEST_PDPTR0, vmcs12->guest_pdptr0); | ||
7766 | vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1); | ||
7767 | vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2); | ||
7768 | vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3); | ||
7769 | } | ||
7770 | |||
7568 | kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->guest_rsp); | 7771 | kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->guest_rsp); |
7569 | kvm_register_write(vcpu, VCPU_REGS_RIP, vmcs12->guest_rip); | 7772 | kvm_register_write(vcpu, VCPU_REGS_RIP, vmcs12->guest_rip); |
7570 | } | 7773 | } |
@@ -7887,6 +8090,22 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7887 | vmcs12->guest_pending_dbg_exceptions = | 8090 | vmcs12->guest_pending_dbg_exceptions = |
7888 | vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS); | 8091 | vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS); |
7889 | 8092 | ||
8093 | /* | ||
8094 | * In some cases (usually, nested EPT), L2 is allowed to change its | ||
8095 | * own CR3 without exiting. If it has changed it, we must keep it. | ||
8096 | * Of course, if L0 is using shadow page tables, GUEST_CR3 was defined | ||
8097 | * by L0, not L1 or L2, so we mustn't unconditionally copy it to vmcs12. | ||
8098 | * | ||
8099 | * Additionally, restore L2's PDPTR to vmcs12. | ||
8100 | */ | ||
8101 | if (enable_ept) { | ||
8102 | vmcs12->guest_cr3 = vmcs_read64(GUEST_CR3); | ||
8103 | vmcs12->guest_pdptr0 = vmcs_read64(GUEST_PDPTR0); | ||
8104 | vmcs12->guest_pdptr1 = vmcs_read64(GUEST_PDPTR1); | ||
8105 | vmcs12->guest_pdptr2 = vmcs_read64(GUEST_PDPTR2); | ||
8106 | vmcs12->guest_pdptr3 = vmcs_read64(GUEST_PDPTR3); | ||
8107 | } | ||
8108 | |||
7890 | vmcs12->vm_entry_controls = | 8109 | vmcs12->vm_entry_controls = |
7891 | (vmcs12->vm_entry_controls & ~VM_ENTRY_IA32E_MODE) | | 8110 | (vmcs12->vm_entry_controls & ~VM_ENTRY_IA32E_MODE) | |
7892 | (vmcs_read32(VM_ENTRY_CONTROLS) & VM_ENTRY_IA32E_MODE); | 8111 | (vmcs_read32(VM_ENTRY_CONTROLS) & VM_ENTRY_IA32E_MODE); |
@@ -7948,6 +8167,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7948 | static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, | 8167 | static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, |
7949 | struct vmcs12 *vmcs12) | 8168 | struct vmcs12 *vmcs12) |
7950 | { | 8169 | { |
8170 | struct kvm_segment seg; | ||
8171 | |||
7951 | if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_EFER) | 8172 | if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_EFER) |
7952 | vcpu->arch.efer = vmcs12->host_ia32_efer; | 8173 | vcpu->arch.efer = vmcs12->host_ia32_efer; |
7953 | else if (vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) | 8174 | else if (vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) |
@@ -7982,7 +8203,9 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, | |||
7982 | vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK); | 8203 | vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK); |
7983 | kvm_set_cr4(vcpu, vmcs12->host_cr4); | 8204 | kvm_set_cr4(vcpu, vmcs12->host_cr4); |
7984 | 8205 | ||
7985 | /* shadow page tables on either EPT or shadow page tables */ | 8206 | if (nested_cpu_has_ept(vmcs12)) |
8207 | nested_ept_uninit_mmu_context(vcpu); | ||
8208 | |||
7986 | kvm_set_cr3(vcpu, vmcs12->host_cr3); | 8209 | kvm_set_cr3(vcpu, vmcs12->host_cr3); |
7987 | kvm_mmu_reset_context(vcpu); | 8210 | kvm_mmu_reset_context(vcpu); |
7988 | 8211 | ||
@@ -8001,23 +8224,61 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, | |||
8001 | vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->host_ia32_sysenter_eip); | 8224 | vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->host_ia32_sysenter_eip); |
8002 | vmcs_writel(GUEST_IDTR_BASE, vmcs12->host_idtr_base); | 8225 | vmcs_writel(GUEST_IDTR_BASE, vmcs12->host_idtr_base); |
8003 | vmcs_writel(GUEST_GDTR_BASE, vmcs12->host_gdtr_base); | 8226 | vmcs_writel(GUEST_GDTR_BASE, vmcs12->host_gdtr_base); |
8004 | vmcs_writel(GUEST_TR_BASE, vmcs12->host_tr_base); | 8227 | |
8005 | vmcs_writel(GUEST_GS_BASE, vmcs12->host_gs_base); | 8228 | if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PAT) { |
8006 | vmcs_writel(GUEST_FS_BASE, vmcs12->host_fs_base); | ||
8007 | vmcs_write16(GUEST_ES_SELECTOR, vmcs12->host_es_selector); | ||
8008 | vmcs_write16(GUEST_CS_SELECTOR, vmcs12->host_cs_selector); | ||
8009 | vmcs_write16(GUEST_SS_SELECTOR, vmcs12->host_ss_selector); | ||
8010 | vmcs_write16(GUEST_DS_SELECTOR, vmcs12->host_ds_selector); | ||
8011 | vmcs_write16(GUEST_FS_SELECTOR, vmcs12->host_fs_selector); | ||
8012 | vmcs_write16(GUEST_GS_SELECTOR, vmcs12->host_gs_selector); | ||
8013 | vmcs_write16(GUEST_TR_SELECTOR, vmcs12->host_tr_selector); | ||
8014 | |||
8015 | if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PAT) | ||
8016 | vmcs_write64(GUEST_IA32_PAT, vmcs12->host_ia32_pat); | 8229 | vmcs_write64(GUEST_IA32_PAT, vmcs12->host_ia32_pat); |
8230 | vcpu->arch.pat = vmcs12->host_ia32_pat; | ||
8231 | } | ||
8017 | if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL) | 8232 | if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL) |
8018 | vmcs_write64(GUEST_IA32_PERF_GLOBAL_CTRL, | 8233 | vmcs_write64(GUEST_IA32_PERF_GLOBAL_CTRL, |
8019 | vmcs12->host_ia32_perf_global_ctrl); | 8234 | vmcs12->host_ia32_perf_global_ctrl); |
8020 | 8235 | ||
8236 | /* Set L1 segment info according to Intel SDM | ||
8237 | 27.5.2 Loading Host Segment and Descriptor-Table Registers */ | ||
8238 | seg = (struct kvm_segment) { | ||
8239 | .base = 0, | ||
8240 | .limit = 0xFFFFFFFF, | ||
8241 | .selector = vmcs12->host_cs_selector, | ||
8242 | .type = 11, | ||
8243 | .present = 1, | ||
8244 | .s = 1, | ||
8245 | .g = 1 | ||
8246 | }; | ||
8247 | if (vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) | ||
8248 | seg.l = 1; | ||
8249 | else | ||
8250 | seg.db = 1; | ||
8251 | vmx_set_segment(vcpu, &seg, VCPU_SREG_CS); | ||
8252 | seg = (struct kvm_segment) { | ||
8253 | .base = 0, | ||
8254 | .limit = 0xFFFFFFFF, | ||
8255 | .type = 3, | ||
8256 | .present = 1, | ||
8257 | .s = 1, | ||
8258 | .db = 1, | ||
8259 | .g = 1 | ||
8260 | }; | ||
8261 | seg.selector = vmcs12->host_ds_selector; | ||
8262 | vmx_set_segment(vcpu, &seg, VCPU_SREG_DS); | ||
8263 | seg.selector = vmcs12->host_es_selector; | ||
8264 | vmx_set_segment(vcpu, &seg, VCPU_SREG_ES); | ||
8265 | seg.selector = vmcs12->host_ss_selector; | ||
8266 | vmx_set_segment(vcpu, &seg, VCPU_SREG_SS); | ||
8267 | seg.selector = vmcs12->host_fs_selector; | ||
8268 | seg.base = vmcs12->host_fs_base; | ||
8269 | vmx_set_segment(vcpu, &seg, VCPU_SREG_FS); | ||
8270 | seg.selector = vmcs12->host_gs_selector; | ||
8271 | seg.base = vmcs12->host_gs_base; | ||
8272 | vmx_set_segment(vcpu, &seg, VCPU_SREG_GS); | ||
8273 | seg = (struct kvm_segment) { | ||
8274 | .base = vmcs12->host_tr_base, | ||
8275 | .limit = 0x67, | ||
8276 | .selector = vmcs12->host_tr_selector, | ||
8277 | .type = 11, | ||
8278 | .present = 1 | ||
8279 | }; | ||
8280 | vmx_set_segment(vcpu, &seg, VCPU_SREG_TR); | ||
8281 | |||
8021 | kvm_set_dr(vcpu, 7, 0x400); | 8282 | kvm_set_dr(vcpu, 7, 0x400); |
8022 | vmcs_write64(GUEST_IA32_DEBUGCTL, 0); | 8283 | vmcs_write64(GUEST_IA32_DEBUGCTL, 0); |
8023 | } | 8284 | } |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d21bce505315..e5ca72a5cdb6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -682,17 +682,6 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
682 | */ | 682 | */ |
683 | } | 683 | } |
684 | 684 | ||
685 | /* | ||
686 | * Does the new cr3 value map to physical memory? (Note, we | ||
687 | * catch an invalid cr3 even in real-mode, because it would | ||
688 | * cause trouble later on when we turn on paging anyway.) | ||
689 | * | ||
690 | * A real CPU would silently accept an invalid cr3 and would | ||
691 | * attempt to use it - with largely undefined (and often hard | ||
692 | * to debug) behavior on the guest side. | ||
693 | */ | ||
694 | if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT))) | ||
695 | return 1; | ||
696 | vcpu->arch.cr3 = cr3; | 685 | vcpu->arch.cr3 = cr3; |
697 | __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); | 686 | __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); |
698 | vcpu->arch.mmu.new_cr3(vcpu); | 687 | vcpu->arch.mmu.new_cr3(vcpu); |
@@ -850,7 +839,8 @@ static u32 msrs_to_save[] = { | |||
850 | #ifdef CONFIG_X86_64 | 839 | #ifdef CONFIG_X86_64 |
851 | MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, | 840 | MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, |
852 | #endif | 841 | #endif |
853 | MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA | 842 | MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA, |
843 | MSR_IA32_FEATURE_CONTROL | ||
854 | }; | 844 | }; |
855 | 845 | ||
856 | static unsigned num_msrs_to_save; | 846 | static unsigned num_msrs_to_save; |
@@ -1457,6 +1447,29 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm) | |||
1457 | #endif | 1447 | #endif |
1458 | } | 1448 | } |
1459 | 1449 | ||
1450 | static void kvm_gen_update_masterclock(struct kvm *kvm) | ||
1451 | { | ||
1452 | #ifdef CONFIG_X86_64 | ||
1453 | int i; | ||
1454 | struct kvm_vcpu *vcpu; | ||
1455 | struct kvm_arch *ka = &kvm->arch; | ||
1456 | |||
1457 | spin_lock(&ka->pvclock_gtod_sync_lock); | ||
1458 | kvm_make_mclock_inprogress_request(kvm); | ||
1459 | /* no guest entries from this point */ | ||
1460 | pvclock_update_vm_gtod_copy(kvm); | ||
1461 | |||
1462 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
1463 | set_bit(KVM_REQ_CLOCK_UPDATE, &vcpu->requests); | ||
1464 | |||
1465 | /* guest entries allowed */ | ||
1466 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
1467 | clear_bit(KVM_REQ_MCLOCK_INPROGRESS, &vcpu->requests); | ||
1468 | |||
1469 | spin_unlock(&ka->pvclock_gtod_sync_lock); | ||
1470 | #endif | ||
1471 | } | ||
1472 | |||
1460 | static int kvm_guest_time_update(struct kvm_vcpu *v) | 1473 | static int kvm_guest_time_update(struct kvm_vcpu *v) |
1461 | { | 1474 | { |
1462 | unsigned long flags, this_tsc_khz; | 1475 | unsigned long flags, this_tsc_khz; |
@@ -3806,6 +3819,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
3806 | delta = user_ns.clock - now_ns; | 3819 | delta = user_ns.clock - now_ns; |
3807 | local_irq_enable(); | 3820 | local_irq_enable(); |
3808 | kvm->arch.kvmclock_offset = delta; | 3821 | kvm->arch.kvmclock_offset = delta; |
3822 | kvm_gen_update_masterclock(kvm); | ||
3809 | break; | 3823 | break; |
3810 | } | 3824 | } |
3811 | case KVM_GET_CLOCK: { | 3825 | case KVM_GET_CLOCK: { |
@@ -4955,6 +4969,97 @@ static bool retry_instruction(struct x86_emulate_ctxt *ctxt, | |||
4955 | static int complete_emulated_mmio(struct kvm_vcpu *vcpu); | 4969 | static int complete_emulated_mmio(struct kvm_vcpu *vcpu); |
4956 | static int complete_emulated_pio(struct kvm_vcpu *vcpu); | 4970 | static int complete_emulated_pio(struct kvm_vcpu *vcpu); |
4957 | 4971 | ||
4972 | static int kvm_vcpu_check_hw_bp(unsigned long addr, u32 type, u32 dr7, | ||
4973 | unsigned long *db) | ||
4974 | { | ||
4975 | u32 dr6 = 0; | ||
4976 | int i; | ||
4977 | u32 enable, rwlen; | ||
4978 | |||
4979 | enable = dr7; | ||
4980 | rwlen = dr7 >> 16; | ||
4981 | for (i = 0; i < 4; i++, enable >>= 2, rwlen >>= 4) | ||
4982 | if ((enable & 3) && (rwlen & 15) == type && db[i] == addr) | ||
4983 | dr6 |= (1 << i); | ||
4984 | return dr6; | ||
4985 | } | ||
4986 | |||
4987 | static void kvm_vcpu_check_singlestep(struct kvm_vcpu *vcpu, int *r) | ||
4988 | { | ||
4989 | struct kvm_run *kvm_run = vcpu->run; | ||
4990 | |||
4991 | /* | ||
4992 | * Use the "raw" value to see if TF was passed to the processor. | ||
4993 | * Note that the new value of the flags has not been saved yet. | ||
4994 | * | ||
4995 | * This is correct even for TF set by the guest, because "the | ||
4996 | * processor will not generate this exception after the instruction | ||
4997 | * that sets the TF flag". | ||
4998 | */ | ||
4999 | unsigned long rflags = kvm_x86_ops->get_rflags(vcpu); | ||
5000 | |||
5001 | if (unlikely(rflags & X86_EFLAGS_TF)) { | ||
5002 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { | ||
5003 | kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1; | ||
5004 | kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip; | ||
5005 | kvm_run->debug.arch.exception = DB_VECTOR; | ||
5006 | kvm_run->exit_reason = KVM_EXIT_DEBUG; | ||
5007 | *r = EMULATE_USER_EXIT; | ||
5008 | } else { | ||
5009 | vcpu->arch.emulate_ctxt.eflags &= ~X86_EFLAGS_TF; | ||
5010 | /* | ||
5011 | * "Certain debug exceptions may clear bit 0-3. The | ||
5012 | * remaining contents of the DR6 register are never | ||
5013 | * cleared by the processor". | ||
5014 | */ | ||
5015 | vcpu->arch.dr6 &= ~15; | ||
5016 | vcpu->arch.dr6 |= DR6_BS; | ||
5017 | kvm_queue_exception(vcpu, DB_VECTOR); | ||
5018 | } | ||
5019 | } | ||
5020 | } | ||
5021 | |||
5022 | static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) | ||
5023 | { | ||
5024 | struct kvm_run *kvm_run = vcpu->run; | ||
5025 | unsigned long eip = vcpu->arch.emulate_ctxt.eip; | ||
5026 | u32 dr6 = 0; | ||
5027 | |||
5028 | if (unlikely(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) && | ||
5029 | (vcpu->arch.guest_debug_dr7 & DR7_BP_EN_MASK)) { | ||
5030 | dr6 = kvm_vcpu_check_hw_bp(eip, 0, | ||
5031 | vcpu->arch.guest_debug_dr7, | ||
5032 | vcpu->arch.eff_db); | ||
5033 | |||
5034 | if (dr6 != 0) { | ||
5035 | kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1; | ||
5036 | kvm_run->debug.arch.pc = kvm_rip_read(vcpu) + | ||
5037 | get_segment_base(vcpu, VCPU_SREG_CS); | ||
5038 | |||
5039 | kvm_run->debug.arch.exception = DB_VECTOR; | ||
5040 | kvm_run->exit_reason = KVM_EXIT_DEBUG; | ||
5041 | *r = EMULATE_USER_EXIT; | ||
5042 | return true; | ||
5043 | } | ||
5044 | } | ||
5045 | |||
5046 | if (unlikely(vcpu->arch.dr7 & DR7_BP_EN_MASK)) { | ||
5047 | dr6 = kvm_vcpu_check_hw_bp(eip, 0, | ||
5048 | vcpu->arch.dr7, | ||
5049 | vcpu->arch.db); | ||
5050 | |||
5051 | if (dr6 != 0) { | ||
5052 | vcpu->arch.dr6 &= ~15; | ||
5053 | vcpu->arch.dr6 |= dr6; | ||
5054 | kvm_queue_exception(vcpu, DB_VECTOR); | ||
5055 | *r = EMULATE_DONE; | ||
5056 | return true; | ||
5057 | } | ||
5058 | } | ||
5059 | |||
5060 | return false; | ||
5061 | } | ||
5062 | |||
4958 | int x86_emulate_instruction(struct kvm_vcpu *vcpu, | 5063 | int x86_emulate_instruction(struct kvm_vcpu *vcpu, |
4959 | unsigned long cr2, | 5064 | unsigned long cr2, |
4960 | int emulation_type, | 5065 | int emulation_type, |
@@ -4975,6 +5080,16 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, | |||
4975 | 5080 | ||
4976 | if (!(emulation_type & EMULTYPE_NO_DECODE)) { | 5081 | if (!(emulation_type & EMULTYPE_NO_DECODE)) { |
4977 | init_emulate_ctxt(vcpu); | 5082 | init_emulate_ctxt(vcpu); |
5083 | |||
5084 | /* | ||
5085 | * We will reenter on the same instruction since | ||
5086 | * we do not set complete_userspace_io. This does not | ||
5087 | * handle watchpoints yet, those would be handled in | ||
5088 | * the emulate_ops. | ||
5089 | */ | ||
5090 | if (kvm_vcpu_check_breakpoint(vcpu, &r)) | ||
5091 | return r; | ||
5092 | |||
4978 | ctxt->interruptibility = 0; | 5093 | ctxt->interruptibility = 0; |
4979 | ctxt->have_exception = false; | 5094 | ctxt->have_exception = false; |
4980 | ctxt->perm_ok = false; | 5095 | ctxt->perm_ok = false; |
@@ -5031,17 +5146,18 @@ restart: | |||
5031 | inject_emulated_exception(vcpu); | 5146 | inject_emulated_exception(vcpu); |
5032 | r = EMULATE_DONE; | 5147 | r = EMULATE_DONE; |
5033 | } else if (vcpu->arch.pio.count) { | 5148 | } else if (vcpu->arch.pio.count) { |
5034 | if (!vcpu->arch.pio.in) | 5149 | if (!vcpu->arch.pio.in) { |
5150 | /* FIXME: return into emulator if single-stepping. */ | ||
5035 | vcpu->arch.pio.count = 0; | 5151 | vcpu->arch.pio.count = 0; |
5036 | else { | 5152 | } else { |
5037 | writeback = false; | 5153 | writeback = false; |
5038 | vcpu->arch.complete_userspace_io = complete_emulated_pio; | 5154 | vcpu->arch.complete_userspace_io = complete_emulated_pio; |
5039 | } | 5155 | } |
5040 | r = EMULATE_DO_MMIO; | 5156 | r = EMULATE_USER_EXIT; |
5041 | } else if (vcpu->mmio_needed) { | 5157 | } else if (vcpu->mmio_needed) { |
5042 | if (!vcpu->mmio_is_write) | 5158 | if (!vcpu->mmio_is_write) |
5043 | writeback = false; | 5159 | writeback = false; |
5044 | r = EMULATE_DO_MMIO; | 5160 | r = EMULATE_USER_EXIT; |
5045 | vcpu->arch.complete_userspace_io = complete_emulated_mmio; | 5161 | vcpu->arch.complete_userspace_io = complete_emulated_mmio; |
5046 | } else if (r == EMULATION_RESTART) | 5162 | } else if (r == EMULATION_RESTART) |
5047 | goto restart; | 5163 | goto restart; |
@@ -5050,10 +5166,12 @@ restart: | |||
5050 | 5166 | ||
5051 | if (writeback) { | 5167 | if (writeback) { |
5052 | toggle_interruptibility(vcpu, ctxt->interruptibility); | 5168 | toggle_interruptibility(vcpu, ctxt->interruptibility); |
5053 | kvm_set_rflags(vcpu, ctxt->eflags); | ||
5054 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 5169 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
5055 | vcpu->arch.emulate_regs_need_sync_to_vcpu = false; | 5170 | vcpu->arch.emulate_regs_need_sync_to_vcpu = false; |
5056 | kvm_rip_write(vcpu, ctxt->eip); | 5171 | kvm_rip_write(vcpu, ctxt->eip); |
5172 | if (r == EMULATE_DONE) | ||
5173 | kvm_vcpu_check_singlestep(vcpu, &r); | ||
5174 | kvm_set_rflags(vcpu, ctxt->eflags); | ||
5057 | } else | 5175 | } else |
5058 | vcpu->arch.emulate_regs_need_sync_to_vcpu = true; | 5176 | vcpu->arch.emulate_regs_need_sync_to_vcpu = true; |
5059 | 5177 | ||
@@ -5347,7 +5465,7 @@ static struct notifier_block pvclock_gtod_notifier = { | |||
5347 | int kvm_arch_init(void *opaque) | 5465 | int kvm_arch_init(void *opaque) |
5348 | { | 5466 | { |
5349 | int r; | 5467 | int r; |
5350 | struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque; | 5468 | struct kvm_x86_ops *ops = opaque; |
5351 | 5469 | ||
5352 | if (kvm_x86_ops) { | 5470 | if (kvm_x86_ops) { |
5353 | printk(KERN_ERR "kvm: already loaded the other module\n"); | 5471 | printk(KERN_ERR "kvm: already loaded the other module\n"); |
@@ -5495,6 +5613,23 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) | |||
5495 | return 1; | 5613 | return 1; |
5496 | } | 5614 | } |
5497 | 5615 | ||
5616 | /* | ||
5617 | * kvm_pv_kick_cpu_op: Kick a vcpu. | ||
5618 | * | ||
5619 | * @apicid - apicid of vcpu to be kicked. | ||
5620 | */ | ||
5621 | static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid) | ||
5622 | { | ||
5623 | struct kvm_lapic_irq lapic_irq; | ||
5624 | |||
5625 | lapic_irq.shorthand = 0; | ||
5626 | lapic_irq.dest_mode = 0; | ||
5627 | lapic_irq.dest_id = apicid; | ||
5628 | |||
5629 | lapic_irq.delivery_mode = APIC_DM_REMRD; | ||
5630 | kvm_irq_delivery_to_apic(kvm, 0, &lapic_irq, NULL); | ||
5631 | } | ||
5632 | |||
5498 | int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | 5633 | int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) |
5499 | { | 5634 | { |
5500 | unsigned long nr, a0, a1, a2, a3, ret; | 5635 | unsigned long nr, a0, a1, a2, a3, ret; |
@@ -5528,6 +5663,10 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | |||
5528 | case KVM_HC_VAPIC_POLL_IRQ: | 5663 | case KVM_HC_VAPIC_POLL_IRQ: |
5529 | ret = 0; | 5664 | ret = 0; |
5530 | break; | 5665 | break; |
5666 | case KVM_HC_KICK_CPU: | ||
5667 | kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1); | ||
5668 | ret = 0; | ||
5669 | break; | ||
5531 | default: | 5670 | default: |
5532 | ret = -KVM_ENOSYS; | 5671 | ret = -KVM_ENOSYS; |
5533 | break; | 5672 | break; |
@@ -5689,29 +5828,6 @@ static void process_nmi(struct kvm_vcpu *vcpu) | |||
5689 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 5828 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
5690 | } | 5829 | } |
5691 | 5830 | ||
5692 | static void kvm_gen_update_masterclock(struct kvm *kvm) | ||
5693 | { | ||
5694 | #ifdef CONFIG_X86_64 | ||
5695 | int i; | ||
5696 | struct kvm_vcpu *vcpu; | ||
5697 | struct kvm_arch *ka = &kvm->arch; | ||
5698 | |||
5699 | spin_lock(&ka->pvclock_gtod_sync_lock); | ||
5700 | kvm_make_mclock_inprogress_request(kvm); | ||
5701 | /* no guest entries from this point */ | ||
5702 | pvclock_update_vm_gtod_copy(kvm); | ||
5703 | |||
5704 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
5705 | set_bit(KVM_REQ_CLOCK_UPDATE, &vcpu->requests); | ||
5706 | |||
5707 | /* guest entries allowed */ | ||
5708 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
5709 | clear_bit(KVM_REQ_MCLOCK_INPROGRESS, &vcpu->requests); | ||
5710 | |||
5711 | spin_unlock(&ka->pvclock_gtod_sync_lock); | ||
5712 | #endif | ||
5713 | } | ||
5714 | |||
5715 | static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) | 5831 | static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) |
5716 | { | 5832 | { |
5717 | u64 eoi_exit_bitmap[4]; | 5833 | u64 eoi_exit_bitmap[4]; |
@@ -5950,6 +6066,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
5950 | kvm_apic_accept_events(vcpu); | 6066 | kvm_apic_accept_events(vcpu); |
5951 | switch(vcpu->arch.mp_state) { | 6067 | switch(vcpu->arch.mp_state) { |
5952 | case KVM_MP_STATE_HALTED: | 6068 | case KVM_MP_STATE_HALTED: |
6069 | vcpu->arch.pv.pv_unhalted = false; | ||
5953 | vcpu->arch.mp_state = | 6070 | vcpu->arch.mp_state = |
5954 | KVM_MP_STATE_RUNNABLE; | 6071 | KVM_MP_STATE_RUNNABLE; |
5955 | case KVM_MP_STATE_RUNNABLE: | 6072 | case KVM_MP_STATE_RUNNABLE: |
@@ -6061,6 +6178,8 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) | |||
6061 | 6178 | ||
6062 | if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { | 6179 | if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { |
6063 | vcpu->mmio_needed = 0; | 6180 | vcpu->mmio_needed = 0; |
6181 | |||
6182 | /* FIXME: return into emulator if single-stepping. */ | ||
6064 | if (vcpu->mmio_is_write) | 6183 | if (vcpu->mmio_is_write) |
6065 | return 1; | 6184 | return 1; |
6066 | vcpu->mmio_read_completed = 1; | 6185 | vcpu->mmio_read_completed = 1; |
@@ -6249,7 +6368,12 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, | |||
6249 | struct kvm_mp_state *mp_state) | 6368 | struct kvm_mp_state *mp_state) |
6250 | { | 6369 | { |
6251 | kvm_apic_accept_events(vcpu); | 6370 | kvm_apic_accept_events(vcpu); |
6252 | mp_state->mp_state = vcpu->arch.mp_state; | 6371 | if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED && |
6372 | vcpu->arch.pv.pv_unhalted) | ||
6373 | mp_state->mp_state = KVM_MP_STATE_RUNNABLE; | ||
6374 | else | ||
6375 | mp_state->mp_state = vcpu->arch.mp_state; | ||
6376 | |||
6253 | return 0; | 6377 | return 0; |
6254 | } | 6378 | } |
6255 | 6379 | ||
@@ -6770,6 +6894,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
6770 | BUG_ON(vcpu->kvm == NULL); | 6894 | BUG_ON(vcpu->kvm == NULL); |
6771 | kvm = vcpu->kvm; | 6895 | kvm = vcpu->kvm; |
6772 | 6896 | ||
6897 | vcpu->arch.pv.pv_unhalted = false; | ||
6773 | vcpu->arch.emulate_ctxt.ops = &emulate_ops; | 6898 | vcpu->arch.emulate_ctxt.ops = &emulate_ops; |
6774 | if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu)) | 6899 | if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu)) |
6775 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | 6900 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
@@ -7019,6 +7144,15 @@ out_free: | |||
7019 | return -ENOMEM; | 7144 | return -ENOMEM; |
7020 | } | 7145 | } |
7021 | 7146 | ||
7147 | void kvm_arch_memslots_updated(struct kvm *kvm) | ||
7148 | { | ||
7149 | /* | ||
7150 | * memslots->generation has been incremented. | ||
7151 | * mmio generation may have reached its maximum value. | ||
7152 | */ | ||
7153 | kvm_mmu_invalidate_mmio_sptes(kvm); | ||
7154 | } | ||
7155 | |||
7022 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 7156 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
7023 | struct kvm_memory_slot *memslot, | 7157 | struct kvm_memory_slot *memslot, |
7024 | struct kvm_userspace_memory_region *mem, | 7158 | struct kvm_userspace_memory_region *mem, |
@@ -7079,11 +7213,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
7079 | */ | 7213 | */ |
7080 | if ((change != KVM_MR_DELETE) && (mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) | 7214 | if ((change != KVM_MR_DELETE) && (mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) |
7081 | kvm_mmu_slot_remove_write_access(kvm, mem->slot); | 7215 | kvm_mmu_slot_remove_write_access(kvm, mem->slot); |
7082 | /* | ||
7083 | * If memory slot is created, or moved, we need to clear all | ||
7084 | * mmio sptes. | ||
7085 | */ | ||
7086 | kvm_mmu_invalidate_mmio_sptes(kvm); | ||
7087 | } | 7216 | } |
7088 | 7217 | ||
7089 | void kvm_arch_flush_shadow_all(struct kvm *kvm) | 7218 | void kvm_arch_flush_shadow_all(struct kvm *kvm) |
@@ -7103,6 +7232,7 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | |||
7103 | !vcpu->arch.apf.halted) | 7232 | !vcpu->arch.apf.halted) |
7104 | || !list_empty_careful(&vcpu->async_pf.done) | 7233 | || !list_empty_careful(&vcpu->async_pf.done) |
7105 | || kvm_apic_has_events(vcpu) | 7234 | || kvm_apic_has_events(vcpu) |
7235 | || vcpu->arch.pv.pv_unhalted | ||
7106 | || atomic_read(&vcpu->arch.nmi_queued) || | 7236 | || atomic_read(&vcpu->arch.nmi_queued) || |
7107 | (kvm_arch_interrupt_allowed(vcpu) && | 7237 | (kvm_arch_interrupt_allowed(vcpu) && |
7108 | kvm_cpu_has_interrupt(vcpu)); | 7238 | kvm_cpu_has_interrupt(vcpu)); |
diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c index 25b7ae8d058a..7609e0e421ec 100644 --- a/arch/x86/lib/csum-wrappers_64.c +++ b/arch/x86/lib/csum-wrappers_64.c | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | #include <asm/checksum.h> | 7 | #include <asm/checksum.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <asm/smap.h> | ||
9 | 10 | ||
10 | /** | 11 | /** |
11 | * csum_partial_copy_from_user - Copy and checksum from user space. | 12 | * csum_partial_copy_from_user - Copy and checksum from user space. |
@@ -52,8 +53,10 @@ csum_partial_copy_from_user(const void __user *src, void *dst, | |||
52 | len -= 2; | 53 | len -= 2; |
53 | } | 54 | } |
54 | } | 55 | } |
56 | stac(); | ||
55 | isum = csum_partial_copy_generic((__force const void *)src, | 57 | isum = csum_partial_copy_generic((__force const void *)src, |
56 | dst, len, isum, errp, NULL); | 58 | dst, len, isum, errp, NULL); |
59 | clac(); | ||
57 | if (unlikely(*errp)) | 60 | if (unlikely(*errp)) |
58 | goto out_err; | 61 | goto out_err; |
59 | 62 | ||
@@ -82,6 +85,8 @@ __wsum | |||
82 | csum_partial_copy_to_user(const void *src, void __user *dst, | 85 | csum_partial_copy_to_user(const void *src, void __user *dst, |
83 | int len, __wsum isum, int *errp) | 86 | int len, __wsum isum, int *errp) |
84 | { | 87 | { |
88 | __wsum ret; | ||
89 | |||
85 | might_sleep(); | 90 | might_sleep(); |
86 | 91 | ||
87 | if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { | 92 | if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { |
@@ -105,8 +110,11 @@ csum_partial_copy_to_user(const void *src, void __user *dst, | |||
105 | } | 110 | } |
106 | 111 | ||
107 | *errp = 0; | 112 | *errp = 0; |
108 | return csum_partial_copy_generic(src, (void __force *)dst, | 113 | stac(); |
109 | len, isum, NULL, errp); | 114 | ret = csum_partial_copy_generic(src, (void __force *)dst, |
115 | len, isum, NULL, errp); | ||
116 | clac(); | ||
117 | return ret; | ||
110 | } | 118 | } |
111 | EXPORT_SYMBOL(csum_partial_copy_to_user); | 119 | EXPORT_SYMBOL(csum_partial_copy_to_user); |
112 | 120 | ||
diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index 906fea315791..c905e89e19fe 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c | |||
@@ -68,7 +68,7 @@ EXPORT_SYMBOL(copy_in_user); | |||
68 | * Since protection fault in copy_from/to_user is not a normal situation, | 68 | * Since protection fault in copy_from/to_user is not a normal situation, |
69 | * it is not necessary to optimize tail handling. | 69 | * it is not necessary to optimize tail handling. |
70 | */ | 70 | */ |
71 | unsigned long | 71 | __visible unsigned long |
72 | copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest) | 72 | copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest) |
73 | { | 73 | { |
74 | char c; | 74 | char c; |
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt index 5d7e51f3fd28..533a85e3a07e 100644 --- a/arch/x86/lib/x86-opcode-map.txt +++ b/arch/x86/lib/x86-opcode-map.txt | |||
@@ -1,10 +1,8 @@ | |||
1 | # x86 Opcode Maps | 1 | # x86 Opcode Maps |
2 | # | 2 | # |
3 | # This is (mostly) based on following documentations. | 3 | # This is (mostly) based on following documentations. |
4 | # - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2 | 4 | # - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C |
5 | # (#325383-040US, October 2011) | 5 | # (#326018-047US, June 2013) |
6 | # - Intel(R) Advanced Vector Extensions Programming Reference | ||
7 | # (#319433-011,JUNE 2011). | ||
8 | # | 6 | # |
9 | #<Opcode maps> | 7 | #<Opcode maps> |
10 | # Table: table-name | 8 | # Table: table-name |
@@ -29,6 +27,7 @@ | |||
29 | # - (F3): the last prefix is 0xF3 | 27 | # - (F3): the last prefix is 0xF3 |
30 | # - (F2): the last prefix is 0xF2 | 28 | # - (F2): the last prefix is 0xF2 |
31 | # - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) | 29 | # - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) |
30 | # - (66&F2): Both 0x66 and 0xF2 prefixes are specified. | ||
32 | 31 | ||
33 | Table: one byte opcode | 32 | Table: one byte opcode |
34 | Referrer: | 33 | Referrer: |
@@ -246,8 +245,8 @@ c2: RETN Iw (f64) | |||
246 | c3: RETN | 245 | c3: RETN |
247 | c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) | 246 | c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) |
248 | c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) | 247 | c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) |
249 | c6: Grp11 Eb,Ib (1A) | 248 | c6: Grp11A Eb,Ib (1A) |
250 | c7: Grp11 Ev,Iz (1A) | 249 | c7: Grp11B Ev,Iz (1A) |
251 | c8: ENTER Iw,Ib | 250 | c8: ENTER Iw,Ib |
252 | c9: LEAVE (d64) | 251 | c9: LEAVE (d64) |
253 | ca: RETF Iw | 252 | ca: RETF Iw |
@@ -293,8 +292,8 @@ ef: OUT DX,eAX | |||
293 | # 0xf0 - 0xff | 292 | # 0xf0 - 0xff |
294 | f0: LOCK (Prefix) | 293 | f0: LOCK (Prefix) |
295 | f1: | 294 | f1: |
296 | f2: REPNE (Prefix) | 295 | f2: REPNE (Prefix) | XACQUIRE (Prefix) |
297 | f3: REP/REPE (Prefix) | 296 | f3: REP/REPE (Prefix) | XRELEASE (Prefix) |
298 | f4: HLT | 297 | f4: HLT |
299 | f5: CMC | 298 | f5: CMC |
300 | f6: Grp3_1 Eb (1A) | 299 | f6: Grp3_1 Eb (1A) |
@@ -326,7 +325,8 @@ AVXcode: 1 | |||
326 | 0a: | 325 | 0a: |
327 | 0b: UD2 (1B) | 326 | 0b: UD2 (1B) |
328 | 0c: | 327 | 0c: |
329 | 0d: NOP Ev | GrpP | 328 | # AMD's prefetch group. Intel supports prefetchw(/1) only. |
329 | 0d: GrpP | ||
330 | 0e: FEMMS | 330 | 0e: FEMMS |
331 | # 3DNow! uses the last imm byte as opcode extension. | 331 | # 3DNow! uses the last imm byte as opcode extension. |
332 | 0f: 3DNow! Pq,Qq,Ib | 332 | 0f: 3DNow! Pq,Qq,Ib |
@@ -729,12 +729,12 @@ dc: VAESENC Vdq,Hdq,Wdq (66),(v1) | |||
729 | dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) | 729 | dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) |
730 | de: VAESDEC Vdq,Hdq,Wdq (66),(v1) | 730 | de: VAESDEC Vdq,Hdq,Wdq (66),(v1) |
731 | df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) | 731 | df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) |
732 | f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | 732 | f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) |
733 | f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | 733 | f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) |
734 | f2: ANDN Gy,By,Ey (v) | 734 | f2: ANDN Gy,By,Ey (v) |
735 | f3: Grp17 (1A) | 735 | f3: Grp17 (1A) |
736 | f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) | 736 | f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) |
737 | f6: MULX By,Gy,rDX,Ey (F2),(v) | 737 | f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) |
738 | f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) | 738 | f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) |
739 | EndTable | 739 | EndTable |
740 | 740 | ||
@@ -861,8 +861,8 @@ EndTable | |||
861 | 861 | ||
862 | GrpTable: Grp7 | 862 | GrpTable: Grp7 |
863 | 0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | 863 | 0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) |
864 | 1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001) | 864 | 1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) |
865 | 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | 865 | 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) |
866 | 3: LIDT Ms | 866 | 3: LIDT Ms |
867 | 4: SMSW Mw/Rv | 867 | 4: SMSW Mw/Rv |
868 | 5: | 868 | 5: |
@@ -880,15 +880,21 @@ EndTable | |||
880 | GrpTable: Grp9 | 880 | GrpTable: Grp9 |
881 | 1: CMPXCHG8B/16B Mq/Mdq | 881 | 1: CMPXCHG8B/16B Mq/Mdq |
882 | 6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) | 882 | 6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) |
883 | 7: VMPTRST Mq | VMPTRST Mq (F3) | 883 | 7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B) |
884 | EndTable | 884 | EndTable |
885 | 885 | ||
886 | GrpTable: Grp10 | 886 | GrpTable: Grp10 |
887 | EndTable | 887 | EndTable |
888 | 888 | ||
889 | GrpTable: Grp11 | 889 | # Grp11A and Grp11B are expressed as Grp11 in Intel SDM |
890 | # Note: the operands are given by group opcode | 890 | GrpTable: Grp11A |
891 | 0: MOV | 891 | 0: MOV Eb,Ib |
892 | 7: XABORT Ib (000),(11B) | ||
893 | EndTable | ||
894 | |||
895 | GrpTable: Grp11B | ||
896 | 0: MOV Eb,Iz | ||
897 | 7: XBEGIN Jz (000),(11B) | ||
892 | EndTable | 898 | EndTable |
893 | 899 | ||
894 | GrpTable: Grp12 | 900 | GrpTable: Grp12 |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 2ec29ac78ae6..04664cdb7fda 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
@@ -78,8 +78,8 @@ __ref void *alloc_low_pages(unsigned int num) | |||
78 | return __va(pfn << PAGE_SHIFT); | 78 | return __va(pfn << PAGE_SHIFT); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* need 4 4k for initial PMD_SIZE, 4k for 0-ISA_END_ADDRESS */ | 81 | /* need 3 4k for initial PMD_SIZE, 3 4k for 0-ISA_END_ADDRESS */ |
82 | #define INIT_PGT_BUF_SIZE (5 * PAGE_SIZE) | 82 | #define INIT_PGT_BUF_SIZE (6 * PAGE_SIZE) |
83 | RESERVE_BRK(early_pgt_alloc, INIT_PGT_BUF_SIZE); | 83 | RESERVE_BRK(early_pgt_alloc, INIT_PGT_BUF_SIZE); |
84 | void __init early_alloc_pgt_buf(void) | 84 | void __init early_alloc_pgt_buf(void) |
85 | { | 85 | { |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 0215e2c563ef..799580cabc78 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -487,7 +487,7 @@ __early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot) | |||
487 | unsigned long offset; | 487 | unsigned long offset; |
488 | resource_size_t last_addr; | 488 | resource_size_t last_addr; |
489 | unsigned int nrpages; | 489 | unsigned int nrpages; |
490 | enum fixed_addresses idx0, idx; | 490 | enum fixed_addresses idx; |
491 | int i, slot; | 491 | int i, slot; |
492 | 492 | ||
493 | WARN_ON(system_state != SYSTEM_BOOTING); | 493 | WARN_ON(system_state != SYSTEM_BOOTING); |
@@ -540,8 +540,7 @@ __early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot) | |||
540 | /* | 540 | /* |
541 | * Ok, go for it.. | 541 | * Ok, go for it.. |
542 | */ | 542 | */ |
543 | idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot; | 543 | idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot; |
544 | idx = idx0; | ||
545 | while (nrpages > 0) { | 544 | while (nrpages > 0) { |
546 | early_set_fixmap(idx, phys_addr, prot); | 545 | early_set_fixmap(idx, phys_addr, prot); |
547 | phys_addr += PAGE_SIZE; | 546 | phys_addr += PAGE_SIZE; |
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 62c29a5bfe26..25e7e1372bb2 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c | |||
@@ -112,11 +112,13 @@ static unsigned long mmap_legacy_base(void) | |||
112 | */ | 112 | */ |
113 | void arch_pick_mmap_layout(struct mm_struct *mm) | 113 | void arch_pick_mmap_layout(struct mm_struct *mm) |
114 | { | 114 | { |
115 | mm->mmap_legacy_base = mmap_legacy_base(); | ||
116 | mm->mmap_base = mmap_base(); | ||
117 | |||
115 | if (mmap_is_legacy()) { | 118 | if (mmap_is_legacy()) { |
116 | mm->mmap_base = mmap_legacy_base(); | 119 | mm->mmap_base = mm->mmap_legacy_base; |
117 | mm->get_unmapped_area = arch_get_unmapped_area; | 120 | mm->get_unmapped_area = arch_get_unmapped_area; |
118 | } else { | 121 | } else { |
119 | mm->mmap_base = mmap_base(); | ||
120 | mm->get_unmapped_area = arch_get_unmapped_area_topdown; | 122 | mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
121 | } | 123 | } |
122 | } | 124 | } |
diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c index cdd0da9dd530..266ca912f62e 100644 --- a/arch/x86/mm/srat.c +++ b/arch/x86/mm/srat.c | |||
@@ -146,6 +146,7 @@ int __init | |||
146 | acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | 146 | acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) |
147 | { | 147 | { |
148 | u64 start, end; | 148 | u64 start, end; |
149 | u32 hotpluggable; | ||
149 | int node, pxm; | 150 | int node, pxm; |
150 | 151 | ||
151 | if (srat_disabled()) | 152 | if (srat_disabled()) |
@@ -154,7 +155,8 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
154 | goto out_err_bad_srat; | 155 | goto out_err_bad_srat; |
155 | if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) | 156 | if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) |
156 | goto out_err; | 157 | goto out_err; |
157 | if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info()) | 158 | hotpluggable = ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE; |
159 | if (hotpluggable && !save_add_info()) | ||
158 | goto out_err; | 160 | goto out_err; |
159 | 161 | ||
160 | start = ma->base_address; | 162 | start = ma->base_address; |
@@ -174,9 +176,10 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
174 | 176 | ||
175 | node_set(node, numa_nodes_parsed); | 177 | node_set(node, numa_nodes_parsed); |
176 | 178 | ||
177 | printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n", | 179 | pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]%s\n", |
178 | node, pxm, | 180 | node, pxm, |
179 | (unsigned long long) start, (unsigned long long) end - 1); | 181 | (unsigned long long) start, (unsigned long long) end - 1, |
182 | hotpluggable ? " hotplug" : ""); | ||
180 | 183 | ||
181 | return 0; | 184 | return 0; |
182 | out_err_bad_srat: | 185 | out_err_bad_srat: |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 48768df2471a..6890d8498e0b 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -403,7 +403,7 @@ static void nmi_cpu_down(void *dummy) | |||
403 | nmi_cpu_shutdown(dummy); | 403 | nmi_cpu_shutdown(dummy); |
404 | } | 404 | } |
405 | 405 | ||
406 | static int nmi_create_files(struct super_block *sb, struct dentry *root) | 406 | static int nmi_create_files(struct dentry *root) |
407 | { | 407 | { |
408 | unsigned int i; | 408 | unsigned int i; |
409 | 409 | ||
@@ -420,14 +420,14 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root) | |||
420 | continue; | 420 | continue; |
421 | 421 | ||
422 | snprintf(buf, sizeof(buf), "%d", i); | 422 | snprintf(buf, sizeof(buf), "%d", i); |
423 | dir = oprofilefs_mkdir(sb, root, buf); | 423 | dir = oprofilefs_mkdir(root, buf); |
424 | oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); | 424 | oprofilefs_create_ulong(dir, "enabled", &counter_config[i].enabled); |
425 | oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event); | 425 | oprofilefs_create_ulong(dir, "event", &counter_config[i].event); |
426 | oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count); | 426 | oprofilefs_create_ulong(dir, "count", &counter_config[i].count); |
427 | oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); | 427 | oprofilefs_create_ulong(dir, "unit_mask", &counter_config[i].unit_mask); |
428 | oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); | 428 | oprofilefs_create_ulong(dir, "kernel", &counter_config[i].kernel); |
429 | oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); | 429 | oprofilefs_create_ulong(dir, "user", &counter_config[i].user); |
430 | oprofilefs_create_ulong(sb, dir, "extra", &counter_config[i].extra); | 430 | oprofilefs_create_ulong(dir, "extra", &counter_config[i].extra); |
431 | } | 431 | } |
432 | 432 | ||
433 | return 0; | 433 | return 0; |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index b2b94438ff05..50d86c0e9ba4 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -454,16 +454,16 @@ static void init_ibs(void) | |||
454 | printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); | 454 | printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); |
455 | } | 455 | } |
456 | 456 | ||
457 | static int (*create_arch_files)(struct super_block *sb, struct dentry *root); | 457 | static int (*create_arch_files)(struct dentry *root); |
458 | 458 | ||
459 | static int setup_ibs_files(struct super_block *sb, struct dentry *root) | 459 | static int setup_ibs_files(struct dentry *root) |
460 | { | 460 | { |
461 | struct dentry *dir; | 461 | struct dentry *dir; |
462 | int ret = 0; | 462 | int ret = 0; |
463 | 463 | ||
464 | /* architecture specific files */ | 464 | /* architecture specific files */ |
465 | if (create_arch_files) | 465 | if (create_arch_files) |
466 | ret = create_arch_files(sb, root); | 466 | ret = create_arch_files(root); |
467 | 467 | ||
468 | if (ret) | 468 | if (ret) |
469 | return ret; | 469 | return ret; |
@@ -479,26 +479,26 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root) | |||
479 | ibs_config.max_cnt_op = 250000; | 479 | ibs_config.max_cnt_op = 250000; |
480 | 480 | ||
481 | if (ibs_caps & IBS_CAPS_FETCHSAM) { | 481 | if (ibs_caps & IBS_CAPS_FETCHSAM) { |
482 | dir = oprofilefs_mkdir(sb, root, "ibs_fetch"); | 482 | dir = oprofilefs_mkdir(root, "ibs_fetch"); |
483 | oprofilefs_create_ulong(sb, dir, "enable", | 483 | oprofilefs_create_ulong(dir, "enable", |
484 | &ibs_config.fetch_enabled); | 484 | &ibs_config.fetch_enabled); |
485 | oprofilefs_create_ulong(sb, dir, "max_count", | 485 | oprofilefs_create_ulong(dir, "max_count", |
486 | &ibs_config.max_cnt_fetch); | 486 | &ibs_config.max_cnt_fetch); |
487 | oprofilefs_create_ulong(sb, dir, "rand_enable", | 487 | oprofilefs_create_ulong(dir, "rand_enable", |
488 | &ibs_config.rand_en); | 488 | &ibs_config.rand_en); |
489 | } | 489 | } |
490 | 490 | ||
491 | if (ibs_caps & IBS_CAPS_OPSAM) { | 491 | if (ibs_caps & IBS_CAPS_OPSAM) { |
492 | dir = oprofilefs_mkdir(sb, root, "ibs_op"); | 492 | dir = oprofilefs_mkdir(root, "ibs_op"); |
493 | oprofilefs_create_ulong(sb, dir, "enable", | 493 | oprofilefs_create_ulong(dir, "enable", |
494 | &ibs_config.op_enabled); | 494 | &ibs_config.op_enabled); |
495 | oprofilefs_create_ulong(sb, dir, "max_count", | 495 | oprofilefs_create_ulong(dir, "max_count", |
496 | &ibs_config.max_cnt_op); | 496 | &ibs_config.max_cnt_op); |
497 | if (ibs_caps & IBS_CAPS_OPCNT) | 497 | if (ibs_caps & IBS_CAPS_OPCNT) |
498 | oprofilefs_create_ulong(sb, dir, "dispatched_ops", | 498 | oprofilefs_create_ulong(dir, "dispatched_ops", |
499 | &ibs_config.dispatched_ops); | 499 | &ibs_config.dispatched_ops); |
500 | if (ibs_caps & IBS_CAPS_BRNTRGT) | 500 | if (ibs_caps & IBS_CAPS_BRNTRGT) |
501 | oprofilefs_create_ulong(sb, dir, "branch_target", | 501 | oprofilefs_create_ulong(dir, "branch_target", |
502 | &ibs_config.branch_target); | 502 | &ibs_config.branch_target); |
503 | } | 503 | } |
504 | 504 | ||
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index d641897a1f4e..b30e937689d6 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -568,13 +568,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | |||
568 | */ | 568 | */ |
569 | if (bus) { | 569 | if (bus) { |
570 | struct pci_bus *child; | 570 | struct pci_bus *child; |
571 | list_for_each_entry(child, &bus->children, node) { | 571 | list_for_each_entry(child, &bus->children, node) |
572 | struct pci_dev *self = child->self; | 572 | pcie_bus_configure_settings(child); |
573 | if (!self) | ||
574 | continue; | ||
575 | |||
576 | pcie_bus_configure_settings(child, self->pcie_mpss); | ||
577 | } | ||
578 | } | 573 | } |
579 | 574 | ||
580 | if (bus && node != -1) { | 575 | if (bus && node != -1) { |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 94919e307f8e..db6b1ab43255 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -210,6 +210,8 @@ static void pcibios_allocate_bridge_resources(struct pci_dev *dev) | |||
210 | r = &dev->resource[idx]; | 210 | r = &dev->resource[idx]; |
211 | if (!r->flags) | 211 | if (!r->flags) |
212 | continue; | 212 | continue; |
213 | if (r->parent) /* Already allocated */ | ||
214 | continue; | ||
213 | if (!r->start || pci_claim_resource(dev, idx) < 0) { | 215 | if (!r->start || pci_claim_resource(dev, idx) < 0) { |
214 | /* | 216 | /* |
215 | * Something is wrong with the region. | 217 | * Something is wrong with the region. |
@@ -318,6 +320,8 @@ static void pcibios_allocate_dev_rom_resource(struct pci_dev *dev) | |||
318 | r = &dev->resource[PCI_ROM_RESOURCE]; | 320 | r = &dev->resource[PCI_ROM_RESOURCE]; |
319 | if (!r->flags || !r->start) | 321 | if (!r->flags || !r->start) |
320 | return; | 322 | return; |
323 | if (r->parent) /* Already allocated */ | ||
324 | return; | ||
321 | 325 | ||
322 | if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) { | 326 | if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) { |
323 | r->end -= r->start; | 327 | r->end -= r->start; |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 082e88129712..5596c7bdd327 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -700,7 +700,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, | |||
700 | if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed) | 700 | if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed) |
701 | return -ENODEV; | 701 | return -ENODEV; |
702 | 702 | ||
703 | if (start > end) | 703 | if (start > end || !addr) |
704 | return -EINVAL; | 704 | return -EINVAL; |
705 | 705 | ||
706 | mutex_lock(&pci_mmcfg_lock); | 706 | mutex_lock(&pci_mmcfg_lock); |
@@ -716,11 +716,6 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, | |||
716 | return -EEXIST; | 716 | return -EEXIST; |
717 | } | 717 | } |
718 | 718 | ||
719 | if (!addr) { | ||
720 | mutex_unlock(&pci_mmcfg_lock); | ||
721 | return -EINVAL; | ||
722 | } | ||
723 | |||
724 | rc = -EBUSY; | 719 | rc = -EBUSY; |
725 | cfg = pci_mmconfig_alloc(seg, start, end, addr); | 720 | cfg = pci_mmconfig_alloc(seg, start, end, addr); |
726 | if (cfg == NULL) { | 721 | if (cfg == NULL) { |
diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c index 6eb18c42a28a..903fded50786 100644 --- a/arch/x86/pci/mrst.c +++ b/arch/x86/pci/mrst.c | |||
@@ -23,11 +23,11 @@ | |||
23 | #include <linux/ioport.h> | 23 | #include <linux/ioport.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/dmi.h> | 25 | #include <linux/dmi.h> |
26 | #include <linux/acpi.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/smp.h> | ||
26 | 29 | ||
27 | #include <asm/acpi.h> | ||
28 | #include <asm/segment.h> | 30 | #include <asm/segment.h> |
29 | #include <asm/io.h> | ||
30 | #include <asm/smp.h> | ||
31 | #include <asm/pci_x86.h> | 31 | #include <asm/pci_x86.h> |
32 | #include <asm/hw_irq.h> | 32 | #include <asm/hw_irq.h> |
33 | #include <asm/io_apic.h> | 33 | #include <asm/io_apic.h> |
@@ -43,7 +43,7 @@ | |||
43 | #define PCI_FIXED_BAR_4_SIZE 0x14 | 43 | #define PCI_FIXED_BAR_4_SIZE 0x14 |
44 | #define PCI_FIXED_BAR_5_SIZE 0x1c | 44 | #define PCI_FIXED_BAR_5_SIZE 0x1c |
45 | 45 | ||
46 | static int pci_soc_mode = 0; | 46 | static int pci_soc_mode; |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * fixed_bar_cap - return the offset of the fixed BAR cap if found | 49 | * fixed_bar_cap - return the offset of the fixed BAR cap if found |
@@ -141,7 +141,8 @@ static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn, | |||
141 | */ | 141 | */ |
142 | static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) | 142 | static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) |
143 | { | 143 | { |
144 | /* This is a workaround for A0 LNC bug where PCI status register does | 144 | /* |
145 | * This is a workaround for A0 LNC bug where PCI status register does | ||
145 | * not have new CAP bit set. can not be written by SW either. | 146 | * not have new CAP bit set. can not be written by SW either. |
146 | * | 147 | * |
147 | * PCI header type in real LNC indicates a single function device, this | 148 | * PCI header type in real LNC indicates a single function device, this |
@@ -154,7 +155,7 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) | |||
154 | || devfn == PCI_DEVFN(0, 0) | 155 | || devfn == PCI_DEVFN(0, 0) |
155 | || devfn == PCI_DEVFN(3, 0))) | 156 | || devfn == PCI_DEVFN(3, 0))) |
156 | return 1; | 157 | return 1; |
157 | return 0; /* langwell on others */ | 158 | return 0; /* Langwell on others */ |
158 | } | 159 | } |
159 | 160 | ||
160 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, | 161 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, |
@@ -172,7 +173,8 @@ static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
172 | { | 173 | { |
173 | int offset; | 174 | int offset; |
174 | 175 | ||
175 | /* On MRST, there is no PCI ROM BAR, this will cause a subsequent read | 176 | /* |
177 | * On MRST, there is no PCI ROM BAR, this will cause a subsequent read | ||
176 | * to ROM BAR return 0 then being ignored. | 178 | * to ROM BAR return 0 then being ignored. |
177 | */ | 179 | */ |
178 | if (where == PCI_ROM_ADDRESS) | 180 | if (where == PCI_ROM_ADDRESS) |
@@ -210,7 +212,8 @@ static int mrst_pci_irq_enable(struct pci_dev *dev) | |||
210 | 212 | ||
211 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | 213 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
212 | 214 | ||
213 | /* MRST only have IOAPIC, the PCI irq lines are 1:1 mapped to | 215 | /* |
216 | * MRST only have IOAPIC, the PCI irq lines are 1:1 mapped to | ||
214 | * IOAPIC RTE entries, so we just enable RTE for the device. | 217 | * IOAPIC RTE entries, so we just enable RTE for the device. |
215 | */ | 218 | */ |
216 | irq_attr.ioapic = mp_find_ioapic(dev->irq); | 219 | irq_attr.ioapic = mp_find_ioapic(dev->irq); |
@@ -235,7 +238,7 @@ struct pci_ops pci_mrst_ops = { | |||
235 | */ | 238 | */ |
236 | int __init pci_mrst_init(void) | 239 | int __init pci_mrst_init(void) |
237 | { | 240 | { |
238 | printk(KERN_INFO "Intel MID platform detected, using MID PCI ops\n"); | 241 | pr_info("Intel MID platform detected, using MID PCI ops\n"); |
239 | pci_mmcfg_late_init(); | 242 | pci_mmcfg_late_init(); |
240 | pcibios_enable_irq = mrst_pci_irq_enable; | 243 | pcibios_enable_irq = mrst_pci_irq_enable; |
241 | pci_root_ops = pci_mrst_ops; | 244 | pci_root_ops = pci_mrst_ops; |
@@ -244,17 +247,21 @@ int __init pci_mrst_init(void) | |||
244 | return 1; | 247 | return 1; |
245 | } | 248 | } |
246 | 249 | ||
247 | /* Langwell devices are not true pci devices, they are not subject to 10 ms | 250 | /* |
248 | * d3 to d0 delay required by pci spec. | 251 | * Langwell devices are not true PCI devices; they are not subject to 10 ms |
252 | * d3 to d0 delay required by PCI spec. | ||
249 | */ | 253 | */ |
250 | static void pci_d3delay_fixup(struct pci_dev *dev) | 254 | static void pci_d3delay_fixup(struct pci_dev *dev) |
251 | { | 255 | { |
252 | /* PCI fixups are effectively decided compile time. If we have a dual | 256 | /* |
253 | SoC/non-SoC kernel we don't want to mangle d3 on non SoC devices */ | 257 | * PCI fixups are effectively decided compile time. If we have a dual |
254 | if (!pci_soc_mode) | 258 | * SoC/non-SoC kernel we don't want to mangle d3 on non-SoC devices. |
255 | return; | 259 | */ |
256 | /* true pci devices in lincroft should allow type 1 access, the rest | 260 | if (!pci_soc_mode) |
257 | * are langwell fake pci devices. | 261 | return; |
262 | /* | ||
263 | * True PCI devices in Lincroft should allow type 1 access, the rest | ||
264 | * are Langwell fake PCI devices. | ||
258 | */ | 265 | */ |
259 | if (type1_access_ok(dev->bus->number, dev->devfn, PCI_DEVICE_ID)) | 266 | if (type1_access_ok(dev->bus->number, dev->devfn, PCI_DEVICE_ID)) |
260 | return; | 267 | return; |
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 1cf5b300305e..424f4c97a44d 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c | |||
@@ -25,10 +25,10 @@ | |||
25 | #include <asm/cpu.h> | 25 | #include <asm/cpu.h> |
26 | 26 | ||
27 | #ifdef CONFIG_X86_32 | 27 | #ifdef CONFIG_X86_32 |
28 | unsigned long saved_context_ebx; | 28 | __visible unsigned long saved_context_ebx; |
29 | unsigned long saved_context_esp, saved_context_ebp; | 29 | __visible unsigned long saved_context_esp, saved_context_ebp; |
30 | unsigned long saved_context_esi, saved_context_edi; | 30 | __visible unsigned long saved_context_esi, saved_context_edi; |
31 | unsigned long saved_context_eflags; | 31 | __visible unsigned long saved_context_eflags; |
32 | #endif | 32 | #endif |
33 | struct saved_context saved_context; | 33 | struct saved_context saved_context; |
34 | 34 | ||
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c index a0fde91c16cf..304fca20d96e 100644 --- a/arch/x86/power/hibernate_64.c +++ b/arch/x86/power/hibernate_64.c | |||
@@ -20,26 +20,26 @@ | |||
20 | #include <asm/suspend.h> | 20 | #include <asm/suspend.h> |
21 | 21 | ||
22 | /* References to section boundaries */ | 22 | /* References to section boundaries */ |
23 | extern const void __nosave_begin, __nosave_end; | 23 | extern __visible const void __nosave_begin, __nosave_end; |
24 | 24 | ||
25 | /* Defined in hibernate_asm_64.S */ | 25 | /* Defined in hibernate_asm_64.S */ |
26 | extern int restore_image(void); | 26 | extern asmlinkage int restore_image(void); |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * Address to jump to in the last phase of restore in order to get to the image | 29 | * Address to jump to in the last phase of restore in order to get to the image |
30 | * kernel's text (this value is passed in the image header). | 30 | * kernel's text (this value is passed in the image header). |
31 | */ | 31 | */ |
32 | unsigned long restore_jump_address; | 32 | unsigned long restore_jump_address __visible; |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Value of the cr3 register from before the hibernation (this value is passed | 35 | * Value of the cr3 register from before the hibernation (this value is passed |
36 | * in the image header). | 36 | * in the image header). |
37 | */ | 37 | */ |
38 | unsigned long restore_cr3; | 38 | unsigned long restore_cr3 __visible; |
39 | 39 | ||
40 | pgd_t *temp_level4_pgt; | 40 | pgd_t *temp_level4_pgt __visible; |
41 | 41 | ||
42 | void *relocated_restore_code; | 42 | void *relocated_restore_code __visible; |
43 | 43 | ||
44 | static void *alloc_pgt_page(void *context) | 44 | static void *alloc_pgt_page(void *context) |
45 | { | 45 | { |
diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk index e6773dc8ac41..093a892026f9 100644 --- a/arch/x86/tools/gen-insn-attr-x86.awk +++ b/arch/x86/tools/gen-insn-attr-x86.awk | |||
@@ -68,7 +68,7 @@ BEGIN { | |||
68 | 68 | ||
69 | lprefix1_expr = "\\((66|!F3)\\)" | 69 | lprefix1_expr = "\\((66|!F3)\\)" |
70 | lprefix2_expr = "\\(F3\\)" | 70 | lprefix2_expr = "\\(F3\\)" |
71 | lprefix3_expr = "\\((F2|!F3)\\)" | 71 | lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)" |
72 | lprefix_expr = "\\((66|F2|F3)\\)" | 72 | lprefix_expr = "\\((66|F2|F3)\\)" |
73 | max_lprefix = 4 | 73 | max_lprefix = 4 |
74 | 74 | ||
@@ -83,6 +83,8 @@ BEGIN { | |||
83 | prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" | 83 | prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" |
84 | prefix_num["REPNE"] = "INAT_PFX_REPNE" | 84 | prefix_num["REPNE"] = "INAT_PFX_REPNE" |
85 | prefix_num["REP/REPE"] = "INAT_PFX_REPE" | 85 | prefix_num["REP/REPE"] = "INAT_PFX_REPE" |
86 | prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" | ||
87 | prefix_num["XRELEASE"] = "INAT_PFX_REPE" | ||
86 | prefix_num["LOCK"] = "INAT_PFX_LOCK" | 88 | prefix_num["LOCK"] = "INAT_PFX_LOCK" |
87 | prefix_num["SEG=CS"] = "INAT_PFX_CS" | 89 | prefix_num["SEG=CS"] = "INAT_PFX_CS" |
88 | prefix_num["SEG=DS"] = "INAT_PFX_DS" | 90 | prefix_num["SEG=DS"] = "INAT_PFX_DS" |
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c index c74436e687bf..72074d528400 100644 --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c | |||
@@ -85,15 +85,18 @@ static notrace cycle_t vread_pvclock(int *mode) | |||
85 | cycle_t ret; | 85 | cycle_t ret; |
86 | u64 last; | 86 | u64 last; |
87 | u32 version; | 87 | u32 version; |
88 | u32 migrate_count; | ||
89 | u8 flags; | 88 | u8 flags; |
90 | unsigned cpu, cpu1; | 89 | unsigned cpu, cpu1; |
91 | 90 | ||
92 | 91 | ||
93 | /* | 92 | /* |
94 | * When looping to get a consistent (time-info, tsc) pair, we | 93 | * Note: hypervisor must guarantee that: |
95 | * also need to deal with the possibility we can switch vcpus, | 94 | * 1. cpu ID number maps 1:1 to per-CPU pvclock time info. |
96 | * so make sure we always re-fetch time-info for the current vcpu. | 95 | * 2. that per-CPU pvclock time info is updated if the |
96 | * underlying CPU changes. | ||
97 | * 3. that version is increased whenever underlying CPU | ||
98 | * changes. | ||
99 | * | ||
97 | */ | 100 | */ |
98 | do { | 101 | do { |
99 | cpu = __getcpu() & VGETCPU_CPU_MASK; | 102 | cpu = __getcpu() & VGETCPU_CPU_MASK; |
@@ -104,8 +107,6 @@ static notrace cycle_t vread_pvclock(int *mode) | |||
104 | 107 | ||
105 | pvti = get_pvti(cpu); | 108 | pvti = get_pvti(cpu); |
106 | 109 | ||
107 | migrate_count = pvti->migrate_count; | ||
108 | |||
109 | version = __pvclock_read_cycles(&pvti->pvti, &ret, &flags); | 110 | version = __pvclock_read_cycles(&pvti->pvti, &ret, &flags); |
110 | 111 | ||
111 | /* | 112 | /* |
@@ -117,8 +118,7 @@ static notrace cycle_t vread_pvclock(int *mode) | |||
117 | cpu1 = __getcpu() & VGETCPU_CPU_MASK; | 118 | cpu1 = __getcpu() & VGETCPU_CPU_MASK; |
118 | } while (unlikely(cpu != cpu1 || | 119 | } while (unlikely(cpu != cpu1 || |
119 | (pvti->pvti.version & 1) || | 120 | (pvti->pvti.version & 1) || |
120 | pvti->pvti.version != version || | 121 | pvti->pvti.version != version)); |
121 | pvti->migrate_count != migrate_count)); | ||
122 | 122 | ||
123 | if (unlikely(!(flags & PVCLOCK_TSC_STABLE_BIT))) | 123 | if (unlikely(!(flags & PVCLOCK_TSC_STABLE_BIT))) |
124 | *mode = VCLOCK_NONE; | 124 | *mode = VCLOCK_NONE; |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 193097ef3d7d..2fc216dfbd9c 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -427,8 +427,7 @@ static void __init xen_init_cpuid_mask(void) | |||
427 | 427 | ||
428 | if (!xen_initial_domain()) | 428 | if (!xen_initial_domain()) |
429 | cpuid_leaf1_edx_mask &= | 429 | cpuid_leaf1_edx_mask &= |
430 | ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ | 430 | ~((1 << X86_FEATURE_ACPI)); /* disable ACPI */ |
431 | (1 << X86_FEATURE_ACPI)); /* disable ACPI */ | ||
432 | 431 | ||
433 | cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_X2APIC % 32)); | 432 | cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_X2APIC % 32)); |
434 | 433 | ||
@@ -735,8 +734,7 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val, | |||
735 | addr = (unsigned long)xen_int3; | 734 | addr = (unsigned long)xen_int3; |
736 | else if (addr == (unsigned long)stack_segment) | 735 | else if (addr == (unsigned long)stack_segment) |
737 | addr = (unsigned long)xen_stack_segment; | 736 | addr = (unsigned long)xen_stack_segment; |
738 | else if (addr == (unsigned long)double_fault || | 737 | else if (addr == (unsigned long)double_fault) { |
739 | addr == (unsigned long)nmi) { | ||
740 | /* Don't need to handle these */ | 738 | /* Don't need to handle these */ |
741 | return 0; | 739 | return 0; |
742 | #ifdef CONFIG_X86_MCE | 740 | #ifdef CONFIG_X86_MCE |
@@ -747,7 +745,12 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val, | |||
747 | */ | 745 | */ |
748 | ; | 746 | ; |
749 | #endif | 747 | #endif |
750 | } else { | 748 | } else if (addr == (unsigned long)nmi) |
749 | /* | ||
750 | * Use the native version as well. | ||
751 | */ | ||
752 | ; | ||
753 | else { | ||
751 | /* Some other trap using IST? */ | 754 | /* Some other trap using IST? */ |
752 | if (WARN_ON(val->ist != 0)) | 755 | if (WARN_ON(val->ist != 0)) |
753 | return 0; | 756 | return 0; |
@@ -1710,6 +1713,8 @@ static void __init xen_hvm_guest_init(void) | |||
1710 | 1713 | ||
1711 | xen_hvm_init_shared_info(); | 1714 | xen_hvm_init_shared_info(); |
1712 | 1715 | ||
1716 | xen_panic_handler_init(); | ||
1717 | |||
1713 | if (xen_feature(XENFEAT_hvm_callback_vector)) | 1718 | if (xen_feature(XENFEAT_hvm_callback_vector)) |
1714 | xen_have_vector_callback = 1; | 1719 | xen_have_vector_callback = 1; |
1715 | xen_hvm_smp_init(); | 1720 | xen_hvm_smp_init(); |
@@ -1720,15 +1725,12 @@ static void __init xen_hvm_guest_init(void) | |||
1720 | xen_hvm_init_mmu_ops(); | 1725 | xen_hvm_init_mmu_ops(); |
1721 | } | 1726 | } |
1722 | 1727 | ||
1723 | static bool __init xen_hvm_platform(void) | 1728 | static uint32_t __init xen_hvm_platform(void) |
1724 | { | 1729 | { |
1725 | if (xen_pv_domain()) | 1730 | if (xen_pv_domain()) |
1726 | return false; | 1731 | return 0; |
1727 | |||
1728 | if (!xen_cpuid_base()) | ||
1729 | return false; | ||
1730 | 1732 | ||
1731 | return true; | 1733 | return xen_cpuid_base(); |
1732 | } | 1734 | } |
1733 | 1735 | ||
1734 | bool xen_hvm_need_lapic(void) | 1736 | bool xen_hvm_need_lapic(void) |
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c index 01a4dc015ae1..0da7f863056f 100644 --- a/arch/x86/xen/irq.c +++ b/arch/x86/xen/irq.c | |||
@@ -47,23 +47,18 @@ static void xen_restore_fl(unsigned long flags) | |||
47 | /* convert from IF type flag */ | 47 | /* convert from IF type flag */ |
48 | flags = !(flags & X86_EFLAGS_IF); | 48 | flags = !(flags & X86_EFLAGS_IF); |
49 | 49 | ||
50 | /* There's a one instruction preempt window here. We need to | 50 | /* See xen_irq_enable() for why preemption must be disabled. */ |
51 | make sure we're don't switch CPUs between getting the vcpu | ||
52 | pointer and updating the mask. */ | ||
53 | preempt_disable(); | 51 | preempt_disable(); |
54 | vcpu = this_cpu_read(xen_vcpu); | 52 | vcpu = this_cpu_read(xen_vcpu); |
55 | vcpu->evtchn_upcall_mask = flags; | 53 | vcpu->evtchn_upcall_mask = flags; |
56 | preempt_enable_no_resched(); | ||
57 | |||
58 | /* Doesn't matter if we get preempted here, because any | ||
59 | pending event will get dealt with anyway. */ | ||
60 | 54 | ||
61 | if (flags == 0) { | 55 | if (flags == 0) { |
62 | preempt_check_resched(); | ||
63 | barrier(); /* unmask then check (avoid races) */ | 56 | barrier(); /* unmask then check (avoid races) */ |
64 | if (unlikely(vcpu->evtchn_upcall_pending)) | 57 | if (unlikely(vcpu->evtchn_upcall_pending)) |
65 | xen_force_evtchn_callback(); | 58 | xen_force_evtchn_callback(); |
66 | } | 59 | preempt_enable(); |
60 | } else | ||
61 | preempt_enable_no_resched(); | ||
67 | } | 62 | } |
68 | PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl); | 63 | PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl); |
69 | 64 | ||
@@ -82,10 +77,12 @@ static void xen_irq_enable(void) | |||
82 | { | 77 | { |
83 | struct vcpu_info *vcpu; | 78 | struct vcpu_info *vcpu; |
84 | 79 | ||
85 | /* We don't need to worry about being preempted here, since | 80 | /* |
86 | either a) interrupts are disabled, so no preemption, or b) | 81 | * We may be preempted as soon as vcpu->evtchn_upcall_mask is |
87 | the caller is confused and is trying to re-enable interrupts | 82 | * cleared, so disable preemption to ensure we check for |
88 | on an indeterminate processor. */ | 83 | * events on the VCPU we are still running on. |
84 | */ | ||
85 | preempt_disable(); | ||
89 | 86 | ||
90 | vcpu = this_cpu_read(xen_vcpu); | 87 | vcpu = this_cpu_read(xen_vcpu); |
91 | vcpu->evtchn_upcall_mask = 0; | 88 | vcpu->evtchn_upcall_mask = 0; |
@@ -96,6 +93,8 @@ static void xen_irq_enable(void) | |||
96 | barrier(); /* unmask then check (avoid races) */ | 93 | barrier(); /* unmask then check (avoid races) */ |
97 | if (unlikely(vcpu->evtchn_upcall_pending)) | 94 | if (unlikely(vcpu->evtchn_upcall_pending)) |
98 | xen_force_evtchn_callback(); | 95 | xen_force_evtchn_callback(); |
96 | |||
97 | preempt_enable(); | ||
99 | } | 98 | } |
100 | PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable); | 99 | PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable); |
101 | 100 | ||
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 95fb2aa5927e..0d4ec35895d4 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -161,6 +161,7 @@ | |||
161 | #include <asm/xen/page.h> | 161 | #include <asm/xen/page.h> |
162 | #include <asm/xen/hypercall.h> | 162 | #include <asm/xen/hypercall.h> |
163 | #include <asm/xen/hypervisor.h> | 163 | #include <asm/xen/hypervisor.h> |
164 | #include <xen/balloon.h> | ||
164 | #include <xen/grant_table.h> | 165 | #include <xen/grant_table.h> |
165 | 166 | ||
166 | #include "multicalls.h" | 167 | #include "multicalls.h" |
@@ -967,7 +968,10 @@ int m2p_remove_override(struct page *page, | |||
967 | if (kmap_op != NULL) { | 968 | if (kmap_op != NULL) { |
968 | if (!PageHighMem(page)) { | 969 | if (!PageHighMem(page)) { |
969 | struct multicall_space mcs; | 970 | struct multicall_space mcs; |
970 | struct gnttab_unmap_grant_ref *unmap_op; | 971 | struct gnttab_unmap_and_replace *unmap_op; |
972 | struct page *scratch_page = get_balloon_scratch_page(); | ||
973 | unsigned long scratch_page_address = (unsigned long) | ||
974 | __va(page_to_pfn(scratch_page) << PAGE_SHIFT); | ||
971 | 975 | ||
972 | /* | 976 | /* |
973 | * It might be that we queued all the m2p grant table | 977 | * It might be that we queued all the m2p grant table |
@@ -990,21 +994,25 @@ int m2p_remove_override(struct page *page, | |||
990 | } | 994 | } |
991 | 995 | ||
992 | mcs = xen_mc_entry( | 996 | mcs = xen_mc_entry( |
993 | sizeof(struct gnttab_unmap_grant_ref)); | 997 | sizeof(struct gnttab_unmap_and_replace)); |
994 | unmap_op = mcs.args; | 998 | unmap_op = mcs.args; |
995 | unmap_op->host_addr = kmap_op->host_addr; | 999 | unmap_op->host_addr = kmap_op->host_addr; |
1000 | unmap_op->new_addr = scratch_page_address; | ||
996 | unmap_op->handle = kmap_op->handle; | 1001 | unmap_op->handle = kmap_op->handle; |
997 | unmap_op->dev_bus_addr = 0; | ||
998 | 1002 | ||
999 | MULTI_grant_table_op(mcs.mc, | 1003 | MULTI_grant_table_op(mcs.mc, |
1000 | GNTTABOP_unmap_grant_ref, unmap_op, 1); | 1004 | GNTTABOP_unmap_and_replace, unmap_op, 1); |
1001 | 1005 | ||
1002 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 1006 | xen_mc_issue(PARAVIRT_LAZY_MMU); |
1003 | 1007 | ||
1004 | set_pte_at(&init_mm, address, ptep, | 1008 | mcs = __xen_mc_entry(0); |
1005 | pfn_pte(pfn, PAGE_KERNEL)); | 1009 | MULTI_update_va_mapping(mcs.mc, scratch_page_address, |
1006 | __flush_tlb_single(address); | 1010 | pfn_pte(page_to_pfn(get_balloon_scratch_page()), |
1011 | PAGE_KERNEL_RO), 0); | ||
1012 | xen_mc_issue(PARAVIRT_LAZY_MMU); | ||
1013 | |||
1007 | kmap_op->host_addr = 0; | 1014 | kmap_op->host_addr = 0; |
1015 | put_balloon_scratch_page(); | ||
1008 | } | 1016 | } |
1009 | } | 1017 | } |
1010 | 1018 | ||
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 056d11faef21..09f3059cb00b 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -33,6 +33,9 @@ | |||
33 | /* These are code, but not functions. Defined in entry.S */ | 33 | /* These are code, but not functions. Defined in entry.S */ |
34 | extern const char xen_hypervisor_callback[]; | 34 | extern const char xen_hypervisor_callback[]; |
35 | extern const char xen_failsafe_callback[]; | 35 | extern const char xen_failsafe_callback[]; |
36 | #ifdef CONFIG_X86_64 | ||
37 | extern const char nmi[]; | ||
38 | #endif | ||
36 | extern void xen_sysenter_target(void); | 39 | extern void xen_sysenter_target(void); |
37 | extern void xen_syscall_target(void); | 40 | extern void xen_syscall_target(void); |
38 | extern void xen_syscall32_target(void); | 41 | extern void xen_syscall32_target(void); |
@@ -215,13 +218,19 @@ static void __init xen_set_identity_and_release_chunk( | |||
215 | unsigned long pfn; | 218 | unsigned long pfn; |
216 | 219 | ||
217 | /* | 220 | /* |
218 | * If the PFNs are currently mapped, the VA mapping also needs | 221 | * If the PFNs are currently mapped, clear the mappings |
219 | * to be updated to be 1:1. | 222 | * (except for the ISA region which must be 1:1 mapped) to |
223 | * release the refcounts (in Xen) on the original frames. | ||
220 | */ | 224 | */ |
221 | for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++) | 225 | for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++) { |
226 | pte_t pte = __pte_ma(0); | ||
227 | |||
228 | if (pfn < PFN_UP(ISA_END_ADDRESS)) | ||
229 | pte = mfn_pte(pfn, PAGE_KERNEL_IO); | ||
230 | |||
222 | (void)HYPERVISOR_update_va_mapping( | 231 | (void)HYPERVISOR_update_va_mapping( |
223 | (unsigned long)__va(pfn << PAGE_SHIFT), | 232 | (unsigned long)__va(pfn << PAGE_SHIFT), pte, 0); |
224 | mfn_pte(pfn, PAGE_KERNEL_IO), 0); | 233 | } |
225 | 234 | ||
226 | if (start_pfn < nr_pages) | 235 | if (start_pfn < nr_pages) |
227 | *released += xen_release_chunk( | 236 | *released += xen_release_chunk( |
@@ -313,6 +322,17 @@ static void xen_align_and_add_e820_region(u64 start, u64 size, int type) | |||
313 | e820_add_region(start, end - start, type); | 322 | e820_add_region(start, end - start, type); |
314 | } | 323 | } |
315 | 324 | ||
325 | void xen_ignore_unusable(struct e820entry *list, size_t map_size) | ||
326 | { | ||
327 | struct e820entry *entry; | ||
328 | unsigned int i; | ||
329 | |||
330 | for (i = 0, entry = list; i < map_size; i++, entry++) { | ||
331 | if (entry->type == E820_UNUSABLE) | ||
332 | entry->type = E820_RAM; | ||
333 | } | ||
334 | } | ||
335 | |||
316 | /** | 336 | /** |
317 | * machine_specific_memory_setup - Hook for machine specific memory setup. | 337 | * machine_specific_memory_setup - Hook for machine specific memory setup. |
318 | **/ | 338 | **/ |
@@ -353,6 +373,17 @@ char * __init xen_memory_setup(void) | |||
353 | } | 373 | } |
354 | BUG_ON(rc); | 374 | BUG_ON(rc); |
355 | 375 | ||
376 | /* | ||
377 | * Xen won't allow a 1:1 mapping to be created to UNUSABLE | ||
378 | * regions, so if we're using the machine memory map leave the | ||
379 | * region as RAM as it is in the pseudo-physical map. | ||
380 | * | ||
381 | * UNUSABLE regions in domUs are not handled and will need | ||
382 | * a patch in the future. | ||
383 | */ | ||
384 | if (xen_initial_domain()) | ||
385 | xen_ignore_unusable(map, memmap.nr_entries); | ||
386 | |||
356 | /* Make sure the Xen-supplied memory map is well-ordered. */ | 387 | /* Make sure the Xen-supplied memory map is well-ordered. */ |
357 | sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries); | 388 | sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries); |
358 | 389 | ||
@@ -525,7 +556,13 @@ void xen_enable_syscall(void) | |||
525 | } | 556 | } |
526 | #endif /* CONFIG_X86_64 */ | 557 | #endif /* CONFIG_X86_64 */ |
527 | } | 558 | } |
528 | 559 | void __cpuinit xen_enable_nmi(void) | |
560 | { | ||
561 | #ifdef CONFIG_X86_64 | ||
562 | if (register_callback(CALLBACKTYPE_nmi, nmi)) | ||
563 | BUG(); | ||
564 | #endif | ||
565 | } | ||
529 | void __init xen_arch_setup(void) | 566 | void __init xen_arch_setup(void) |
530 | { | 567 | { |
531 | xen_panic_handler_init(); | 568 | xen_panic_handler_init(); |
@@ -543,7 +580,7 @@ void __init xen_arch_setup(void) | |||
543 | 580 | ||
544 | xen_enable_sysenter(); | 581 | xen_enable_sysenter(); |
545 | xen_enable_syscall(); | 582 | xen_enable_syscall(); |
546 | 583 | xen_enable_nmi(); | |
547 | #ifdef CONFIG_ACPI | 584 | #ifdef CONFIG_ACPI |
548 | if (!(xen_start_info->flags & SIF_INITDOMAIN)) { | 585 | if (!(xen_start_info->flags & SIF_INITDOMAIN)) { |
549 | printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); | 586 | printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index ca92754eb846..9235842cd76a 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -279,6 +279,7 @@ static void __init xen_smp_prepare_boot_cpu(void) | |||
279 | 279 | ||
280 | xen_filter_cpu_maps(); | 280 | xen_filter_cpu_maps(); |
281 | xen_setup_vcpu_info_placement(); | 281 | xen_setup_vcpu_info_placement(); |
282 | xen_init_spinlocks(); | ||
282 | } | 283 | } |
283 | 284 | ||
284 | static void __init xen_smp_prepare_cpus(unsigned int max_cpus) | 285 | static void __init xen_smp_prepare_cpus(unsigned int max_cpus) |
@@ -572,6 +573,12 @@ static inline int xen_map_vector(int vector) | |||
572 | case IRQ_WORK_VECTOR: | 573 | case IRQ_WORK_VECTOR: |
573 | xen_vector = XEN_IRQ_WORK_VECTOR; | 574 | xen_vector = XEN_IRQ_WORK_VECTOR; |
574 | break; | 575 | break; |
576 | #ifdef CONFIG_X86_64 | ||
577 | case NMI_VECTOR: | ||
578 | case APIC_DM_NMI: /* Some use that instead of NMI_VECTOR */ | ||
579 | xen_vector = XEN_NMI_VECTOR; | ||
580 | break; | ||
581 | #endif | ||
575 | default: | 582 | default: |
576 | xen_vector = -1; | 583 | xen_vector = -1; |
577 | printk(KERN_ERR "xen: vector 0x%x is not implemented\n", | 584 | printk(KERN_ERR "xen: vector 0x%x is not implemented\n", |
@@ -680,7 +687,6 @@ void __init xen_smp_init(void) | |||
680 | { | 687 | { |
681 | smp_ops = xen_smp_ops; | 688 | smp_ops = xen_smp_ops; |
682 | xen_fill_possible_map(); | 689 | xen_fill_possible_map(); |
683 | xen_init_spinlocks(); | ||
684 | } | 690 | } |
685 | 691 | ||
686 | static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) | 692 | static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) |
@@ -694,8 +700,15 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) | |||
694 | static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) | 700 | static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) |
695 | { | 701 | { |
696 | int rc; | 702 | int rc; |
697 | rc = native_cpu_up(cpu, tidle); | 703 | /* |
698 | WARN_ON (xen_smp_intr_init(cpu)); | 704 | * xen_smp_intr_init() needs to run before native_cpu_up() |
705 | * so that IPI vectors are set up on the booting CPU before | ||
706 | * it is marked online in native_cpu_up(). | ||
707 | */ | ||
708 | rc = xen_smp_intr_init(cpu); | ||
709 | WARN_ON(rc); | ||
710 | if (!rc) | ||
711 | rc = native_cpu_up(cpu, tidle); | ||
699 | return rc; | 712 | return rc; |
700 | } | 713 | } |
701 | 714 | ||
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index cf3caee356b3..0438b9324a72 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
@@ -17,45 +17,44 @@ | |||
17 | #include "xen-ops.h" | 17 | #include "xen-ops.h" |
18 | #include "debugfs.h" | 18 | #include "debugfs.h" |
19 | 19 | ||
20 | #ifdef CONFIG_XEN_DEBUG_FS | 20 | enum xen_contention_stat { |
21 | static struct xen_spinlock_stats | 21 | TAKEN_SLOW, |
22 | { | 22 | TAKEN_SLOW_PICKUP, |
23 | u64 taken; | 23 | TAKEN_SLOW_SPURIOUS, |
24 | u32 taken_slow; | 24 | RELEASED_SLOW, |
25 | u32 taken_slow_nested; | 25 | RELEASED_SLOW_KICKED, |
26 | u32 taken_slow_pickup; | 26 | NR_CONTENTION_STATS |
27 | u32 taken_slow_spurious; | 27 | }; |
28 | u32 taken_slow_irqenable; | ||
29 | 28 | ||
30 | u64 released; | ||
31 | u32 released_slow; | ||
32 | u32 released_slow_kicked; | ||
33 | 29 | ||
30 | #ifdef CONFIG_XEN_DEBUG_FS | ||
34 | #define HISTO_BUCKETS 30 | 31 | #define HISTO_BUCKETS 30 |
35 | u32 histo_spin_total[HISTO_BUCKETS+1]; | 32 | static struct xen_spinlock_stats |
36 | u32 histo_spin_spinning[HISTO_BUCKETS+1]; | 33 | { |
34 | u32 contention_stats[NR_CONTENTION_STATS]; | ||
37 | u32 histo_spin_blocked[HISTO_BUCKETS+1]; | 35 | u32 histo_spin_blocked[HISTO_BUCKETS+1]; |
38 | |||
39 | u64 time_total; | ||
40 | u64 time_spinning; | ||
41 | u64 time_blocked; | 36 | u64 time_blocked; |
42 | } spinlock_stats; | 37 | } spinlock_stats; |
43 | 38 | ||
44 | static u8 zero_stats; | 39 | static u8 zero_stats; |
45 | 40 | ||
46 | static unsigned lock_timeout = 1 << 10; | ||
47 | #define TIMEOUT lock_timeout | ||
48 | |||
49 | static inline void check_zero(void) | 41 | static inline void check_zero(void) |
50 | { | 42 | { |
51 | if (unlikely(zero_stats)) { | 43 | u8 ret; |
52 | memset(&spinlock_stats, 0, sizeof(spinlock_stats)); | 44 | u8 old = ACCESS_ONCE(zero_stats); |
53 | zero_stats = 0; | 45 | if (unlikely(old)) { |
46 | ret = cmpxchg(&zero_stats, old, 0); | ||
47 | /* This ensures only one fellow resets the stat */ | ||
48 | if (ret == old) | ||
49 | memset(&spinlock_stats, 0, sizeof(spinlock_stats)); | ||
54 | } | 50 | } |
55 | } | 51 | } |
56 | 52 | ||
57 | #define ADD_STATS(elem, val) \ | 53 | static inline void add_stats(enum xen_contention_stat var, u32 val) |
58 | do { check_zero(); spinlock_stats.elem += (val); } while(0) | 54 | { |
55 | check_zero(); | ||
56 | spinlock_stats.contention_stats[var] += val; | ||
57 | } | ||
59 | 58 | ||
60 | static inline u64 spin_time_start(void) | 59 | static inline u64 spin_time_start(void) |
61 | { | 60 | { |
@@ -74,22 +73,6 @@ static void __spin_time_accum(u64 delta, u32 *array) | |||
74 | array[HISTO_BUCKETS]++; | 73 | array[HISTO_BUCKETS]++; |
75 | } | 74 | } |
76 | 75 | ||
77 | static inline void spin_time_accum_spinning(u64 start) | ||
78 | { | ||
79 | u32 delta = xen_clocksource_read() - start; | ||
80 | |||
81 | __spin_time_accum(delta, spinlock_stats.histo_spin_spinning); | ||
82 | spinlock_stats.time_spinning += delta; | ||
83 | } | ||
84 | |||
85 | static inline void spin_time_accum_total(u64 start) | ||
86 | { | ||
87 | u32 delta = xen_clocksource_read() - start; | ||
88 | |||
89 | __spin_time_accum(delta, spinlock_stats.histo_spin_total); | ||
90 | spinlock_stats.time_total += delta; | ||
91 | } | ||
92 | |||
93 | static inline void spin_time_accum_blocked(u64 start) | 76 | static inline void spin_time_accum_blocked(u64 start) |
94 | { | 77 | { |
95 | u32 delta = xen_clocksource_read() - start; | 78 | u32 delta = xen_clocksource_read() - start; |
@@ -99,19 +82,15 @@ static inline void spin_time_accum_blocked(u64 start) | |||
99 | } | 82 | } |
100 | #else /* !CONFIG_XEN_DEBUG_FS */ | 83 | #else /* !CONFIG_XEN_DEBUG_FS */ |
101 | #define TIMEOUT (1 << 10) | 84 | #define TIMEOUT (1 << 10) |
102 | #define ADD_STATS(elem, val) do { (void)(val); } while(0) | 85 | static inline void add_stats(enum xen_contention_stat var, u32 val) |
86 | { | ||
87 | } | ||
103 | 88 | ||
104 | static inline u64 spin_time_start(void) | 89 | static inline u64 spin_time_start(void) |
105 | { | 90 | { |
106 | return 0; | 91 | return 0; |
107 | } | 92 | } |
108 | 93 | ||
109 | static inline void spin_time_accum_total(u64 start) | ||
110 | { | ||
111 | } | ||
112 | static inline void spin_time_accum_spinning(u64 start) | ||
113 | { | ||
114 | } | ||
115 | static inline void spin_time_accum_blocked(u64 start) | 94 | static inline void spin_time_accum_blocked(u64 start) |
116 | { | 95 | { |
117 | } | 96 | } |
@@ -134,227 +113,123 @@ typedef u16 xen_spinners_t; | |||
134 | asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory"); | 113 | asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory"); |
135 | #endif | 114 | #endif |
136 | 115 | ||
137 | struct xen_spinlock { | 116 | struct xen_lock_waiting { |
138 | unsigned char lock; /* 0 -> free; 1 -> locked */ | 117 | struct arch_spinlock *lock; |
139 | xen_spinners_t spinners; /* count of waiting cpus */ | 118 | __ticket_t want; |
140 | }; | 119 | }; |
141 | 120 | ||
142 | static int xen_spin_is_locked(struct arch_spinlock *lock) | ||
143 | { | ||
144 | struct xen_spinlock *xl = (struct xen_spinlock *)lock; | ||
145 | |||
146 | return xl->lock != 0; | ||
147 | } | ||
148 | |||
149 | static int xen_spin_is_contended(struct arch_spinlock *lock) | ||
150 | { | ||
151 | struct xen_spinlock *xl = (struct xen_spinlock *)lock; | ||
152 | |||
153 | /* Not strictly true; this is only the count of contended | ||
154 | lock-takers entering the slow path. */ | ||
155 | return xl->spinners != 0; | ||
156 | } | ||
157 | |||
158 | static int xen_spin_trylock(struct arch_spinlock *lock) | ||
159 | { | ||
160 | struct xen_spinlock *xl = (struct xen_spinlock *)lock; | ||
161 | u8 old = 1; | ||
162 | |||
163 | asm("xchgb %b0,%1" | ||
164 | : "+q" (old), "+m" (xl->lock) : : "memory"); | ||
165 | |||
166 | return old == 0; | ||
167 | } | ||
168 | |||
169 | static DEFINE_PER_CPU(char *, irq_name); | ||
170 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; | 121 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; |
171 | static DEFINE_PER_CPU(struct xen_spinlock *, lock_spinners); | 122 | static DEFINE_PER_CPU(char *, irq_name); |
172 | 123 | static DEFINE_PER_CPU(struct xen_lock_waiting, lock_waiting); | |
173 | /* | 124 | static cpumask_t waiting_cpus; |
174 | * Mark a cpu as interested in a lock. Returns the CPU's previous | ||
175 | * lock of interest, in case we got preempted by an interrupt. | ||
176 | */ | ||
177 | static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl) | ||
178 | { | ||
179 | struct xen_spinlock *prev; | ||
180 | |||
181 | prev = __this_cpu_read(lock_spinners); | ||
182 | __this_cpu_write(lock_spinners, xl); | ||
183 | |||
184 | wmb(); /* set lock of interest before count */ | ||
185 | |||
186 | inc_spinners(xl); | ||
187 | |||
188 | return prev; | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * Mark a cpu as no longer interested in a lock. Restores previous | ||
193 | * lock of interest (NULL for none). | ||
194 | */ | ||
195 | static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock *prev) | ||
196 | { | ||
197 | dec_spinners(xl); | ||
198 | wmb(); /* decrement count before restoring lock */ | ||
199 | __this_cpu_write(lock_spinners, prev); | ||
200 | } | ||
201 | 125 | ||
202 | static noinline int xen_spin_lock_slow(struct arch_spinlock *lock, bool irq_enable) | 126 | static void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want) |
203 | { | 127 | { |
204 | struct xen_spinlock *xl = (struct xen_spinlock *)lock; | ||
205 | struct xen_spinlock *prev; | ||
206 | int irq = __this_cpu_read(lock_kicker_irq); | 128 | int irq = __this_cpu_read(lock_kicker_irq); |
207 | int ret; | 129 | struct xen_lock_waiting *w = &__get_cpu_var(lock_waiting); |
130 | int cpu = smp_processor_id(); | ||
208 | u64 start; | 131 | u64 start; |
132 | unsigned long flags; | ||
209 | 133 | ||
210 | /* If kicker interrupts not initialized yet, just spin */ | 134 | /* If kicker interrupts not initialized yet, just spin */ |
211 | if (irq == -1) | 135 | if (irq == -1) |
212 | return 0; | 136 | return; |
213 | 137 | ||
214 | start = spin_time_start(); | 138 | start = spin_time_start(); |
215 | 139 | ||
216 | /* announce we're spinning */ | 140 | /* |
217 | prev = spinning_lock(xl); | 141 | * Make sure an interrupt handler can't upset things in a |
142 | * partially setup state. | ||
143 | */ | ||
144 | local_irq_save(flags); | ||
145 | /* | ||
146 | * We don't really care if we're overwriting some other | ||
147 | * (lock,want) pair, as that would mean that we're currently | ||
148 | * in an interrupt context, and the outer context had | ||
149 | * interrupts enabled. That has already kicked the VCPU out | ||
150 | * of xen_poll_irq(), so it will just return spuriously and | ||
151 | * retry with newly setup (lock,want). | ||
152 | * | ||
153 | * The ordering protocol on this is that the "lock" pointer | ||
154 | * may only be set non-NULL if the "want" ticket is correct. | ||
155 | * If we're updating "want", we must first clear "lock". | ||
156 | */ | ||
157 | w->lock = NULL; | ||
158 | smp_wmb(); | ||
159 | w->want = want; | ||
160 | smp_wmb(); | ||
161 | w->lock = lock; | ||
218 | 162 | ||
219 | ADD_STATS(taken_slow, 1); | 163 | /* This uses set_bit, which atomic and therefore a barrier */ |
220 | ADD_STATS(taken_slow_nested, prev != NULL); | 164 | cpumask_set_cpu(cpu, &waiting_cpus); |
165 | add_stats(TAKEN_SLOW, 1); | ||
221 | 166 | ||
222 | do { | 167 | /* clear pending */ |
223 | unsigned long flags; | 168 | xen_clear_irq_pending(irq); |
224 | 169 | ||
225 | /* clear pending */ | 170 | /* Only check lock once pending cleared */ |
226 | xen_clear_irq_pending(irq); | 171 | barrier(); |
227 | 172 | ||
228 | /* check again make sure it didn't become free while | 173 | /* |
229 | we weren't looking */ | 174 | * Mark entry to slowpath before doing the pickup test to make |
230 | ret = xen_spin_trylock(lock); | 175 | * sure we don't deadlock with an unlocker. |
231 | if (ret) { | 176 | */ |
232 | ADD_STATS(taken_slow_pickup, 1); | 177 | __ticket_enter_slowpath(lock); |
233 | 178 | ||
234 | /* | 179 | /* |
235 | * If we interrupted another spinlock while it | 180 | * check again make sure it didn't become free while |
236 | * was blocking, make sure it doesn't block | 181 | * we weren't looking |
237 | * without rechecking the lock. | 182 | */ |
238 | */ | 183 | if (ACCESS_ONCE(lock->tickets.head) == want) { |
239 | if (prev != NULL) | 184 | add_stats(TAKEN_SLOW_PICKUP, 1); |
240 | xen_set_irq_pending(irq); | 185 | goto out; |
241 | goto out; | 186 | } |
242 | } | ||
243 | 187 | ||
244 | flags = arch_local_save_flags(); | 188 | /* Allow interrupts while blocked */ |
245 | if (irq_enable) { | 189 | local_irq_restore(flags); |
246 | ADD_STATS(taken_slow_irqenable, 1); | ||
247 | raw_local_irq_enable(); | ||
248 | } | ||
249 | 190 | ||
250 | /* | 191 | /* |
251 | * Block until irq becomes pending. If we're | 192 | * If an interrupt happens here, it will leave the wakeup irq |
252 | * interrupted at this point (after the trylock but | 193 | * pending, which will cause xen_poll_irq() to return |
253 | * before entering the block), then the nested lock | 194 | * immediately. |
254 | * handler guarantees that the irq will be left | 195 | */ |
255 | * pending if there's any chance the lock became free; | ||
256 | * xen_poll_irq() returns immediately if the irq is | ||
257 | * pending. | ||
258 | */ | ||
259 | xen_poll_irq(irq); | ||
260 | 196 | ||
261 | raw_local_irq_restore(flags); | 197 | /* Block until irq becomes pending (or perhaps a spurious wakeup) */ |
198 | xen_poll_irq(irq); | ||
199 | add_stats(TAKEN_SLOW_SPURIOUS, !xen_test_irq_pending(irq)); | ||
262 | 200 | ||
263 | ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq)); | 201 | local_irq_save(flags); |
264 | } while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */ | ||
265 | 202 | ||
266 | kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); | 203 | kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); |
267 | |||
268 | out: | 204 | out: |
269 | unspinning_lock(xl, prev); | 205 | cpumask_clear_cpu(cpu, &waiting_cpus); |
270 | spin_time_accum_blocked(start); | 206 | w->lock = NULL; |
271 | |||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | static inline void __xen_spin_lock(struct arch_spinlock *lock, bool irq_enable) | ||
276 | { | ||
277 | struct xen_spinlock *xl = (struct xen_spinlock *)lock; | ||
278 | unsigned timeout; | ||
279 | u8 oldval; | ||
280 | u64 start_spin; | ||
281 | |||
282 | ADD_STATS(taken, 1); | ||
283 | |||
284 | start_spin = spin_time_start(); | ||
285 | |||
286 | do { | ||
287 | u64 start_spin_fast = spin_time_start(); | ||
288 | |||
289 | timeout = TIMEOUT; | ||
290 | |||
291 | asm("1: xchgb %1,%0\n" | ||
292 | " testb %1,%1\n" | ||
293 | " jz 3f\n" | ||
294 | "2: rep;nop\n" | ||
295 | " cmpb $0,%0\n" | ||
296 | " je 1b\n" | ||
297 | " dec %2\n" | ||
298 | " jnz 2b\n" | ||
299 | "3:\n" | ||
300 | : "+m" (xl->lock), "=q" (oldval), "+r" (timeout) | ||
301 | : "1" (1) | ||
302 | : "memory"); | ||
303 | 207 | ||
304 | spin_time_accum_spinning(start_spin_fast); | 208 | local_irq_restore(flags); |
305 | 209 | ||
306 | } while (unlikely(oldval != 0 && | 210 | spin_time_accum_blocked(start); |
307 | (TIMEOUT == ~0 || !xen_spin_lock_slow(lock, irq_enable)))); | ||
308 | |||
309 | spin_time_accum_total(start_spin); | ||
310 | } | ||
311 | |||
312 | static void xen_spin_lock(struct arch_spinlock *lock) | ||
313 | { | ||
314 | __xen_spin_lock(lock, false); | ||
315 | } | ||
316 | |||
317 | static void xen_spin_lock_flags(struct arch_spinlock *lock, unsigned long flags) | ||
318 | { | ||
319 | __xen_spin_lock(lock, !raw_irqs_disabled_flags(flags)); | ||
320 | } | 211 | } |
212 | PV_CALLEE_SAVE_REGS_THUNK(xen_lock_spinning); | ||
321 | 213 | ||
322 | static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl) | 214 | static void xen_unlock_kick(struct arch_spinlock *lock, __ticket_t next) |
323 | { | 215 | { |
324 | int cpu; | 216 | int cpu; |
325 | 217 | ||
326 | ADD_STATS(released_slow, 1); | 218 | add_stats(RELEASED_SLOW, 1); |
219 | |||
220 | for_each_cpu(cpu, &waiting_cpus) { | ||
221 | const struct xen_lock_waiting *w = &per_cpu(lock_waiting, cpu); | ||
327 | 222 | ||
328 | for_each_online_cpu(cpu) { | 223 | /* Make sure we read lock before want */ |
329 | /* XXX should mix up next cpu selection */ | 224 | if (ACCESS_ONCE(w->lock) == lock && |
330 | if (per_cpu(lock_spinners, cpu) == xl) { | 225 | ACCESS_ONCE(w->want) == next) { |
331 | ADD_STATS(released_slow_kicked, 1); | 226 | add_stats(RELEASED_SLOW_KICKED, 1); |
332 | xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); | 227 | xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); |
228 | break; | ||
333 | } | 229 | } |
334 | } | 230 | } |
335 | } | 231 | } |
336 | 232 | ||
337 | static void xen_spin_unlock(struct arch_spinlock *lock) | ||
338 | { | ||
339 | struct xen_spinlock *xl = (struct xen_spinlock *)lock; | ||
340 | |||
341 | ADD_STATS(released, 1); | ||
342 | |||
343 | smp_wmb(); /* make sure no writes get moved after unlock */ | ||
344 | xl->lock = 0; /* release lock */ | ||
345 | |||
346 | /* | ||
347 | * Make sure unlock happens before checking for waiting | ||
348 | * spinners. We need a strong barrier to enforce the | ||
349 | * write-read ordering to different memory locations, as the | ||
350 | * CPU makes no implied guarantees about their ordering. | ||
351 | */ | ||
352 | mb(); | ||
353 | |||
354 | if (unlikely(xl->spinners)) | ||
355 | xen_spin_unlock_slow(xl); | ||
356 | } | ||
357 | |||
358 | static irqreturn_t dummy_handler(int irq, void *dev_id) | 233 | static irqreturn_t dummy_handler(int irq, void *dev_id) |
359 | { | 234 | { |
360 | BUG(); | 235 | BUG(); |
@@ -408,6 +283,8 @@ void xen_uninit_lock_cpu(int cpu) | |||
408 | per_cpu(irq_name, cpu) = NULL; | 283 | per_cpu(irq_name, cpu) = NULL; |
409 | } | 284 | } |
410 | 285 | ||
286 | static bool xen_pvspin __initdata = true; | ||
287 | |||
411 | void __init xen_init_spinlocks(void) | 288 | void __init xen_init_spinlocks(void) |
412 | { | 289 | { |
413 | /* | 290 | /* |
@@ -417,15 +294,23 @@ void __init xen_init_spinlocks(void) | |||
417 | if (xen_hvm_domain()) | 294 | if (xen_hvm_domain()) |
418 | return; | 295 | return; |
419 | 296 | ||
420 | BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); | 297 | if (!xen_pvspin) { |
298 | printk(KERN_DEBUG "xen: PV spinlocks disabled\n"); | ||
299 | return; | ||
300 | } | ||
421 | 301 | ||
422 | pv_lock_ops.spin_is_locked = xen_spin_is_locked; | 302 | static_key_slow_inc(¶virt_ticketlocks_enabled); |
423 | pv_lock_ops.spin_is_contended = xen_spin_is_contended; | 303 | |
424 | pv_lock_ops.spin_lock = xen_spin_lock; | 304 | pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning); |
425 | pv_lock_ops.spin_lock_flags = xen_spin_lock_flags; | 305 | pv_lock_ops.unlock_kick = xen_unlock_kick; |
426 | pv_lock_ops.spin_trylock = xen_spin_trylock; | 306 | } |
427 | pv_lock_ops.spin_unlock = xen_spin_unlock; | 307 | |
308 | static __init int xen_parse_nopvspin(char *arg) | ||
309 | { | ||
310 | xen_pvspin = false; | ||
311 | return 0; | ||
428 | } | 312 | } |
313 | early_param("xen_nopvspin", xen_parse_nopvspin); | ||
429 | 314 | ||
430 | #ifdef CONFIG_XEN_DEBUG_FS | 315 | #ifdef CONFIG_XEN_DEBUG_FS |
431 | 316 | ||
@@ -442,37 +327,21 @@ static int __init xen_spinlock_debugfs(void) | |||
442 | 327 | ||
443 | debugfs_create_u8("zero_stats", 0644, d_spin_debug, &zero_stats); | 328 | debugfs_create_u8("zero_stats", 0644, d_spin_debug, &zero_stats); |
444 | 329 | ||
445 | debugfs_create_u32("timeout", 0644, d_spin_debug, &lock_timeout); | ||
446 | |||
447 | debugfs_create_u64("taken", 0444, d_spin_debug, &spinlock_stats.taken); | ||
448 | debugfs_create_u32("taken_slow", 0444, d_spin_debug, | 330 | debugfs_create_u32("taken_slow", 0444, d_spin_debug, |
449 | &spinlock_stats.taken_slow); | 331 | &spinlock_stats.contention_stats[TAKEN_SLOW]); |
450 | debugfs_create_u32("taken_slow_nested", 0444, d_spin_debug, | ||
451 | &spinlock_stats.taken_slow_nested); | ||
452 | debugfs_create_u32("taken_slow_pickup", 0444, d_spin_debug, | 332 | debugfs_create_u32("taken_slow_pickup", 0444, d_spin_debug, |
453 | &spinlock_stats.taken_slow_pickup); | 333 | &spinlock_stats.contention_stats[TAKEN_SLOW_PICKUP]); |
454 | debugfs_create_u32("taken_slow_spurious", 0444, d_spin_debug, | 334 | debugfs_create_u32("taken_slow_spurious", 0444, d_spin_debug, |
455 | &spinlock_stats.taken_slow_spurious); | 335 | &spinlock_stats.contention_stats[TAKEN_SLOW_SPURIOUS]); |
456 | debugfs_create_u32("taken_slow_irqenable", 0444, d_spin_debug, | ||
457 | &spinlock_stats.taken_slow_irqenable); | ||
458 | 336 | ||
459 | debugfs_create_u64("released", 0444, d_spin_debug, &spinlock_stats.released); | ||
460 | debugfs_create_u32("released_slow", 0444, d_spin_debug, | 337 | debugfs_create_u32("released_slow", 0444, d_spin_debug, |
461 | &spinlock_stats.released_slow); | 338 | &spinlock_stats.contention_stats[RELEASED_SLOW]); |
462 | debugfs_create_u32("released_slow_kicked", 0444, d_spin_debug, | 339 | debugfs_create_u32("released_slow_kicked", 0444, d_spin_debug, |
463 | &spinlock_stats.released_slow_kicked); | 340 | &spinlock_stats.contention_stats[RELEASED_SLOW_KICKED]); |
464 | 341 | ||
465 | debugfs_create_u64("time_spinning", 0444, d_spin_debug, | ||
466 | &spinlock_stats.time_spinning); | ||
467 | debugfs_create_u64("time_blocked", 0444, d_spin_debug, | 342 | debugfs_create_u64("time_blocked", 0444, d_spin_debug, |
468 | &spinlock_stats.time_blocked); | 343 | &spinlock_stats.time_blocked); |
469 | debugfs_create_u64("time_total", 0444, d_spin_debug, | ||
470 | &spinlock_stats.time_total); | ||
471 | 344 | ||
472 | debugfs_create_u32_array("histo_total", 0444, d_spin_debug, | ||
473 | spinlock_stats.histo_spin_total, HISTO_BUCKETS + 1); | ||
474 | debugfs_create_u32_array("histo_spinning", 0444, d_spin_debug, | ||
475 | spinlock_stats.histo_spin_spinning, HISTO_BUCKETS + 1); | ||
476 | debugfs_create_u32_array("histo_blocked", 0444, d_spin_debug, | 345 | debugfs_create_u32_array("histo_blocked", 0444, d_spin_debug, |
477 | spinlock_stats.histo_spin_blocked, HISTO_BUCKETS + 1); | 346 | spinlock_stats.histo_spin_blocked, HISTO_BUCKETS + 1); |
478 | 347 | ||
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 86782c5d7e2a..95f8c6142328 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -105,9 +105,9 @@ static inline void __init xen_init_apic(void) | |||
105 | /* Declare an asm function, along with symbols needed to make it | 105 | /* Declare an asm function, along with symbols needed to make it |
106 | inlineable */ | 106 | inlineable */ |
107 | #define DECL_ASM(ret, name, ...) \ | 107 | #define DECL_ASM(ret, name, ...) \ |
108 | ret name(__VA_ARGS__); \ | 108 | __visible ret name(__VA_ARGS__); \ |
109 | extern char name##_end[]; \ | 109 | extern char name##_end[] __visible; \ |
110 | extern char name##_reloc[] \ | 110 | extern char name##_reloc[] __visible |
111 | 111 | ||
112 | DECL_ASM(void, xen_irq_enable_direct, void); | 112 | DECL_ASM(void, xen_irq_enable_direct, void); |
113 | DECL_ASM(void, xen_irq_disable_direct, void); | 113 | DECL_ASM(void, xen_irq_disable_direct, void); |
@@ -115,11 +115,11 @@ DECL_ASM(unsigned long, xen_save_fl_direct, void); | |||
115 | DECL_ASM(void, xen_restore_fl_direct, unsigned long); | 115 | DECL_ASM(void, xen_restore_fl_direct, unsigned long); |
116 | 116 | ||
117 | /* These are not functions, and cannot be called normally */ | 117 | /* These are not functions, and cannot be called normally */ |
118 | void xen_iret(void); | 118 | __visible void xen_iret(void); |
119 | void xen_sysexit(void); | 119 | __visible void xen_sysexit(void); |
120 | void xen_sysret32(void); | 120 | __visible void xen_sysret32(void); |
121 | void xen_sysret64(void); | 121 | __visible void xen_sysret64(void); |
122 | void xen_adjust_exception_frame(void); | 122 | __visible void xen_adjust_exception_frame(void); |
123 | 123 | ||
124 | extern int xen_panic_handler_init(void); | 124 | extern int xen_panic_handler_init(void); |
125 | 125 | ||