diff options
146 files changed, 2672 insertions, 731 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/lsi,zevio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/lsi,zevio-intc.txt new file mode 100644 index 000000000000..aee38e7c13e7 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/lsi,zevio-intc.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | TI-NSPIRE interrupt controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Compatible property value should be "lsi,zevio-intc". | ||
5 | |||
6 | - reg: Physical base address of the controller and length of memory mapped | ||
7 | region. | ||
8 | |||
9 | - interrupt-controller : Identifies the node as an interrupt controller | ||
10 | |||
11 | Example: | ||
12 | |||
13 | interrupt-controller { | ||
14 | compatible = "lsi,zevio-intc"; | ||
15 | interrupt-controller; | ||
16 | reg = <0xDC000000 0x1000>; | ||
17 | #interrupt-cells = <1>; | ||
18 | }; | ||
diff --git a/Documentation/dvb/contributors.txt b/Documentation/dvb/contributors.txt index 47c30098dab6..731a009723c7 100644 --- a/Documentation/dvb/contributors.txt +++ b/Documentation/dvb/contributors.txt | |||
@@ -78,7 +78,7 @@ Peter Beutner <p.beutner@gmx.net> | |||
78 | Wilson Michaels <wilsonmichaels@earthlink.net> | 78 | Wilson Michaels <wilsonmichaels@earthlink.net> |
79 | for the lgdt330x frontend driver, and various bugfixes | 79 | for the lgdt330x frontend driver, and various bugfixes |
80 | 80 | ||
81 | Michael Krufky <mkrufky@m1k.net> | 81 | Michael Krufky <mkrufky@linuxtv.org> |
82 | for maintaining v4l/dvb inter-tree dependencies | 82 | for maintaining v4l/dvb inter-tree dependencies |
83 | 83 | ||
84 | Taylor Jacob <rtjacob@earthlink.net> | 84 | Taylor Jacob <rtjacob@earthlink.net> |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 8f441dab0396..7116fda7077f 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1726,16 +1726,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1726 | option description. | 1726 | option description. |
1727 | 1727 | ||
1728 | memmap=nn[KMG]@ss[KMG] | 1728 | memmap=nn[KMG]@ss[KMG] |
1729 | [KNL] Force usage of a specific region of memory | 1729 | [KNL] Force usage of a specific region of memory. |
1730 | Region of memory to be used, from ss to ss+nn. | 1730 | Region of memory to be used is from ss to ss+nn. |
1731 | 1731 | ||
1732 | memmap=nn[KMG]#ss[KMG] | 1732 | memmap=nn[KMG]#ss[KMG] |
1733 | [KNL,ACPI] Mark specific memory as ACPI data. | 1733 | [KNL,ACPI] Mark specific memory as ACPI data. |
1734 | Region of memory to be used, from ss to ss+nn. | 1734 | Region of memory to be marked is from ss to ss+nn. |
1735 | 1735 | ||
1736 | memmap=nn[KMG]$ss[KMG] | 1736 | memmap=nn[KMG]$ss[KMG] |
1737 | [KNL,ACPI] Mark specific memory as reserved. | 1737 | [KNL,ACPI] Mark specific memory as reserved. |
1738 | Region of memory to be used, from ss to ss+nn. | 1738 | Region of memory to be reserved is from ss to ss+nn. |
1739 | Example: Exclude memory from 0x18690000-0x1869ffff | 1739 | Example: Exclude memory from 0x18690000-0x1869ffff |
1740 | memmap=64K$0x18690000 | 1740 | memmap=64K$0x18690000 |
1741 | or | 1741 | or |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index dd4327f09ba4..27bbcfc7202a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -36,6 +36,7 @@ config ARM64 | |||
36 | select HAVE_GENERIC_DMA_COHERENT | 36 | select HAVE_GENERIC_DMA_COHERENT |
37 | select HAVE_HW_BREAKPOINT if PERF_EVENTS | 37 | select HAVE_HW_BREAKPOINT if PERF_EVENTS |
38 | select HAVE_MEMBLOCK | 38 | select HAVE_MEMBLOCK |
39 | select HAVE_PATA_PLATFORM | ||
39 | select HAVE_PERF_EVENTS | 40 | select HAVE_PERF_EVENTS |
40 | select IRQ_DOMAIN | 41 | select IRQ_DOMAIN |
41 | select MODULES_USE_ELF_RELA | 42 | select MODULES_USE_ELF_RELA |
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 84139be62ae6..7959dd0ca5d5 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig | |||
@@ -1,4 +1,3 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 1 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | # CONFIG_SWAP is not set | 2 | # CONFIG_SWAP is not set |
4 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
@@ -19,6 +18,7 @@ CONFIG_BLK_DEV_INITRD=y | |||
19 | CONFIG_KALLSYMS_ALL=y | 18 | CONFIG_KALLSYMS_ALL=y |
20 | # CONFIG_COMPAT_BRK is not set | 19 | # CONFIG_COMPAT_BRK is not set |
21 | CONFIG_PROFILING=y | 20 | CONFIG_PROFILING=y |
21 | CONFIG_JUMP_LABEL=y | ||
22 | CONFIG_MODULES=y | 22 | CONFIG_MODULES=y |
23 | CONFIG_MODULE_UNLOAD=y | 23 | CONFIG_MODULE_UNLOAD=y |
24 | # CONFIG_BLK_DEV_BSG is not set | 24 | # CONFIG_BLK_DEV_BSG is not set |
@@ -27,6 +27,7 @@ CONFIG_ARCH_VEXPRESS=y | |||
27 | CONFIG_ARCH_XGENE=y | 27 | CONFIG_ARCH_XGENE=y |
28 | CONFIG_SMP=y | 28 | CONFIG_SMP=y |
29 | CONFIG_PREEMPT=y | 29 | CONFIG_PREEMPT=y |
30 | CONFIG_CMA=y | ||
30 | CONFIG_CMDLINE="console=ttyAMA0" | 31 | CONFIG_CMDLINE="console=ttyAMA0" |
31 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 32 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set |
32 | CONFIG_COMPAT=y | 33 | CONFIG_COMPAT=y |
@@ -42,14 +43,17 @@ CONFIG_IP_PNP_BOOTP=y | |||
42 | # CONFIG_WIRELESS is not set | 43 | # CONFIG_WIRELESS is not set |
43 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 44 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
44 | CONFIG_DEVTMPFS=y | 45 | CONFIG_DEVTMPFS=y |
45 | CONFIG_BLK_DEV=y | 46 | CONFIG_DMA_CMA=y |
46 | CONFIG_SCSI=y | 47 | CONFIG_SCSI=y |
47 | # CONFIG_SCSI_PROC_FS is not set | 48 | # CONFIG_SCSI_PROC_FS is not set |
48 | CONFIG_BLK_DEV_SD=y | 49 | CONFIG_BLK_DEV_SD=y |
49 | # CONFIG_SCSI_LOWLEVEL is not set | 50 | # CONFIG_SCSI_LOWLEVEL is not set |
51 | CONFIG_ATA=y | ||
52 | CONFIG_PATA_PLATFORM=y | ||
53 | CONFIG_PATA_OF_PLATFORM=y | ||
50 | CONFIG_NETDEVICES=y | 54 | CONFIG_NETDEVICES=y |
51 | CONFIG_MII=y | ||
52 | CONFIG_SMC91X=y | 55 | CONFIG_SMC91X=y |
56 | CONFIG_SMSC911X=y | ||
53 | # CONFIG_WLAN is not set | 57 | # CONFIG_WLAN is not set |
54 | CONFIG_INPUT_EVDEV=y | 58 | CONFIG_INPUT_EVDEV=y |
55 | # CONFIG_SERIO_I8042 is not set | 59 | # CONFIG_SERIO_I8042 is not set |
@@ -62,13 +66,19 @@ CONFIG_SERIAL_AMBA_PL011=y | |||
62 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | 66 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y |
63 | # CONFIG_HW_RANDOM is not set | 67 | # CONFIG_HW_RANDOM is not set |
64 | # CONFIG_HWMON is not set | 68 | # CONFIG_HWMON is not set |
69 | CONFIG_REGULATOR=y | ||
70 | CONFIG_REGULATOR_FIXED_VOLTAGE=y | ||
65 | CONFIG_FB=y | 71 | CONFIG_FB=y |
66 | # CONFIG_VGA_CONSOLE is not set | 72 | # CONFIG_VGA_CONSOLE is not set |
67 | CONFIG_FRAMEBUFFER_CONSOLE=y | 73 | CONFIG_FRAMEBUFFER_CONSOLE=y |
68 | CONFIG_LOGO=y | 74 | CONFIG_LOGO=y |
69 | # CONFIG_LOGO_LINUX_MONO is not set | 75 | # CONFIG_LOGO_LINUX_MONO is not set |
70 | # CONFIG_LOGO_LINUX_VGA16 is not set | 76 | # CONFIG_LOGO_LINUX_VGA16 is not set |
71 | # CONFIG_USB_SUPPORT is not set | 77 | CONFIG_USB=y |
78 | CONFIG_USB_ISP1760_HCD=y | ||
79 | CONFIG_USB_STORAGE=y | ||
80 | CONFIG_MMC=y | ||
81 | CONFIG_MMC_ARMMMCI=y | ||
72 | # CONFIG_IOMMU_SUPPORT is not set | 82 | # CONFIG_IOMMU_SUPPORT is not set |
73 | CONFIG_EXT2_FS=y | 83 | CONFIG_EXT2_FS=y |
74 | CONFIG_EXT3_FS=y | 84 | CONFIG_EXT3_FS=y |
diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h index 01de5aaa3edc..0237f0867e37 100644 --- a/arch/arm64/include/asm/atomic.h +++ b/arch/arm64/include/asm/atomic.h | |||
@@ -54,8 +54,7 @@ static inline void atomic_add(int i, atomic_t *v) | |||
54 | " stxr %w1, %w0, %2\n" | 54 | " stxr %w1, %w0, %2\n" |
55 | " cbnz %w1, 1b" | 55 | " cbnz %w1, 1b" |
56 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 56 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
57 | : "Ir" (i) | 57 | : "Ir" (i)); |
58 | : "cc"); | ||
59 | } | 58 | } |
60 | 59 | ||
61 | static inline int atomic_add_return(int i, atomic_t *v) | 60 | static inline int atomic_add_return(int i, atomic_t *v) |
@@ -64,14 +63,15 @@ static inline int atomic_add_return(int i, atomic_t *v) | |||
64 | int result; | 63 | int result; |
65 | 64 | ||
66 | asm volatile("// atomic_add_return\n" | 65 | asm volatile("// atomic_add_return\n" |
67 | "1: ldaxr %w0, %2\n" | 66 | "1: ldxr %w0, %2\n" |
68 | " add %w0, %w0, %w3\n" | 67 | " add %w0, %w0, %w3\n" |
69 | " stlxr %w1, %w0, %2\n" | 68 | " stlxr %w1, %w0, %2\n" |
70 | " cbnz %w1, 1b" | 69 | " cbnz %w1, 1b" |
71 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 70 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
72 | : "Ir" (i) | 71 | : "Ir" (i) |
73 | : "cc", "memory"); | 72 | : "memory"); |
74 | 73 | ||
74 | smp_mb(); | ||
75 | return result; | 75 | return result; |
76 | } | 76 | } |
77 | 77 | ||
@@ -86,8 +86,7 @@ static inline void atomic_sub(int i, atomic_t *v) | |||
86 | " stxr %w1, %w0, %2\n" | 86 | " stxr %w1, %w0, %2\n" |
87 | " cbnz %w1, 1b" | 87 | " cbnz %w1, 1b" |
88 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 88 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
89 | : "Ir" (i) | 89 | : "Ir" (i)); |
90 | : "cc"); | ||
91 | } | 90 | } |
92 | 91 | ||
93 | static inline int atomic_sub_return(int i, atomic_t *v) | 92 | static inline int atomic_sub_return(int i, atomic_t *v) |
@@ -96,14 +95,15 @@ static inline int atomic_sub_return(int i, atomic_t *v) | |||
96 | int result; | 95 | int result; |
97 | 96 | ||
98 | asm volatile("// atomic_sub_return\n" | 97 | asm volatile("// atomic_sub_return\n" |
99 | "1: ldaxr %w0, %2\n" | 98 | "1: ldxr %w0, %2\n" |
100 | " sub %w0, %w0, %w3\n" | 99 | " sub %w0, %w0, %w3\n" |
101 | " stlxr %w1, %w0, %2\n" | 100 | " stlxr %w1, %w0, %2\n" |
102 | " cbnz %w1, 1b" | 101 | " cbnz %w1, 1b" |
103 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 102 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
104 | : "Ir" (i) | 103 | : "Ir" (i) |
105 | : "cc", "memory"); | 104 | : "memory"); |
106 | 105 | ||
106 | smp_mb(); | ||
107 | return result; | 107 | return result; |
108 | } | 108 | } |
109 | 109 | ||
@@ -112,17 +112,20 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) | |||
112 | unsigned long tmp; | 112 | unsigned long tmp; |
113 | int oldval; | 113 | int oldval; |
114 | 114 | ||
115 | smp_mb(); | ||
116 | |||
115 | asm volatile("// atomic_cmpxchg\n" | 117 | asm volatile("// atomic_cmpxchg\n" |
116 | "1: ldaxr %w1, %2\n" | 118 | "1: ldxr %w1, %2\n" |
117 | " cmp %w1, %w3\n" | 119 | " cmp %w1, %w3\n" |
118 | " b.ne 2f\n" | 120 | " b.ne 2f\n" |
119 | " stlxr %w0, %w4, %2\n" | 121 | " stxr %w0, %w4, %2\n" |
120 | " cbnz %w0, 1b\n" | 122 | " cbnz %w0, 1b\n" |
121 | "2:" | 123 | "2:" |
122 | : "=&r" (tmp), "=&r" (oldval), "+Q" (ptr->counter) | 124 | : "=&r" (tmp), "=&r" (oldval), "+Q" (ptr->counter) |
123 | : "Ir" (old), "r" (new) | 125 | : "Ir" (old), "r" (new) |
124 | : "cc", "memory"); | 126 | : "cc"); |
125 | 127 | ||
128 | smp_mb(); | ||
126 | return oldval; | 129 | return oldval; |
127 | } | 130 | } |
128 | 131 | ||
@@ -173,8 +176,7 @@ static inline void atomic64_add(u64 i, atomic64_t *v) | |||
173 | " stxr %w1, %0, %2\n" | 176 | " stxr %w1, %0, %2\n" |
174 | " cbnz %w1, 1b" | 177 | " cbnz %w1, 1b" |
175 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 178 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
176 | : "Ir" (i) | 179 | : "Ir" (i)); |
177 | : "cc"); | ||
178 | } | 180 | } |
179 | 181 | ||
180 | static inline long atomic64_add_return(long i, atomic64_t *v) | 182 | static inline long atomic64_add_return(long i, atomic64_t *v) |
@@ -183,14 +185,15 @@ static inline long atomic64_add_return(long i, atomic64_t *v) | |||
183 | unsigned long tmp; | 185 | unsigned long tmp; |
184 | 186 | ||
185 | asm volatile("// atomic64_add_return\n" | 187 | asm volatile("// atomic64_add_return\n" |
186 | "1: ldaxr %0, %2\n" | 188 | "1: ldxr %0, %2\n" |
187 | " add %0, %0, %3\n" | 189 | " add %0, %0, %3\n" |
188 | " stlxr %w1, %0, %2\n" | 190 | " stlxr %w1, %0, %2\n" |
189 | " cbnz %w1, 1b" | 191 | " cbnz %w1, 1b" |
190 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 192 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
191 | : "Ir" (i) | 193 | : "Ir" (i) |
192 | : "cc", "memory"); | 194 | : "memory"); |
193 | 195 | ||
196 | smp_mb(); | ||
194 | return result; | 197 | return result; |
195 | } | 198 | } |
196 | 199 | ||
@@ -205,8 +208,7 @@ static inline void atomic64_sub(u64 i, atomic64_t *v) | |||
205 | " stxr %w1, %0, %2\n" | 208 | " stxr %w1, %0, %2\n" |
206 | " cbnz %w1, 1b" | 209 | " cbnz %w1, 1b" |
207 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 210 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
208 | : "Ir" (i) | 211 | : "Ir" (i)); |
209 | : "cc"); | ||
210 | } | 212 | } |
211 | 213 | ||
212 | static inline long atomic64_sub_return(long i, atomic64_t *v) | 214 | static inline long atomic64_sub_return(long i, atomic64_t *v) |
@@ -215,14 +217,15 @@ static inline long atomic64_sub_return(long i, atomic64_t *v) | |||
215 | unsigned long tmp; | 217 | unsigned long tmp; |
216 | 218 | ||
217 | asm volatile("// atomic64_sub_return\n" | 219 | asm volatile("// atomic64_sub_return\n" |
218 | "1: ldaxr %0, %2\n" | 220 | "1: ldxr %0, %2\n" |
219 | " sub %0, %0, %3\n" | 221 | " sub %0, %0, %3\n" |
220 | " stlxr %w1, %0, %2\n" | 222 | " stlxr %w1, %0, %2\n" |
221 | " cbnz %w1, 1b" | 223 | " cbnz %w1, 1b" |
222 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 224 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
223 | : "Ir" (i) | 225 | : "Ir" (i) |
224 | : "cc", "memory"); | 226 | : "memory"); |
225 | 227 | ||
228 | smp_mb(); | ||
226 | return result; | 229 | return result; |
227 | } | 230 | } |
228 | 231 | ||
@@ -231,17 +234,20 @@ static inline long atomic64_cmpxchg(atomic64_t *ptr, long old, long new) | |||
231 | long oldval; | 234 | long oldval; |
232 | unsigned long res; | 235 | unsigned long res; |
233 | 236 | ||
237 | smp_mb(); | ||
238 | |||
234 | asm volatile("// atomic64_cmpxchg\n" | 239 | asm volatile("// atomic64_cmpxchg\n" |
235 | "1: ldaxr %1, %2\n" | 240 | "1: ldxr %1, %2\n" |
236 | " cmp %1, %3\n" | 241 | " cmp %1, %3\n" |
237 | " b.ne 2f\n" | 242 | " b.ne 2f\n" |
238 | " stlxr %w0, %4, %2\n" | 243 | " stxr %w0, %4, %2\n" |
239 | " cbnz %w0, 1b\n" | 244 | " cbnz %w0, 1b\n" |
240 | "2:" | 245 | "2:" |
241 | : "=&r" (res), "=&r" (oldval), "+Q" (ptr->counter) | 246 | : "=&r" (res), "=&r" (oldval), "+Q" (ptr->counter) |
242 | : "Ir" (old), "r" (new) | 247 | : "Ir" (old), "r" (new) |
243 | : "cc", "memory"); | 248 | : "cc"); |
244 | 249 | ||
250 | smp_mb(); | ||
245 | return oldval; | 251 | return oldval; |
246 | } | 252 | } |
247 | 253 | ||
@@ -253,11 +259,12 @@ static inline long atomic64_dec_if_positive(atomic64_t *v) | |||
253 | unsigned long tmp; | 259 | unsigned long tmp; |
254 | 260 | ||
255 | asm volatile("// atomic64_dec_if_positive\n" | 261 | asm volatile("// atomic64_dec_if_positive\n" |
256 | "1: ldaxr %0, %2\n" | 262 | "1: ldxr %0, %2\n" |
257 | " subs %0, %0, #1\n" | 263 | " subs %0, %0, #1\n" |
258 | " b.mi 2f\n" | 264 | " b.mi 2f\n" |
259 | " stlxr %w1, %0, %2\n" | 265 | " stlxr %w1, %0, %2\n" |
260 | " cbnz %w1, 1b\n" | 266 | " cbnz %w1, 1b\n" |
267 | " dmb ish\n" | ||
261 | "2:" | 268 | "2:" |
262 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) | 269 | : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) |
263 | : | 270 | : |
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h index 78e20ba8806b..409ca370cfe2 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #define wfi() asm volatile("wfi" : : : "memory") | 25 | #define wfi() asm volatile("wfi" : : : "memory") |
26 | 26 | ||
27 | #define isb() asm volatile("isb" : : : "memory") | 27 | #define isb() asm volatile("isb" : : : "memory") |
28 | #define dsb() asm volatile("dsb sy" : : : "memory") | 28 | #define dsb(opt) asm volatile("dsb sy" : : : "memory") |
29 | 29 | ||
30 | #define mb() dsb() | 30 | #define mb() dsb() |
31 | #define rmb() asm volatile("dsb ld" : : : "memory") | 31 | #define rmb() asm volatile("dsb ld" : : : "memory") |
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h index fea9ee327206..889324981aa4 100644 --- a/arch/arm64/include/asm/cacheflush.h +++ b/arch/arm64/include/asm/cacheflush.h | |||
@@ -116,6 +116,7 @@ extern void flush_dcache_page(struct page *); | |||
116 | static inline void __flush_icache_all(void) | 116 | static inline void __flush_icache_all(void) |
117 | { | 117 | { |
118 | asm("ic ialluis"); | 118 | asm("ic ialluis"); |
119 | dsb(); | ||
119 | } | 120 | } |
120 | 121 | ||
121 | #define flush_dcache_mmap_lock(mapping) \ | 122 | #define flush_dcache_mmap_lock(mapping) \ |
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h index 56166d7f4a25..57c0fa7bf711 100644 --- a/arch/arm64/include/asm/cmpxchg.h +++ b/arch/arm64/include/asm/cmpxchg.h | |||
@@ -29,44 +29,45 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size | |||
29 | switch (size) { | 29 | switch (size) { |
30 | case 1: | 30 | case 1: |
31 | asm volatile("// __xchg1\n" | 31 | asm volatile("// __xchg1\n" |
32 | "1: ldaxrb %w0, %2\n" | 32 | "1: ldxrb %w0, %2\n" |
33 | " stlxrb %w1, %w3, %2\n" | 33 | " stlxrb %w1, %w3, %2\n" |
34 | " cbnz %w1, 1b\n" | 34 | " cbnz %w1, 1b\n" |
35 | : "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr) | 35 | : "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr) |
36 | : "r" (x) | 36 | : "r" (x) |
37 | : "cc", "memory"); | 37 | : "memory"); |
38 | break; | 38 | break; |
39 | case 2: | 39 | case 2: |
40 | asm volatile("// __xchg2\n" | 40 | asm volatile("// __xchg2\n" |
41 | "1: ldaxrh %w0, %2\n" | 41 | "1: ldxrh %w0, %2\n" |
42 | " stlxrh %w1, %w3, %2\n" | 42 | " stlxrh %w1, %w3, %2\n" |
43 | " cbnz %w1, 1b\n" | 43 | " cbnz %w1, 1b\n" |
44 | : "=&r" (ret), "=&r" (tmp), "+Q" (*(u16 *)ptr) | 44 | : "=&r" (ret), "=&r" (tmp), "+Q" (*(u16 *)ptr) |
45 | : "r" (x) | 45 | : "r" (x) |
46 | : "cc", "memory"); | 46 | : "memory"); |
47 | break; | 47 | break; |
48 | case 4: | 48 | case 4: |
49 | asm volatile("// __xchg4\n" | 49 | asm volatile("// __xchg4\n" |
50 | "1: ldaxr %w0, %2\n" | 50 | "1: ldxr %w0, %2\n" |
51 | " stlxr %w1, %w3, %2\n" | 51 | " stlxr %w1, %w3, %2\n" |
52 | " cbnz %w1, 1b\n" | 52 | " cbnz %w1, 1b\n" |
53 | : "=&r" (ret), "=&r" (tmp), "+Q" (*(u32 *)ptr) | 53 | : "=&r" (ret), "=&r" (tmp), "+Q" (*(u32 *)ptr) |
54 | : "r" (x) | 54 | : "r" (x) |
55 | : "cc", "memory"); | 55 | : "memory"); |
56 | break; | 56 | break; |
57 | case 8: | 57 | case 8: |
58 | asm volatile("// __xchg8\n" | 58 | asm volatile("// __xchg8\n" |
59 | "1: ldaxr %0, %2\n" | 59 | "1: ldxr %0, %2\n" |
60 | " stlxr %w1, %3, %2\n" | 60 | " stlxr %w1, %3, %2\n" |
61 | " cbnz %w1, 1b\n" | 61 | " cbnz %w1, 1b\n" |
62 | : "=&r" (ret), "=&r" (tmp), "+Q" (*(u64 *)ptr) | 62 | : "=&r" (ret), "=&r" (tmp), "+Q" (*(u64 *)ptr) |
63 | : "r" (x) | 63 | : "r" (x) |
64 | : "cc", "memory"); | 64 | : "memory"); |
65 | break; | 65 | break; |
66 | default: | 66 | default: |
67 | BUILD_BUG(); | 67 | BUILD_BUG(); |
68 | } | 68 | } |
69 | 69 | ||
70 | smp_mb(); | ||
70 | return ret; | 71 | return ret; |
71 | } | 72 | } |
72 | 73 | ||
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 78834123a32e..c4a7f940b387 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h | |||
@@ -42,7 +42,7 @@ | |||
42 | #define ESR_EL1_EC_SP_ALIGN (0x26) | 42 | #define ESR_EL1_EC_SP_ALIGN (0x26) |
43 | #define ESR_EL1_EC_FP_EXC32 (0x28) | 43 | #define ESR_EL1_EC_FP_EXC32 (0x28) |
44 | #define ESR_EL1_EC_FP_EXC64 (0x2C) | 44 | #define ESR_EL1_EC_FP_EXC64 (0x2C) |
45 | #define ESR_EL1_EC_SERRROR (0x2F) | 45 | #define ESR_EL1_EC_SERROR (0x2F) |
46 | #define ESR_EL1_EC_BREAKPT_EL0 (0x30) | 46 | #define ESR_EL1_EC_BREAKPT_EL0 (0x30) |
47 | #define ESR_EL1_EC_BREAKPT_EL1 (0x31) | 47 | #define ESR_EL1_EC_BREAKPT_EL1 (0x31) |
48 | #define ESR_EL1_EC_SOFTSTP_EL0 (0x32) | 48 | #define ESR_EL1_EC_SOFTSTP_EL0 (0x32) |
diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index 78cc3aba5d69..5f750dc96e0f 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h | |||
@@ -24,10 +24,11 @@ | |||
24 | 24 | ||
25 | #define __futex_atomic_op(insn, ret, oldval, uaddr, tmp, oparg) \ | 25 | #define __futex_atomic_op(insn, ret, oldval, uaddr, tmp, oparg) \ |
26 | asm volatile( \ | 26 | asm volatile( \ |
27 | "1: ldaxr %w1, %2\n" \ | 27 | "1: ldxr %w1, %2\n" \ |
28 | insn "\n" \ | 28 | insn "\n" \ |
29 | "2: stlxr %w3, %w0, %2\n" \ | 29 | "2: stlxr %w3, %w0, %2\n" \ |
30 | " cbnz %w3, 1b\n" \ | 30 | " cbnz %w3, 1b\n" \ |
31 | " dmb ish\n" \ | ||
31 | "3:\n" \ | 32 | "3:\n" \ |
32 | " .pushsection .fixup,\"ax\"\n" \ | 33 | " .pushsection .fixup,\"ax\"\n" \ |
33 | " .align 2\n" \ | 34 | " .align 2\n" \ |
@@ -40,7 +41,7 @@ | |||
40 | " .popsection\n" \ | 41 | " .popsection\n" \ |
41 | : "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp) \ | 42 | : "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp) \ |
42 | : "r" (oparg), "Ir" (-EFAULT) \ | 43 | : "r" (oparg), "Ir" (-EFAULT) \ |
43 | : "cc", "memory") | 44 | : "memory") |
44 | 45 | ||
45 | static inline int | 46 | static inline int |
46 | futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | 47 | futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
@@ -111,11 +112,12 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
111 | return -EFAULT; | 112 | return -EFAULT; |
112 | 113 | ||
113 | asm volatile("// futex_atomic_cmpxchg_inatomic\n" | 114 | asm volatile("// futex_atomic_cmpxchg_inatomic\n" |
114 | "1: ldaxr %w1, %2\n" | 115 | "1: ldxr %w1, %2\n" |
115 | " sub %w3, %w1, %w4\n" | 116 | " sub %w3, %w1, %w4\n" |
116 | " cbnz %w3, 3f\n" | 117 | " cbnz %w3, 3f\n" |
117 | "2: stlxr %w3, %w5, %2\n" | 118 | "2: stlxr %w3, %w5, %2\n" |
118 | " cbnz %w3, 1b\n" | 119 | " cbnz %w3, 1b\n" |
120 | " dmb ish\n" | ||
119 | "3:\n" | 121 | "3:\n" |
120 | " .pushsection .fixup,\"ax\"\n" | 122 | " .pushsection .fixup,\"ax\"\n" |
121 | "4: mov %w0, %w6\n" | 123 | "4: mov %w0, %w6\n" |
@@ -127,7 +129,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
127 | " .popsection\n" | 129 | " .popsection\n" |
128 | : "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp) | 130 | : "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp) |
129 | : "r" (oldval), "r" (newval), "Ir" (-EFAULT) | 131 | : "r" (oldval), "r" (newval), "Ir" (-EFAULT) |
130 | : "cc", "memory"); | 132 | : "memory"); |
131 | 133 | ||
132 | *uval = val; | 134 | *uval = val; |
133 | return ret; | 135 | return ret; |
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index c98ef4771c73..0eb398655378 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h | |||
@@ -231,7 +231,7 @@ | |||
231 | #define ESR_EL2_EC_SP_ALIGN (0x26) | 231 | #define ESR_EL2_EC_SP_ALIGN (0x26) |
232 | #define ESR_EL2_EC_FP_EXC32 (0x28) | 232 | #define ESR_EL2_EC_FP_EXC32 (0x28) |
233 | #define ESR_EL2_EC_FP_EXC64 (0x2C) | 233 | #define ESR_EL2_EC_FP_EXC64 (0x2C) |
234 | #define ESR_EL2_EC_SERRROR (0x2F) | 234 | #define ESR_EL2_EC_SERROR (0x2F) |
235 | #define ESR_EL2_EC_BREAKPT (0x30) | 235 | #define ESR_EL2_EC_BREAKPT (0x30) |
236 | #define ESR_EL2_EC_BREAKPT_HYP (0x31) | 236 | #define ESR_EL2_EC_BREAKPT_HYP (0x31) |
237 | #define ESR_EL2_EC_SOFTSTP (0x32) | 237 | #define ESR_EL2_EC_SOFTSTP (0x32) |
diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h index 3d5cf064d7a1..c45b7b1b7197 100644 --- a/arch/arm64/include/asm/spinlock.h +++ b/arch/arm64/include/asm/spinlock.h | |||
@@ -132,7 +132,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw) | |||
132 | " cbnz %w0, 2b\n" | 132 | " cbnz %w0, 2b\n" |
133 | : "=&r" (tmp), "+Q" (rw->lock) | 133 | : "=&r" (tmp), "+Q" (rw->lock) |
134 | : "r" (0x80000000) | 134 | : "r" (0x80000000) |
135 | : "cc", "memory"); | 135 | : "memory"); |
136 | } | 136 | } |
137 | 137 | ||
138 | static inline int arch_write_trylock(arch_rwlock_t *rw) | 138 | static inline int arch_write_trylock(arch_rwlock_t *rw) |
@@ -146,7 +146,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) | |||
146 | "1:\n" | 146 | "1:\n" |
147 | : "=&r" (tmp), "+Q" (rw->lock) | 147 | : "=&r" (tmp), "+Q" (rw->lock) |
148 | : "r" (0x80000000) | 148 | : "r" (0x80000000) |
149 | : "cc", "memory"); | 149 | : "memory"); |
150 | 150 | ||
151 | return !tmp; | 151 | return !tmp; |
152 | } | 152 | } |
@@ -187,7 +187,7 @@ static inline void arch_read_lock(arch_rwlock_t *rw) | |||
187 | " cbnz %w1, 2b\n" | 187 | " cbnz %w1, 2b\n" |
188 | : "=&r" (tmp), "=&r" (tmp2), "+Q" (rw->lock) | 188 | : "=&r" (tmp), "=&r" (tmp2), "+Q" (rw->lock) |
189 | : | 189 | : |
190 | : "cc", "memory"); | 190 | : "memory"); |
191 | } | 191 | } |
192 | 192 | ||
193 | static inline void arch_read_unlock(arch_rwlock_t *rw) | 193 | static inline void arch_read_unlock(arch_rwlock_t *rw) |
@@ -201,7 +201,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) | |||
201 | " cbnz %w1, 1b\n" | 201 | " cbnz %w1, 1b\n" |
202 | : "=&r" (tmp), "=&r" (tmp2), "+Q" (rw->lock) | 202 | : "=&r" (tmp), "=&r" (tmp2), "+Q" (rw->lock) |
203 | : | 203 | : |
204 | : "cc", "memory"); | 204 | : "memory"); |
205 | } | 205 | } |
206 | 206 | ||
207 | static inline int arch_read_trylock(arch_rwlock_t *rw) | 207 | static inline int arch_read_trylock(arch_rwlock_t *rw) |
@@ -216,7 +216,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) | |||
216 | "1:\n" | 216 | "1:\n" |
217 | : "=&r" (tmp), "+r" (tmp2), "+Q" (rw->lock) | 217 | : "=&r" (tmp), "+r" (tmp2), "+Q" (rw->lock) |
218 | : | 218 | : |
219 | : "cc", "memory"); | 219 | : "memory"); |
220 | 220 | ||
221 | return !tmp2; | 221 | return !tmp2; |
222 | } | 222 | } |
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index 58125bf008d3..bb8eb8a78e67 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h | |||
@@ -399,7 +399,10 @@ __SYSCALL(374, compat_sys_sendmmsg) | |||
399 | __SYSCALL(375, sys_setns) | 399 | __SYSCALL(375, sys_setns) |
400 | __SYSCALL(376, compat_sys_process_vm_readv) | 400 | __SYSCALL(376, compat_sys_process_vm_readv) |
401 | __SYSCALL(377, compat_sys_process_vm_writev) | 401 | __SYSCALL(377, compat_sys_process_vm_writev) |
402 | __SYSCALL(378, sys_ni_syscall) /* 378 for kcmp */ | 402 | __SYSCALL(378, sys_kcmp) |
403 | __SYSCALL(379, sys_finit_module) | ||
404 | __SYSCALL(380, sys_sched_setattr) | ||
405 | __SYSCALL(381, sys_sched_getattr) | ||
403 | 406 | ||
404 | #define __NR_compat_syscalls 379 | 407 | #define __NR_compat_syscalls 379 |
405 | 408 | ||
diff --git a/arch/arm64/kernel/kuser32.S b/arch/arm64/kernel/kuser32.S index 63c48ffdf230..7787208e8cc6 100644 --- a/arch/arm64/kernel/kuser32.S +++ b/arch/arm64/kernel/kuser32.S | |||
@@ -38,12 +38,13 @@ __kuser_cmpxchg64: // 0xffff0f60 | |||
38 | .inst 0xe92d00f0 // push {r4, r5, r6, r7} | 38 | .inst 0xe92d00f0 // push {r4, r5, r6, r7} |
39 | .inst 0xe1c040d0 // ldrd r4, r5, [r0] | 39 | .inst 0xe1c040d0 // ldrd r4, r5, [r0] |
40 | .inst 0xe1c160d0 // ldrd r6, r7, [r1] | 40 | .inst 0xe1c160d0 // ldrd r6, r7, [r1] |
41 | .inst 0xe1b20e9f // 1: ldaexd r0, r1, [r2] | 41 | .inst 0xe1b20f9f // 1: ldrexd r0, r1, [r2] |
42 | .inst 0xe0303004 // eors r3, r0, r4 | 42 | .inst 0xe0303004 // eors r3, r0, r4 |
43 | .inst 0x00313005 // eoreqs r3, r1, r5 | 43 | .inst 0x00313005 // eoreqs r3, r1, r5 |
44 | .inst 0x01a23e96 // stlexdeq r3, r6, [r2] | 44 | .inst 0x01a23e96 // stlexdeq r3, r6, [r2] |
45 | .inst 0x03330001 // teqeq r3, #1 | 45 | .inst 0x03330001 // teqeq r3, #1 |
46 | .inst 0x0afffff9 // beq 1b | 46 | .inst 0x0afffff9 // beq 1b |
47 | .inst 0xf57ff05b // dmb ish | ||
47 | .inst 0xe2730000 // rsbs r0, r3, #0 | 48 | .inst 0xe2730000 // rsbs r0, r3, #0 |
48 | .inst 0xe8bd00f0 // pop {r4, r5, r6, r7} | 49 | .inst 0xe8bd00f0 // pop {r4, r5, r6, r7} |
49 | .inst 0xe12fff1e // bx lr | 50 | .inst 0xe12fff1e // bx lr |
@@ -55,11 +56,12 @@ __kuser_memory_barrier: // 0xffff0fa0 | |||
55 | 56 | ||
56 | .align 5 | 57 | .align 5 |
57 | __kuser_cmpxchg: // 0xffff0fc0 | 58 | __kuser_cmpxchg: // 0xffff0fc0 |
58 | .inst 0xe1923e9f // 1: ldaex r3, [r2] | 59 | .inst 0xe1923f9f // 1: ldrex r3, [r2] |
59 | .inst 0xe0533000 // subs r3, r3, r0 | 60 | .inst 0xe0533000 // subs r3, r3, r0 |
60 | .inst 0x01823e91 // stlexeq r3, r1, [r2] | 61 | .inst 0x01823e91 // stlexeq r3, r1, [r2] |
61 | .inst 0x03330001 // teqeq r3, #1 | 62 | .inst 0x03330001 // teqeq r3, #1 |
62 | .inst 0x0afffffa // beq 1b | 63 | .inst 0x0afffffa // beq 1b |
64 | .inst 0xf57ff05b // dmb ish | ||
63 | .inst 0xe2730000 // rsbs r0, r3, #0 | 65 | .inst 0xe2730000 // rsbs r0, r3, #0 |
64 | .inst 0xe12fff1e // bx lr | 66 | .inst 0xe12fff1e // bx lr |
65 | 67 | ||
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 65d40cf6945a..a7149cae1615 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c | |||
@@ -238,6 +238,8 @@ void update_vsyscall(struct timekeeper *tk) | |||
238 | vdso_data->use_syscall = use_syscall; | 238 | vdso_data->use_syscall = use_syscall; |
239 | vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec; | 239 | vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec; |
240 | vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec; | 240 | vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec; |
241 | vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; | ||
242 | vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; | ||
241 | 243 | ||
242 | if (!use_syscall) { | 244 | if (!use_syscall) { |
243 | vdso_data->cs_cycle_last = tk->clock->cycle_last; | 245 | vdso_data->cs_cycle_last = tk->clock->cycle_last; |
@@ -245,8 +247,6 @@ void update_vsyscall(struct timekeeper *tk) | |||
245 | vdso_data->xtime_clock_nsec = tk->xtime_nsec; | 247 | vdso_data->xtime_clock_nsec = tk->xtime_nsec; |
246 | vdso_data->cs_mult = tk->mult; | 248 | vdso_data->cs_mult = tk->mult; |
247 | vdso_data->cs_shift = tk->shift; | 249 | vdso_data->cs_shift = tk->shift; |
248 | vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; | ||
249 | vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; | ||
250 | } | 250 | } |
251 | 251 | ||
252 | smp_wmb(); | 252 | smp_wmb(); |
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index d8064af42e62..6d20b7d162d8 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile | |||
@@ -48,7 +48,7 @@ $(obj-vdso): %.o: %.S | |||
48 | 48 | ||
49 | # Actual build commands | 49 | # Actual build commands |
50 | quiet_cmd_vdsold = VDSOL $@ | 50 | quiet_cmd_vdsold = VDSOL $@ |
51 | cmd_vdsold = $(CC) $(c_flags) -Wl,-T $^ -o $@ | 51 | cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@ |
52 | quiet_cmd_vdsoas = VDSOA $@ | 52 | quiet_cmd_vdsoas = VDSOA $@ |
53 | cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $< | 53 | cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $< |
54 | 54 | ||
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S index f0a6d10b5211..fe652ffd34c2 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S | |||
@@ -103,6 +103,8 @@ ENTRY(__kernel_clock_gettime) | |||
103 | bl __do_get_tspec | 103 | bl __do_get_tspec |
104 | seqcnt_check w9, 1b | 104 | seqcnt_check w9, 1b |
105 | 105 | ||
106 | mov x30, x2 | ||
107 | |||
106 | cmp w0, #CLOCK_MONOTONIC | 108 | cmp w0, #CLOCK_MONOTONIC |
107 | b.ne 6f | 109 | b.ne 6f |
108 | 110 | ||
@@ -118,6 +120,9 @@ ENTRY(__kernel_clock_gettime) | |||
118 | ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne | 120 | ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne |
119 | b.ne 8f | 121 | b.ne 8f |
120 | 122 | ||
123 | /* xtime_coarse_nsec is already right-shifted */ | ||
124 | mov x12, #0 | ||
125 | |||
121 | /* Get coarse timespec. */ | 126 | /* Get coarse timespec. */ |
122 | adr vdso_data, _vdso_data | 127 | adr vdso_data, _vdso_data |
123 | 3: seqcnt_acquire | 128 | 3: seqcnt_acquire |
@@ -156,7 +161,7 @@ ENTRY(__kernel_clock_gettime) | |||
156 | lsr x11, x11, x12 | 161 | lsr x11, x11, x12 |
157 | stp x10, x11, [x1, #TSPEC_TV_SEC] | 162 | stp x10, x11, [x1, #TSPEC_TV_SEC] |
158 | mov x0, xzr | 163 | mov x0, xzr |
159 | ret x2 | 164 | ret |
160 | 7: | 165 | 7: |
161 | mov x30, x2 | 166 | mov x30, x2 |
162 | 8: /* Syscall fallback. */ | 167 | 8: /* Syscall fallback. */ |
diff --git a/arch/arm64/lib/bitops.S b/arch/arm64/lib/bitops.S index e5db797790d3..7dac371cc9a2 100644 --- a/arch/arm64/lib/bitops.S +++ b/arch/arm64/lib/bitops.S | |||
@@ -46,11 +46,12 @@ ENTRY( \name ) | |||
46 | mov x2, #1 | 46 | mov x2, #1 |
47 | add x1, x1, x0, lsr #3 // Get word offset | 47 | add x1, x1, x0, lsr #3 // Get word offset |
48 | lsl x4, x2, x3 // Create mask | 48 | lsl x4, x2, x3 // Create mask |
49 | 1: ldaxr x2, [x1] | 49 | 1: ldxr x2, [x1] |
50 | lsr x0, x2, x3 // Save old value of bit | 50 | lsr x0, x2, x3 // Save old value of bit |
51 | \instr x2, x2, x4 // toggle bit | 51 | \instr x2, x2, x4 // toggle bit |
52 | stlxr w5, x2, [x1] | 52 | stlxr w5, x2, [x1] |
53 | cbnz w5, 1b | 53 | cbnz w5, 1b |
54 | dmb ish | ||
54 | and x0, x0, #1 | 55 | and x0, x0, #1 |
55 | 3: ret | 56 | 3: ret |
56 | ENDPROC(\name ) | 57 | ENDPROC(\name ) |
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 45b5ab54c9ee..fbd76785c5db 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c | |||
@@ -45,6 +45,7 @@ static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size, | |||
45 | if (IS_ENABLED(CONFIG_DMA_CMA)) { | 45 | if (IS_ENABLED(CONFIG_DMA_CMA)) { |
46 | struct page *page; | 46 | struct page *page; |
47 | 47 | ||
48 | size = PAGE_ALIGN(size); | ||
48 | page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, | 49 | page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, |
49 | get_order(size)); | 50 | get_order(size)); |
50 | if (!page) | 51 | if (!page) |
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index f557ebbe7013..f8dc7e8fce6f 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
@@ -203,10 +203,18 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, | |||
203 | do { | 203 | do { |
204 | next = pmd_addr_end(addr, end); | 204 | next = pmd_addr_end(addr, end); |
205 | /* try section mapping first */ | 205 | /* try section mapping first */ |
206 | if (((addr | next | phys) & ~SECTION_MASK) == 0) | 206 | if (((addr | next | phys) & ~SECTION_MASK) == 0) { |
207 | pmd_t old_pmd =*pmd; | ||
207 | set_pmd(pmd, __pmd(phys | prot_sect_kernel)); | 208 | set_pmd(pmd, __pmd(phys | prot_sect_kernel)); |
208 | else | 209 | /* |
210 | * Check for previous table entries created during | ||
211 | * boot (__create_page_tables) and flush them. | ||
212 | */ | ||
213 | if (!pmd_none(old_pmd)) | ||
214 | flush_tlb_all(); | ||
215 | } else { | ||
209 | alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys)); | 216 | alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys)); |
217 | } | ||
210 | phys += next - addr; | 218 | phys += next - addr; |
211 | } while (pmd++, addr = next, addr != end); | 219 | } while (pmd++, addr = next, addr != end); |
212 | } | 220 | } |
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c index 7083cdada657..62c6101df260 100644 --- a/arch/arm64/mm/pgd.c +++ b/arch/arm64/mm/pgd.c | |||
@@ -32,17 +32,10 @@ | |||
32 | 32 | ||
33 | pgd_t *pgd_alloc(struct mm_struct *mm) | 33 | pgd_t *pgd_alloc(struct mm_struct *mm) |
34 | { | 34 | { |
35 | pgd_t *new_pgd; | ||
36 | |||
37 | if (PGD_SIZE == PAGE_SIZE) | 35 | if (PGD_SIZE == PAGE_SIZE) |
38 | new_pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL); | 36 | return (pgd_t *)get_zeroed_page(GFP_KERNEL); |
39 | else | 37 | else |
40 | new_pgd = kzalloc(PGD_SIZE, GFP_KERNEL); | 38 | return kzalloc(PGD_SIZE, GFP_KERNEL); |
41 | |||
42 | if (!new_pgd) | ||
43 | return NULL; | ||
44 | |||
45 | return new_pgd; | ||
46 | } | 39 | } |
47 | 40 | ||
48 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) | 41 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) |
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index afd45e0d552e..ae763d8bf55a 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | 12 | ||
13 | 13 | ||
14 | #define NR_syscalls 312 /* length of syscall table */ | 14 | #define NR_syscalls 314 /* length of syscall table */ |
15 | 15 | ||
16 | /* | 16 | /* |
17 | * The following defines stop scripts/checksyscalls.sh from complaining about | 17 | * The following defines stop scripts/checksyscalls.sh from complaining about |
diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h index 34fd6fe46da1..715e85f858de 100644 --- a/arch/ia64/include/uapi/asm/unistd.h +++ b/arch/ia64/include/uapi/asm/unistd.h | |||
@@ -325,5 +325,7 @@ | |||
325 | #define __NR_process_vm_writev 1333 | 325 | #define __NR_process_vm_writev 1333 |
326 | #define __NR_accept4 1334 | 326 | #define __NR_accept4 1334 |
327 | #define __NR_finit_module 1335 | 327 | #define __NR_finit_module 1335 |
328 | #define __NR_sched_setattr 1336 | ||
329 | #define __NR_sched_getattr 1337 | ||
328 | 330 | ||
329 | #endif /* _UAPI_ASM_IA64_UNISTD_H */ | 331 | #endif /* _UAPI_ASM_IA64_UNISTD_H */ |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index ddea607f948a..fa8d61a312a7 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1773,6 +1773,8 @@ sys_call_table: | |||
1773 | data8 sys_process_vm_writev | 1773 | data8 sys_process_vm_writev |
1774 | data8 sys_accept4 | 1774 | data8 sys_accept4 |
1775 | data8 sys_finit_module // 1335 | 1775 | data8 sys_finit_module // 1335 |
1776 | data8 sys_sched_setattr | ||
1777 | data8 sys_sched_getattr | ||
1776 | 1778 | ||
1777 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1779 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
1778 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ | 1780 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ |
diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c index 11f3ad20321c..5483906e0f86 100644 --- a/arch/mips/alchemy/devboards/db1000.c +++ b/arch/mips/alchemy/devboards/db1000.c | |||
@@ -534,13 +534,10 @@ static int __init db1000_dev_init(void) | |||
534 | s0 = AU1100_GPIO1_INT; | 534 | s0 = AU1100_GPIO1_INT; |
535 | s1 = AU1100_GPIO4_INT; | 535 | s1 = AU1100_GPIO4_INT; |
536 | 536 | ||
537 | gpio_request(19, "sd0_cd"); | ||
538 | gpio_request(20, "sd1_cd"); | ||
537 | gpio_direction_input(19); /* sd0 cd# */ | 539 | gpio_direction_input(19); /* sd0 cd# */ |
538 | gpio_direction_input(20); /* sd1 cd# */ | 540 | gpio_direction_input(20); /* sd1 cd# */ |
539 | gpio_direction_input(21); /* touch pendown# */ | ||
540 | gpio_direction_input(207); /* SPI MISO */ | ||
541 | gpio_direction_output(208, 0); /* SPI MOSI */ | ||
542 | gpio_direction_output(209, 1); /* SPI SCK */ | ||
543 | gpio_direction_output(210, 1); /* SPI CS# */ | ||
544 | 541 | ||
545 | /* spi_gpio on SSI0 pins */ | 542 | /* spi_gpio on SSI0 pins */ |
546 | pfc = __raw_readl((void __iomem *)SYS_PINFUNC); | 543 | pfc = __raw_readl((void __iomem *)SYS_PINFUNC); |
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index cfe092fc720d..6b9749540edf 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h | |||
@@ -74,6 +74,8 @@ static inline int __enable_fpu(enum fpu_mode mode) | |||
74 | default: | 74 | default: |
75 | BUG(); | 75 | BUG(); |
76 | } | 76 | } |
77 | |||
78 | return SIGFPE; | ||
77 | } | 79 | } |
78 | 80 | ||
79 | #define __disable_fpu() \ | 81 | #define __disable_fpu() \ |
diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h index 1dee279f9665..d6e154a9e6a5 100644 --- a/arch/mips/include/uapi/asm/unistd.h +++ b/arch/mips/include/uapi/asm/unistd.h | |||
@@ -369,16 +369,18 @@ | |||
369 | #define __NR_process_vm_writev (__NR_Linux + 346) | 369 | #define __NR_process_vm_writev (__NR_Linux + 346) |
370 | #define __NR_kcmp (__NR_Linux + 347) | 370 | #define __NR_kcmp (__NR_Linux + 347) |
371 | #define __NR_finit_module (__NR_Linux + 348) | 371 | #define __NR_finit_module (__NR_Linux + 348) |
372 | #define __NR_sched_setattr (__NR_Linux + 349) | ||
373 | #define __NR_sched_getattr (__NR_Linux + 350) | ||
372 | 374 | ||
373 | /* | 375 | /* |
374 | * Offset of the last Linux o32 flavoured syscall | 376 | * Offset of the last Linux o32 flavoured syscall |
375 | */ | 377 | */ |
376 | #define __NR_Linux_syscalls 348 | 378 | #define __NR_Linux_syscalls 350 |
377 | 379 | ||
378 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 380 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
379 | 381 | ||
380 | #define __NR_O32_Linux 4000 | 382 | #define __NR_O32_Linux 4000 |
381 | #define __NR_O32_Linux_syscalls 348 | 383 | #define __NR_O32_Linux_syscalls 350 |
382 | 384 | ||
383 | #if _MIPS_SIM == _MIPS_SIM_ABI64 | 385 | #if _MIPS_SIM == _MIPS_SIM_ABI64 |
384 | 386 | ||
@@ -695,16 +697,18 @@ | |||
695 | #define __NR_kcmp (__NR_Linux + 306) | 697 | #define __NR_kcmp (__NR_Linux + 306) |
696 | #define __NR_finit_module (__NR_Linux + 307) | 698 | #define __NR_finit_module (__NR_Linux + 307) |
697 | #define __NR_getdents64 (__NR_Linux + 308) | 699 | #define __NR_getdents64 (__NR_Linux + 308) |
700 | #define __NR_sched_setattr (__NR_Linux + 309) | ||
701 | #define __NR_sched_getattr (__NR_Linux + 310) | ||
698 | 702 | ||
699 | /* | 703 | /* |
700 | * Offset of the last Linux 64-bit flavoured syscall | 704 | * Offset of the last Linux 64-bit flavoured syscall |
701 | */ | 705 | */ |
702 | #define __NR_Linux_syscalls 308 | 706 | #define __NR_Linux_syscalls 310 |
703 | 707 | ||
704 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ | 708 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ |
705 | 709 | ||
706 | #define __NR_64_Linux 5000 | 710 | #define __NR_64_Linux 5000 |
707 | #define __NR_64_Linux_syscalls 308 | 711 | #define __NR_64_Linux_syscalls 310 |
708 | 712 | ||
709 | #if _MIPS_SIM == _MIPS_SIM_NABI32 | 713 | #if _MIPS_SIM == _MIPS_SIM_NABI32 |
710 | 714 | ||
@@ -1025,15 +1029,17 @@ | |||
1025 | #define __NR_process_vm_writev (__NR_Linux + 310) | 1029 | #define __NR_process_vm_writev (__NR_Linux + 310) |
1026 | #define __NR_kcmp (__NR_Linux + 311) | 1030 | #define __NR_kcmp (__NR_Linux + 311) |
1027 | #define __NR_finit_module (__NR_Linux + 312) | 1031 | #define __NR_finit_module (__NR_Linux + 312) |
1032 | #define __NR_sched_setattr (__NR_Linux + 313) | ||
1033 | #define __NR_sched_getattr (__NR_Linux + 314) | ||
1028 | 1034 | ||
1029 | /* | 1035 | /* |
1030 | * Offset of the last N32 flavoured syscall | 1036 | * Offset of the last N32 flavoured syscall |
1031 | */ | 1037 | */ |
1032 | #define __NR_Linux_syscalls 312 | 1038 | #define __NR_Linux_syscalls 314 |
1033 | 1039 | ||
1034 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ | 1040 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ |
1035 | 1041 | ||
1036 | #define __NR_N32_Linux 6000 | 1042 | #define __NR_N32_Linux 6000 |
1037 | #define __NR_N32_Linux_syscalls 312 | 1043 | #define __NR_N32_Linux_syscalls 314 |
1038 | 1044 | ||
1039 | #endif /* _UAPI_ASM_UNISTD_H */ | 1045 | #endif /* _UAPI_ASM_UNISTD_H */ |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index e8e541b40d86..a5b14f48e1af 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -563,3 +563,5 @@ EXPORT(sys_call_table) | |||
563 | PTR sys_process_vm_writev | 563 | PTR sys_process_vm_writev |
564 | PTR sys_kcmp | 564 | PTR sys_kcmp |
565 | PTR sys_finit_module | 565 | PTR sys_finit_module |
566 | PTR sys_sched_setattr | ||
567 | PTR sys_sched_getattr /* 4350 */ | ||
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 57e3742fec59..b56e254beb15 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -425,4 +425,6 @@ EXPORT(sys_call_table) | |||
425 | PTR sys_kcmp | 425 | PTR sys_kcmp |
426 | PTR sys_finit_module | 426 | PTR sys_finit_module |
427 | PTR sys_getdents64 | 427 | PTR sys_getdents64 |
428 | PTR sys_sched_setattr | ||
429 | PTR sys_sched_getattr /* 5310 */ | ||
428 | .size sys_call_table,.-sys_call_table | 430 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 2f48f5934399..f7e5b72cf481 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -418,4 +418,6 @@ EXPORT(sysn32_call_table) | |||
418 | PTR compat_sys_process_vm_writev /* 6310 */ | 418 | PTR compat_sys_process_vm_writev /* 6310 */ |
419 | PTR sys_kcmp | 419 | PTR sys_kcmp |
420 | PTR sys_finit_module | 420 | PTR sys_finit_module |
421 | PTR sys_sched_setattr | ||
422 | PTR sys_sched_getattr | ||
421 | .size sysn32_call_table,.-sysn32_call_table | 423 | .size sysn32_call_table,.-sysn32_call_table |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index f1acdb429f4f..6788727d91af 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -541,4 +541,6 @@ EXPORT(sys32_call_table) | |||
541 | PTR compat_sys_process_vm_writev | 541 | PTR compat_sys_process_vm_writev |
542 | PTR sys_kcmp | 542 | PTR sys_kcmp |
543 | PTR sys_finit_module | 543 | PTR sys_finit_module |
544 | PTR sys_sched_setattr | ||
545 | PTR sys_sched_getattr /* 4350 */ | ||
544 | .size sys32_call_table,.-sys32_call_table | 546 | .size sys32_call_table,.-sys32_call_table |
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 88d0962de65a..2bedafea3d94 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c | |||
@@ -33,22 +33,9 @@ | |||
33 | 33 | ||
34 | int hpux_execve(struct pt_regs *regs) | 34 | int hpux_execve(struct pt_regs *regs) |
35 | { | 35 | { |
36 | int error; | 36 | return do_execve(getname((const char __user *) regs->gr[26]), |
37 | struct filename *filename; | ||
38 | |||
39 | filename = getname((const char __user *) regs->gr[26]); | ||
40 | error = PTR_ERR(filename); | ||
41 | if (IS_ERR(filename)) | ||
42 | goto out; | ||
43 | |||
44 | error = do_execve(filename->name, | ||
45 | (const char __user *const __user *) regs->gr[25], | 37 | (const char __user *const __user *) regs->gr[25], |
46 | (const char __user *const __user *) regs->gr[24]); | 38 | (const char __user *const __user *) regs->gr[24]); |
47 | |||
48 | putname(filename); | ||
49 | |||
50 | out: | ||
51 | return error; | ||
52 | } | 39 | } |
53 | 40 | ||
54 | struct hpux_dirent { | 41 | struct hpux_dirent { |
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index b3feabd39f31..cf3c0089bef2 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/spinlock.h> | ||
28 | #include "crypt_s390.h" | 29 | #include "crypt_s390.h" |
29 | 30 | ||
30 | #define AES_KEYLEN_128 1 | 31 | #define AES_KEYLEN_128 1 |
@@ -32,6 +33,7 @@ | |||
32 | #define AES_KEYLEN_256 4 | 33 | #define AES_KEYLEN_256 4 |
33 | 34 | ||
34 | static u8 *ctrblk; | 35 | static u8 *ctrblk; |
36 | static DEFINE_SPINLOCK(ctrblk_lock); | ||
35 | static char keylen_flag; | 37 | static char keylen_flag; |
36 | 38 | ||
37 | struct s390_aes_ctx { | 39 | struct s390_aes_ctx { |
@@ -758,43 +760,67 @@ static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | |||
758 | return aes_set_key(tfm, in_key, key_len); | 760 | return aes_set_key(tfm, in_key, key_len); |
759 | } | 761 | } |
760 | 762 | ||
763 | static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes) | ||
764 | { | ||
765 | unsigned int i, n; | ||
766 | |||
767 | /* only use complete blocks, max. PAGE_SIZE */ | ||
768 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(AES_BLOCK_SIZE - 1); | ||
769 | for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) { | ||
770 | memcpy(ctrptr + i, ctrptr + i - AES_BLOCK_SIZE, | ||
771 | AES_BLOCK_SIZE); | ||
772 | crypto_inc(ctrptr + i, AES_BLOCK_SIZE); | ||
773 | } | ||
774 | return n; | ||
775 | } | ||
776 | |||
761 | static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, | 777 | static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, |
762 | struct s390_aes_ctx *sctx, struct blkcipher_walk *walk) | 778 | struct s390_aes_ctx *sctx, struct blkcipher_walk *walk) |
763 | { | 779 | { |
764 | int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE); | 780 | int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE); |
765 | unsigned int i, n, nbytes; | 781 | unsigned int n, nbytes; |
766 | u8 buf[AES_BLOCK_SIZE]; | 782 | u8 buf[AES_BLOCK_SIZE], ctrbuf[AES_BLOCK_SIZE]; |
767 | u8 *out, *in; | 783 | u8 *out, *in, *ctrptr = ctrbuf; |
768 | 784 | ||
769 | if (!walk->nbytes) | 785 | if (!walk->nbytes) |
770 | return ret; | 786 | return ret; |
771 | 787 | ||
772 | memcpy(ctrblk, walk->iv, AES_BLOCK_SIZE); | 788 | if (spin_trylock(&ctrblk_lock)) |
789 | ctrptr = ctrblk; | ||
790 | |||
791 | memcpy(ctrptr, walk->iv, AES_BLOCK_SIZE); | ||
773 | while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { | 792 | while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { |
774 | out = walk->dst.virt.addr; | 793 | out = walk->dst.virt.addr; |
775 | in = walk->src.virt.addr; | 794 | in = walk->src.virt.addr; |
776 | while (nbytes >= AES_BLOCK_SIZE) { | 795 | while (nbytes >= AES_BLOCK_SIZE) { |
777 | /* only use complete blocks, max. PAGE_SIZE */ | 796 | if (ctrptr == ctrblk) |
778 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : | 797 | n = __ctrblk_init(ctrptr, nbytes); |
779 | nbytes & ~(AES_BLOCK_SIZE - 1); | 798 | else |
780 | for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) { | 799 | n = AES_BLOCK_SIZE; |
781 | memcpy(ctrblk + i, ctrblk + i - AES_BLOCK_SIZE, | 800 | ret = crypt_s390_kmctr(func, sctx->key, out, in, |
782 | AES_BLOCK_SIZE); | 801 | n, ctrptr); |
783 | crypto_inc(ctrblk + i, AES_BLOCK_SIZE); | 802 | if (ret < 0 || ret != n) { |
784 | } | 803 | if (ctrptr == ctrblk) |
785 | ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk); | 804 | spin_unlock(&ctrblk_lock); |
786 | if (ret < 0 || ret != n) | ||
787 | return -EIO; | 805 | return -EIO; |
806 | } | ||
788 | if (n > AES_BLOCK_SIZE) | 807 | if (n > AES_BLOCK_SIZE) |
789 | memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE, | 808 | memcpy(ctrptr, ctrptr + n - AES_BLOCK_SIZE, |
790 | AES_BLOCK_SIZE); | 809 | AES_BLOCK_SIZE); |
791 | crypto_inc(ctrblk, AES_BLOCK_SIZE); | 810 | crypto_inc(ctrptr, AES_BLOCK_SIZE); |
792 | out += n; | 811 | out += n; |
793 | in += n; | 812 | in += n; |
794 | nbytes -= n; | 813 | nbytes -= n; |
795 | } | 814 | } |
796 | ret = blkcipher_walk_done(desc, walk, nbytes); | 815 | ret = blkcipher_walk_done(desc, walk, nbytes); |
797 | } | 816 | } |
817 | if (ctrptr == ctrblk) { | ||
818 | if (nbytes) | ||
819 | memcpy(ctrbuf, ctrptr, AES_BLOCK_SIZE); | ||
820 | else | ||
821 | memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE); | ||
822 | spin_unlock(&ctrblk_lock); | ||
823 | } | ||
798 | /* | 824 | /* |
799 | * final block may be < AES_BLOCK_SIZE, copy only nbytes | 825 | * final block may be < AES_BLOCK_SIZE, copy only nbytes |
800 | */ | 826 | */ |
@@ -802,14 +828,15 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, | |||
802 | out = walk->dst.virt.addr; | 828 | out = walk->dst.virt.addr; |
803 | in = walk->src.virt.addr; | 829 | in = walk->src.virt.addr; |
804 | ret = crypt_s390_kmctr(func, sctx->key, buf, in, | 830 | ret = crypt_s390_kmctr(func, sctx->key, buf, in, |
805 | AES_BLOCK_SIZE, ctrblk); | 831 | AES_BLOCK_SIZE, ctrbuf); |
806 | if (ret < 0 || ret != AES_BLOCK_SIZE) | 832 | if (ret < 0 || ret != AES_BLOCK_SIZE) |
807 | return -EIO; | 833 | return -EIO; |
808 | memcpy(out, buf, nbytes); | 834 | memcpy(out, buf, nbytes); |
809 | crypto_inc(ctrblk, AES_BLOCK_SIZE); | 835 | crypto_inc(ctrbuf, AES_BLOCK_SIZE); |
810 | ret = blkcipher_walk_done(desc, walk, 0); | 836 | ret = blkcipher_walk_done(desc, walk, 0); |
837 | memcpy(walk->iv, ctrbuf, AES_BLOCK_SIZE); | ||
811 | } | 838 | } |
812 | memcpy(walk->iv, ctrblk, AES_BLOCK_SIZE); | 839 | |
813 | return ret; | 840 | return ret; |
814 | } | 841 | } |
815 | 842 | ||
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index 200f2a1b599d..0a5aac8a9412 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #define DES3_KEY_SIZE (3 * DES_KEY_SIZE) | 25 | #define DES3_KEY_SIZE (3 * DES_KEY_SIZE) |
26 | 26 | ||
27 | static u8 *ctrblk; | 27 | static u8 *ctrblk; |
28 | static DEFINE_SPINLOCK(ctrblk_lock); | ||
28 | 29 | ||
29 | struct s390_des_ctx { | 30 | struct s390_des_ctx { |
30 | u8 iv[DES_BLOCK_SIZE]; | 31 | u8 iv[DES_BLOCK_SIZE]; |
@@ -105,29 +106,35 @@ static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, | |||
105 | } | 106 | } |
106 | 107 | ||
107 | static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, | 108 | static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, |
108 | u8 *iv, struct blkcipher_walk *walk) | 109 | struct blkcipher_walk *walk) |
109 | { | 110 | { |
111 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
110 | int ret = blkcipher_walk_virt(desc, walk); | 112 | int ret = blkcipher_walk_virt(desc, walk); |
111 | unsigned int nbytes = walk->nbytes; | 113 | unsigned int nbytes = walk->nbytes; |
114 | struct { | ||
115 | u8 iv[DES_BLOCK_SIZE]; | ||
116 | u8 key[DES3_KEY_SIZE]; | ||
117 | } param; | ||
112 | 118 | ||
113 | if (!nbytes) | 119 | if (!nbytes) |
114 | goto out; | 120 | goto out; |
115 | 121 | ||
116 | memcpy(iv, walk->iv, DES_BLOCK_SIZE); | 122 | memcpy(param.iv, walk->iv, DES_BLOCK_SIZE); |
123 | memcpy(param.key, ctx->key, DES3_KEY_SIZE); | ||
117 | do { | 124 | do { |
118 | /* only use complete blocks */ | 125 | /* only use complete blocks */ |
119 | unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); | 126 | unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); |
120 | u8 *out = walk->dst.virt.addr; | 127 | u8 *out = walk->dst.virt.addr; |
121 | u8 *in = walk->src.virt.addr; | 128 | u8 *in = walk->src.virt.addr; |
122 | 129 | ||
123 | ret = crypt_s390_kmc(func, iv, out, in, n); | 130 | ret = crypt_s390_kmc(func, ¶m, out, in, n); |
124 | if (ret < 0 || ret != n) | 131 | if (ret < 0 || ret != n) |
125 | return -EIO; | 132 | return -EIO; |
126 | 133 | ||
127 | nbytes &= DES_BLOCK_SIZE - 1; | 134 | nbytes &= DES_BLOCK_SIZE - 1; |
128 | ret = blkcipher_walk_done(desc, walk, nbytes); | 135 | ret = blkcipher_walk_done(desc, walk, nbytes); |
129 | } while ((nbytes = walk->nbytes)); | 136 | } while ((nbytes = walk->nbytes)); |
130 | memcpy(walk->iv, iv, DES_BLOCK_SIZE); | 137 | memcpy(walk->iv, param.iv, DES_BLOCK_SIZE); |
131 | 138 | ||
132 | out: | 139 | out: |
133 | return ret; | 140 | return ret; |
@@ -179,22 +186,20 @@ static int cbc_des_encrypt(struct blkcipher_desc *desc, | |||
179 | struct scatterlist *dst, struct scatterlist *src, | 186 | struct scatterlist *dst, struct scatterlist *src, |
180 | unsigned int nbytes) | 187 | unsigned int nbytes) |
181 | { | 188 | { |
182 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
183 | struct blkcipher_walk walk; | 189 | struct blkcipher_walk walk; |
184 | 190 | ||
185 | blkcipher_walk_init(&walk, dst, src, nbytes); | 191 | blkcipher_walk_init(&walk, dst, src, nbytes); |
186 | return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, ctx->iv, &walk); | 192 | return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, &walk); |
187 | } | 193 | } |
188 | 194 | ||
189 | static int cbc_des_decrypt(struct blkcipher_desc *desc, | 195 | static int cbc_des_decrypt(struct blkcipher_desc *desc, |
190 | struct scatterlist *dst, struct scatterlist *src, | 196 | struct scatterlist *dst, struct scatterlist *src, |
191 | unsigned int nbytes) | 197 | unsigned int nbytes) |
192 | { | 198 | { |
193 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
194 | struct blkcipher_walk walk; | 199 | struct blkcipher_walk walk; |
195 | 200 | ||
196 | blkcipher_walk_init(&walk, dst, src, nbytes); | 201 | blkcipher_walk_init(&walk, dst, src, nbytes); |
197 | return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, ctx->iv, &walk); | 202 | return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, &walk); |
198 | } | 203 | } |
199 | 204 | ||
200 | static struct crypto_alg cbc_des_alg = { | 205 | static struct crypto_alg cbc_des_alg = { |
@@ -327,22 +332,20 @@ static int cbc_des3_encrypt(struct blkcipher_desc *desc, | |||
327 | struct scatterlist *dst, struct scatterlist *src, | 332 | struct scatterlist *dst, struct scatterlist *src, |
328 | unsigned int nbytes) | 333 | unsigned int nbytes) |
329 | { | 334 | { |
330 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
331 | struct blkcipher_walk walk; | 335 | struct blkcipher_walk walk; |
332 | 336 | ||
333 | blkcipher_walk_init(&walk, dst, src, nbytes); | 337 | blkcipher_walk_init(&walk, dst, src, nbytes); |
334 | return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, ctx->iv, &walk); | 338 | return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, &walk); |
335 | } | 339 | } |
336 | 340 | ||
337 | static int cbc_des3_decrypt(struct blkcipher_desc *desc, | 341 | static int cbc_des3_decrypt(struct blkcipher_desc *desc, |
338 | struct scatterlist *dst, struct scatterlist *src, | 342 | struct scatterlist *dst, struct scatterlist *src, |
339 | unsigned int nbytes) | 343 | unsigned int nbytes) |
340 | { | 344 | { |
341 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
342 | struct blkcipher_walk walk; | 345 | struct blkcipher_walk walk; |
343 | 346 | ||
344 | blkcipher_walk_init(&walk, dst, src, nbytes); | 347 | blkcipher_walk_init(&walk, dst, src, nbytes); |
345 | return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, ctx->iv, &walk); | 348 | return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, &walk); |
346 | } | 349 | } |
347 | 350 | ||
348 | static struct crypto_alg cbc_des3_alg = { | 351 | static struct crypto_alg cbc_des3_alg = { |
@@ -366,54 +369,80 @@ static struct crypto_alg cbc_des3_alg = { | |||
366 | } | 369 | } |
367 | }; | 370 | }; |
368 | 371 | ||
372 | static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes) | ||
373 | { | ||
374 | unsigned int i, n; | ||
375 | |||
376 | /* align to block size, max. PAGE_SIZE */ | ||
377 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(DES_BLOCK_SIZE - 1); | ||
378 | for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { | ||
379 | memcpy(ctrptr + i, ctrptr + i - DES_BLOCK_SIZE, DES_BLOCK_SIZE); | ||
380 | crypto_inc(ctrptr + i, DES_BLOCK_SIZE); | ||
381 | } | ||
382 | return n; | ||
383 | } | ||
384 | |||
369 | static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, | 385 | static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, |
370 | struct s390_des_ctx *ctx, struct blkcipher_walk *walk) | 386 | struct s390_des_ctx *ctx, |
387 | struct blkcipher_walk *walk) | ||
371 | { | 388 | { |
372 | int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE); | 389 | int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE); |
373 | unsigned int i, n, nbytes; | 390 | unsigned int n, nbytes; |
374 | u8 buf[DES_BLOCK_SIZE]; | 391 | u8 buf[DES_BLOCK_SIZE], ctrbuf[DES_BLOCK_SIZE]; |
375 | u8 *out, *in; | 392 | u8 *out, *in, *ctrptr = ctrbuf; |
393 | |||
394 | if (!walk->nbytes) | ||
395 | return ret; | ||
376 | 396 | ||
377 | memcpy(ctrblk, walk->iv, DES_BLOCK_SIZE); | 397 | if (spin_trylock(&ctrblk_lock)) |
398 | ctrptr = ctrblk; | ||
399 | |||
400 | memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE); | ||
378 | while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { | 401 | while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { |
379 | out = walk->dst.virt.addr; | 402 | out = walk->dst.virt.addr; |
380 | in = walk->src.virt.addr; | 403 | in = walk->src.virt.addr; |
381 | while (nbytes >= DES_BLOCK_SIZE) { | 404 | while (nbytes >= DES_BLOCK_SIZE) { |
382 | /* align to block size, max. PAGE_SIZE */ | 405 | if (ctrptr == ctrblk) |
383 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : | 406 | n = __ctrblk_init(ctrptr, nbytes); |
384 | nbytes & ~(DES_BLOCK_SIZE - 1); | 407 | else |
385 | for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { | 408 | n = DES_BLOCK_SIZE; |
386 | memcpy(ctrblk + i, ctrblk + i - DES_BLOCK_SIZE, | 409 | ret = crypt_s390_kmctr(func, ctx->key, out, in, |
387 | DES_BLOCK_SIZE); | 410 | n, ctrptr); |
388 | crypto_inc(ctrblk + i, DES_BLOCK_SIZE); | 411 | if (ret < 0 || ret != n) { |
389 | } | 412 | if (ctrptr == ctrblk) |
390 | ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk); | 413 | spin_unlock(&ctrblk_lock); |
391 | if (ret < 0 || ret != n) | ||
392 | return -EIO; | 414 | return -EIO; |
415 | } | ||
393 | if (n > DES_BLOCK_SIZE) | 416 | if (n > DES_BLOCK_SIZE) |
394 | memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE, | 417 | memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE, |
395 | DES_BLOCK_SIZE); | 418 | DES_BLOCK_SIZE); |
396 | crypto_inc(ctrblk, DES_BLOCK_SIZE); | 419 | crypto_inc(ctrptr, DES_BLOCK_SIZE); |
397 | out += n; | 420 | out += n; |
398 | in += n; | 421 | in += n; |
399 | nbytes -= n; | 422 | nbytes -= n; |
400 | } | 423 | } |
401 | ret = blkcipher_walk_done(desc, walk, nbytes); | 424 | ret = blkcipher_walk_done(desc, walk, nbytes); |
402 | } | 425 | } |
403 | 426 | if (ctrptr == ctrblk) { | |
427 | if (nbytes) | ||
428 | memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE); | ||
429 | else | ||
430 | memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); | ||
431 | spin_unlock(&ctrblk_lock); | ||
432 | } | ||
404 | /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ | 433 | /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ |
405 | if (nbytes) { | 434 | if (nbytes) { |
406 | out = walk->dst.virt.addr; | 435 | out = walk->dst.virt.addr; |
407 | in = walk->src.virt.addr; | 436 | in = walk->src.virt.addr; |
408 | ret = crypt_s390_kmctr(func, ctx->key, buf, in, | 437 | ret = crypt_s390_kmctr(func, ctx->key, buf, in, |
409 | DES_BLOCK_SIZE, ctrblk); | 438 | DES_BLOCK_SIZE, ctrbuf); |
410 | if (ret < 0 || ret != DES_BLOCK_SIZE) | 439 | if (ret < 0 || ret != DES_BLOCK_SIZE) |
411 | return -EIO; | 440 | return -EIO; |
412 | memcpy(out, buf, nbytes); | 441 | memcpy(out, buf, nbytes); |
413 | crypto_inc(ctrblk, DES_BLOCK_SIZE); | 442 | crypto_inc(ctrbuf, DES_BLOCK_SIZE); |
414 | ret = blkcipher_walk_done(desc, walk, 0); | 443 | ret = blkcipher_walk_done(desc, walk, 0); |
444 | memcpy(walk->iv, ctrbuf, DES_BLOCK_SIZE); | ||
415 | } | 445 | } |
416 | memcpy(walk->iv, ctrblk, DES_BLOCK_SIZE); | ||
417 | return ret; | 446 | return ret; |
418 | } | 447 | } |
419 | 448 | ||
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 0f3621ed1db6..321a52ccf63a 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
@@ -184,6 +184,7 @@ config HAVE_MMIOTRACE_SUPPORT | |||
184 | config X86_DECODER_SELFTEST | 184 | config X86_DECODER_SELFTEST |
185 | bool "x86 instruction decoder selftest" | 185 | bool "x86 instruction decoder selftest" |
186 | depends on DEBUG_KERNEL && KPROBES | 186 | depends on DEBUG_KERNEL && KPROBES |
187 | depends on !COMPILE_TEST | ||
187 | ---help--- | 188 | ---help--- |
188 | Perform x86 instruction decoder selftests at build time. | 189 | Perform x86 instruction decoder selftests at build time. |
189 | This option is useful for checking the sanity of x86 instruction | 190 | This option is useful for checking the sanity of x86 instruction |
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 787e1bb5aafc..3e276eb23d1b 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h | |||
@@ -52,8 +52,7 @@ extern unsigned long set_phys_range_identity(unsigned long pfn_s, | |||
52 | extern int m2p_add_override(unsigned long mfn, struct page *page, | 52 | extern int m2p_add_override(unsigned long mfn, struct page *page, |
53 | struct gnttab_map_grant_ref *kmap_op); | 53 | struct gnttab_map_grant_ref *kmap_op); |
54 | extern int m2p_remove_override(struct page *page, | 54 | extern int m2p_remove_override(struct page *page, |
55 | struct gnttab_map_grant_ref *kmap_op, | 55 | struct gnttab_map_grant_ref *kmap_op); |
56 | unsigned long mfn); | ||
57 | extern struct page *m2p_find_override(unsigned long mfn); | 56 | extern struct page *m2p_find_override(unsigned long mfn); |
58 | extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); | 57 | extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); |
59 | 58 | ||
@@ -122,7 +121,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) | |||
122 | pfn = m2p_find_override_pfn(mfn, ~0); | 121 | pfn = m2p_find_override_pfn(mfn, ~0); |
123 | } | 122 | } |
124 | 123 | ||
125 | /* | 124 | /* |
126 | * pfn is ~0 if there are no entries in the m2p for mfn or if the | 125 | * pfn is ~0 if there are no entries in the m2p for mfn or if the |
127 | * entry doesn't map back to the mfn and m2p_override doesn't have a | 126 | * entry doesn't map back to the mfn and m2p_override doesn't have a |
128 | * valid entry for it. | 127 | * valid entry for it. |
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 81b2750f3666..27aa0455fab3 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c | |||
@@ -493,14 +493,6 @@ static int __init numa_register_memblks(struct numa_meminfo *mi) | |||
493 | struct numa_memblk *mb = &mi->blk[i]; | 493 | struct numa_memblk *mb = &mi->blk[i]; |
494 | memblock_set_node(mb->start, mb->end - mb->start, | 494 | memblock_set_node(mb->start, mb->end - mb->start, |
495 | &memblock.memory, mb->nid); | 495 | &memblock.memory, mb->nid); |
496 | |||
497 | /* | ||
498 | * At this time, all memory regions reserved by memblock are | ||
499 | * used by the kernel. Set the nid in memblock.reserved will | ||
500 | * mark out all the nodes the kernel resides in. | ||
501 | */ | ||
502 | memblock_set_node(mb->start, mb->end - mb->start, | ||
503 | &memblock.reserved, mb->nid); | ||
504 | } | 496 | } |
505 | 497 | ||
506 | /* | 498 | /* |
@@ -565,10 +557,21 @@ static void __init numa_init_array(void) | |||
565 | static void __init numa_clear_kernel_node_hotplug(void) | 557 | static void __init numa_clear_kernel_node_hotplug(void) |
566 | { | 558 | { |
567 | int i, nid; | 559 | int i, nid; |
568 | nodemask_t numa_kernel_nodes; | 560 | nodemask_t numa_kernel_nodes = NODE_MASK_NONE; |
569 | unsigned long start, end; | 561 | unsigned long start, end; |
570 | struct memblock_type *type = &memblock.reserved; | 562 | struct memblock_type *type = &memblock.reserved; |
571 | 563 | ||
564 | /* | ||
565 | * At this time, all memory regions reserved by memblock are | ||
566 | * used by the kernel. Set the nid in memblock.reserved will | ||
567 | * mark out all the nodes the kernel resides in. | ||
568 | */ | ||
569 | for (i = 0; i < numa_meminfo.nr_blks; i++) { | ||
570 | struct numa_memblk *mb = &numa_meminfo.blk[i]; | ||
571 | memblock_set_node(mb->start, mb->end - mb->start, | ||
572 | &memblock.reserved, mb->nid); | ||
573 | } | ||
574 | |||
572 | /* Mark all kernel nodes. */ | 575 | /* Mark all kernel nodes. */ |
573 | for (i = 0; i < type->cnt; i++) | 576 | for (i = 0; i < type->cnt; i++) |
574 | node_set(type->regions[i].nid, numa_kernel_nodes); | 577 | node_set(type->regions[i].nid, numa_kernel_nodes); |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index a4d7b647867f..201d09a7c46b 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1473,6 +1473,18 @@ static void xen_pvh_set_cr_flags(int cpu) | |||
1473 | * X86_CR0_TS, X86_CR0_PE, X86_CR0_ET are set by Xen for HVM guests | 1473 | * X86_CR0_TS, X86_CR0_PE, X86_CR0_ET are set by Xen for HVM guests |
1474 | * (which PVH shared codepaths), while X86_CR0_PG is for PVH. */ | 1474 | * (which PVH shared codepaths), while X86_CR0_PG is for PVH. */ |
1475 | write_cr0(read_cr0() | X86_CR0_MP | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM); | 1475 | write_cr0(read_cr0() | X86_CR0_MP | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM); |
1476 | |||
1477 | if (!cpu) | ||
1478 | return; | ||
1479 | /* | ||
1480 | * For BSP, PSE PGE are set in probe_page_size_mask(), for APs | ||
1481 | * set them here. For all, OSFXSR OSXMMEXCPT are set in fpu_init. | ||
1482 | */ | ||
1483 | if (cpu_has_pse) | ||
1484 | set_in_cr4(X86_CR4_PSE); | ||
1485 | |||
1486 | if (cpu_has_pge) | ||
1487 | set_in_cr4(X86_CR4_PGE); | ||
1476 | } | 1488 | } |
1477 | 1489 | ||
1478 | /* | 1490 | /* |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 8009acbe41e4..696c694986d0 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -899,6 +899,13 @@ int m2p_add_override(unsigned long mfn, struct page *page, | |||
899 | "m2p_add_override: pfn %lx not mapped", pfn)) | 899 | "m2p_add_override: pfn %lx not mapped", pfn)) |
900 | return -EINVAL; | 900 | return -EINVAL; |
901 | } | 901 | } |
902 | WARN_ON(PagePrivate(page)); | ||
903 | SetPagePrivate(page); | ||
904 | set_page_private(page, mfn); | ||
905 | page->index = pfn_to_mfn(pfn); | ||
906 | |||
907 | if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) | ||
908 | return -ENOMEM; | ||
902 | 909 | ||
903 | if (kmap_op != NULL) { | 910 | if (kmap_op != NULL) { |
904 | if (!PageHighMem(page)) { | 911 | if (!PageHighMem(page)) { |
@@ -937,16 +944,19 @@ int m2p_add_override(unsigned long mfn, struct page *page, | |||
937 | } | 944 | } |
938 | EXPORT_SYMBOL_GPL(m2p_add_override); | 945 | EXPORT_SYMBOL_GPL(m2p_add_override); |
939 | int m2p_remove_override(struct page *page, | 946 | int m2p_remove_override(struct page *page, |
940 | struct gnttab_map_grant_ref *kmap_op, | 947 | struct gnttab_map_grant_ref *kmap_op) |
941 | unsigned long mfn) | ||
942 | { | 948 | { |
943 | unsigned long flags; | 949 | unsigned long flags; |
950 | unsigned long mfn; | ||
944 | unsigned long pfn; | 951 | unsigned long pfn; |
945 | unsigned long uninitialized_var(address); | 952 | unsigned long uninitialized_var(address); |
946 | unsigned level; | 953 | unsigned level; |
947 | pte_t *ptep = NULL; | 954 | pte_t *ptep = NULL; |
948 | 955 | ||
949 | pfn = page_to_pfn(page); | 956 | pfn = page_to_pfn(page); |
957 | mfn = get_phys_to_machine(pfn); | ||
958 | if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) | ||
959 | return -EINVAL; | ||
950 | 960 | ||
951 | if (!PageHighMem(page)) { | 961 | if (!PageHighMem(page)) { |
952 | address = (unsigned long)__va(pfn << PAGE_SHIFT); | 962 | address = (unsigned long)__va(pfn << PAGE_SHIFT); |
@@ -960,7 +970,10 @@ int m2p_remove_override(struct page *page, | |||
960 | spin_lock_irqsave(&m2p_override_lock, flags); | 970 | spin_lock_irqsave(&m2p_override_lock, flags); |
961 | list_del(&page->lru); | 971 | list_del(&page->lru); |
962 | spin_unlock_irqrestore(&m2p_override_lock, flags); | 972 | spin_unlock_irqrestore(&m2p_override_lock, flags); |
973 | WARN_ON(!PagePrivate(page)); | ||
974 | ClearPagePrivate(page); | ||
963 | 975 | ||
976 | set_phys_to_machine(pfn, page->index); | ||
964 | if (kmap_op != NULL) { | 977 | if (kmap_op != NULL) { |
965 | if (!PageHighMem(page)) { | 978 | if (!PageHighMem(page)) { |
966 | struct multicall_space mcs; | 979 | struct multicall_space mcs; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 470e7542bf31..018a42883706 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -549,7 +549,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
549 | { | 549 | { |
550 | unsigned long x; | 550 | unsigned long x; |
551 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); | 551 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); |
552 | if (sscanf(buf, "%ld\n", &x) == 1) | 552 | if (sscanf(buf, "%lu\n", &x) == 1) |
553 | battery->alarm = x/1000; | 553 | battery->alarm = x/1000; |
554 | if (acpi_battery_present(battery)) | 554 | if (acpi_battery_present(battery)) |
555 | acpi_battery_set_alarm(battery); | 555 | acpi_battery_set_alarm(battery); |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 50fe34ffe932..75c28eae8860 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -60,7 +60,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
60 | seq_printf(seq, "%c%-8s %s:%s\n", | 60 | seq_printf(seq, "%c%-8s %s:%s\n", |
61 | dev->wakeup.flags.run_wake ? '*' : ' ', | 61 | dev->wakeup.flags.run_wake ? '*' : ' ', |
62 | (device_may_wakeup(&dev->dev) || | 62 | (device_may_wakeup(&dev->dev) || |
63 | (ldev && device_may_wakeup(ldev))) ? | 63 | device_may_wakeup(ldev)) ? |
64 | "enabled" : "disabled", | 64 | "enabled" : "disabled", |
65 | ldev->bus ? ldev->bus->name : | 65 | ldev->bus ? ldev->bus->name : |
66 | "no-bus", dev_name(ldev)); | 66 | "no-bus", dev_name(ldev)); |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7384158c7f87..57b053f424d1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -484,7 +484,6 @@ static void acpi_device_hotplug(void *data, u32 src) | |||
484 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | 484 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) |
485 | { | 485 | { |
486 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 486 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
487 | struct acpi_scan_handler *handler = data; | ||
488 | struct acpi_device *adev; | 487 | struct acpi_device *adev; |
489 | acpi_status status; | 488 | acpi_status status; |
490 | 489 | ||
@@ -500,7 +499,10 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
500 | break; | 499 | break; |
501 | case ACPI_NOTIFY_EJECT_REQUEST: | 500 | case ACPI_NOTIFY_EJECT_REQUEST: |
502 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); | 501 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); |
503 | if (!handler->hotplug.enabled) { | 502 | if (!adev->handler) |
503 | goto err_out; | ||
504 | |||
505 | if (!adev->handler->hotplug.enabled) { | ||
504 | acpi_handle_err(handle, "Eject disabled\n"); | 506 | acpi_handle_err(handle, "Eject disabled\n"); |
505 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | 507 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; |
506 | goto err_out; | 508 | goto err_out; |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 0347a37eb438..85e3b612bdc0 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -99,10 +99,6 @@ acpi_extract_package(union acpi_object *package, | |||
99 | 99 | ||
100 | union acpi_object *element = &(package->package.elements[i]); | 100 | union acpi_object *element = &(package->package.elements[i]); |
101 | 101 | ||
102 | if (!element) { | ||
103 | return AE_BAD_DATA; | ||
104 | } | ||
105 | |||
106 | switch (element->type) { | 102 | switch (element->type) { |
107 | 103 | ||
108 | case ACPI_TYPE_INTEGER: | 104 | case ACPI_TYPE_INTEGER: |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index f0447d3daf2c..a697b77b8865 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -170,6 +170,14 @@ static struct dmi_system_id video_detect_dmi_table[] = { | |||
170 | }, | 170 | }, |
171 | { | 171 | { |
172 | .callback = video_detect_force_vendor, | 172 | .callback = video_detect_force_vendor, |
173 | .ident = "HP EliteBook Revolve 810", | ||
174 | .matches = { | ||
175 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
176 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook Revolve 810 G1"), | ||
177 | }, | ||
178 | }, | ||
179 | { | ||
180 | .callback = video_detect_force_vendor, | ||
173 | .ident = "Lenovo Yoga 13", | 181 | .ident = "Lenovo Yoga 13", |
174 | .matches = { | 182 | .matches = { |
175 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 183 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 1f14ac403945..51824d1f23ea 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #define NVME_Q_DEPTH 1024 | 46 | #define NVME_Q_DEPTH 1024 |
47 | #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) | 47 | #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) |
48 | #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) | 48 | #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) |
49 | #define NVME_MINORS 64 | ||
50 | #define ADMIN_TIMEOUT (60 * HZ) | 49 | #define ADMIN_TIMEOUT (60 * HZ) |
51 | 50 | ||
52 | static int nvme_major; | 51 | static int nvme_major; |
@@ -58,6 +57,17 @@ module_param(use_threaded_interrupts, int, 0); | |||
58 | static DEFINE_SPINLOCK(dev_list_lock); | 57 | static DEFINE_SPINLOCK(dev_list_lock); |
59 | static LIST_HEAD(dev_list); | 58 | static LIST_HEAD(dev_list); |
60 | static struct task_struct *nvme_thread; | 59 | static struct task_struct *nvme_thread; |
60 | static struct workqueue_struct *nvme_workq; | ||
61 | |||
62 | static void nvme_reset_failed_dev(struct work_struct *ws); | ||
63 | |||
64 | struct async_cmd_info { | ||
65 | struct kthread_work work; | ||
66 | struct kthread_worker *worker; | ||
67 | u32 result; | ||
68 | int status; | ||
69 | void *ctx; | ||
70 | }; | ||
61 | 71 | ||
62 | /* | 72 | /* |
63 | * An NVM Express queue. Each device has at least two (one for admin | 73 | * An NVM Express queue. Each device has at least two (one for admin |
@@ -66,6 +76,7 @@ static struct task_struct *nvme_thread; | |||
66 | struct nvme_queue { | 76 | struct nvme_queue { |
67 | struct device *q_dmadev; | 77 | struct device *q_dmadev; |
68 | struct nvme_dev *dev; | 78 | struct nvme_dev *dev; |
79 | char irqname[24]; /* nvme4294967295-65535\0 */ | ||
69 | spinlock_t q_lock; | 80 | spinlock_t q_lock; |
70 | struct nvme_command *sq_cmds; | 81 | struct nvme_command *sq_cmds; |
71 | volatile struct nvme_completion *cqes; | 82 | volatile struct nvme_completion *cqes; |
@@ -80,9 +91,11 @@ struct nvme_queue { | |||
80 | u16 sq_head; | 91 | u16 sq_head; |
81 | u16 sq_tail; | 92 | u16 sq_tail; |
82 | u16 cq_head; | 93 | u16 cq_head; |
94 | u16 qid; | ||
83 | u8 cq_phase; | 95 | u8 cq_phase; |
84 | u8 cqe_seen; | 96 | u8 cqe_seen; |
85 | u8 q_suspended; | 97 | u8 q_suspended; |
98 | struct async_cmd_info cmdinfo; | ||
86 | unsigned long cmdid_data[]; | 99 | unsigned long cmdid_data[]; |
87 | }; | 100 | }; |
88 | 101 | ||
@@ -97,6 +110,7 @@ static inline void _nvme_check_size(void) | |||
97 | BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64); | 110 | BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64); |
98 | BUILD_BUG_ON(sizeof(struct nvme_features) != 64); | 111 | BUILD_BUG_ON(sizeof(struct nvme_features) != 64); |
99 | BUILD_BUG_ON(sizeof(struct nvme_format_cmd) != 64); | 112 | BUILD_BUG_ON(sizeof(struct nvme_format_cmd) != 64); |
113 | BUILD_BUG_ON(sizeof(struct nvme_abort_cmd) != 64); | ||
100 | BUILD_BUG_ON(sizeof(struct nvme_command) != 64); | 114 | BUILD_BUG_ON(sizeof(struct nvme_command) != 64); |
101 | BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096); | 115 | BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096); |
102 | BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096); | 116 | BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096); |
@@ -111,6 +125,7 @@ struct nvme_cmd_info { | |||
111 | nvme_completion_fn fn; | 125 | nvme_completion_fn fn; |
112 | void *ctx; | 126 | void *ctx; |
113 | unsigned long timeout; | 127 | unsigned long timeout; |
128 | int aborted; | ||
114 | }; | 129 | }; |
115 | 130 | ||
116 | static struct nvme_cmd_info *nvme_cmd_info(struct nvme_queue *nvmeq) | 131 | static struct nvme_cmd_info *nvme_cmd_info(struct nvme_queue *nvmeq) |
@@ -154,6 +169,7 @@ static int alloc_cmdid(struct nvme_queue *nvmeq, void *ctx, | |||
154 | info[cmdid].fn = handler; | 169 | info[cmdid].fn = handler; |
155 | info[cmdid].ctx = ctx; | 170 | info[cmdid].ctx = ctx; |
156 | info[cmdid].timeout = jiffies + timeout; | 171 | info[cmdid].timeout = jiffies + timeout; |
172 | info[cmdid].aborted = 0; | ||
157 | return cmdid; | 173 | return cmdid; |
158 | } | 174 | } |
159 | 175 | ||
@@ -172,6 +188,7 @@ static int alloc_cmdid_killable(struct nvme_queue *nvmeq, void *ctx, | |||
172 | #define CMD_CTX_COMPLETED (0x310 + CMD_CTX_BASE) | 188 | #define CMD_CTX_COMPLETED (0x310 + CMD_CTX_BASE) |
173 | #define CMD_CTX_INVALID (0x314 + CMD_CTX_BASE) | 189 | #define CMD_CTX_INVALID (0x314 + CMD_CTX_BASE) |
174 | #define CMD_CTX_FLUSH (0x318 + CMD_CTX_BASE) | 190 | #define CMD_CTX_FLUSH (0x318 + CMD_CTX_BASE) |
191 | #define CMD_CTX_ABORT (0x31C + CMD_CTX_BASE) | ||
175 | 192 | ||
176 | static void special_completion(struct nvme_dev *dev, void *ctx, | 193 | static void special_completion(struct nvme_dev *dev, void *ctx, |
177 | struct nvme_completion *cqe) | 194 | struct nvme_completion *cqe) |
@@ -180,6 +197,10 @@ static void special_completion(struct nvme_dev *dev, void *ctx, | |||
180 | return; | 197 | return; |
181 | if (ctx == CMD_CTX_FLUSH) | 198 | if (ctx == CMD_CTX_FLUSH) |
182 | return; | 199 | return; |
200 | if (ctx == CMD_CTX_ABORT) { | ||
201 | ++dev->abort_limit; | ||
202 | return; | ||
203 | } | ||
183 | if (ctx == CMD_CTX_COMPLETED) { | 204 | if (ctx == CMD_CTX_COMPLETED) { |
184 | dev_warn(&dev->pci_dev->dev, | 205 | dev_warn(&dev->pci_dev->dev, |
185 | "completed id %d twice on queue %d\n", | 206 | "completed id %d twice on queue %d\n", |
@@ -196,6 +217,15 @@ static void special_completion(struct nvme_dev *dev, void *ctx, | |||
196 | dev_warn(&dev->pci_dev->dev, "Unknown special completion %p\n", ctx); | 217 | dev_warn(&dev->pci_dev->dev, "Unknown special completion %p\n", ctx); |
197 | } | 218 | } |
198 | 219 | ||
220 | static void async_completion(struct nvme_dev *dev, void *ctx, | ||
221 | struct nvme_completion *cqe) | ||
222 | { | ||
223 | struct async_cmd_info *cmdinfo = ctx; | ||
224 | cmdinfo->result = le32_to_cpup(&cqe->result); | ||
225 | cmdinfo->status = le16_to_cpup(&cqe->status) >> 1; | ||
226 | queue_kthread_work(cmdinfo->worker, &cmdinfo->work); | ||
227 | } | ||
228 | |||
199 | /* | 229 | /* |
200 | * Called with local interrupts disabled and the q_lock held. May not sleep. | 230 | * Called with local interrupts disabled and the q_lock held. May not sleep. |
201 | */ | 231 | */ |
@@ -693,7 +723,7 @@ static int nvme_process_cq(struct nvme_queue *nvmeq) | |||
693 | if (head == nvmeq->cq_head && phase == nvmeq->cq_phase) | 723 | if (head == nvmeq->cq_head && phase == nvmeq->cq_phase) |
694 | return 0; | 724 | return 0; |
695 | 725 | ||
696 | writel(head, nvmeq->q_db + (1 << nvmeq->dev->db_stride)); | 726 | writel(head, nvmeq->q_db + nvmeq->dev->db_stride); |
697 | nvmeq->cq_head = head; | 727 | nvmeq->cq_head = head; |
698 | nvmeq->cq_phase = phase; | 728 | nvmeq->cq_phase = phase; |
699 | 729 | ||
@@ -804,12 +834,34 @@ int nvme_submit_sync_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd, | |||
804 | return cmdinfo.status; | 834 | return cmdinfo.status; |
805 | } | 835 | } |
806 | 836 | ||
837 | static int nvme_submit_async_cmd(struct nvme_queue *nvmeq, | ||
838 | struct nvme_command *cmd, | ||
839 | struct async_cmd_info *cmdinfo, unsigned timeout) | ||
840 | { | ||
841 | int cmdid; | ||
842 | |||
843 | cmdid = alloc_cmdid_killable(nvmeq, cmdinfo, async_completion, timeout); | ||
844 | if (cmdid < 0) | ||
845 | return cmdid; | ||
846 | cmdinfo->status = -EINTR; | ||
847 | cmd->common.command_id = cmdid; | ||
848 | nvme_submit_cmd(nvmeq, cmd); | ||
849 | return 0; | ||
850 | } | ||
851 | |||
807 | int nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, | 852 | int nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, |
808 | u32 *result) | 853 | u32 *result) |
809 | { | 854 | { |
810 | return nvme_submit_sync_cmd(dev->queues[0], cmd, result, ADMIN_TIMEOUT); | 855 | return nvme_submit_sync_cmd(dev->queues[0], cmd, result, ADMIN_TIMEOUT); |
811 | } | 856 | } |
812 | 857 | ||
858 | static int nvme_submit_admin_cmd_async(struct nvme_dev *dev, | ||
859 | struct nvme_command *cmd, struct async_cmd_info *cmdinfo) | ||
860 | { | ||
861 | return nvme_submit_async_cmd(dev->queues[0], cmd, cmdinfo, | ||
862 | ADMIN_TIMEOUT); | ||
863 | } | ||
864 | |||
813 | static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) | 865 | static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) |
814 | { | 866 | { |
815 | int status; | 867 | int status; |
@@ -920,6 +972,56 @@ int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, | |||
920 | } | 972 | } |
921 | 973 | ||
922 | /** | 974 | /** |
975 | * nvme_abort_cmd - Attempt aborting a command | ||
976 | * @cmdid: Command id of a timed out IO | ||
977 | * @queue: The queue with timed out IO | ||
978 | * | ||
979 | * Schedule controller reset if the command was already aborted once before and | ||
980 | * still hasn't been returned to the driver, or if this is the admin queue. | ||
981 | */ | ||
982 | static void nvme_abort_cmd(int cmdid, struct nvme_queue *nvmeq) | ||
983 | { | ||
984 | int a_cmdid; | ||
985 | struct nvme_command cmd; | ||
986 | struct nvme_dev *dev = nvmeq->dev; | ||
987 | struct nvme_cmd_info *info = nvme_cmd_info(nvmeq); | ||
988 | |||
989 | if (!nvmeq->qid || info[cmdid].aborted) { | ||
990 | if (work_busy(&dev->reset_work)) | ||
991 | return; | ||
992 | list_del_init(&dev->node); | ||
993 | dev_warn(&dev->pci_dev->dev, | ||
994 | "I/O %d QID %d timeout, reset controller\n", cmdid, | ||
995 | nvmeq->qid); | ||
996 | PREPARE_WORK(&dev->reset_work, nvme_reset_failed_dev); | ||
997 | queue_work(nvme_workq, &dev->reset_work); | ||
998 | return; | ||
999 | } | ||
1000 | |||
1001 | if (!dev->abort_limit) | ||
1002 | return; | ||
1003 | |||
1004 | a_cmdid = alloc_cmdid(dev->queues[0], CMD_CTX_ABORT, special_completion, | ||
1005 | ADMIN_TIMEOUT); | ||
1006 | if (a_cmdid < 0) | ||
1007 | return; | ||
1008 | |||
1009 | memset(&cmd, 0, sizeof(cmd)); | ||
1010 | cmd.abort.opcode = nvme_admin_abort_cmd; | ||
1011 | cmd.abort.cid = cmdid; | ||
1012 | cmd.abort.sqid = cpu_to_le16(nvmeq->qid); | ||
1013 | cmd.abort.command_id = a_cmdid; | ||
1014 | |||
1015 | --dev->abort_limit; | ||
1016 | info[cmdid].aborted = 1; | ||
1017 | info[cmdid].timeout = jiffies + ADMIN_TIMEOUT; | ||
1018 | |||
1019 | dev_warn(nvmeq->q_dmadev, "Aborting I/O %d QID %d\n", cmdid, | ||
1020 | nvmeq->qid); | ||
1021 | nvme_submit_cmd(dev->queues[0], &cmd); | ||
1022 | } | ||
1023 | |||
1024 | /** | ||
923 | * nvme_cancel_ios - Cancel outstanding I/Os | 1025 | * nvme_cancel_ios - Cancel outstanding I/Os |
924 | * @queue: The queue to cancel I/Os on | 1026 | * @queue: The queue to cancel I/Os on |
925 | * @timeout: True to only cancel I/Os which have timed out | 1027 | * @timeout: True to only cancel I/Os which have timed out |
@@ -942,7 +1044,12 @@ static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout) | |||
942 | continue; | 1044 | continue; |
943 | if (info[cmdid].ctx == CMD_CTX_CANCELLED) | 1045 | if (info[cmdid].ctx == CMD_CTX_CANCELLED) |
944 | continue; | 1046 | continue; |
945 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d\n", cmdid); | 1047 | if (timeout && nvmeq->dev->initialized) { |
1048 | nvme_abort_cmd(cmdid, nvmeq); | ||
1049 | continue; | ||
1050 | } | ||
1051 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", cmdid, | ||
1052 | nvmeq->qid); | ||
946 | ctx = cancel_cmdid(nvmeq, cmdid, &fn); | 1053 | ctx = cancel_cmdid(nvmeq, cmdid, &fn); |
947 | fn(nvmeq->dev, ctx, &cqe); | 1054 | fn(nvmeq->dev, ctx, &cqe); |
948 | } | 1055 | } |
@@ -964,26 +1071,31 @@ static void nvme_free_queue(struct nvme_queue *nvmeq) | |||
964 | kfree(nvmeq); | 1071 | kfree(nvmeq); |
965 | } | 1072 | } |
966 | 1073 | ||
967 | static void nvme_free_queues(struct nvme_dev *dev) | 1074 | static void nvme_free_queues(struct nvme_dev *dev, int lowest) |
968 | { | 1075 | { |
969 | int i; | 1076 | int i; |
970 | 1077 | ||
971 | for (i = dev->queue_count - 1; i >= 0; i--) { | 1078 | for (i = dev->queue_count - 1; i >= lowest; i--) { |
972 | nvme_free_queue(dev->queues[i]); | 1079 | nvme_free_queue(dev->queues[i]); |
973 | dev->queue_count--; | 1080 | dev->queue_count--; |
974 | dev->queues[i] = NULL; | 1081 | dev->queues[i] = NULL; |
975 | } | 1082 | } |
976 | } | 1083 | } |
977 | 1084 | ||
978 | static void nvme_disable_queue(struct nvme_dev *dev, int qid) | 1085 | /** |
1086 | * nvme_suspend_queue - put queue into suspended state | ||
1087 | * @nvmeq - queue to suspend | ||
1088 | * | ||
1089 | * Returns 1 if already suspended, 0 otherwise. | ||
1090 | */ | ||
1091 | static int nvme_suspend_queue(struct nvme_queue *nvmeq) | ||
979 | { | 1092 | { |
980 | struct nvme_queue *nvmeq = dev->queues[qid]; | 1093 | int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; |
981 | int vector = dev->entry[nvmeq->cq_vector].vector; | ||
982 | 1094 | ||
983 | spin_lock_irq(&nvmeq->q_lock); | 1095 | spin_lock_irq(&nvmeq->q_lock); |
984 | if (nvmeq->q_suspended) { | 1096 | if (nvmeq->q_suspended) { |
985 | spin_unlock_irq(&nvmeq->q_lock); | 1097 | spin_unlock_irq(&nvmeq->q_lock); |
986 | return; | 1098 | return 1; |
987 | } | 1099 | } |
988 | nvmeq->q_suspended = 1; | 1100 | nvmeq->q_suspended = 1; |
989 | spin_unlock_irq(&nvmeq->q_lock); | 1101 | spin_unlock_irq(&nvmeq->q_lock); |
@@ -991,18 +1103,35 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid) | |||
991 | irq_set_affinity_hint(vector, NULL); | 1103 | irq_set_affinity_hint(vector, NULL); |
992 | free_irq(vector, nvmeq); | 1104 | free_irq(vector, nvmeq); |
993 | 1105 | ||
994 | /* Don't tell the adapter to delete the admin queue */ | 1106 | return 0; |
995 | if (qid) { | 1107 | } |
996 | adapter_delete_sq(dev, qid); | ||
997 | adapter_delete_cq(dev, qid); | ||
998 | } | ||
999 | 1108 | ||
1109 | static void nvme_clear_queue(struct nvme_queue *nvmeq) | ||
1110 | { | ||
1000 | spin_lock_irq(&nvmeq->q_lock); | 1111 | spin_lock_irq(&nvmeq->q_lock); |
1001 | nvme_process_cq(nvmeq); | 1112 | nvme_process_cq(nvmeq); |
1002 | nvme_cancel_ios(nvmeq, false); | 1113 | nvme_cancel_ios(nvmeq, false); |
1003 | spin_unlock_irq(&nvmeq->q_lock); | 1114 | spin_unlock_irq(&nvmeq->q_lock); |
1004 | } | 1115 | } |
1005 | 1116 | ||
1117 | static void nvme_disable_queue(struct nvme_dev *dev, int qid) | ||
1118 | { | ||
1119 | struct nvme_queue *nvmeq = dev->queues[qid]; | ||
1120 | |||
1121 | if (!nvmeq) | ||
1122 | return; | ||
1123 | if (nvme_suspend_queue(nvmeq)) | ||
1124 | return; | ||
1125 | |||
1126 | /* Don't tell the adapter to delete the admin queue. | ||
1127 | * Don't tell a removed adapter to delete IO queues. */ | ||
1128 | if (qid && readl(&dev->bar->csts) != -1) { | ||
1129 | adapter_delete_sq(dev, qid); | ||
1130 | adapter_delete_cq(dev, qid); | ||
1131 | } | ||
1132 | nvme_clear_queue(nvmeq); | ||
1133 | } | ||
1134 | |||
1006 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | 1135 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, |
1007 | int depth, int vector) | 1136 | int depth, int vector) |
1008 | { | 1137 | { |
@@ -1025,15 +1154,18 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | |||
1025 | 1154 | ||
1026 | nvmeq->q_dmadev = dmadev; | 1155 | nvmeq->q_dmadev = dmadev; |
1027 | nvmeq->dev = dev; | 1156 | nvmeq->dev = dev; |
1157 | snprintf(nvmeq->irqname, sizeof(nvmeq->irqname), "nvme%dq%d", | ||
1158 | dev->instance, qid); | ||
1028 | spin_lock_init(&nvmeq->q_lock); | 1159 | spin_lock_init(&nvmeq->q_lock); |
1029 | nvmeq->cq_head = 0; | 1160 | nvmeq->cq_head = 0; |
1030 | nvmeq->cq_phase = 1; | 1161 | nvmeq->cq_phase = 1; |
1031 | init_waitqueue_head(&nvmeq->sq_full); | 1162 | init_waitqueue_head(&nvmeq->sq_full); |
1032 | init_waitqueue_entry(&nvmeq->sq_cong_wait, nvme_thread); | 1163 | init_waitqueue_entry(&nvmeq->sq_cong_wait, nvme_thread); |
1033 | bio_list_init(&nvmeq->sq_cong); | 1164 | bio_list_init(&nvmeq->sq_cong); |
1034 | nvmeq->q_db = &dev->dbs[qid << (dev->db_stride + 1)]; | 1165 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; |
1035 | nvmeq->q_depth = depth; | 1166 | nvmeq->q_depth = depth; |
1036 | nvmeq->cq_vector = vector; | 1167 | nvmeq->cq_vector = vector; |
1168 | nvmeq->qid = qid; | ||
1037 | nvmeq->q_suspended = 1; | 1169 | nvmeq->q_suspended = 1; |
1038 | dev->queue_count++; | 1170 | dev->queue_count++; |
1039 | 1171 | ||
@@ -1052,11 +1184,10 @@ static int queue_request_irq(struct nvme_dev *dev, struct nvme_queue *nvmeq, | |||
1052 | { | 1184 | { |
1053 | if (use_threaded_interrupts) | 1185 | if (use_threaded_interrupts) |
1054 | return request_threaded_irq(dev->entry[nvmeq->cq_vector].vector, | 1186 | return request_threaded_irq(dev->entry[nvmeq->cq_vector].vector, |
1055 | nvme_irq_check, nvme_irq, | 1187 | nvme_irq_check, nvme_irq, IRQF_SHARED, |
1056 | IRQF_DISABLED | IRQF_SHARED, | ||
1057 | name, nvmeq); | 1188 | name, nvmeq); |
1058 | return request_irq(dev->entry[nvmeq->cq_vector].vector, nvme_irq, | 1189 | return request_irq(dev->entry[nvmeq->cq_vector].vector, nvme_irq, |
1059 | IRQF_DISABLED | IRQF_SHARED, name, nvmeq); | 1190 | IRQF_SHARED, name, nvmeq); |
1060 | } | 1191 | } |
1061 | 1192 | ||
1062 | static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) | 1193 | static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) |
@@ -1067,7 +1198,7 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) | |||
1067 | nvmeq->sq_tail = 0; | 1198 | nvmeq->sq_tail = 0; |
1068 | nvmeq->cq_head = 0; | 1199 | nvmeq->cq_head = 0; |
1069 | nvmeq->cq_phase = 1; | 1200 | nvmeq->cq_phase = 1; |
1070 | nvmeq->q_db = &dev->dbs[qid << (dev->db_stride + 1)]; | 1201 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; |
1071 | memset(nvmeq->cmdid_data, 0, extra); | 1202 | memset(nvmeq->cmdid_data, 0, extra); |
1072 | memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth)); | 1203 | memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth)); |
1073 | nvme_cancel_ios(nvmeq, false); | 1204 | nvme_cancel_ios(nvmeq, false); |
@@ -1087,13 +1218,13 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) | |||
1087 | if (result < 0) | 1218 | if (result < 0) |
1088 | goto release_cq; | 1219 | goto release_cq; |
1089 | 1220 | ||
1090 | result = queue_request_irq(dev, nvmeq, "nvme"); | 1221 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); |
1091 | if (result < 0) | 1222 | if (result < 0) |
1092 | goto release_sq; | 1223 | goto release_sq; |
1093 | 1224 | ||
1094 | spin_lock(&nvmeq->q_lock); | 1225 | spin_lock_irq(&nvmeq->q_lock); |
1095 | nvme_init_queue(nvmeq, qid); | 1226 | nvme_init_queue(nvmeq, qid); |
1096 | spin_unlock(&nvmeq->q_lock); | 1227 | spin_unlock_irq(&nvmeq->q_lock); |
1097 | 1228 | ||
1098 | return result; | 1229 | return result; |
1099 | 1230 | ||
@@ -1205,13 +1336,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) | |||
1205 | if (result) | 1336 | if (result) |
1206 | return result; | 1337 | return result; |
1207 | 1338 | ||
1208 | result = queue_request_irq(dev, nvmeq, "nvme admin"); | 1339 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); |
1209 | if (result) | 1340 | if (result) |
1210 | return result; | 1341 | return result; |
1211 | 1342 | ||
1212 | spin_lock(&nvmeq->q_lock); | 1343 | spin_lock_irq(&nvmeq->q_lock); |
1213 | nvme_init_queue(nvmeq, 0); | 1344 | nvme_init_queue(nvmeq, 0); |
1214 | spin_unlock(&nvmeq->q_lock); | 1345 | spin_unlock_irq(&nvmeq->q_lock); |
1215 | return result; | 1346 | return result; |
1216 | } | 1347 | } |
1217 | 1348 | ||
@@ -1487,10 +1618,47 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
1487 | } | 1618 | } |
1488 | } | 1619 | } |
1489 | 1620 | ||
1621 | #ifdef CONFIG_COMPAT | ||
1622 | static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode, | ||
1623 | unsigned int cmd, unsigned long arg) | ||
1624 | { | ||
1625 | struct nvme_ns *ns = bdev->bd_disk->private_data; | ||
1626 | |||
1627 | switch (cmd) { | ||
1628 | case SG_IO: | ||
1629 | return nvme_sg_io32(ns, arg); | ||
1630 | } | ||
1631 | return nvme_ioctl(bdev, mode, cmd, arg); | ||
1632 | } | ||
1633 | #else | ||
1634 | #define nvme_compat_ioctl NULL | ||
1635 | #endif | ||
1636 | |||
1637 | static int nvme_open(struct block_device *bdev, fmode_t mode) | ||
1638 | { | ||
1639 | struct nvme_ns *ns = bdev->bd_disk->private_data; | ||
1640 | struct nvme_dev *dev = ns->dev; | ||
1641 | |||
1642 | kref_get(&dev->kref); | ||
1643 | return 0; | ||
1644 | } | ||
1645 | |||
1646 | static void nvme_free_dev(struct kref *kref); | ||
1647 | |||
1648 | static void nvme_release(struct gendisk *disk, fmode_t mode) | ||
1649 | { | ||
1650 | struct nvme_ns *ns = disk->private_data; | ||
1651 | struct nvme_dev *dev = ns->dev; | ||
1652 | |||
1653 | kref_put(&dev->kref, nvme_free_dev); | ||
1654 | } | ||
1655 | |||
1490 | static const struct block_device_operations nvme_fops = { | 1656 | static const struct block_device_operations nvme_fops = { |
1491 | .owner = THIS_MODULE, | 1657 | .owner = THIS_MODULE, |
1492 | .ioctl = nvme_ioctl, | 1658 | .ioctl = nvme_ioctl, |
1493 | .compat_ioctl = nvme_ioctl, | 1659 | .compat_ioctl = nvme_compat_ioctl, |
1660 | .open = nvme_open, | ||
1661 | .release = nvme_release, | ||
1494 | }; | 1662 | }; |
1495 | 1663 | ||
1496 | static void nvme_resubmit_bios(struct nvme_queue *nvmeq) | 1664 | static void nvme_resubmit_bios(struct nvme_queue *nvmeq) |
@@ -1514,13 +1682,25 @@ static void nvme_resubmit_bios(struct nvme_queue *nvmeq) | |||
1514 | 1682 | ||
1515 | static int nvme_kthread(void *data) | 1683 | static int nvme_kthread(void *data) |
1516 | { | 1684 | { |
1517 | struct nvme_dev *dev; | 1685 | struct nvme_dev *dev, *next; |
1518 | 1686 | ||
1519 | while (!kthread_should_stop()) { | 1687 | while (!kthread_should_stop()) { |
1520 | set_current_state(TASK_INTERRUPTIBLE); | 1688 | set_current_state(TASK_INTERRUPTIBLE); |
1521 | spin_lock(&dev_list_lock); | 1689 | spin_lock(&dev_list_lock); |
1522 | list_for_each_entry(dev, &dev_list, node) { | 1690 | list_for_each_entry_safe(dev, next, &dev_list, node) { |
1523 | int i; | 1691 | int i; |
1692 | if (readl(&dev->bar->csts) & NVME_CSTS_CFS && | ||
1693 | dev->initialized) { | ||
1694 | if (work_busy(&dev->reset_work)) | ||
1695 | continue; | ||
1696 | list_del_init(&dev->node); | ||
1697 | dev_warn(&dev->pci_dev->dev, | ||
1698 | "Failed status, reset controller\n"); | ||
1699 | PREPARE_WORK(&dev->reset_work, | ||
1700 | nvme_reset_failed_dev); | ||
1701 | queue_work(nvme_workq, &dev->reset_work); | ||
1702 | continue; | ||
1703 | } | ||
1524 | for (i = 0; i < dev->queue_count; i++) { | 1704 | for (i = 0; i < dev->queue_count; i++) { |
1525 | struct nvme_queue *nvmeq = dev->queues[i]; | 1705 | struct nvme_queue *nvmeq = dev->queues[i]; |
1526 | if (!nvmeq) | 1706 | if (!nvmeq) |
@@ -1541,33 +1721,6 @@ static int nvme_kthread(void *data) | |||
1541 | return 0; | 1721 | return 0; |
1542 | } | 1722 | } |
1543 | 1723 | ||
1544 | static DEFINE_IDA(nvme_index_ida); | ||
1545 | |||
1546 | static int nvme_get_ns_idx(void) | ||
1547 | { | ||
1548 | int index, error; | ||
1549 | |||
1550 | do { | ||
1551 | if (!ida_pre_get(&nvme_index_ida, GFP_KERNEL)) | ||
1552 | return -1; | ||
1553 | |||
1554 | spin_lock(&dev_list_lock); | ||
1555 | error = ida_get_new(&nvme_index_ida, &index); | ||
1556 | spin_unlock(&dev_list_lock); | ||
1557 | } while (error == -EAGAIN); | ||
1558 | |||
1559 | if (error) | ||
1560 | index = -1; | ||
1561 | return index; | ||
1562 | } | ||
1563 | |||
1564 | static void nvme_put_ns_idx(int index) | ||
1565 | { | ||
1566 | spin_lock(&dev_list_lock); | ||
1567 | ida_remove(&nvme_index_ida, index); | ||
1568 | spin_unlock(&dev_list_lock); | ||
1569 | } | ||
1570 | |||
1571 | static void nvme_config_discard(struct nvme_ns *ns) | 1724 | static void nvme_config_discard(struct nvme_ns *ns) |
1572 | { | 1725 | { |
1573 | u32 logical_block_size = queue_logical_block_size(ns->queue); | 1726 | u32 logical_block_size = queue_logical_block_size(ns->queue); |
@@ -1601,7 +1754,7 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, | |||
1601 | ns->dev = dev; | 1754 | ns->dev = dev; |
1602 | ns->queue->queuedata = ns; | 1755 | ns->queue->queuedata = ns; |
1603 | 1756 | ||
1604 | disk = alloc_disk(NVME_MINORS); | 1757 | disk = alloc_disk(0); |
1605 | if (!disk) | 1758 | if (!disk) |
1606 | goto out_free_queue; | 1759 | goto out_free_queue; |
1607 | ns->ns_id = nsid; | 1760 | ns->ns_id = nsid; |
@@ -1614,12 +1767,12 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, | |||
1614 | blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors); | 1767 | blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors); |
1615 | 1768 | ||
1616 | disk->major = nvme_major; | 1769 | disk->major = nvme_major; |
1617 | disk->minors = NVME_MINORS; | 1770 | disk->first_minor = 0; |
1618 | disk->first_minor = NVME_MINORS * nvme_get_ns_idx(); | ||
1619 | disk->fops = &nvme_fops; | 1771 | disk->fops = &nvme_fops; |
1620 | disk->private_data = ns; | 1772 | disk->private_data = ns; |
1621 | disk->queue = ns->queue; | 1773 | disk->queue = ns->queue; |
1622 | disk->driverfs_dev = &dev->pci_dev->dev; | 1774 | disk->driverfs_dev = &dev->pci_dev->dev; |
1775 | disk->flags = GENHD_FL_EXT_DEVT; | ||
1623 | sprintf(disk->disk_name, "nvme%dn%d", dev->instance, nsid); | 1776 | sprintf(disk->disk_name, "nvme%dn%d", dev->instance, nsid); |
1624 | set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9)); | 1777 | set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9)); |
1625 | 1778 | ||
@@ -1635,15 +1788,6 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, | |||
1635 | return NULL; | 1788 | return NULL; |
1636 | } | 1789 | } |
1637 | 1790 | ||
1638 | static void nvme_ns_free(struct nvme_ns *ns) | ||
1639 | { | ||
1640 | int index = ns->disk->first_minor / NVME_MINORS; | ||
1641 | put_disk(ns->disk); | ||
1642 | nvme_put_ns_idx(index); | ||
1643 | blk_cleanup_queue(ns->queue); | ||
1644 | kfree(ns); | ||
1645 | } | ||
1646 | |||
1647 | static int set_queue_count(struct nvme_dev *dev, int count) | 1791 | static int set_queue_count(struct nvme_dev *dev, int count) |
1648 | { | 1792 | { |
1649 | int status; | 1793 | int status; |
@@ -1659,11 +1803,12 @@ static int set_queue_count(struct nvme_dev *dev, int count) | |||
1659 | 1803 | ||
1660 | static size_t db_bar_size(struct nvme_dev *dev, unsigned nr_io_queues) | 1804 | static size_t db_bar_size(struct nvme_dev *dev, unsigned nr_io_queues) |
1661 | { | 1805 | { |
1662 | return 4096 + ((nr_io_queues + 1) << (dev->db_stride + 3)); | 1806 | return 4096 + ((nr_io_queues + 1) * 8 * dev->db_stride); |
1663 | } | 1807 | } |
1664 | 1808 | ||
1665 | static int nvme_setup_io_queues(struct nvme_dev *dev) | 1809 | static int nvme_setup_io_queues(struct nvme_dev *dev) |
1666 | { | 1810 | { |
1811 | struct nvme_queue *adminq = dev->queues[0]; | ||
1667 | struct pci_dev *pdev = dev->pci_dev; | 1812 | struct pci_dev *pdev = dev->pci_dev; |
1668 | int result, cpu, i, vecs, nr_io_queues, size, q_depth; | 1813 | int result, cpu, i, vecs, nr_io_queues, size, q_depth; |
1669 | 1814 | ||
@@ -1690,7 +1835,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1690 | } | 1835 | } |
1691 | 1836 | ||
1692 | /* Deregister the admin queue's interrupt */ | 1837 | /* Deregister the admin queue's interrupt */ |
1693 | free_irq(dev->entry[0].vector, dev->queues[0]); | 1838 | free_irq(dev->entry[0].vector, adminq); |
1694 | 1839 | ||
1695 | vecs = nr_io_queues; | 1840 | vecs = nr_io_queues; |
1696 | for (i = 0; i < vecs; i++) | 1841 | for (i = 0; i < vecs; i++) |
@@ -1728,9 +1873,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1728 | */ | 1873 | */ |
1729 | nr_io_queues = vecs; | 1874 | nr_io_queues = vecs; |
1730 | 1875 | ||
1731 | result = queue_request_irq(dev, dev->queues[0], "nvme admin"); | 1876 | result = queue_request_irq(dev, adminq, adminq->irqname); |
1732 | if (result) { | 1877 | if (result) { |
1733 | dev->queues[0]->q_suspended = 1; | 1878 | adminq->q_suspended = 1; |
1734 | goto free_queues; | 1879 | goto free_queues; |
1735 | } | 1880 | } |
1736 | 1881 | ||
@@ -1739,9 +1884,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1739 | for (i = dev->queue_count - 1; i > nr_io_queues; i--) { | 1884 | for (i = dev->queue_count - 1; i > nr_io_queues; i--) { |
1740 | struct nvme_queue *nvmeq = dev->queues[i]; | 1885 | struct nvme_queue *nvmeq = dev->queues[i]; |
1741 | 1886 | ||
1742 | spin_lock(&nvmeq->q_lock); | 1887 | spin_lock_irq(&nvmeq->q_lock); |
1743 | nvme_cancel_ios(nvmeq, false); | 1888 | nvme_cancel_ios(nvmeq, false); |
1744 | spin_unlock(&nvmeq->q_lock); | 1889 | spin_unlock_irq(&nvmeq->q_lock); |
1745 | 1890 | ||
1746 | nvme_free_queue(nvmeq); | 1891 | nvme_free_queue(nvmeq); |
1747 | dev->queue_count--; | 1892 | dev->queue_count--; |
@@ -1782,7 +1927,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1782 | return 0; | 1927 | return 0; |
1783 | 1928 | ||
1784 | free_queues: | 1929 | free_queues: |
1785 | nvme_free_queues(dev); | 1930 | nvme_free_queues(dev, 1); |
1786 | return result; | 1931 | return result; |
1787 | } | 1932 | } |
1788 | 1933 | ||
@@ -1794,6 +1939,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1794 | */ | 1939 | */ |
1795 | static int nvme_dev_add(struct nvme_dev *dev) | 1940 | static int nvme_dev_add(struct nvme_dev *dev) |
1796 | { | 1941 | { |
1942 | struct pci_dev *pdev = dev->pci_dev; | ||
1797 | int res; | 1943 | int res; |
1798 | unsigned nn, i; | 1944 | unsigned nn, i; |
1799 | struct nvme_ns *ns; | 1945 | struct nvme_ns *ns; |
@@ -1803,8 +1949,7 @@ static int nvme_dev_add(struct nvme_dev *dev) | |||
1803 | dma_addr_t dma_addr; | 1949 | dma_addr_t dma_addr; |
1804 | int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12; | 1950 | int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12; |
1805 | 1951 | ||
1806 | mem = dma_alloc_coherent(&dev->pci_dev->dev, 8192, &dma_addr, | 1952 | mem = dma_alloc_coherent(&pdev->dev, 8192, &dma_addr, GFP_KERNEL); |
1807 | GFP_KERNEL); | ||
1808 | if (!mem) | 1953 | if (!mem) |
1809 | return -ENOMEM; | 1954 | return -ENOMEM; |
1810 | 1955 | ||
@@ -1817,13 +1962,14 @@ static int nvme_dev_add(struct nvme_dev *dev) | |||
1817 | ctrl = mem; | 1962 | ctrl = mem; |
1818 | nn = le32_to_cpup(&ctrl->nn); | 1963 | nn = le32_to_cpup(&ctrl->nn); |
1819 | dev->oncs = le16_to_cpup(&ctrl->oncs); | 1964 | dev->oncs = le16_to_cpup(&ctrl->oncs); |
1965 | dev->abort_limit = ctrl->acl + 1; | ||
1820 | memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn)); | 1966 | memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn)); |
1821 | memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn)); | 1967 | memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn)); |
1822 | memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr)); | 1968 | memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr)); |
1823 | if (ctrl->mdts) | 1969 | if (ctrl->mdts) |
1824 | dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9); | 1970 | dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9); |
1825 | if ((dev->pci_dev->vendor == PCI_VENDOR_ID_INTEL) && | 1971 | if ((pdev->vendor == PCI_VENDOR_ID_INTEL) && |
1826 | (dev->pci_dev->device == 0x0953) && ctrl->vs[3]) | 1972 | (pdev->device == 0x0953) && ctrl->vs[3]) |
1827 | dev->stripe_size = 1 << (ctrl->vs[3] + shift); | 1973 | dev->stripe_size = 1 << (ctrl->vs[3] + shift); |
1828 | 1974 | ||
1829 | id_ns = mem; | 1975 | id_ns = mem; |
@@ -1871,16 +2017,21 @@ static int nvme_dev_map(struct nvme_dev *dev) | |||
1871 | dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) | 2017 | dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) |
1872 | goto disable; | 2018 | goto disable; |
1873 | 2019 | ||
1874 | pci_set_drvdata(pdev, dev); | ||
1875 | dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); | 2020 | dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); |
1876 | if (!dev->bar) | 2021 | if (!dev->bar) |
1877 | goto disable; | 2022 | goto disable; |
1878 | 2023 | if (readl(&dev->bar->csts) == -1) { | |
1879 | dev->db_stride = NVME_CAP_STRIDE(readq(&dev->bar->cap)); | 2024 | result = -ENODEV; |
2025 | goto unmap; | ||
2026 | } | ||
2027 | dev->db_stride = 1 << NVME_CAP_STRIDE(readq(&dev->bar->cap)); | ||
1880 | dev->dbs = ((void __iomem *)dev->bar) + 4096; | 2028 | dev->dbs = ((void __iomem *)dev->bar) + 4096; |
1881 | 2029 | ||
1882 | return 0; | 2030 | return 0; |
1883 | 2031 | ||
2032 | unmap: | ||
2033 | iounmap(dev->bar); | ||
2034 | dev->bar = NULL; | ||
1884 | disable: | 2035 | disable: |
1885 | pci_release_regions(pdev); | 2036 | pci_release_regions(pdev); |
1886 | disable_pci: | 2037 | disable_pci: |
@@ -1898,37 +2049,183 @@ static void nvme_dev_unmap(struct nvme_dev *dev) | |||
1898 | if (dev->bar) { | 2049 | if (dev->bar) { |
1899 | iounmap(dev->bar); | 2050 | iounmap(dev->bar); |
1900 | dev->bar = NULL; | 2051 | dev->bar = NULL; |
2052 | pci_release_regions(dev->pci_dev); | ||
1901 | } | 2053 | } |
1902 | 2054 | ||
1903 | pci_release_regions(dev->pci_dev); | ||
1904 | if (pci_is_enabled(dev->pci_dev)) | 2055 | if (pci_is_enabled(dev->pci_dev)) |
1905 | pci_disable_device(dev->pci_dev); | 2056 | pci_disable_device(dev->pci_dev); |
1906 | } | 2057 | } |
1907 | 2058 | ||
2059 | struct nvme_delq_ctx { | ||
2060 | struct task_struct *waiter; | ||
2061 | struct kthread_worker *worker; | ||
2062 | atomic_t refcount; | ||
2063 | }; | ||
2064 | |||
2065 | static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev) | ||
2066 | { | ||
2067 | dq->waiter = current; | ||
2068 | mb(); | ||
2069 | |||
2070 | for (;;) { | ||
2071 | set_current_state(TASK_KILLABLE); | ||
2072 | if (!atomic_read(&dq->refcount)) | ||
2073 | break; | ||
2074 | if (!schedule_timeout(ADMIN_TIMEOUT) || | ||
2075 | fatal_signal_pending(current)) { | ||
2076 | set_current_state(TASK_RUNNING); | ||
2077 | |||
2078 | nvme_disable_ctrl(dev, readq(&dev->bar->cap)); | ||
2079 | nvme_disable_queue(dev, 0); | ||
2080 | |||
2081 | send_sig(SIGKILL, dq->worker->task, 1); | ||
2082 | flush_kthread_worker(dq->worker); | ||
2083 | return; | ||
2084 | } | ||
2085 | } | ||
2086 | set_current_state(TASK_RUNNING); | ||
2087 | } | ||
2088 | |||
2089 | static void nvme_put_dq(struct nvme_delq_ctx *dq) | ||
2090 | { | ||
2091 | atomic_dec(&dq->refcount); | ||
2092 | if (dq->waiter) | ||
2093 | wake_up_process(dq->waiter); | ||
2094 | } | ||
2095 | |||
2096 | static struct nvme_delq_ctx *nvme_get_dq(struct nvme_delq_ctx *dq) | ||
2097 | { | ||
2098 | atomic_inc(&dq->refcount); | ||
2099 | return dq; | ||
2100 | } | ||
2101 | |||
2102 | static void nvme_del_queue_end(struct nvme_queue *nvmeq) | ||
2103 | { | ||
2104 | struct nvme_delq_ctx *dq = nvmeq->cmdinfo.ctx; | ||
2105 | |||
2106 | nvme_clear_queue(nvmeq); | ||
2107 | nvme_put_dq(dq); | ||
2108 | } | ||
2109 | |||
2110 | static int adapter_async_del_queue(struct nvme_queue *nvmeq, u8 opcode, | ||
2111 | kthread_work_func_t fn) | ||
2112 | { | ||
2113 | struct nvme_command c; | ||
2114 | |||
2115 | memset(&c, 0, sizeof(c)); | ||
2116 | c.delete_queue.opcode = opcode; | ||
2117 | c.delete_queue.qid = cpu_to_le16(nvmeq->qid); | ||
2118 | |||
2119 | init_kthread_work(&nvmeq->cmdinfo.work, fn); | ||
2120 | return nvme_submit_admin_cmd_async(nvmeq->dev, &c, &nvmeq->cmdinfo); | ||
2121 | } | ||
2122 | |||
2123 | static void nvme_del_cq_work_handler(struct kthread_work *work) | ||
2124 | { | ||
2125 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | ||
2126 | cmdinfo.work); | ||
2127 | nvme_del_queue_end(nvmeq); | ||
2128 | } | ||
2129 | |||
2130 | static int nvme_delete_cq(struct nvme_queue *nvmeq) | ||
2131 | { | ||
2132 | return adapter_async_del_queue(nvmeq, nvme_admin_delete_cq, | ||
2133 | nvme_del_cq_work_handler); | ||
2134 | } | ||
2135 | |||
2136 | static void nvme_del_sq_work_handler(struct kthread_work *work) | ||
2137 | { | ||
2138 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | ||
2139 | cmdinfo.work); | ||
2140 | int status = nvmeq->cmdinfo.status; | ||
2141 | |||
2142 | if (!status) | ||
2143 | status = nvme_delete_cq(nvmeq); | ||
2144 | if (status) | ||
2145 | nvme_del_queue_end(nvmeq); | ||
2146 | } | ||
2147 | |||
2148 | static int nvme_delete_sq(struct nvme_queue *nvmeq) | ||
2149 | { | ||
2150 | return adapter_async_del_queue(nvmeq, nvme_admin_delete_sq, | ||
2151 | nvme_del_sq_work_handler); | ||
2152 | } | ||
2153 | |||
2154 | static void nvme_del_queue_start(struct kthread_work *work) | ||
2155 | { | ||
2156 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | ||
2157 | cmdinfo.work); | ||
2158 | allow_signal(SIGKILL); | ||
2159 | if (nvme_delete_sq(nvmeq)) | ||
2160 | nvme_del_queue_end(nvmeq); | ||
2161 | } | ||
2162 | |||
2163 | static void nvme_disable_io_queues(struct nvme_dev *dev) | ||
2164 | { | ||
2165 | int i; | ||
2166 | DEFINE_KTHREAD_WORKER_ONSTACK(worker); | ||
2167 | struct nvme_delq_ctx dq; | ||
2168 | struct task_struct *kworker_task = kthread_run(kthread_worker_fn, | ||
2169 | &worker, "nvme%d", dev->instance); | ||
2170 | |||
2171 | if (IS_ERR(kworker_task)) { | ||
2172 | dev_err(&dev->pci_dev->dev, | ||
2173 | "Failed to create queue del task\n"); | ||
2174 | for (i = dev->queue_count - 1; i > 0; i--) | ||
2175 | nvme_disable_queue(dev, i); | ||
2176 | return; | ||
2177 | } | ||
2178 | |||
2179 | dq.waiter = NULL; | ||
2180 | atomic_set(&dq.refcount, 0); | ||
2181 | dq.worker = &worker; | ||
2182 | for (i = dev->queue_count - 1; i > 0; i--) { | ||
2183 | struct nvme_queue *nvmeq = dev->queues[i]; | ||
2184 | |||
2185 | if (nvme_suspend_queue(nvmeq)) | ||
2186 | continue; | ||
2187 | nvmeq->cmdinfo.ctx = nvme_get_dq(&dq); | ||
2188 | nvmeq->cmdinfo.worker = dq.worker; | ||
2189 | init_kthread_work(&nvmeq->cmdinfo.work, nvme_del_queue_start); | ||
2190 | queue_kthread_work(dq.worker, &nvmeq->cmdinfo.work); | ||
2191 | } | ||
2192 | nvme_wait_dq(&dq, dev); | ||
2193 | kthread_stop(kworker_task); | ||
2194 | } | ||
2195 | |||
1908 | static void nvme_dev_shutdown(struct nvme_dev *dev) | 2196 | static void nvme_dev_shutdown(struct nvme_dev *dev) |
1909 | { | 2197 | { |
1910 | int i; | 2198 | int i; |
1911 | 2199 | ||
1912 | for (i = dev->queue_count - 1; i >= 0; i--) | 2200 | dev->initialized = 0; |
1913 | nvme_disable_queue(dev, i); | ||
1914 | 2201 | ||
1915 | spin_lock(&dev_list_lock); | 2202 | spin_lock(&dev_list_lock); |
1916 | list_del_init(&dev->node); | 2203 | list_del_init(&dev->node); |
1917 | spin_unlock(&dev_list_lock); | 2204 | spin_unlock(&dev_list_lock); |
1918 | 2205 | ||
1919 | if (dev->bar) | 2206 | if (!dev->bar || (dev->bar && readl(&dev->bar->csts) == -1)) { |
2207 | for (i = dev->queue_count - 1; i >= 0; i--) { | ||
2208 | struct nvme_queue *nvmeq = dev->queues[i]; | ||
2209 | nvme_suspend_queue(nvmeq); | ||
2210 | nvme_clear_queue(nvmeq); | ||
2211 | } | ||
2212 | } else { | ||
2213 | nvme_disable_io_queues(dev); | ||
1920 | nvme_shutdown_ctrl(dev); | 2214 | nvme_shutdown_ctrl(dev); |
2215 | nvme_disable_queue(dev, 0); | ||
2216 | } | ||
1921 | nvme_dev_unmap(dev); | 2217 | nvme_dev_unmap(dev); |
1922 | } | 2218 | } |
1923 | 2219 | ||
1924 | static void nvme_dev_remove(struct nvme_dev *dev) | 2220 | static void nvme_dev_remove(struct nvme_dev *dev) |
1925 | { | 2221 | { |
1926 | struct nvme_ns *ns, *next; | 2222 | struct nvme_ns *ns; |
1927 | 2223 | ||
1928 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) { | 2224 | list_for_each_entry(ns, &dev->namespaces, list) { |
1929 | list_del(&ns->list); | 2225 | if (ns->disk->flags & GENHD_FL_UP) |
1930 | del_gendisk(ns->disk); | 2226 | del_gendisk(ns->disk); |
1931 | nvme_ns_free(ns); | 2227 | if (!blk_queue_dying(ns->queue)) |
2228 | blk_cleanup_queue(ns->queue); | ||
1932 | } | 2229 | } |
1933 | } | 2230 | } |
1934 | 2231 | ||
@@ -1985,14 +2282,22 @@ static void nvme_release_instance(struct nvme_dev *dev) | |||
1985 | spin_unlock(&dev_list_lock); | 2282 | spin_unlock(&dev_list_lock); |
1986 | } | 2283 | } |
1987 | 2284 | ||
2285 | static void nvme_free_namespaces(struct nvme_dev *dev) | ||
2286 | { | ||
2287 | struct nvme_ns *ns, *next; | ||
2288 | |||
2289 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) { | ||
2290 | list_del(&ns->list); | ||
2291 | put_disk(ns->disk); | ||
2292 | kfree(ns); | ||
2293 | } | ||
2294 | } | ||
2295 | |||
1988 | static void nvme_free_dev(struct kref *kref) | 2296 | static void nvme_free_dev(struct kref *kref) |
1989 | { | 2297 | { |
1990 | struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); | 2298 | struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); |
1991 | nvme_dev_remove(dev); | 2299 | |
1992 | nvme_dev_shutdown(dev); | 2300 | nvme_free_namespaces(dev); |
1993 | nvme_free_queues(dev); | ||
1994 | nvme_release_instance(dev); | ||
1995 | nvme_release_prp_pools(dev); | ||
1996 | kfree(dev->queues); | 2301 | kfree(dev->queues); |
1997 | kfree(dev->entry); | 2302 | kfree(dev->entry); |
1998 | kfree(dev); | 2303 | kfree(dev); |
@@ -2056,6 +2361,7 @@ static int nvme_dev_start(struct nvme_dev *dev) | |||
2056 | return result; | 2361 | return result; |
2057 | 2362 | ||
2058 | disable: | 2363 | disable: |
2364 | nvme_disable_queue(dev, 0); | ||
2059 | spin_lock(&dev_list_lock); | 2365 | spin_lock(&dev_list_lock); |
2060 | list_del_init(&dev->node); | 2366 | list_del_init(&dev->node); |
2061 | spin_unlock(&dev_list_lock); | 2367 | spin_unlock(&dev_list_lock); |
@@ -2064,6 +2370,71 @@ static int nvme_dev_start(struct nvme_dev *dev) | |||
2064 | return result; | 2370 | return result; |
2065 | } | 2371 | } |
2066 | 2372 | ||
2373 | static int nvme_remove_dead_ctrl(void *arg) | ||
2374 | { | ||
2375 | struct nvme_dev *dev = (struct nvme_dev *)arg; | ||
2376 | struct pci_dev *pdev = dev->pci_dev; | ||
2377 | |||
2378 | if (pci_get_drvdata(pdev)) | ||
2379 | pci_stop_and_remove_bus_device(pdev); | ||
2380 | kref_put(&dev->kref, nvme_free_dev); | ||
2381 | return 0; | ||
2382 | } | ||
2383 | |||
2384 | static void nvme_remove_disks(struct work_struct *ws) | ||
2385 | { | ||
2386 | int i; | ||
2387 | struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); | ||
2388 | |||
2389 | nvme_dev_remove(dev); | ||
2390 | spin_lock(&dev_list_lock); | ||
2391 | for (i = dev->queue_count - 1; i > 0; i--) { | ||
2392 | BUG_ON(!dev->queues[i] || !dev->queues[i]->q_suspended); | ||
2393 | nvme_free_queue(dev->queues[i]); | ||
2394 | dev->queue_count--; | ||
2395 | dev->queues[i] = NULL; | ||
2396 | } | ||
2397 | spin_unlock(&dev_list_lock); | ||
2398 | } | ||
2399 | |||
2400 | static int nvme_dev_resume(struct nvme_dev *dev) | ||
2401 | { | ||
2402 | int ret; | ||
2403 | |||
2404 | ret = nvme_dev_start(dev); | ||
2405 | if (ret && ret != -EBUSY) | ||
2406 | return ret; | ||
2407 | if (ret == -EBUSY) { | ||
2408 | spin_lock(&dev_list_lock); | ||
2409 | PREPARE_WORK(&dev->reset_work, nvme_remove_disks); | ||
2410 | queue_work(nvme_workq, &dev->reset_work); | ||
2411 | spin_unlock(&dev_list_lock); | ||
2412 | } | ||
2413 | dev->initialized = 1; | ||
2414 | return 0; | ||
2415 | } | ||
2416 | |||
2417 | static void nvme_dev_reset(struct nvme_dev *dev) | ||
2418 | { | ||
2419 | nvme_dev_shutdown(dev); | ||
2420 | if (nvme_dev_resume(dev)) { | ||
2421 | dev_err(&dev->pci_dev->dev, "Device failed to resume\n"); | ||
2422 | kref_get(&dev->kref); | ||
2423 | if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d", | ||
2424 | dev->instance))) { | ||
2425 | dev_err(&dev->pci_dev->dev, | ||
2426 | "Failed to start controller remove task\n"); | ||
2427 | kref_put(&dev->kref, nvme_free_dev); | ||
2428 | } | ||
2429 | } | ||
2430 | } | ||
2431 | |||
2432 | static void nvme_reset_failed_dev(struct work_struct *ws) | ||
2433 | { | ||
2434 | struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); | ||
2435 | nvme_dev_reset(dev); | ||
2436 | } | ||
2437 | |||
2067 | static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 2438 | static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
2068 | { | 2439 | { |
2069 | int result = -ENOMEM; | 2440 | int result = -ENOMEM; |
@@ -2082,8 +2453,9 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2082 | goto free; | 2453 | goto free; |
2083 | 2454 | ||
2084 | INIT_LIST_HEAD(&dev->namespaces); | 2455 | INIT_LIST_HEAD(&dev->namespaces); |
2456 | INIT_WORK(&dev->reset_work, nvme_reset_failed_dev); | ||
2085 | dev->pci_dev = pdev; | 2457 | dev->pci_dev = pdev; |
2086 | 2458 | pci_set_drvdata(pdev, dev); | |
2087 | result = nvme_set_instance(dev); | 2459 | result = nvme_set_instance(dev); |
2088 | if (result) | 2460 | if (result) |
2089 | goto free; | 2461 | goto free; |
@@ -2099,6 +2471,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2099 | goto release_pools; | 2471 | goto release_pools; |
2100 | } | 2472 | } |
2101 | 2473 | ||
2474 | kref_init(&dev->kref); | ||
2102 | result = nvme_dev_add(dev); | 2475 | result = nvme_dev_add(dev); |
2103 | if (result) | 2476 | if (result) |
2104 | goto shutdown; | 2477 | goto shutdown; |
@@ -2113,15 +2486,16 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2113 | if (result) | 2486 | if (result) |
2114 | goto remove; | 2487 | goto remove; |
2115 | 2488 | ||
2116 | kref_init(&dev->kref); | 2489 | dev->initialized = 1; |
2117 | return 0; | 2490 | return 0; |
2118 | 2491 | ||
2119 | remove: | 2492 | remove: |
2120 | nvme_dev_remove(dev); | 2493 | nvme_dev_remove(dev); |
2494 | nvme_free_namespaces(dev); | ||
2121 | shutdown: | 2495 | shutdown: |
2122 | nvme_dev_shutdown(dev); | 2496 | nvme_dev_shutdown(dev); |
2123 | release_pools: | 2497 | release_pools: |
2124 | nvme_free_queues(dev); | 2498 | nvme_free_queues(dev, 0); |
2125 | nvme_release_prp_pools(dev); | 2499 | nvme_release_prp_pools(dev); |
2126 | release: | 2500 | release: |
2127 | nvme_release_instance(dev); | 2501 | nvme_release_instance(dev); |
@@ -2132,10 +2506,28 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2132 | return result; | 2506 | return result; |
2133 | } | 2507 | } |
2134 | 2508 | ||
2509 | static void nvme_shutdown(struct pci_dev *pdev) | ||
2510 | { | ||
2511 | struct nvme_dev *dev = pci_get_drvdata(pdev); | ||
2512 | nvme_dev_shutdown(dev); | ||
2513 | } | ||
2514 | |||
2135 | static void nvme_remove(struct pci_dev *pdev) | 2515 | static void nvme_remove(struct pci_dev *pdev) |
2136 | { | 2516 | { |
2137 | struct nvme_dev *dev = pci_get_drvdata(pdev); | 2517 | struct nvme_dev *dev = pci_get_drvdata(pdev); |
2518 | |||
2519 | spin_lock(&dev_list_lock); | ||
2520 | list_del_init(&dev->node); | ||
2521 | spin_unlock(&dev_list_lock); | ||
2522 | |||
2523 | pci_set_drvdata(pdev, NULL); | ||
2524 | flush_work(&dev->reset_work); | ||
2138 | misc_deregister(&dev->miscdev); | 2525 | misc_deregister(&dev->miscdev); |
2526 | nvme_dev_remove(dev); | ||
2527 | nvme_dev_shutdown(dev); | ||
2528 | nvme_free_queues(dev, 0); | ||
2529 | nvme_release_instance(dev); | ||
2530 | nvme_release_prp_pools(dev); | ||
2139 | kref_put(&dev->kref, nvme_free_dev); | 2531 | kref_put(&dev->kref, nvme_free_dev); |
2140 | } | 2532 | } |
2141 | 2533 | ||
@@ -2159,13 +2551,12 @@ static int nvme_resume(struct device *dev) | |||
2159 | { | 2551 | { |
2160 | struct pci_dev *pdev = to_pci_dev(dev); | 2552 | struct pci_dev *pdev = to_pci_dev(dev); |
2161 | struct nvme_dev *ndev = pci_get_drvdata(pdev); | 2553 | struct nvme_dev *ndev = pci_get_drvdata(pdev); |
2162 | int ret; | ||
2163 | 2554 | ||
2164 | ret = nvme_dev_start(ndev); | 2555 | if (nvme_dev_resume(ndev) && !work_busy(&ndev->reset_work)) { |
2165 | /* XXX: should remove gendisks if resume fails */ | 2556 | PREPARE_WORK(&ndev->reset_work, nvme_reset_failed_dev); |
2166 | if (ret) | 2557 | queue_work(nvme_workq, &ndev->reset_work); |
2167 | nvme_free_queues(ndev); | 2558 | } |
2168 | return ret; | 2559 | return 0; |
2169 | } | 2560 | } |
2170 | 2561 | ||
2171 | static SIMPLE_DEV_PM_OPS(nvme_dev_pm_ops, nvme_suspend, nvme_resume); | 2562 | static SIMPLE_DEV_PM_OPS(nvme_dev_pm_ops, nvme_suspend, nvme_resume); |
@@ -2192,6 +2583,7 @@ static struct pci_driver nvme_driver = { | |||
2192 | .id_table = nvme_id_table, | 2583 | .id_table = nvme_id_table, |
2193 | .probe = nvme_probe, | 2584 | .probe = nvme_probe, |
2194 | .remove = nvme_remove, | 2585 | .remove = nvme_remove, |
2586 | .shutdown = nvme_shutdown, | ||
2195 | .driver = { | 2587 | .driver = { |
2196 | .pm = &nvme_dev_pm_ops, | 2588 | .pm = &nvme_dev_pm_ops, |
2197 | }, | 2589 | }, |
@@ -2206,9 +2598,14 @@ static int __init nvme_init(void) | |||
2206 | if (IS_ERR(nvme_thread)) | 2598 | if (IS_ERR(nvme_thread)) |
2207 | return PTR_ERR(nvme_thread); | 2599 | return PTR_ERR(nvme_thread); |
2208 | 2600 | ||
2601 | result = -ENOMEM; | ||
2602 | nvme_workq = create_singlethread_workqueue("nvme"); | ||
2603 | if (!nvme_workq) | ||
2604 | goto kill_kthread; | ||
2605 | |||
2209 | result = register_blkdev(nvme_major, "nvme"); | 2606 | result = register_blkdev(nvme_major, "nvme"); |
2210 | if (result < 0) | 2607 | if (result < 0) |
2211 | goto kill_kthread; | 2608 | goto kill_workq; |
2212 | else if (result > 0) | 2609 | else if (result > 0) |
2213 | nvme_major = result; | 2610 | nvme_major = result; |
2214 | 2611 | ||
@@ -2219,6 +2616,8 @@ static int __init nvme_init(void) | |||
2219 | 2616 | ||
2220 | unregister_blkdev: | 2617 | unregister_blkdev: |
2221 | unregister_blkdev(nvme_major, "nvme"); | 2618 | unregister_blkdev(nvme_major, "nvme"); |
2619 | kill_workq: | ||
2620 | destroy_workqueue(nvme_workq); | ||
2222 | kill_kthread: | 2621 | kill_kthread: |
2223 | kthread_stop(nvme_thread); | 2622 | kthread_stop(nvme_thread); |
2224 | return result; | 2623 | return result; |
@@ -2228,6 +2627,7 @@ static void __exit nvme_exit(void) | |||
2228 | { | 2627 | { |
2229 | pci_unregister_driver(&nvme_driver); | 2628 | pci_unregister_driver(&nvme_driver); |
2230 | unregister_blkdev(nvme_major, "nvme"); | 2629 | unregister_blkdev(nvme_major, "nvme"); |
2630 | destroy_workqueue(nvme_workq); | ||
2231 | kthread_stop(nvme_thread); | 2631 | kthread_stop(nvme_thread); |
2232 | } | 2632 | } |
2233 | 2633 | ||
diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index 4a4ff4eb8e23..4a0ceb64e269 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/bio.h> | 25 | #include <linux/bio.h> |
26 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
27 | #include <linux/blkdev.h> | 27 | #include <linux/blkdev.h> |
28 | #include <linux/compat.h> | ||
28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
29 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
30 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
@@ -3038,6 +3039,152 @@ int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr) | |||
3038 | return retcode; | 3039 | return retcode; |
3039 | } | 3040 | } |
3040 | 3041 | ||
3042 | #ifdef CONFIG_COMPAT | ||
3043 | typedef struct sg_io_hdr32 { | ||
3044 | compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ | ||
3045 | compat_int_t dxfer_direction; /* [i] data transfer direction */ | ||
3046 | unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ | ||
3047 | unsigned char mx_sb_len; /* [i] max length to write to sbp */ | ||
3048 | unsigned short iovec_count; /* [i] 0 implies no scatter gather */ | ||
3049 | compat_uint_t dxfer_len; /* [i] byte count of data transfer */ | ||
3050 | compat_uint_t dxferp; /* [i], [*io] points to data transfer memory | ||
3051 | or scatter gather list */ | ||
3052 | compat_uptr_t cmdp; /* [i], [*i] points to command to perform */ | ||
3053 | compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */ | ||
3054 | compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ | ||
3055 | compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */ | ||
3056 | compat_int_t pack_id; /* [i->o] unused internally (normally) */ | ||
3057 | compat_uptr_t usr_ptr; /* [i->o] unused internally */ | ||
3058 | unsigned char status; /* [o] scsi status */ | ||
3059 | unsigned char masked_status; /* [o] shifted, masked scsi status */ | ||
3060 | unsigned char msg_status; /* [o] messaging level data (optional) */ | ||
3061 | unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ | ||
3062 | unsigned short host_status; /* [o] errors from host adapter */ | ||
3063 | unsigned short driver_status; /* [o] errors from software driver */ | ||
3064 | compat_int_t resid; /* [o] dxfer_len - actual_transferred */ | ||
3065 | compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */ | ||
3066 | compat_uint_t info; /* [o] auxiliary information */ | ||
3067 | } sg_io_hdr32_t; /* 64 bytes long (on sparc32) */ | ||
3068 | |||
3069 | typedef struct sg_iovec32 { | ||
3070 | compat_uint_t iov_base; | ||
3071 | compat_uint_t iov_len; | ||
3072 | } sg_iovec32_t; | ||
3073 | |||
3074 | static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count) | ||
3075 | { | ||
3076 | sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1); | ||
3077 | sg_iovec32_t __user *iov32 = dxferp; | ||
3078 | int i; | ||
3079 | |||
3080 | for (i = 0; i < iovec_count; i++) { | ||
3081 | u32 base, len; | ||
3082 | |||
3083 | if (get_user(base, &iov32[i].iov_base) || | ||
3084 | get_user(len, &iov32[i].iov_len) || | ||
3085 | put_user(compat_ptr(base), &iov[i].iov_base) || | ||
3086 | put_user(len, &iov[i].iov_len)) | ||
3087 | return -EFAULT; | ||
3088 | } | ||
3089 | |||
3090 | if (put_user(iov, &sgio->dxferp)) | ||
3091 | return -EFAULT; | ||
3092 | return 0; | ||
3093 | } | ||
3094 | |||
3095 | int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg) | ||
3096 | { | ||
3097 | sg_io_hdr32_t __user *sgio32 = (sg_io_hdr32_t __user *)arg; | ||
3098 | sg_io_hdr_t __user *sgio; | ||
3099 | u16 iovec_count; | ||
3100 | u32 data; | ||
3101 | void __user *dxferp; | ||
3102 | int err; | ||
3103 | int interface_id; | ||
3104 | |||
3105 | if (get_user(interface_id, &sgio32->interface_id)) | ||
3106 | return -EFAULT; | ||
3107 | if (interface_id != 'S') | ||
3108 | return -EINVAL; | ||
3109 | |||
3110 | if (get_user(iovec_count, &sgio32->iovec_count)) | ||
3111 | return -EFAULT; | ||
3112 | |||
3113 | { | ||
3114 | void __user *top = compat_alloc_user_space(0); | ||
3115 | void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) + | ||
3116 | (iovec_count * sizeof(sg_iovec_t))); | ||
3117 | if (new > top) | ||
3118 | return -EINVAL; | ||
3119 | |||
3120 | sgio = new; | ||
3121 | } | ||
3122 | |||
3123 | /* Ok, now construct. */ | ||
3124 | if (copy_in_user(&sgio->interface_id, &sgio32->interface_id, | ||
3125 | (2 * sizeof(int)) + | ||
3126 | (2 * sizeof(unsigned char)) + | ||
3127 | (1 * sizeof(unsigned short)) + | ||
3128 | (1 * sizeof(unsigned int)))) | ||
3129 | return -EFAULT; | ||
3130 | |||
3131 | if (get_user(data, &sgio32->dxferp)) | ||
3132 | return -EFAULT; | ||
3133 | dxferp = compat_ptr(data); | ||
3134 | if (iovec_count) { | ||
3135 | if (sg_build_iovec(sgio, dxferp, iovec_count)) | ||
3136 | return -EFAULT; | ||
3137 | } else { | ||
3138 | if (put_user(dxferp, &sgio->dxferp)) | ||
3139 | return -EFAULT; | ||
3140 | } | ||
3141 | |||
3142 | { | ||
3143 | unsigned char __user *cmdp; | ||
3144 | unsigned char __user *sbp; | ||
3145 | |||
3146 | if (get_user(data, &sgio32->cmdp)) | ||
3147 | return -EFAULT; | ||
3148 | cmdp = compat_ptr(data); | ||
3149 | |||
3150 | if (get_user(data, &sgio32->sbp)) | ||
3151 | return -EFAULT; | ||
3152 | sbp = compat_ptr(data); | ||
3153 | |||
3154 | if (put_user(cmdp, &sgio->cmdp) || | ||
3155 | put_user(sbp, &sgio->sbp)) | ||
3156 | return -EFAULT; | ||
3157 | } | ||
3158 | |||
3159 | if (copy_in_user(&sgio->timeout, &sgio32->timeout, | ||
3160 | 3 * sizeof(int))) | ||
3161 | return -EFAULT; | ||
3162 | |||
3163 | if (get_user(data, &sgio32->usr_ptr)) | ||
3164 | return -EFAULT; | ||
3165 | if (put_user(compat_ptr(data), &sgio->usr_ptr)) | ||
3166 | return -EFAULT; | ||
3167 | |||
3168 | err = nvme_sg_io(ns, sgio); | ||
3169 | if (err >= 0) { | ||
3170 | void __user *datap; | ||
3171 | |||
3172 | if (copy_in_user(&sgio32->pack_id, &sgio->pack_id, | ||
3173 | sizeof(int)) || | ||
3174 | get_user(datap, &sgio->usr_ptr) || | ||
3175 | put_user((u32)(unsigned long)datap, | ||
3176 | &sgio32->usr_ptr) || | ||
3177 | copy_in_user(&sgio32->status, &sgio->status, | ||
3178 | (4 * sizeof(unsigned char)) + | ||
3179 | (2 * sizeof(unsigned short)) + | ||
3180 | (3 * sizeof(int)))) | ||
3181 | err = -EFAULT; | ||
3182 | } | ||
3183 | |||
3184 | return err; | ||
3185 | } | ||
3186 | #endif | ||
3187 | |||
3041 | int nvme_sg_get_version_num(int __user *ip) | 3188 | int nvme_sg_get_version_num(int __user *ip) |
3042 | { | 3189 | { |
3043 | return put_user(sg_version_num, ip); | 3190 | return put_user(sg_version_num, ip); |
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index da18046d0e07..4b97b86da926 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -285,7 +285,8 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, | |||
285 | 285 | ||
286 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || | 286 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || |
287 | !rb_next(&persistent_gnt->node)) { | 287 | !rb_next(&persistent_gnt->node)) { |
288 | ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); | 288 | ret = gnttab_unmap_refs(unmap, NULL, pages, |
289 | segs_to_unmap); | ||
289 | BUG_ON(ret); | 290 | BUG_ON(ret); |
290 | put_free_pages(blkif, pages, segs_to_unmap); | 291 | put_free_pages(blkif, pages, segs_to_unmap); |
291 | segs_to_unmap = 0; | 292 | segs_to_unmap = 0; |
@@ -320,7 +321,8 @@ static void unmap_purged_grants(struct work_struct *work) | |||
320 | pages[segs_to_unmap] = persistent_gnt->page; | 321 | pages[segs_to_unmap] = persistent_gnt->page; |
321 | 322 | ||
322 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { | 323 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { |
323 | ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); | 324 | ret = gnttab_unmap_refs(unmap, NULL, pages, |
325 | segs_to_unmap); | ||
324 | BUG_ON(ret); | 326 | BUG_ON(ret); |
325 | put_free_pages(blkif, pages, segs_to_unmap); | 327 | put_free_pages(blkif, pages, segs_to_unmap); |
326 | segs_to_unmap = 0; | 328 | segs_to_unmap = 0; |
@@ -328,7 +330,7 @@ static void unmap_purged_grants(struct work_struct *work) | |||
328 | kfree(persistent_gnt); | 330 | kfree(persistent_gnt); |
329 | } | 331 | } |
330 | if (segs_to_unmap > 0) { | 332 | if (segs_to_unmap > 0) { |
331 | ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); | 333 | ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); |
332 | BUG_ON(ret); | 334 | BUG_ON(ret); |
333 | put_free_pages(blkif, pages, segs_to_unmap); | 335 | put_free_pages(blkif, pages, segs_to_unmap); |
334 | } | 336 | } |
@@ -668,14 +670,15 @@ static void xen_blkbk_unmap(struct xen_blkif *blkif, | |||
668 | GNTMAP_host_map, pages[i]->handle); | 670 | GNTMAP_host_map, pages[i]->handle); |
669 | pages[i]->handle = BLKBACK_INVALID_HANDLE; | 671 | pages[i]->handle = BLKBACK_INVALID_HANDLE; |
670 | if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { | 672 | if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { |
671 | ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); | 673 | ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, |
674 | invcount); | ||
672 | BUG_ON(ret); | 675 | BUG_ON(ret); |
673 | put_free_pages(blkif, unmap_pages, invcount); | 676 | put_free_pages(blkif, unmap_pages, invcount); |
674 | invcount = 0; | 677 | invcount = 0; |
675 | } | 678 | } |
676 | } | 679 | } |
677 | if (invcount) { | 680 | if (invcount) { |
678 | ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); | 681 | ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount); |
679 | BUG_ON(ret); | 682 | BUG_ON(ret); |
680 | put_free_pages(blkif, unmap_pages, invcount); | 683 | put_free_pages(blkif, unmap_pages, invcount); |
681 | } | 684 | } |
@@ -737,7 +740,7 @@ again: | |||
737 | } | 740 | } |
738 | 741 | ||
739 | if (segs_to_map) { | 742 | if (segs_to_map) { |
740 | ret = gnttab_map_refs(map, pages_to_gnt, segs_to_map); | 743 | ret = gnttab_map_refs(map, NULL, pages_to_gnt, segs_to_map); |
741 | BUG_ON(ret); | 744 | BUG_ON(ret); |
742 | } | 745 | } |
743 | 746 | ||
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 7e257b233602..79606f473f48 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -57,6 +57,7 @@ struct sample { | |||
57 | int32_t core_pct_busy; | 57 | int32_t core_pct_busy; |
58 | u64 aperf; | 58 | u64 aperf; |
59 | u64 mperf; | 59 | u64 mperf; |
60 | unsigned long long tsc; | ||
60 | int freq; | 61 | int freq; |
61 | }; | 62 | }; |
62 | 63 | ||
@@ -96,6 +97,7 @@ struct cpudata { | |||
96 | 97 | ||
97 | u64 prev_aperf; | 98 | u64 prev_aperf; |
98 | u64 prev_mperf; | 99 | u64 prev_mperf; |
100 | unsigned long long prev_tsc; | ||
99 | int sample_ptr; | 101 | int sample_ptr; |
100 | struct sample samples[SAMPLE_COUNT]; | 102 | struct sample samples[SAMPLE_COUNT]; |
101 | }; | 103 | }; |
@@ -548,30 +550,41 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu, | |||
548 | struct sample *sample) | 550 | struct sample *sample) |
549 | { | 551 | { |
550 | u64 core_pct; | 552 | u64 core_pct; |
551 | core_pct = div64_u64(int_tofp(sample->aperf * 100), | 553 | u64 c0_pct; |
552 | sample->mperf); | ||
553 | sample->freq = fp_toint(cpu->pstate.max_pstate * core_pct * 1000); | ||
554 | 554 | ||
555 | sample->core_pct_busy = core_pct; | 555 | core_pct = div64_u64(sample->aperf * 100, sample->mperf); |
556 | |||
557 | c0_pct = div64_u64(sample->mperf * 100, sample->tsc); | ||
558 | sample->freq = fp_toint( | ||
559 | mul_fp(int_tofp(cpu->pstate.max_pstate), | ||
560 | int_tofp(core_pct * 1000))); | ||
561 | |||
562 | sample->core_pct_busy = mul_fp(int_tofp(core_pct), | ||
563 | div_fp(int_tofp(c0_pct + 1), int_tofp(100))); | ||
556 | } | 564 | } |
557 | 565 | ||
558 | static inline void intel_pstate_sample(struct cpudata *cpu) | 566 | static inline void intel_pstate_sample(struct cpudata *cpu) |
559 | { | 567 | { |
560 | u64 aperf, mperf; | 568 | u64 aperf, mperf; |
569 | unsigned long long tsc; | ||
561 | 570 | ||
562 | rdmsrl(MSR_IA32_APERF, aperf); | 571 | rdmsrl(MSR_IA32_APERF, aperf); |
563 | rdmsrl(MSR_IA32_MPERF, mperf); | 572 | rdmsrl(MSR_IA32_MPERF, mperf); |
573 | tsc = native_read_tsc(); | ||
564 | 574 | ||
565 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; | 575 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; |
566 | cpu->samples[cpu->sample_ptr].aperf = aperf; | 576 | cpu->samples[cpu->sample_ptr].aperf = aperf; |
567 | cpu->samples[cpu->sample_ptr].mperf = mperf; | 577 | cpu->samples[cpu->sample_ptr].mperf = mperf; |
578 | cpu->samples[cpu->sample_ptr].tsc = tsc; | ||
568 | cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; | 579 | cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; |
569 | cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; | 580 | cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; |
581 | cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc; | ||
570 | 582 | ||
571 | intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); | 583 | intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); |
572 | 584 | ||
573 | cpu->prev_aperf = aperf; | 585 | cpu->prev_aperf = aperf; |
574 | cpu->prev_mperf = mperf; | 586 | cpu->prev_mperf = mperf; |
587 | cpu->prev_tsc = tsc; | ||
575 | } | 588 | } |
576 | 589 | ||
577 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | 590 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) |
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index 3f65dd6676b2..a28640f47c27 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c | |||
@@ -65,7 +65,7 @@ static void ast_dirty_update(struct ast_fbdev *afbdev, | |||
65 | * then the BO is being moved and we should | 65 | * then the BO is being moved and we should |
66 | * store up the damage until later. | 66 | * store up the damage until later. |
67 | */ | 67 | */ |
68 | if (!drm_can_sleep()) | 68 | if (drm_can_sleep()) |
69 | ret = ast_bo_reserve(bo, true); | 69 | ret = ast_bo_reserve(bo, true); |
70 | if (ret) { | 70 | if (ret) { |
71 | if (ret != -EBUSY) | 71 | if (ret != -EBUSY) |
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c index 2fd4a92162cb..32bbba0a787b 100644 --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c | |||
@@ -39,7 +39,7 @@ static void cirrus_dirty_update(struct cirrus_fbdev *afbdev, | |||
39 | * then the BO is being moved and we should | 39 | * then the BO is being moved and we should |
40 | * store up the damage until later. | 40 | * store up the damage until later. |
41 | */ | 41 | */ |
42 | if (!drm_can_sleep()) | 42 | if (drm_can_sleep()) |
43 | ret = cirrus_bo_reserve(bo, true); | 43 | ret = cirrus_bo_reserve(bo, true); |
44 | if (ret) { | 44 | if (ret) { |
45 | if (ret != -EBUSY) | 45 | if (ret != -EBUSY) |
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c index f9adc27ef32a..13b7dd83faa9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_fb.c +++ b/drivers/gpu/drm/mgag200/mgag200_fb.c | |||
@@ -41,7 +41,7 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev, | |||
41 | * then the BO is being moved and we should | 41 | * then the BO is being moved and we should |
42 | * store up the damage until later. | 42 | * store up the damage until later. |
43 | */ | 43 | */ |
44 | if (!drm_can_sleep()) | 44 | if (drm_can_sleep()) |
45 | ret = mgag200_bo_reserve(bo, true); | 45 | ret = mgag200_bo_reserve(bo, true); |
46 | if (ret) { | 46 | if (ret) { |
47 | if (ret != -EBUSY) | 47 | if (ret != -EBUSY) |
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index b8583f275e80..968374776db9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
@@ -1519,11 +1519,11 @@ static int mga_vga_mode_valid(struct drm_connector *connector, | |||
1519 | (mga_vga_calculate_mode_bandwidth(mode, bpp) | 1519 | (mga_vga_calculate_mode_bandwidth(mode, bpp) |
1520 | > (32700 * 1024))) { | 1520 | > (32700 * 1024))) { |
1521 | return MODE_BANDWIDTH; | 1521 | return MODE_BANDWIDTH; |
1522 | } else if (mode->type == G200_EH && | 1522 | } else if (mdev->type == G200_EH && |
1523 | (mga_vga_calculate_mode_bandwidth(mode, bpp) | 1523 | (mga_vga_calculate_mode_bandwidth(mode, bpp) |
1524 | > (37500 * 1024))) { | 1524 | > (37500 * 1024))) { |
1525 | return MODE_BANDWIDTH; | 1525 | return MODE_BANDWIDTH; |
1526 | } else if (mode->type == G200_ER && | 1526 | } else if (mdev->type == G200_ER && |
1527 | (mga_vga_calculate_mode_bandwidth(mode, | 1527 | (mga_vga_calculate_mode_bandwidth(mode, |
1528 | bpp) > (55000 * 1024))) { | 1528 | bpp) > (55000 * 1024))) { |
1529 | return MODE_BANDWIDTH; | 1529 | return MODE_BANDWIDTH; |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 7b399dc5fd54..2812c7d1ae6f 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -1007,8 +1007,22 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1007 | case R_008C64_SQ_VSTMP_RING_SIZE: | 1007 | case R_008C64_SQ_VSTMP_RING_SIZE: |
1008 | case R_0288C8_SQ_GS_VERT_ITEMSIZE: | 1008 | case R_0288C8_SQ_GS_VERT_ITEMSIZE: |
1009 | /* get value to populate the IB don't remove */ | 1009 | /* get value to populate the IB don't remove */ |
1010 | tmp =radeon_get_ib_value(p, idx); | 1010 | /*tmp =radeon_get_ib_value(p, idx); |
1011 | ib[idx] = 0; | 1011 | ib[idx] = 0;*/ |
1012 | break; | ||
1013 | case SQ_ESGS_RING_BASE: | ||
1014 | case SQ_GSVS_RING_BASE: | ||
1015 | case SQ_ESTMP_RING_BASE: | ||
1016 | case SQ_GSTMP_RING_BASE: | ||
1017 | case SQ_PSTMP_RING_BASE: | ||
1018 | case SQ_VSTMP_RING_BASE: | ||
1019 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); | ||
1020 | if (r) { | ||
1021 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
1022 | "0x%04X\n", reg); | ||
1023 | return -EINVAL; | ||
1024 | } | ||
1025 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1012 | break; | 1026 | break; |
1013 | case SQ_CONFIG: | 1027 | case SQ_CONFIG: |
1014 | track->sq_config = radeon_get_ib_value(p, idx); | 1028 | track->sq_config = radeon_get_ib_value(p, idx); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index ec8c388eec17..84a1bbb75f91 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -78,9 +78,10 @@ | |||
78 | * 2.34.0 - Add CIK tiling mode array query | 78 | * 2.34.0 - Add CIK tiling mode array query |
79 | * 2.35.0 - Add CIK macrotile mode array query | 79 | * 2.35.0 - Add CIK macrotile mode array query |
80 | * 2.36.0 - Fix CIK DCE tiling setup | 80 | * 2.36.0 - Fix CIK DCE tiling setup |
81 | * 2.37.0 - allow GS ring setup on r6xx/r7xx | ||
81 | */ | 82 | */ |
82 | #define KMS_DRIVER_MAJOR 2 | 83 | #define KMS_DRIVER_MAJOR 2 |
83 | #define KMS_DRIVER_MINOR 36 | 84 | #define KMS_DRIVER_MINOR 37 |
84 | #define KMS_DRIVER_PATCHLEVEL 0 | 85 | #define KMS_DRIVER_PATCHLEVEL 0 |
85 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 86 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
86 | int radeon_driver_unload_kms(struct drm_device *dev); | 87 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index 20bfbda7b3f1..ec0c6829c1dc 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
@@ -18,6 +18,7 @@ r600 0x9400 | |||
18 | 0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL | 18 | 0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL |
19 | 0x00028A40 VGT_GS_MODE | 19 | 0x00028A40 VGT_GS_MODE |
20 | 0x00028A6C VGT_GS_OUT_PRIM_TYPE | 20 | 0x00028A6C VGT_GS_OUT_PRIM_TYPE |
21 | 0x00028B38 VGT_GS_MAX_VERT_OUT | ||
21 | 0x000088C8 VGT_GS_PER_ES | 22 | 0x000088C8 VGT_GS_PER_ES |
22 | 0x000088E8 VGT_GS_PER_VS | 23 | 0x000088E8 VGT_GS_PER_VS |
23 | 0x000088D4 VGT_GS_VERTEX_REUSE | 24 | 0x000088D4 VGT_GS_VERTEX_REUSE |
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c index 37079859afc8..53b51c4e671a 100644 --- a/drivers/gpu/drm/ttm/ttm_object.c +++ b/drivers/gpu/drm/ttm/ttm_object.c | |||
@@ -292,7 +292,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, | |||
292 | 292 | ||
293 | if (ret == 0) { | 293 | if (ret == 0) { |
294 | ref = drm_hash_entry(hash, struct ttm_ref_object, hash); | 294 | ref = drm_hash_entry(hash, struct ttm_ref_object, hash); |
295 | if (!kref_get_unless_zero(&ref->kref)) { | 295 | if (kref_get_unless_zero(&ref->kref)) { |
296 | rcu_read_unlock(); | 296 | rcu_read_unlock(); |
297 | break; | 297 | break; |
298 | } | 298 | } |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 9af99084b344..75f319090043 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -380,6 +380,9 @@ static void ttm_tt_clear_mapping(struct ttm_tt *ttm) | |||
380 | pgoff_t i; | 380 | pgoff_t i; |
381 | struct page **page = ttm->pages; | 381 | struct page **page = ttm->pages; |
382 | 382 | ||
383 | if (ttm->page_flags & TTM_PAGE_FLAG_SG) | ||
384 | return; | ||
385 | |||
383 | for (i = 0; i < ttm->num_pages; ++i) { | 386 | for (i = 0; i < ttm->num_pages; ++i) { |
384 | (*page)->mapping = NULL; | 387 | (*page)->mapping = NULL; |
385 | (*page++)->index = 0; | 388 | (*page++)->index = 0; |
diff --git a/drivers/gpu/drm/vmwgfx/svga3d_reg.h b/drivers/gpu/drm/vmwgfx/svga3d_reg.h index d95335cb90bd..b645647b7776 100644 --- a/drivers/gpu/drm/vmwgfx/svga3d_reg.h +++ b/drivers/gpu/drm/vmwgfx/svga3d_reg.h | |||
@@ -2583,4 +2583,28 @@ typedef union { | |||
2583 | float f; | 2583 | float f; |
2584 | } SVGA3dDevCapResult; | 2584 | } SVGA3dDevCapResult; |
2585 | 2585 | ||
2586 | typedef enum { | ||
2587 | SVGA3DCAPS_RECORD_UNKNOWN = 0, | ||
2588 | SVGA3DCAPS_RECORD_DEVCAPS_MIN = 0x100, | ||
2589 | SVGA3DCAPS_RECORD_DEVCAPS = 0x100, | ||
2590 | SVGA3DCAPS_RECORD_DEVCAPS_MAX = 0x1ff, | ||
2591 | } SVGA3dCapsRecordType; | ||
2592 | |||
2593 | typedef | ||
2594 | struct SVGA3dCapsRecordHeader { | ||
2595 | uint32 length; | ||
2596 | SVGA3dCapsRecordType type; | ||
2597 | } | ||
2598 | SVGA3dCapsRecordHeader; | ||
2599 | |||
2600 | typedef | ||
2601 | struct SVGA3dCapsRecord { | ||
2602 | SVGA3dCapsRecordHeader header; | ||
2603 | uint32 data[1]; | ||
2604 | } | ||
2605 | SVGA3dCapsRecord; | ||
2606 | |||
2607 | |||
2608 | typedef uint32 SVGA3dCapPair[2]; | ||
2609 | |||
2586 | #endif /* _SVGA3D_REG_H_ */ | 2610 | #endif /* _SVGA3D_REG_H_ */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index 82c41daebc0e..9426c53fb483 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c | |||
@@ -37,7 +37,7 @@ struct vmw_user_context { | |||
37 | 37 | ||
38 | 38 | ||
39 | 39 | ||
40 | typedef int (*vmw_scrub_func)(struct vmw_ctx_bindinfo *); | 40 | typedef int (*vmw_scrub_func)(struct vmw_ctx_bindinfo *, bool); |
41 | 41 | ||
42 | static void vmw_user_context_free(struct vmw_resource *res); | 42 | static void vmw_user_context_free(struct vmw_resource *res); |
43 | static struct vmw_resource * | 43 | static struct vmw_resource * |
@@ -50,9 +50,11 @@ static int vmw_gb_context_unbind(struct vmw_resource *res, | |||
50 | bool readback, | 50 | bool readback, |
51 | struct ttm_validate_buffer *val_buf); | 51 | struct ttm_validate_buffer *val_buf); |
52 | static int vmw_gb_context_destroy(struct vmw_resource *res); | 52 | static int vmw_gb_context_destroy(struct vmw_resource *res); |
53 | static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi); | 53 | static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind); |
54 | static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi); | 54 | static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi, |
55 | static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi); | 55 | bool rebind); |
56 | static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi, bool rebind); | ||
57 | static void vmw_context_binding_state_scrub(struct vmw_ctx_binding_state *cbs); | ||
56 | static void vmw_context_binding_state_kill(struct vmw_ctx_binding_state *cbs); | 58 | static void vmw_context_binding_state_kill(struct vmw_ctx_binding_state *cbs); |
57 | static uint64_t vmw_user_context_size; | 59 | static uint64_t vmw_user_context_size; |
58 | 60 | ||
@@ -111,10 +113,14 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) | |||
111 | 113 | ||
112 | if (res->func->destroy == vmw_gb_context_destroy) { | 114 | if (res->func->destroy == vmw_gb_context_destroy) { |
113 | mutex_lock(&dev_priv->cmdbuf_mutex); | 115 | mutex_lock(&dev_priv->cmdbuf_mutex); |
116 | mutex_lock(&dev_priv->binding_mutex); | ||
117 | (void) vmw_context_binding_state_kill | ||
118 | (&container_of(res, struct vmw_user_context, res)->cbs); | ||
114 | (void) vmw_gb_context_destroy(res); | 119 | (void) vmw_gb_context_destroy(res); |
115 | if (dev_priv->pinned_bo != NULL && | 120 | if (dev_priv->pinned_bo != NULL && |
116 | !dev_priv->query_cid_valid) | 121 | !dev_priv->query_cid_valid) |
117 | __vmw_execbuf_release_pinned_bo(dev_priv, NULL); | 122 | __vmw_execbuf_release_pinned_bo(dev_priv, NULL); |
123 | mutex_unlock(&dev_priv->binding_mutex); | ||
118 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 124 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
119 | return; | 125 | return; |
120 | } | 126 | } |
@@ -328,7 +334,7 @@ static int vmw_gb_context_unbind(struct vmw_resource *res, | |||
328 | BUG_ON(bo->mem.mem_type != VMW_PL_MOB); | 334 | BUG_ON(bo->mem.mem_type != VMW_PL_MOB); |
329 | 335 | ||
330 | mutex_lock(&dev_priv->binding_mutex); | 336 | mutex_lock(&dev_priv->binding_mutex); |
331 | vmw_context_binding_state_kill(&uctx->cbs); | 337 | vmw_context_binding_state_scrub(&uctx->cbs); |
332 | 338 | ||
333 | submit_size = sizeof(*cmd2) + (readback ? sizeof(*cmd1) : 0); | 339 | submit_size = sizeof(*cmd2) + (readback ? sizeof(*cmd1) : 0); |
334 | 340 | ||
@@ -378,10 +384,6 @@ static int vmw_gb_context_destroy(struct vmw_resource *res) | |||
378 | SVGA3dCmdHeader header; | 384 | SVGA3dCmdHeader header; |
379 | SVGA3dCmdDestroyGBContext body; | 385 | SVGA3dCmdDestroyGBContext body; |
380 | } *cmd; | 386 | } *cmd; |
381 | struct vmw_user_context *uctx = | ||
382 | container_of(res, struct vmw_user_context, res); | ||
383 | |||
384 | BUG_ON(!list_empty(&uctx->cbs.list)); | ||
385 | 387 | ||
386 | if (likely(res->id == -1)) | 388 | if (likely(res->id == -1)) |
387 | return 0; | 389 | return 0; |
@@ -528,8 +530,9 @@ out_unlock: | |||
528 | * vmw_context_scrub_shader - scrub a shader binding from a context. | 530 | * vmw_context_scrub_shader - scrub a shader binding from a context. |
529 | * | 531 | * |
530 | * @bi: single binding information. | 532 | * @bi: single binding information. |
533 | * @rebind: Whether to issue a bind instead of scrub command. | ||
531 | */ | 534 | */ |
532 | static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi) | 535 | static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind) |
533 | { | 536 | { |
534 | struct vmw_private *dev_priv = bi->ctx->dev_priv; | 537 | struct vmw_private *dev_priv = bi->ctx->dev_priv; |
535 | struct { | 538 | struct { |
@@ -548,7 +551,8 @@ static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi) | |||
548 | cmd->header.size = sizeof(cmd->body); | 551 | cmd->header.size = sizeof(cmd->body); |
549 | cmd->body.cid = bi->ctx->id; | 552 | cmd->body.cid = bi->ctx->id; |
550 | cmd->body.type = bi->i1.shader_type; | 553 | cmd->body.type = bi->i1.shader_type; |
551 | cmd->body.shid = SVGA3D_INVALID_ID; | 554 | cmd->body.shid = |
555 | cpu_to_le32((rebind) ? bi->res->id : SVGA3D_INVALID_ID); | ||
552 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 556 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
553 | 557 | ||
554 | return 0; | 558 | return 0; |
@@ -559,8 +563,10 @@ static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi) | |||
559 | * from a context. | 563 | * from a context. |
560 | * | 564 | * |
561 | * @bi: single binding information. | 565 | * @bi: single binding information. |
566 | * @rebind: Whether to issue a bind instead of scrub command. | ||
562 | */ | 567 | */ |
563 | static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi) | 568 | static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi, |
569 | bool rebind) | ||
564 | { | 570 | { |
565 | struct vmw_private *dev_priv = bi->ctx->dev_priv; | 571 | struct vmw_private *dev_priv = bi->ctx->dev_priv; |
566 | struct { | 572 | struct { |
@@ -579,7 +585,8 @@ static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi) | |||
579 | cmd->header.size = sizeof(cmd->body); | 585 | cmd->header.size = sizeof(cmd->body); |
580 | cmd->body.cid = bi->ctx->id; | 586 | cmd->body.cid = bi->ctx->id; |
581 | cmd->body.type = bi->i1.rt_type; | 587 | cmd->body.type = bi->i1.rt_type; |
582 | cmd->body.target.sid = SVGA3D_INVALID_ID; | 588 | cmd->body.target.sid = |
589 | cpu_to_le32((rebind) ? bi->res->id : SVGA3D_INVALID_ID); | ||
583 | cmd->body.target.face = 0; | 590 | cmd->body.target.face = 0; |
584 | cmd->body.target.mipmap = 0; | 591 | cmd->body.target.mipmap = 0; |
585 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 592 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
@@ -591,11 +598,13 @@ static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi) | |||
591 | * vmw_context_scrub_texture - scrub a texture binding from a context. | 598 | * vmw_context_scrub_texture - scrub a texture binding from a context. |
592 | * | 599 | * |
593 | * @bi: single binding information. | 600 | * @bi: single binding information. |
601 | * @rebind: Whether to issue a bind instead of scrub command. | ||
594 | * | 602 | * |
595 | * TODO: Possibly complement this function with a function that takes | 603 | * TODO: Possibly complement this function with a function that takes |
596 | * a list of texture bindings and combines them to a single command. | 604 | * a list of texture bindings and combines them to a single command. |
597 | */ | 605 | */ |
598 | static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi) | 606 | static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi, |
607 | bool rebind) | ||
599 | { | 608 | { |
600 | struct vmw_private *dev_priv = bi->ctx->dev_priv; | 609 | struct vmw_private *dev_priv = bi->ctx->dev_priv; |
601 | struct { | 610 | struct { |
@@ -619,7 +628,8 @@ static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi) | |||
619 | cmd->body.c.cid = bi->ctx->id; | 628 | cmd->body.c.cid = bi->ctx->id; |
620 | cmd->body.s1.stage = bi->i1.texture_stage; | 629 | cmd->body.s1.stage = bi->i1.texture_stage; |
621 | cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE; | 630 | cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE; |
622 | cmd->body.s1.value = (uint32) SVGA3D_INVALID_ID; | 631 | cmd->body.s1.value = |
632 | cpu_to_le32((rebind) ? bi->res->id : SVGA3D_INVALID_ID); | ||
623 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 633 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
624 | 634 | ||
625 | return 0; | 635 | return 0; |
@@ -692,6 +702,7 @@ int vmw_context_binding_add(struct vmw_ctx_binding_state *cbs, | |||
692 | vmw_context_binding_drop(loc); | 702 | vmw_context_binding_drop(loc); |
693 | 703 | ||
694 | loc->bi = *bi; | 704 | loc->bi = *bi; |
705 | loc->bi.scrubbed = false; | ||
695 | list_add_tail(&loc->ctx_list, &cbs->list); | 706 | list_add_tail(&loc->ctx_list, &cbs->list); |
696 | INIT_LIST_HEAD(&loc->res_list); | 707 | INIT_LIST_HEAD(&loc->res_list); |
697 | 708 | ||
@@ -727,12 +738,11 @@ static void vmw_context_binding_transfer(struct vmw_ctx_binding_state *cbs, | |||
727 | if (loc->bi.ctx != NULL) | 738 | if (loc->bi.ctx != NULL) |
728 | vmw_context_binding_drop(loc); | 739 | vmw_context_binding_drop(loc); |
729 | 740 | ||
730 | loc->bi = *bi; | 741 | if (bi->res != NULL) { |
731 | list_add_tail(&loc->ctx_list, &cbs->list); | 742 | loc->bi = *bi; |
732 | if (bi->res != NULL) | 743 | list_add_tail(&loc->ctx_list, &cbs->list); |
733 | list_add_tail(&loc->res_list, &bi->res->binding_head); | 744 | list_add_tail(&loc->res_list, &bi->res->binding_head); |
734 | else | 745 | } |
735 | INIT_LIST_HEAD(&loc->res_list); | ||
736 | } | 746 | } |
737 | 747 | ||
738 | /** | 748 | /** |
@@ -746,7 +756,10 @@ static void vmw_context_binding_transfer(struct vmw_ctx_binding_state *cbs, | |||
746 | */ | 756 | */ |
747 | static void vmw_context_binding_kill(struct vmw_ctx_binding *cb) | 757 | static void vmw_context_binding_kill(struct vmw_ctx_binding *cb) |
748 | { | 758 | { |
749 | (void) vmw_scrub_funcs[cb->bi.bt](&cb->bi); | 759 | if (!cb->bi.scrubbed) { |
760 | (void) vmw_scrub_funcs[cb->bi.bt](&cb->bi, false); | ||
761 | cb->bi.scrubbed = true; | ||
762 | } | ||
750 | vmw_context_binding_drop(cb); | 763 | vmw_context_binding_drop(cb); |
751 | } | 764 | } |
752 | 765 | ||
@@ -768,6 +781,27 @@ static void vmw_context_binding_state_kill(struct vmw_ctx_binding_state *cbs) | |||
768 | } | 781 | } |
769 | 782 | ||
770 | /** | 783 | /** |
784 | * vmw_context_binding_state_scrub - Scrub all bindings associated with a | ||
785 | * struct vmw_ctx_binding state structure. | ||
786 | * | ||
787 | * @cbs: Pointer to the context binding state tracker. | ||
788 | * | ||
789 | * Emits commands to scrub all bindings associated with the | ||
790 | * context binding state tracker. | ||
791 | */ | ||
792 | static void vmw_context_binding_state_scrub(struct vmw_ctx_binding_state *cbs) | ||
793 | { | ||
794 | struct vmw_ctx_binding *entry; | ||
795 | |||
796 | list_for_each_entry(entry, &cbs->list, ctx_list) { | ||
797 | if (!entry->bi.scrubbed) { | ||
798 | (void) vmw_scrub_funcs[entry->bi.bt](&entry->bi, false); | ||
799 | entry->bi.scrubbed = true; | ||
800 | } | ||
801 | } | ||
802 | } | ||
803 | |||
804 | /** | ||
771 | * vmw_context_binding_res_list_kill - Kill all bindings on a | 805 | * vmw_context_binding_res_list_kill - Kill all bindings on a |
772 | * resource binding list | 806 | * resource binding list |
773 | * | 807 | * |
@@ -785,6 +819,27 @@ void vmw_context_binding_res_list_kill(struct list_head *head) | |||
785 | } | 819 | } |
786 | 820 | ||
787 | /** | 821 | /** |
822 | * vmw_context_binding_res_list_scrub - Scrub all bindings on a | ||
823 | * resource binding list | ||
824 | * | ||
825 | * @head: list head of resource binding list | ||
826 | * | ||
827 | * Scrub all bindings associated with a specific resource. Typically | ||
828 | * called before the resource is evicted. | ||
829 | */ | ||
830 | void vmw_context_binding_res_list_scrub(struct list_head *head) | ||
831 | { | ||
832 | struct vmw_ctx_binding *entry; | ||
833 | |||
834 | list_for_each_entry(entry, head, res_list) { | ||
835 | if (!entry->bi.scrubbed) { | ||
836 | (void) vmw_scrub_funcs[entry->bi.bt](&entry->bi, false); | ||
837 | entry->bi.scrubbed = true; | ||
838 | } | ||
839 | } | ||
840 | } | ||
841 | |||
842 | /** | ||
788 | * vmw_context_binding_state_transfer - Commit staged binding info | 843 | * vmw_context_binding_state_transfer - Commit staged binding info |
789 | * | 844 | * |
790 | * @ctx: Pointer to context to commit the staged binding info to. | 845 | * @ctx: Pointer to context to commit the staged binding info to. |
@@ -803,3 +858,50 @@ void vmw_context_binding_state_transfer(struct vmw_resource *ctx, | |||
803 | list_for_each_entry_safe(entry, next, &from->list, ctx_list) | 858 | list_for_each_entry_safe(entry, next, &from->list, ctx_list) |
804 | vmw_context_binding_transfer(&uctx->cbs, &entry->bi); | 859 | vmw_context_binding_transfer(&uctx->cbs, &entry->bi); |
805 | } | 860 | } |
861 | |||
862 | /** | ||
863 | * vmw_context_rebind_all - Rebind all scrubbed bindings of a context | ||
864 | * | ||
865 | * @ctx: The context resource | ||
866 | * | ||
867 | * Walks through the context binding list and rebinds all scrubbed | ||
868 | * resources. | ||
869 | */ | ||
870 | int vmw_context_rebind_all(struct vmw_resource *ctx) | ||
871 | { | ||
872 | struct vmw_ctx_binding *entry; | ||
873 | struct vmw_user_context *uctx = | ||
874 | container_of(ctx, struct vmw_user_context, res); | ||
875 | struct vmw_ctx_binding_state *cbs = &uctx->cbs; | ||
876 | int ret; | ||
877 | |||
878 | list_for_each_entry(entry, &cbs->list, ctx_list) { | ||
879 | if (likely(!entry->bi.scrubbed)) | ||
880 | continue; | ||
881 | |||
882 | if (WARN_ON(entry->bi.res == NULL || entry->bi.res->id == | ||
883 | SVGA3D_INVALID_ID)) | ||
884 | continue; | ||
885 | |||
886 | ret = vmw_scrub_funcs[entry->bi.bt](&entry->bi, true); | ||
887 | if (unlikely(ret != 0)) | ||
888 | return ret; | ||
889 | |||
890 | entry->bi.scrubbed = false; | ||
891 | } | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | /** | ||
897 | * vmw_context_binding_list - Return a list of context bindings | ||
898 | * | ||
899 | * @ctx: The context resource | ||
900 | * | ||
901 | * Returns the current list of bindings of the given context. Note that | ||
902 | * this list becomes stale as soon as the dev_priv::binding_mutex is unlocked. | ||
903 | */ | ||
904 | struct list_head *vmw_context_binding_list(struct vmw_resource *ctx) | ||
905 | { | ||
906 | return &(container_of(ctx, struct vmw_user_context, res)->cbs.list); | ||
907 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 9893328f8fdc..3bdc0adc656d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -941,6 +941,7 @@ static void vmw_postclose(struct drm_device *dev, | |||
941 | drm_master_put(&vmw_fp->locked_master); | 941 | drm_master_put(&vmw_fp->locked_master); |
942 | } | 942 | } |
943 | 943 | ||
944 | vmw_compat_shader_man_destroy(vmw_fp->shman); | ||
944 | ttm_object_file_release(&vmw_fp->tfile); | 945 | ttm_object_file_release(&vmw_fp->tfile); |
945 | kfree(vmw_fp); | 946 | kfree(vmw_fp); |
946 | } | 947 | } |
@@ -960,11 +961,17 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) | |||
960 | if (unlikely(vmw_fp->tfile == NULL)) | 961 | if (unlikely(vmw_fp->tfile == NULL)) |
961 | goto out_no_tfile; | 962 | goto out_no_tfile; |
962 | 963 | ||
964 | vmw_fp->shman = vmw_compat_shader_man_create(dev_priv); | ||
965 | if (IS_ERR(vmw_fp->shman)) | ||
966 | goto out_no_shman; | ||
967 | |||
963 | file_priv->driver_priv = vmw_fp; | 968 | file_priv->driver_priv = vmw_fp; |
964 | dev_priv->bdev.dev_mapping = dev->dev_mapping; | 969 | dev_priv->bdev.dev_mapping = dev->dev_mapping; |
965 | 970 | ||
966 | return 0; | 971 | return 0; |
967 | 972 | ||
973 | out_no_shman: | ||
974 | ttm_object_file_release(&vmw_fp->tfile); | ||
968 | out_no_tfile: | 975 | out_no_tfile: |
969 | kfree(vmw_fp); | 976 | kfree(vmw_fp); |
970 | return ret; | 977 | return ret; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 554e7fa33082..ecaa302a6154 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -75,10 +75,14 @@ | |||
75 | #define VMW_RES_FENCE ttm_driver_type3 | 75 | #define VMW_RES_FENCE ttm_driver_type3 |
76 | #define VMW_RES_SHADER ttm_driver_type4 | 76 | #define VMW_RES_SHADER ttm_driver_type4 |
77 | 77 | ||
78 | struct vmw_compat_shader_manager; | ||
79 | |||
78 | struct vmw_fpriv { | 80 | struct vmw_fpriv { |
79 | struct drm_master *locked_master; | 81 | struct drm_master *locked_master; |
80 | struct ttm_object_file *tfile; | 82 | struct ttm_object_file *tfile; |
81 | struct list_head fence_events; | 83 | struct list_head fence_events; |
84 | bool gb_aware; | ||
85 | struct vmw_compat_shader_manager *shman; | ||
82 | }; | 86 | }; |
83 | 87 | ||
84 | struct vmw_dma_buffer { | 88 | struct vmw_dma_buffer { |
@@ -272,6 +276,7 @@ struct vmw_ctx_bindinfo { | |||
272 | struct vmw_resource *ctx; | 276 | struct vmw_resource *ctx; |
273 | struct vmw_resource *res; | 277 | struct vmw_resource *res; |
274 | enum vmw_ctx_binding_type bt; | 278 | enum vmw_ctx_binding_type bt; |
279 | bool scrubbed; | ||
275 | union { | 280 | union { |
276 | SVGA3dShaderType shader_type; | 281 | SVGA3dShaderType shader_type; |
277 | SVGA3dRenderTargetType rt_type; | 282 | SVGA3dRenderTargetType rt_type; |
@@ -318,7 +323,7 @@ struct vmw_sw_context{ | |||
318 | struct drm_open_hash res_ht; | 323 | struct drm_open_hash res_ht; |
319 | bool res_ht_initialized; | 324 | bool res_ht_initialized; |
320 | bool kernel; /**< is the called made from the kernel */ | 325 | bool kernel; /**< is the called made from the kernel */ |
321 | struct ttm_object_file *tfile; | 326 | struct vmw_fpriv *fp; |
322 | struct list_head validate_nodes; | 327 | struct list_head validate_nodes; |
323 | struct vmw_relocation relocs[VMWGFX_MAX_RELOCATIONS]; | 328 | struct vmw_relocation relocs[VMWGFX_MAX_RELOCATIONS]; |
324 | uint32_t cur_reloc; | 329 | uint32_t cur_reloc; |
@@ -336,6 +341,7 @@ struct vmw_sw_context{ | |||
336 | bool needs_post_query_barrier; | 341 | bool needs_post_query_barrier; |
337 | struct vmw_resource *error_resource; | 342 | struct vmw_resource *error_resource; |
338 | struct vmw_ctx_binding_state staged_bindings; | 343 | struct vmw_ctx_binding_state staged_bindings; |
344 | struct list_head staged_shaders; | ||
339 | }; | 345 | }; |
340 | 346 | ||
341 | struct vmw_legacy_display; | 347 | struct vmw_legacy_display; |
@@ -569,6 +575,8 @@ struct vmw_user_resource_conv; | |||
569 | 575 | ||
570 | extern void vmw_resource_unreference(struct vmw_resource **p_res); | 576 | extern void vmw_resource_unreference(struct vmw_resource **p_res); |
571 | extern struct vmw_resource *vmw_resource_reference(struct vmw_resource *res); | 577 | extern struct vmw_resource *vmw_resource_reference(struct vmw_resource *res); |
578 | extern struct vmw_resource * | ||
579 | vmw_resource_reference_unless_doomed(struct vmw_resource *res); | ||
572 | extern int vmw_resource_validate(struct vmw_resource *res); | 580 | extern int vmw_resource_validate(struct vmw_resource *res); |
573 | extern int vmw_resource_reserve(struct vmw_resource *res, bool no_backup); | 581 | extern int vmw_resource_reserve(struct vmw_resource *res, bool no_backup); |
574 | extern bool vmw_resource_needs_backup(const struct vmw_resource *res); | 582 | extern bool vmw_resource_needs_backup(const struct vmw_resource *res); |
@@ -957,6 +965,9 @@ extern void | |||
957 | vmw_context_binding_state_transfer(struct vmw_resource *res, | 965 | vmw_context_binding_state_transfer(struct vmw_resource *res, |
958 | struct vmw_ctx_binding_state *cbs); | 966 | struct vmw_ctx_binding_state *cbs); |
959 | extern void vmw_context_binding_res_list_kill(struct list_head *head); | 967 | extern void vmw_context_binding_res_list_kill(struct list_head *head); |
968 | extern void vmw_context_binding_res_list_scrub(struct list_head *head); | ||
969 | extern int vmw_context_rebind_all(struct vmw_resource *ctx); | ||
970 | extern struct list_head *vmw_context_binding_list(struct vmw_resource *ctx); | ||
960 | 971 | ||
961 | /* | 972 | /* |
962 | * Surface management - vmwgfx_surface.c | 973 | * Surface management - vmwgfx_surface.c |
@@ -991,6 +1002,28 @@ extern int vmw_shader_define_ioctl(struct drm_device *dev, void *data, | |||
991 | struct drm_file *file_priv); | 1002 | struct drm_file *file_priv); |
992 | extern int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, | 1003 | extern int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, |
993 | struct drm_file *file_priv); | 1004 | struct drm_file *file_priv); |
1005 | extern int vmw_compat_shader_lookup(struct vmw_compat_shader_manager *man, | ||
1006 | SVGA3dShaderType shader_type, | ||
1007 | u32 *user_key); | ||
1008 | extern void vmw_compat_shaders_commit(struct vmw_compat_shader_manager *man, | ||
1009 | struct list_head *list); | ||
1010 | extern void vmw_compat_shaders_revert(struct vmw_compat_shader_manager *man, | ||
1011 | struct list_head *list); | ||
1012 | extern int vmw_compat_shader_remove(struct vmw_compat_shader_manager *man, | ||
1013 | u32 user_key, | ||
1014 | SVGA3dShaderType shader_type, | ||
1015 | struct list_head *list); | ||
1016 | extern int vmw_compat_shader_add(struct vmw_compat_shader_manager *man, | ||
1017 | u32 user_key, const void *bytecode, | ||
1018 | SVGA3dShaderType shader_type, | ||
1019 | size_t size, | ||
1020 | struct ttm_object_file *tfile, | ||
1021 | struct list_head *list); | ||
1022 | extern struct vmw_compat_shader_manager * | ||
1023 | vmw_compat_shader_man_create(struct vmw_private *dev_priv); | ||
1024 | extern void | ||
1025 | vmw_compat_shader_man_destroy(struct vmw_compat_shader_manager *man); | ||
1026 | |||
994 | 1027 | ||
995 | /** | 1028 | /** |
996 | * Inline helper functions | 1029 | * Inline helper functions |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 7a5f1eb55c5a..269b85cc875a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -114,8 +114,10 @@ static void vmw_resource_list_unreserve(struct list_head *list, | |||
114 | * persistent context binding tracker. | 114 | * persistent context binding tracker. |
115 | */ | 115 | */ |
116 | if (unlikely(val->staged_bindings)) { | 116 | if (unlikely(val->staged_bindings)) { |
117 | vmw_context_binding_state_transfer | 117 | if (!backoff) { |
118 | (val->res, val->staged_bindings); | 118 | vmw_context_binding_state_transfer |
119 | (val->res, val->staged_bindings); | ||
120 | } | ||
119 | kfree(val->staged_bindings); | 121 | kfree(val->staged_bindings); |
120 | val->staged_bindings = NULL; | 122 | val->staged_bindings = NULL; |
121 | } | 123 | } |
@@ -178,6 +180,44 @@ static int vmw_resource_val_add(struct vmw_sw_context *sw_context, | |||
178 | } | 180 | } |
179 | 181 | ||
180 | /** | 182 | /** |
183 | * vmw_resource_context_res_add - Put resources previously bound to a context on | ||
184 | * the validation list | ||
185 | * | ||
186 | * @dev_priv: Pointer to a device private structure | ||
187 | * @sw_context: Pointer to a software context used for this command submission | ||
188 | * @ctx: Pointer to the context resource | ||
189 | * | ||
190 | * This function puts all resources that were previously bound to @ctx on | ||
191 | * the resource validation list. This is part of the context state reemission | ||
192 | */ | ||
193 | static int vmw_resource_context_res_add(struct vmw_private *dev_priv, | ||
194 | struct vmw_sw_context *sw_context, | ||
195 | struct vmw_resource *ctx) | ||
196 | { | ||
197 | struct list_head *binding_list; | ||
198 | struct vmw_ctx_binding *entry; | ||
199 | int ret = 0; | ||
200 | struct vmw_resource *res; | ||
201 | |||
202 | mutex_lock(&dev_priv->binding_mutex); | ||
203 | binding_list = vmw_context_binding_list(ctx); | ||
204 | |||
205 | list_for_each_entry(entry, binding_list, ctx_list) { | ||
206 | res = vmw_resource_reference_unless_doomed(entry->bi.res); | ||
207 | if (unlikely(res == NULL)) | ||
208 | continue; | ||
209 | |||
210 | ret = vmw_resource_val_add(sw_context, entry->bi.res, NULL); | ||
211 | vmw_resource_unreference(&res); | ||
212 | if (unlikely(ret != 0)) | ||
213 | break; | ||
214 | } | ||
215 | |||
216 | mutex_unlock(&dev_priv->binding_mutex); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | /** | ||
181 | * vmw_resource_relocation_add - Add a relocation to the relocation list | 221 | * vmw_resource_relocation_add - Add a relocation to the relocation list |
182 | * | 222 | * |
183 | * @list: Pointer to head of relocation list. | 223 | * @list: Pointer to head of relocation list. |
@@ -233,8 +273,12 @@ static void vmw_resource_relocations_apply(uint32_t *cb, | |||
233 | { | 273 | { |
234 | struct vmw_resource_relocation *rel; | 274 | struct vmw_resource_relocation *rel; |
235 | 275 | ||
236 | list_for_each_entry(rel, list, head) | 276 | list_for_each_entry(rel, list, head) { |
237 | cb[rel->offset] = rel->res->id; | 277 | if (likely(rel->res != NULL)) |
278 | cb[rel->offset] = rel->res->id; | ||
279 | else | ||
280 | cb[rel->offset] = SVGA_3D_CMD_NOP; | ||
281 | } | ||
238 | } | 282 | } |
239 | 283 | ||
240 | static int vmw_cmd_invalid(struct vmw_private *dev_priv, | 284 | static int vmw_cmd_invalid(struct vmw_private *dev_priv, |
@@ -379,22 +423,27 @@ static int vmw_resources_validate(struct vmw_sw_context *sw_context) | |||
379 | } | 423 | } |
380 | 424 | ||
381 | /** | 425 | /** |
382 | * vmw_cmd_res_check - Check that a resource is present and if so, put it | 426 | * vmw_cmd_compat_res_check - Check that a resource is present and if so, put it |
383 | * on the resource validate list unless it's already there. | 427 | * on the resource validate list unless it's already there. |
384 | * | 428 | * |
385 | * @dev_priv: Pointer to a device private structure. | 429 | * @dev_priv: Pointer to a device private structure. |
386 | * @sw_context: Pointer to the software context. | 430 | * @sw_context: Pointer to the software context. |
387 | * @res_type: Resource type. | 431 | * @res_type: Resource type. |
388 | * @converter: User-space visisble type specific information. | 432 | * @converter: User-space visisble type specific information. |
389 | * @id: Pointer to the location in the command buffer currently being | 433 | * @id: user-space resource id handle. |
434 | * @id_loc: Pointer to the location in the command buffer currently being | ||
390 | * parsed from where the user-space resource id handle is located. | 435 | * parsed from where the user-space resource id handle is located. |
436 | * @p_val: Pointer to pointer to resource validalidation node. Populated | ||
437 | * on exit. | ||
391 | */ | 438 | */ |
392 | static int vmw_cmd_res_check(struct vmw_private *dev_priv, | 439 | static int |
393 | struct vmw_sw_context *sw_context, | 440 | vmw_cmd_compat_res_check(struct vmw_private *dev_priv, |
394 | enum vmw_res_type res_type, | 441 | struct vmw_sw_context *sw_context, |
395 | const struct vmw_user_resource_conv *converter, | 442 | enum vmw_res_type res_type, |
396 | uint32_t *id, | 443 | const struct vmw_user_resource_conv *converter, |
397 | struct vmw_resource_val_node **p_val) | 444 | uint32_t id, |
445 | uint32_t *id_loc, | ||
446 | struct vmw_resource_val_node **p_val) | ||
398 | { | 447 | { |
399 | struct vmw_res_cache_entry *rcache = | 448 | struct vmw_res_cache_entry *rcache = |
400 | &sw_context->res_cache[res_type]; | 449 | &sw_context->res_cache[res_type]; |
@@ -402,7 +451,7 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, | |||
402 | struct vmw_resource_val_node *node; | 451 | struct vmw_resource_val_node *node; |
403 | int ret; | 452 | int ret; |
404 | 453 | ||
405 | if (*id == SVGA3D_INVALID_ID) { | 454 | if (id == SVGA3D_INVALID_ID) { |
406 | if (p_val) | 455 | if (p_val) |
407 | *p_val = NULL; | 456 | *p_val = NULL; |
408 | if (res_type == vmw_res_context) { | 457 | if (res_type == vmw_res_context) { |
@@ -417,7 +466,7 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, | |||
417 | * resource | 466 | * resource |
418 | */ | 467 | */ |
419 | 468 | ||
420 | if (likely(rcache->valid && *id == rcache->handle)) { | 469 | if (likely(rcache->valid && id == rcache->handle)) { |
421 | const struct vmw_resource *res = rcache->res; | 470 | const struct vmw_resource *res = rcache->res; |
422 | 471 | ||
423 | rcache->node->first_usage = false; | 472 | rcache->node->first_usage = false; |
@@ -426,28 +475,28 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, | |||
426 | 475 | ||
427 | return vmw_resource_relocation_add | 476 | return vmw_resource_relocation_add |
428 | (&sw_context->res_relocations, res, | 477 | (&sw_context->res_relocations, res, |
429 | id - sw_context->buf_start); | 478 | id_loc - sw_context->buf_start); |
430 | } | 479 | } |
431 | 480 | ||
432 | ret = vmw_user_resource_lookup_handle(dev_priv, | 481 | ret = vmw_user_resource_lookup_handle(dev_priv, |
433 | sw_context->tfile, | 482 | sw_context->fp->tfile, |
434 | *id, | 483 | id, |
435 | converter, | 484 | converter, |
436 | &res); | 485 | &res); |
437 | if (unlikely(ret != 0)) { | 486 | if (unlikely(ret != 0)) { |
438 | DRM_ERROR("Could not find or use resource 0x%08x.\n", | 487 | DRM_ERROR("Could not find or use resource 0x%08x.\n", |
439 | (unsigned) *id); | 488 | (unsigned) id); |
440 | dump_stack(); | 489 | dump_stack(); |
441 | return ret; | 490 | return ret; |
442 | } | 491 | } |
443 | 492 | ||
444 | rcache->valid = true; | 493 | rcache->valid = true; |
445 | rcache->res = res; | 494 | rcache->res = res; |
446 | rcache->handle = *id; | 495 | rcache->handle = id; |
447 | 496 | ||
448 | ret = vmw_resource_relocation_add(&sw_context->res_relocations, | 497 | ret = vmw_resource_relocation_add(&sw_context->res_relocations, |
449 | res, | 498 | res, |
450 | id - sw_context->buf_start); | 499 | id_loc - sw_context->buf_start); |
451 | if (unlikely(ret != 0)) | 500 | if (unlikely(ret != 0)) |
452 | goto out_no_reloc; | 501 | goto out_no_reloc; |
453 | 502 | ||
@@ -459,7 +508,11 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, | |||
459 | if (p_val) | 508 | if (p_val) |
460 | *p_val = node; | 509 | *p_val = node; |
461 | 510 | ||
462 | if (node->first_usage && res_type == vmw_res_context) { | 511 | if (dev_priv->has_mob && node->first_usage && |
512 | res_type == vmw_res_context) { | ||
513 | ret = vmw_resource_context_res_add(dev_priv, sw_context, res); | ||
514 | if (unlikely(ret != 0)) | ||
515 | goto out_no_reloc; | ||
463 | node->staged_bindings = | 516 | node->staged_bindings = |
464 | kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); | 517 | kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); |
465 | if (node->staged_bindings == NULL) { | 518 | if (node->staged_bindings == NULL) { |
@@ -481,6 +534,59 @@ out_no_reloc: | |||
481 | } | 534 | } |
482 | 535 | ||
483 | /** | 536 | /** |
537 | * vmw_cmd_res_check - Check that a resource is present and if so, put it | ||
538 | * on the resource validate list unless it's already there. | ||
539 | * | ||
540 | * @dev_priv: Pointer to a device private structure. | ||
541 | * @sw_context: Pointer to the software context. | ||
542 | * @res_type: Resource type. | ||
543 | * @converter: User-space visisble type specific information. | ||
544 | * @id_loc: Pointer to the location in the command buffer currently being | ||
545 | * parsed from where the user-space resource id handle is located. | ||
546 | * @p_val: Pointer to pointer to resource validalidation node. Populated | ||
547 | * on exit. | ||
548 | */ | ||
549 | static int | ||
550 | vmw_cmd_res_check(struct vmw_private *dev_priv, | ||
551 | struct vmw_sw_context *sw_context, | ||
552 | enum vmw_res_type res_type, | ||
553 | const struct vmw_user_resource_conv *converter, | ||
554 | uint32_t *id_loc, | ||
555 | struct vmw_resource_val_node **p_val) | ||
556 | { | ||
557 | return vmw_cmd_compat_res_check(dev_priv, sw_context, res_type, | ||
558 | converter, *id_loc, id_loc, p_val); | ||
559 | } | ||
560 | |||
561 | /** | ||
562 | * vmw_rebind_contexts - Rebind all resources previously bound to | ||
563 | * referenced contexts. | ||
564 | * | ||
565 | * @sw_context: Pointer to the software context. | ||
566 | * | ||
567 | * Rebind context binding points that have been scrubbed because of eviction. | ||
568 | */ | ||
569 | static int vmw_rebind_contexts(struct vmw_sw_context *sw_context) | ||
570 | { | ||
571 | struct vmw_resource_val_node *val; | ||
572 | int ret; | ||
573 | |||
574 | list_for_each_entry(val, &sw_context->resource_list, head) { | ||
575 | if (likely(!val->staged_bindings)) | ||
576 | continue; | ||
577 | |||
578 | ret = vmw_context_rebind_all(val->res); | ||
579 | if (unlikely(ret != 0)) { | ||
580 | if (ret != -ERESTARTSYS) | ||
581 | DRM_ERROR("Failed to rebind context.\n"); | ||
582 | return ret; | ||
583 | } | ||
584 | } | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | /** | ||
484 | * vmw_cmd_cid_check - Check a command header for valid context information. | 590 | * vmw_cmd_cid_check - Check a command header for valid context information. |
485 | * | 591 | * |
486 | * @dev_priv: Pointer to a device private structure. | 592 | * @dev_priv: Pointer to a device private structure. |
@@ -767,7 +873,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, | |||
767 | struct vmw_relocation *reloc; | 873 | struct vmw_relocation *reloc; |
768 | int ret; | 874 | int ret; |
769 | 875 | ||
770 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); | 876 | ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo); |
771 | if (unlikely(ret != 0)) { | 877 | if (unlikely(ret != 0)) { |
772 | DRM_ERROR("Could not find or use MOB buffer.\n"); | 878 | DRM_ERROR("Could not find or use MOB buffer.\n"); |
773 | return -EINVAL; | 879 | return -EINVAL; |
@@ -828,7 +934,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, | |||
828 | struct vmw_relocation *reloc; | 934 | struct vmw_relocation *reloc; |
829 | int ret; | 935 | int ret; |
830 | 936 | ||
831 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); | 937 | ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo); |
832 | if (unlikely(ret != 0)) { | 938 | if (unlikely(ret != 0)) { |
833 | DRM_ERROR("Could not find or use GMR region.\n"); | 939 | DRM_ERROR("Could not find or use GMR region.\n"); |
834 | return -EINVAL; | 940 | return -EINVAL; |
@@ -1127,7 +1233,8 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
1127 | 1233 | ||
1128 | srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res); | 1234 | srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res); |
1129 | 1235 | ||
1130 | vmw_kms_cursor_snoop(srf, sw_context->tfile, &vmw_bo->base, header); | 1236 | vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->base, |
1237 | header); | ||
1131 | 1238 | ||
1132 | out_no_surface: | 1239 | out_no_surface: |
1133 | vmw_dmabuf_unreference(&vmw_bo); | 1240 | vmw_dmabuf_unreference(&vmw_bo); |
@@ -1478,6 +1585,98 @@ static int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv, | |||
1478 | &cmd->body.sid, NULL); | 1585 | &cmd->body.sid, NULL); |
1479 | } | 1586 | } |
1480 | 1587 | ||
1588 | |||
1589 | /** | ||
1590 | * vmw_cmd_shader_define - Validate an SVGA_3D_CMD_SHADER_DEFINE | ||
1591 | * command | ||
1592 | * | ||
1593 | * @dev_priv: Pointer to a device private struct. | ||
1594 | * @sw_context: The software context being used for this batch. | ||
1595 | * @header: Pointer to the command header in the command stream. | ||
1596 | */ | ||
1597 | static int vmw_cmd_shader_define(struct vmw_private *dev_priv, | ||
1598 | struct vmw_sw_context *sw_context, | ||
1599 | SVGA3dCmdHeader *header) | ||
1600 | { | ||
1601 | struct vmw_shader_define_cmd { | ||
1602 | SVGA3dCmdHeader header; | ||
1603 | SVGA3dCmdDefineShader body; | ||
1604 | } *cmd; | ||
1605 | int ret; | ||
1606 | size_t size; | ||
1607 | |||
1608 | cmd = container_of(header, struct vmw_shader_define_cmd, | ||
1609 | header); | ||
1610 | |||
1611 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, | ||
1612 | user_context_converter, &cmd->body.cid, | ||
1613 | NULL); | ||
1614 | if (unlikely(ret != 0)) | ||
1615 | return ret; | ||
1616 | |||
1617 | if (unlikely(!dev_priv->has_mob)) | ||
1618 | return 0; | ||
1619 | |||
1620 | size = cmd->header.size - sizeof(cmd->body); | ||
1621 | ret = vmw_compat_shader_add(sw_context->fp->shman, | ||
1622 | cmd->body.shid, cmd + 1, | ||
1623 | cmd->body.type, size, | ||
1624 | sw_context->fp->tfile, | ||
1625 | &sw_context->staged_shaders); | ||
1626 | if (unlikely(ret != 0)) | ||
1627 | return ret; | ||
1628 | |||
1629 | return vmw_resource_relocation_add(&sw_context->res_relocations, | ||
1630 | NULL, &cmd->header.id - | ||
1631 | sw_context->buf_start); | ||
1632 | |||
1633 | return 0; | ||
1634 | } | ||
1635 | |||
1636 | /** | ||
1637 | * vmw_cmd_shader_destroy - Validate an SVGA_3D_CMD_SHADER_DESTROY | ||
1638 | * command | ||
1639 | * | ||
1640 | * @dev_priv: Pointer to a device private struct. | ||
1641 | * @sw_context: The software context being used for this batch. | ||
1642 | * @header: Pointer to the command header in the command stream. | ||
1643 | */ | ||
1644 | static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, | ||
1645 | struct vmw_sw_context *sw_context, | ||
1646 | SVGA3dCmdHeader *header) | ||
1647 | { | ||
1648 | struct vmw_shader_destroy_cmd { | ||
1649 | SVGA3dCmdHeader header; | ||
1650 | SVGA3dCmdDestroyShader body; | ||
1651 | } *cmd; | ||
1652 | int ret; | ||
1653 | |||
1654 | cmd = container_of(header, struct vmw_shader_destroy_cmd, | ||
1655 | header); | ||
1656 | |||
1657 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, | ||
1658 | user_context_converter, &cmd->body.cid, | ||
1659 | NULL); | ||
1660 | if (unlikely(ret != 0)) | ||
1661 | return ret; | ||
1662 | |||
1663 | if (unlikely(!dev_priv->has_mob)) | ||
1664 | return 0; | ||
1665 | |||
1666 | ret = vmw_compat_shader_remove(sw_context->fp->shman, | ||
1667 | cmd->body.shid, | ||
1668 | cmd->body.type, | ||
1669 | &sw_context->staged_shaders); | ||
1670 | if (unlikely(ret != 0)) | ||
1671 | return ret; | ||
1672 | |||
1673 | return vmw_resource_relocation_add(&sw_context->res_relocations, | ||
1674 | NULL, &cmd->header.id - | ||
1675 | sw_context->buf_start); | ||
1676 | |||
1677 | return 0; | ||
1678 | } | ||
1679 | |||
1481 | /** | 1680 | /** |
1482 | * vmw_cmd_set_shader - Validate an SVGA_3D_CMD_SET_SHADER | 1681 | * vmw_cmd_set_shader - Validate an SVGA_3D_CMD_SET_SHADER |
1483 | * command | 1682 | * command |
@@ -1509,10 +1708,18 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, | |||
1509 | if (dev_priv->has_mob) { | 1708 | if (dev_priv->has_mob) { |
1510 | struct vmw_ctx_bindinfo bi; | 1709 | struct vmw_ctx_bindinfo bi; |
1511 | struct vmw_resource_val_node *res_node; | 1710 | struct vmw_resource_val_node *res_node; |
1512 | 1711 | u32 shid = cmd->body.shid; | |
1513 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_shader, | 1712 | |
1514 | user_shader_converter, | 1713 | if (shid != SVGA3D_INVALID_ID) |
1515 | &cmd->body.shid, &res_node); | 1714 | (void) vmw_compat_shader_lookup(sw_context->fp->shman, |
1715 | cmd->body.type, | ||
1716 | &shid); | ||
1717 | |||
1718 | ret = vmw_cmd_compat_res_check(dev_priv, sw_context, | ||
1719 | vmw_res_shader, | ||
1720 | user_shader_converter, | ||
1721 | shid, | ||
1722 | &cmd->body.shid, &res_node); | ||
1516 | if (unlikely(ret != 0)) | 1723 | if (unlikely(ret != 0)) |
1517 | return ret; | 1724 | return ret; |
1518 | 1725 | ||
@@ -1527,6 +1734,39 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, | |||
1527 | } | 1734 | } |
1528 | 1735 | ||
1529 | /** | 1736 | /** |
1737 | * vmw_cmd_set_shader_const - Validate an SVGA_3D_CMD_SET_SHADER_CONST | ||
1738 | * command | ||
1739 | * | ||
1740 | * @dev_priv: Pointer to a device private struct. | ||
1741 | * @sw_context: The software context being used for this batch. | ||
1742 | * @header: Pointer to the command header in the command stream. | ||
1743 | */ | ||
1744 | static int vmw_cmd_set_shader_const(struct vmw_private *dev_priv, | ||
1745 | struct vmw_sw_context *sw_context, | ||
1746 | SVGA3dCmdHeader *header) | ||
1747 | { | ||
1748 | struct vmw_set_shader_const_cmd { | ||
1749 | SVGA3dCmdHeader header; | ||
1750 | SVGA3dCmdSetShaderConst body; | ||
1751 | } *cmd; | ||
1752 | int ret; | ||
1753 | |||
1754 | cmd = container_of(header, struct vmw_set_shader_const_cmd, | ||
1755 | header); | ||
1756 | |||
1757 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, | ||
1758 | user_context_converter, &cmd->body.cid, | ||
1759 | NULL); | ||
1760 | if (unlikely(ret != 0)) | ||
1761 | return ret; | ||
1762 | |||
1763 | if (dev_priv->has_mob) | ||
1764 | header->id = SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE; | ||
1765 | |||
1766 | return 0; | ||
1767 | } | ||
1768 | |||
1769 | /** | ||
1530 | * vmw_cmd_bind_gb_shader - Validate an SVGA_3D_CMD_BIND_GB_SHADER | 1770 | * vmw_cmd_bind_gb_shader - Validate an SVGA_3D_CMD_BIND_GB_SHADER |
1531 | * command | 1771 | * command |
1532 | * | 1772 | * |
@@ -1634,14 +1874,14 @@ static const struct vmw_cmd_entry const vmw_cmd_entries[SVGA_3D_CMD_MAX] = { | |||
1634 | true, false, false), | 1874 | true, false, false), |
1635 | VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check, | 1875 | VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check, |
1636 | false, false, false), | 1876 | false, false, false), |
1637 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_cid_check, | 1877 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_shader_define, |
1638 | true, true, false), | 1878 | true, false, false), |
1639 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check, | 1879 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_shader_destroy, |
1640 | true, true, false), | 1880 | true, false, false), |
1641 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_set_shader, | 1881 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_set_shader, |
1642 | true, false, false), | 1882 | true, false, false), |
1643 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check, | 1883 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_set_shader_const, |
1644 | true, true, false), | 1884 | true, false, false), |
1645 | VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw, | 1885 | VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw, |
1646 | true, false, false), | 1886 | true, false, false), |
1647 | VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check, | 1887 | VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check, |
@@ -2171,7 +2411,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2171 | } else | 2411 | } else |
2172 | sw_context->kernel = true; | 2412 | sw_context->kernel = true; |
2173 | 2413 | ||
2174 | sw_context->tfile = vmw_fpriv(file_priv)->tfile; | 2414 | sw_context->fp = vmw_fpriv(file_priv); |
2175 | sw_context->cur_reloc = 0; | 2415 | sw_context->cur_reloc = 0; |
2176 | sw_context->cur_val_buf = 0; | 2416 | sw_context->cur_val_buf = 0; |
2177 | sw_context->fence_flags = 0; | 2417 | sw_context->fence_flags = 0; |
@@ -2188,16 +2428,17 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2188 | goto out_unlock; | 2428 | goto out_unlock; |
2189 | sw_context->res_ht_initialized = true; | 2429 | sw_context->res_ht_initialized = true; |
2190 | } | 2430 | } |
2431 | INIT_LIST_HEAD(&sw_context->staged_shaders); | ||
2191 | 2432 | ||
2192 | INIT_LIST_HEAD(&resource_list); | 2433 | INIT_LIST_HEAD(&resource_list); |
2193 | ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands, | 2434 | ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands, |
2194 | command_size); | 2435 | command_size); |
2195 | if (unlikely(ret != 0)) | 2436 | if (unlikely(ret != 0)) |
2196 | goto out_err; | 2437 | goto out_err_nores; |
2197 | 2438 | ||
2198 | ret = vmw_resources_reserve(sw_context); | 2439 | ret = vmw_resources_reserve(sw_context); |
2199 | if (unlikely(ret != 0)) | 2440 | if (unlikely(ret != 0)) |
2200 | goto out_err; | 2441 | goto out_err_nores; |
2201 | 2442 | ||
2202 | ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes); | 2443 | ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes); |
2203 | if (unlikely(ret != 0)) | 2444 | if (unlikely(ret != 0)) |
@@ -2225,6 +2466,12 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2225 | goto out_err; | 2466 | goto out_err; |
2226 | } | 2467 | } |
2227 | 2468 | ||
2469 | if (dev_priv->has_mob) { | ||
2470 | ret = vmw_rebind_contexts(sw_context); | ||
2471 | if (unlikely(ret != 0)) | ||
2472 | goto out_err; | ||
2473 | } | ||
2474 | |||
2228 | cmd = vmw_fifo_reserve(dev_priv, command_size); | 2475 | cmd = vmw_fifo_reserve(dev_priv, command_size); |
2229 | if (unlikely(cmd == NULL)) { | 2476 | if (unlikely(cmd == NULL)) { |
2230 | DRM_ERROR("Failed reserving fifo space for commands.\n"); | 2477 | DRM_ERROR("Failed reserving fifo space for commands.\n"); |
@@ -2276,6 +2523,8 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2276 | } | 2523 | } |
2277 | 2524 | ||
2278 | list_splice_init(&sw_context->resource_list, &resource_list); | 2525 | list_splice_init(&sw_context->resource_list, &resource_list); |
2526 | vmw_compat_shaders_commit(sw_context->fp->shman, | ||
2527 | &sw_context->staged_shaders); | ||
2279 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 2528 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
2280 | 2529 | ||
2281 | /* | 2530 | /* |
@@ -2289,10 +2538,11 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2289 | out_unlock_binding: | 2538 | out_unlock_binding: |
2290 | mutex_unlock(&dev_priv->binding_mutex); | 2539 | mutex_unlock(&dev_priv->binding_mutex); |
2291 | out_err: | 2540 | out_err: |
2292 | vmw_resource_relocations_free(&sw_context->res_relocations); | ||
2293 | vmw_free_relocations(sw_context); | ||
2294 | ttm_eu_backoff_reservation(&ticket, &sw_context->validate_nodes); | 2541 | ttm_eu_backoff_reservation(&ticket, &sw_context->validate_nodes); |
2542 | out_err_nores: | ||
2295 | vmw_resource_list_unreserve(&sw_context->resource_list, true); | 2543 | vmw_resource_list_unreserve(&sw_context->resource_list, true); |
2544 | vmw_resource_relocations_free(&sw_context->res_relocations); | ||
2545 | vmw_free_relocations(sw_context); | ||
2296 | vmw_clear_validations(sw_context); | 2546 | vmw_clear_validations(sw_context); |
2297 | if (unlikely(dev_priv->pinned_bo != NULL && | 2547 | if (unlikely(dev_priv->pinned_bo != NULL && |
2298 | !dev_priv->query_cid_valid)) | 2548 | !dev_priv->query_cid_valid)) |
@@ -2301,6 +2551,8 @@ out_unlock: | |||
2301 | list_splice_init(&sw_context->resource_list, &resource_list); | 2551 | list_splice_init(&sw_context->resource_list, &resource_list); |
2302 | error_resource = sw_context->error_resource; | 2552 | error_resource = sw_context->error_resource; |
2303 | sw_context->error_resource = NULL; | 2553 | sw_context->error_resource = NULL; |
2554 | vmw_compat_shaders_revert(sw_context->fp->shman, | ||
2555 | &sw_context->staged_shaders); | ||
2304 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 2556 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
2305 | 2557 | ||
2306 | /* | 2558 | /* |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 116c49736763..f9881f9e62bd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -29,12 +29,18 @@ | |||
29 | #include <drm/vmwgfx_drm.h> | 29 | #include <drm/vmwgfx_drm.h> |
30 | #include "vmwgfx_kms.h" | 30 | #include "vmwgfx_kms.h" |
31 | 31 | ||
32 | struct svga_3d_compat_cap { | ||
33 | SVGA3dCapsRecordHeader header; | ||
34 | SVGA3dCapPair pairs[SVGA3D_DEVCAP_MAX]; | ||
35 | }; | ||
36 | |||
32 | int vmw_getparam_ioctl(struct drm_device *dev, void *data, | 37 | int vmw_getparam_ioctl(struct drm_device *dev, void *data, |
33 | struct drm_file *file_priv) | 38 | struct drm_file *file_priv) |
34 | { | 39 | { |
35 | struct vmw_private *dev_priv = vmw_priv(dev); | 40 | struct vmw_private *dev_priv = vmw_priv(dev); |
36 | struct drm_vmw_getparam_arg *param = | 41 | struct drm_vmw_getparam_arg *param = |
37 | (struct drm_vmw_getparam_arg *)data; | 42 | (struct drm_vmw_getparam_arg *)data; |
43 | struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); | ||
38 | 44 | ||
39 | switch (param->param) { | 45 | switch (param->param) { |
40 | case DRM_VMW_PARAM_NUM_STREAMS: | 46 | case DRM_VMW_PARAM_NUM_STREAMS: |
@@ -60,6 +66,11 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
60 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 66 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
61 | const struct vmw_fifo_state *fifo = &dev_priv->fifo; | 67 | const struct vmw_fifo_state *fifo = &dev_priv->fifo; |
62 | 68 | ||
69 | if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS)) { | ||
70 | param->value = SVGA3D_HWVERSION_WS8_B1; | ||
71 | break; | ||
72 | } | ||
73 | |||
63 | param->value = | 74 | param->value = |
64 | ioread32(fifo_mem + | 75 | ioread32(fifo_mem + |
65 | ((fifo->capabilities & | 76 | ((fifo->capabilities & |
@@ -69,17 +80,26 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
69 | break; | 80 | break; |
70 | } | 81 | } |
71 | case DRM_VMW_PARAM_MAX_SURF_MEMORY: | 82 | case DRM_VMW_PARAM_MAX_SURF_MEMORY: |
72 | param->value = dev_priv->memory_size; | 83 | if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS) && |
84 | !vmw_fp->gb_aware) | ||
85 | param->value = dev_priv->max_mob_pages * PAGE_SIZE / 2; | ||
86 | else | ||
87 | param->value = dev_priv->memory_size; | ||
73 | break; | 88 | break; |
74 | case DRM_VMW_PARAM_3D_CAPS_SIZE: | 89 | case DRM_VMW_PARAM_3D_CAPS_SIZE: |
75 | if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) | 90 | if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS) && |
76 | param->value = SVGA3D_DEVCAP_MAX; | 91 | vmw_fp->gb_aware) |
92 | param->value = SVGA3D_DEVCAP_MAX * sizeof(uint32_t); | ||
93 | else if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) | ||
94 | param->value = sizeof(struct svga_3d_compat_cap) + | ||
95 | sizeof(uint32_t); | ||
77 | else | 96 | else |
78 | param->value = (SVGA_FIFO_3D_CAPS_LAST - | 97 | param->value = (SVGA_FIFO_3D_CAPS_LAST - |
79 | SVGA_FIFO_3D_CAPS + 1); | 98 | SVGA_FIFO_3D_CAPS + 1) * |
80 | param->value *= sizeof(uint32_t); | 99 | sizeof(uint32_t); |
81 | break; | 100 | break; |
82 | case DRM_VMW_PARAM_MAX_MOB_MEMORY: | 101 | case DRM_VMW_PARAM_MAX_MOB_MEMORY: |
102 | vmw_fp->gb_aware = true; | ||
83 | param->value = dev_priv->max_mob_pages * PAGE_SIZE; | 103 | param->value = dev_priv->max_mob_pages * PAGE_SIZE; |
84 | break; | 104 | break; |
85 | default: | 105 | default: |
@@ -91,6 +111,38 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
91 | return 0; | 111 | return 0; |
92 | } | 112 | } |
93 | 113 | ||
114 | static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce, | ||
115 | size_t size) | ||
116 | { | ||
117 | struct svga_3d_compat_cap *compat_cap = | ||
118 | (struct svga_3d_compat_cap *) bounce; | ||
119 | unsigned int i; | ||
120 | size_t pair_offset = offsetof(struct svga_3d_compat_cap, pairs); | ||
121 | unsigned int max_size; | ||
122 | |||
123 | if (size < pair_offset) | ||
124 | return -EINVAL; | ||
125 | |||
126 | max_size = (size - pair_offset) / sizeof(SVGA3dCapPair); | ||
127 | |||
128 | if (max_size > SVGA3D_DEVCAP_MAX) | ||
129 | max_size = SVGA3D_DEVCAP_MAX; | ||
130 | |||
131 | compat_cap->header.length = | ||
132 | (pair_offset + max_size * sizeof(SVGA3dCapPair)) / sizeof(u32); | ||
133 | compat_cap->header.type = SVGA3DCAPS_RECORD_DEVCAPS; | ||
134 | |||
135 | mutex_lock(&dev_priv->hw_mutex); | ||
136 | for (i = 0; i < max_size; ++i) { | ||
137 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); | ||
138 | compat_cap->pairs[i][0] = i; | ||
139 | compat_cap->pairs[i][1] = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | ||
140 | } | ||
141 | mutex_unlock(&dev_priv->hw_mutex); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
94 | 146 | ||
95 | int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | 147 | int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, |
96 | struct drm_file *file_priv) | 148 | struct drm_file *file_priv) |
@@ -104,41 +156,49 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
104 | void *bounce; | 156 | void *bounce; |
105 | int ret; | 157 | int ret; |
106 | bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); | 158 | bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); |
159 | struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); | ||
107 | 160 | ||
108 | if (unlikely(arg->pad64 != 0)) { | 161 | if (unlikely(arg->pad64 != 0)) { |
109 | DRM_ERROR("Illegal GET_3D_CAP argument.\n"); | 162 | DRM_ERROR("Illegal GET_3D_CAP argument.\n"); |
110 | return -EINVAL; | 163 | return -EINVAL; |
111 | } | 164 | } |
112 | 165 | ||
113 | if (gb_objects) | 166 | if (gb_objects && vmw_fp->gb_aware) |
114 | size = SVGA3D_DEVCAP_MAX; | 167 | size = SVGA3D_DEVCAP_MAX * sizeof(uint32_t); |
168 | else if (gb_objects) | ||
169 | size = sizeof(struct svga_3d_compat_cap) + sizeof(uint32_t); | ||
115 | else | 170 | else |
116 | size = (SVGA_FIFO_3D_CAPS_LAST - SVGA_FIFO_3D_CAPS + 1); | 171 | size = (SVGA_FIFO_3D_CAPS_LAST - SVGA_FIFO_3D_CAPS + 1) * |
117 | 172 | sizeof(uint32_t); | |
118 | size *= sizeof(uint32_t); | ||
119 | 173 | ||
120 | if (arg->max_size < size) | 174 | if (arg->max_size < size) |
121 | size = arg->max_size; | 175 | size = arg->max_size; |
122 | 176 | ||
123 | bounce = vmalloc(size); | 177 | bounce = vzalloc(size); |
124 | if (unlikely(bounce == NULL)) { | 178 | if (unlikely(bounce == NULL)) { |
125 | DRM_ERROR("Failed to allocate bounce buffer for 3D caps.\n"); | 179 | DRM_ERROR("Failed to allocate bounce buffer for 3D caps.\n"); |
126 | return -ENOMEM; | 180 | return -ENOMEM; |
127 | } | 181 | } |
128 | 182 | ||
129 | if (gb_objects) { | 183 | if (gb_objects && vmw_fp->gb_aware) { |
130 | int i; | 184 | int i, num; |
131 | uint32_t *bounce32 = (uint32_t *) bounce; | 185 | uint32_t *bounce32 = (uint32_t *) bounce; |
132 | 186 | ||
187 | num = size / sizeof(uint32_t); | ||
188 | if (num > SVGA3D_DEVCAP_MAX) | ||
189 | num = SVGA3D_DEVCAP_MAX; | ||
190 | |||
133 | mutex_lock(&dev_priv->hw_mutex); | 191 | mutex_lock(&dev_priv->hw_mutex); |
134 | for (i = 0; i < SVGA3D_DEVCAP_MAX; ++i) { | 192 | for (i = 0; i < num; ++i) { |
135 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); | 193 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); |
136 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | 194 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
137 | } | 195 | } |
138 | mutex_unlock(&dev_priv->hw_mutex); | 196 | mutex_unlock(&dev_priv->hw_mutex); |
139 | 197 | } else if (gb_objects) { | |
198 | ret = vmw_fill_compat_cap(dev_priv, bounce, size); | ||
199 | if (unlikely(ret != 0)) | ||
200 | goto out_err; | ||
140 | } else { | 201 | } else { |
141 | |||
142 | fifo_mem = dev_priv->mmio_virt; | 202 | fifo_mem = dev_priv->mmio_virt; |
143 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); | 203 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); |
144 | } | 204 | } |
@@ -146,6 +206,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
146 | ret = copy_to_user(buffer, bounce, size); | 206 | ret = copy_to_user(buffer, bounce, size); |
147 | if (ret) | 207 | if (ret) |
148 | ret = -EFAULT; | 208 | ret = -EFAULT; |
209 | out_err: | ||
149 | vfree(bounce); | 210 | vfree(bounce); |
150 | 211 | ||
151 | if (unlikely(ret != 0)) | 212 | if (unlikely(ret != 0)) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index 4910e7b81811..d4a5a19cb8c3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | |||
@@ -134,6 +134,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv, | |||
134 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | 134 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
135 | if (unlikely(cmd == NULL)) { | 135 | if (unlikely(cmd == NULL)) { |
136 | DRM_ERROR("Failed reserving FIFO space for OTable setup.\n"); | 136 | DRM_ERROR("Failed reserving FIFO space for OTable setup.\n"); |
137 | ret = -ENOMEM; | ||
137 | goto out_no_fifo; | 138 | goto out_no_fifo; |
138 | } | 139 | } |
139 | 140 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 6fdd82d42f65..2aa4bc6a4d60 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -88,6 +88,11 @@ struct vmw_resource *vmw_resource_reference(struct vmw_resource *res) | |||
88 | return res; | 88 | return res; |
89 | } | 89 | } |
90 | 90 | ||
91 | struct vmw_resource * | ||
92 | vmw_resource_reference_unless_doomed(struct vmw_resource *res) | ||
93 | { | ||
94 | return kref_get_unless_zero(&res->kref) ? res : NULL; | ||
95 | } | ||
91 | 96 | ||
92 | /** | 97 | /** |
93 | * vmw_resource_release_id - release a resource id to the id manager. | 98 | * vmw_resource_release_id - release a resource id to the id manager. |
@@ -136,8 +141,12 @@ static void vmw_resource_release(struct kref *kref) | |||
136 | vmw_dmabuf_unreference(&res->backup); | 141 | vmw_dmabuf_unreference(&res->backup); |
137 | } | 142 | } |
138 | 143 | ||
139 | if (likely(res->hw_destroy != NULL)) | 144 | if (likely(res->hw_destroy != NULL)) { |
140 | res->hw_destroy(res); | 145 | res->hw_destroy(res); |
146 | mutex_lock(&dev_priv->binding_mutex); | ||
147 | vmw_context_binding_res_list_kill(&res->binding_head); | ||
148 | mutex_unlock(&dev_priv->binding_mutex); | ||
149 | } | ||
141 | 150 | ||
142 | id = res->id; | 151 | id = res->id; |
143 | if (res->res_free != NULL) | 152 | if (res->res_free != NULL) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index 1457ec4b7125..217d941b8176 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include "vmwgfx_resource_priv.h" | 29 | #include "vmwgfx_resource_priv.h" |
30 | #include "ttm/ttm_placement.h" | 30 | #include "ttm/ttm_placement.h" |
31 | 31 | ||
32 | #define VMW_COMPAT_SHADER_HT_ORDER 12 | ||
33 | |||
32 | struct vmw_shader { | 34 | struct vmw_shader { |
33 | struct vmw_resource res; | 35 | struct vmw_resource res; |
34 | SVGA3dShaderType type; | 36 | SVGA3dShaderType type; |
@@ -40,6 +42,50 @@ struct vmw_user_shader { | |||
40 | struct vmw_shader shader; | 42 | struct vmw_shader shader; |
41 | }; | 43 | }; |
42 | 44 | ||
45 | /** | ||
46 | * enum vmw_compat_shader_state - Staging state for compat shaders | ||
47 | */ | ||
48 | enum vmw_compat_shader_state { | ||
49 | VMW_COMPAT_COMMITED, | ||
50 | VMW_COMPAT_ADD, | ||
51 | VMW_COMPAT_DEL | ||
52 | }; | ||
53 | |||
54 | /** | ||
55 | * struct vmw_compat_shader - Metadata for compat shaders. | ||
56 | * | ||
57 | * @handle: The TTM handle of the guest backed shader. | ||
58 | * @tfile: The struct ttm_object_file the guest backed shader is registered | ||
59 | * with. | ||
60 | * @hash: Hash item for lookup. | ||
61 | * @head: List head for staging lists or the compat shader manager list. | ||
62 | * @state: Staging state. | ||
63 | * | ||
64 | * The structure is protected by the cmdbuf lock. | ||
65 | */ | ||
66 | struct vmw_compat_shader { | ||
67 | u32 handle; | ||
68 | struct ttm_object_file *tfile; | ||
69 | struct drm_hash_item hash; | ||
70 | struct list_head head; | ||
71 | enum vmw_compat_shader_state state; | ||
72 | }; | ||
73 | |||
74 | /** | ||
75 | * struct vmw_compat_shader_manager - Compat shader manager. | ||
76 | * | ||
77 | * @shaders: Hash table containing staged and commited compat shaders | ||
78 | * @list: List of commited shaders. | ||
79 | * @dev_priv: Pointer to a device private structure. | ||
80 | * | ||
81 | * @shaders and @list are protected by the cmdbuf mutex for now. | ||
82 | */ | ||
83 | struct vmw_compat_shader_manager { | ||
84 | struct drm_open_hash shaders; | ||
85 | struct list_head list; | ||
86 | struct vmw_private *dev_priv; | ||
87 | }; | ||
88 | |||
43 | static void vmw_user_shader_free(struct vmw_resource *res); | 89 | static void vmw_user_shader_free(struct vmw_resource *res); |
44 | static struct vmw_resource * | 90 | static struct vmw_resource * |
45 | vmw_user_shader_base_to_res(struct ttm_base_object *base); | 91 | vmw_user_shader_base_to_res(struct ttm_base_object *base); |
@@ -258,7 +304,7 @@ static int vmw_gb_shader_destroy(struct vmw_resource *res) | |||
258 | return 0; | 304 | return 0; |
259 | 305 | ||
260 | mutex_lock(&dev_priv->binding_mutex); | 306 | mutex_lock(&dev_priv->binding_mutex); |
261 | vmw_context_binding_res_list_kill(&res->binding_head); | 307 | vmw_context_binding_res_list_scrub(&res->binding_head); |
262 | 308 | ||
263 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | 309 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
264 | if (unlikely(cmd == NULL)) { | 310 | if (unlikely(cmd == NULL)) { |
@@ -325,13 +371,81 @@ int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, | |||
325 | TTM_REF_USAGE); | 371 | TTM_REF_USAGE); |
326 | } | 372 | } |
327 | 373 | ||
374 | int vmw_shader_alloc(struct vmw_private *dev_priv, | ||
375 | struct vmw_dma_buffer *buffer, | ||
376 | size_t shader_size, | ||
377 | size_t offset, | ||
378 | SVGA3dShaderType shader_type, | ||
379 | struct ttm_object_file *tfile, | ||
380 | u32 *handle) | ||
381 | { | ||
382 | struct vmw_user_shader *ushader; | ||
383 | struct vmw_resource *res, *tmp; | ||
384 | int ret; | ||
385 | |||
386 | /* | ||
387 | * Approximate idr memory usage with 128 bytes. It will be limited | ||
388 | * by maximum number_of shaders anyway. | ||
389 | */ | ||
390 | if (unlikely(vmw_user_shader_size == 0)) | ||
391 | vmw_user_shader_size = | ||
392 | ttm_round_pot(sizeof(struct vmw_user_shader)) + 128; | ||
393 | |||
394 | ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), | ||
395 | vmw_user_shader_size, | ||
396 | false, true); | ||
397 | if (unlikely(ret != 0)) { | ||
398 | if (ret != -ERESTARTSYS) | ||
399 | DRM_ERROR("Out of graphics memory for shader " | ||
400 | "creation.\n"); | ||
401 | goto out; | ||
402 | } | ||
403 | |||
404 | ushader = kzalloc(sizeof(*ushader), GFP_KERNEL); | ||
405 | if (unlikely(ushader == NULL)) { | ||
406 | ttm_mem_global_free(vmw_mem_glob(dev_priv), | ||
407 | vmw_user_shader_size); | ||
408 | ret = -ENOMEM; | ||
409 | goto out; | ||
410 | } | ||
411 | |||
412 | res = &ushader->shader.res; | ||
413 | ushader->base.shareable = false; | ||
414 | ushader->base.tfile = NULL; | ||
415 | |||
416 | /* | ||
417 | * From here on, the destructor takes over resource freeing. | ||
418 | */ | ||
419 | |||
420 | ret = vmw_gb_shader_init(dev_priv, res, shader_size, | ||
421 | offset, shader_type, buffer, | ||
422 | vmw_user_shader_free); | ||
423 | if (unlikely(ret != 0)) | ||
424 | goto out; | ||
425 | |||
426 | tmp = vmw_resource_reference(res); | ||
427 | ret = ttm_base_object_init(tfile, &ushader->base, false, | ||
428 | VMW_RES_SHADER, | ||
429 | &vmw_user_shader_base_release, NULL); | ||
430 | |||
431 | if (unlikely(ret != 0)) { | ||
432 | vmw_resource_unreference(&tmp); | ||
433 | goto out_err; | ||
434 | } | ||
435 | |||
436 | if (handle) | ||
437 | *handle = ushader->base.hash.key; | ||
438 | out_err: | ||
439 | vmw_resource_unreference(&res); | ||
440 | out: | ||
441 | return ret; | ||
442 | } | ||
443 | |||
444 | |||
328 | int vmw_shader_define_ioctl(struct drm_device *dev, void *data, | 445 | int vmw_shader_define_ioctl(struct drm_device *dev, void *data, |
329 | struct drm_file *file_priv) | 446 | struct drm_file *file_priv) |
330 | { | 447 | { |
331 | struct vmw_private *dev_priv = vmw_priv(dev); | 448 | struct vmw_private *dev_priv = vmw_priv(dev); |
332 | struct vmw_user_shader *ushader; | ||
333 | struct vmw_resource *res; | ||
334 | struct vmw_resource *tmp; | ||
335 | struct drm_vmw_shader_create_arg *arg = | 449 | struct drm_vmw_shader_create_arg *arg = |
336 | (struct drm_vmw_shader_create_arg *)data; | 450 | (struct drm_vmw_shader_create_arg *)data; |
337 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; | 451 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
@@ -373,69 +487,324 @@ int vmw_shader_define_ioctl(struct drm_device *dev, void *data, | |||
373 | goto out_bad_arg; | 487 | goto out_bad_arg; |
374 | } | 488 | } |
375 | 489 | ||
376 | /* | 490 | ret = ttm_read_lock(&vmaster->lock, true); |
377 | * Approximate idr memory usage with 128 bytes. It will be limited | 491 | if (unlikely(ret != 0)) |
378 | * by maximum number_of shaders anyway. | 492 | goto out_bad_arg; |
379 | */ | ||
380 | 493 | ||
381 | if (unlikely(vmw_user_shader_size == 0)) | 494 | ret = vmw_shader_alloc(dev_priv, buffer, arg->size, arg->offset, |
382 | vmw_user_shader_size = ttm_round_pot(sizeof(*ushader)) | 495 | shader_type, tfile, &arg->shader_handle); |
383 | + 128; | ||
384 | 496 | ||
385 | ret = ttm_read_lock(&vmaster->lock, true); | 497 | ttm_read_unlock(&vmaster->lock); |
498 | out_bad_arg: | ||
499 | vmw_dmabuf_unreference(&buffer); | ||
500 | return ret; | ||
501 | } | ||
502 | |||
503 | /** | ||
504 | * vmw_compat_shader_lookup - Look up a compat shader | ||
505 | * | ||
506 | * @man: Pointer to the compat shader manager. | ||
507 | * @shader_type: The shader type, that combined with the user_key identifies | ||
508 | * the shader. | ||
509 | * @user_key: On entry, this should be a pointer to the user_key. | ||
510 | * On successful exit, it will contain the guest-backed shader's TTM handle. | ||
511 | * | ||
512 | * Returns 0 on success. Non-zero on failure, in which case the value pointed | ||
513 | * to by @user_key is unmodified. | ||
514 | */ | ||
515 | int vmw_compat_shader_lookup(struct vmw_compat_shader_manager *man, | ||
516 | SVGA3dShaderType shader_type, | ||
517 | u32 *user_key) | ||
518 | { | ||
519 | struct drm_hash_item *hash; | ||
520 | int ret; | ||
521 | unsigned long key = *user_key | (shader_type << 24); | ||
522 | |||
523 | ret = drm_ht_find_item(&man->shaders, key, &hash); | ||
386 | if (unlikely(ret != 0)) | 524 | if (unlikely(ret != 0)) |
387 | return ret; | 525 | return ret; |
388 | 526 | ||
389 | ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), | 527 | *user_key = drm_hash_entry(hash, struct vmw_compat_shader, |
390 | vmw_user_shader_size, | 528 | hash)->handle; |
391 | false, true); | 529 | |
392 | if (unlikely(ret != 0)) { | 530 | return 0; |
393 | if (ret != -ERESTARTSYS) | 531 | } |
394 | DRM_ERROR("Out of graphics memory for shader" | 532 | |
395 | " creation.\n"); | 533 | /** |
396 | goto out_unlock; | 534 | * vmw_compat_shader_free - Free a compat shader. |
535 | * | ||
536 | * @man: Pointer to the compat shader manager. | ||
537 | * @entry: Pointer to a struct vmw_compat_shader. | ||
538 | * | ||
539 | * Frees a struct vmw_compat_shder entry and drops its reference to the | ||
540 | * guest backed shader. | ||
541 | */ | ||
542 | static void vmw_compat_shader_free(struct vmw_compat_shader_manager *man, | ||
543 | struct vmw_compat_shader *entry) | ||
544 | { | ||
545 | list_del(&entry->head); | ||
546 | WARN_ON(drm_ht_remove_item(&man->shaders, &entry->hash)); | ||
547 | WARN_ON(ttm_ref_object_base_unref(entry->tfile, entry->handle, | ||
548 | TTM_REF_USAGE)); | ||
549 | kfree(entry); | ||
550 | } | ||
551 | |||
552 | /** | ||
553 | * vmw_compat_shaders_commit - Commit a list of compat shader actions. | ||
554 | * | ||
555 | * @man: Pointer to the compat shader manager. | ||
556 | * @list: Caller's list of compat shader actions. | ||
557 | * | ||
558 | * This function commits a list of compat shader additions or removals. | ||
559 | * It is typically called when the execbuf ioctl call triggering these | ||
560 | * actions has commited the fifo contents to the device. | ||
561 | */ | ||
562 | void vmw_compat_shaders_commit(struct vmw_compat_shader_manager *man, | ||
563 | struct list_head *list) | ||
564 | { | ||
565 | struct vmw_compat_shader *entry, *next; | ||
566 | |||
567 | list_for_each_entry_safe(entry, next, list, head) { | ||
568 | list_del(&entry->head); | ||
569 | switch (entry->state) { | ||
570 | case VMW_COMPAT_ADD: | ||
571 | entry->state = VMW_COMPAT_COMMITED; | ||
572 | list_add_tail(&entry->head, &man->list); | ||
573 | break; | ||
574 | case VMW_COMPAT_DEL: | ||
575 | ttm_ref_object_base_unref(entry->tfile, entry->handle, | ||
576 | TTM_REF_USAGE); | ||
577 | kfree(entry); | ||
578 | break; | ||
579 | default: | ||
580 | BUG(); | ||
581 | break; | ||
582 | } | ||
397 | } | 583 | } |
584 | } | ||
398 | 585 | ||
399 | ushader = kzalloc(sizeof(*ushader), GFP_KERNEL); | 586 | /** |
400 | if (unlikely(ushader == NULL)) { | 587 | * vmw_compat_shaders_revert - Revert a list of compat shader actions |
401 | ttm_mem_global_free(vmw_mem_glob(dev_priv), | 588 | * |
402 | vmw_user_shader_size); | 589 | * @man: Pointer to the compat shader manager. |
403 | ret = -ENOMEM; | 590 | * @list: Caller's list of compat shader actions. |
404 | goto out_unlock; | 591 | * |
592 | * This function reverts a list of compat shader additions or removals. | ||
593 | * It is typically called when the execbuf ioctl call triggering these | ||
594 | * actions failed for some reason, and the command stream was never | ||
595 | * submitted. | ||
596 | */ | ||
597 | void vmw_compat_shaders_revert(struct vmw_compat_shader_manager *man, | ||
598 | struct list_head *list) | ||
599 | { | ||
600 | struct vmw_compat_shader *entry, *next; | ||
601 | int ret; | ||
602 | |||
603 | list_for_each_entry_safe(entry, next, list, head) { | ||
604 | switch (entry->state) { | ||
605 | case VMW_COMPAT_ADD: | ||
606 | vmw_compat_shader_free(man, entry); | ||
607 | break; | ||
608 | case VMW_COMPAT_DEL: | ||
609 | ret = drm_ht_insert_item(&man->shaders, &entry->hash); | ||
610 | list_del(&entry->head); | ||
611 | list_add_tail(&entry->head, &man->list); | ||
612 | entry->state = VMW_COMPAT_COMMITED; | ||
613 | break; | ||
614 | default: | ||
615 | BUG(); | ||
616 | break; | ||
617 | } | ||
405 | } | 618 | } |
619 | } | ||
406 | 620 | ||
407 | res = &ushader->shader.res; | 621 | /** |
408 | ushader->base.shareable = false; | 622 | * vmw_compat_shader_remove - Stage a compat shader for removal. |
409 | ushader->base.tfile = NULL; | 623 | * |
624 | * @man: Pointer to the compat shader manager | ||
625 | * @user_key: The key that is used to identify the shader. The key is | ||
626 | * unique to the shader type. | ||
627 | * @shader_type: Shader type. | ||
628 | * @list: Caller's list of staged shader actions. | ||
629 | * | ||
630 | * This function stages a compat shader for removal and removes the key from | ||
631 | * the shader manager's hash table. If the shader was previously only staged | ||
632 | * for addition it is completely removed (But the execbuf code may keep a | ||
633 | * reference if it was bound to a context between addition and removal). If | ||
634 | * it was previously commited to the manager, it is staged for removal. | ||
635 | */ | ||
636 | int vmw_compat_shader_remove(struct vmw_compat_shader_manager *man, | ||
637 | u32 user_key, SVGA3dShaderType shader_type, | ||
638 | struct list_head *list) | ||
639 | { | ||
640 | struct vmw_compat_shader *entry; | ||
641 | struct drm_hash_item *hash; | ||
642 | int ret; | ||
410 | 643 | ||
411 | /* | 644 | ret = drm_ht_find_item(&man->shaders, user_key | (shader_type << 24), |
412 | * From here on, the destructor takes over resource freeing. | 645 | &hash); |
413 | */ | 646 | if (likely(ret != 0)) |
647 | return -EINVAL; | ||
414 | 648 | ||
415 | ret = vmw_gb_shader_init(dev_priv, res, arg->size, | 649 | entry = drm_hash_entry(hash, struct vmw_compat_shader, hash); |
416 | arg->offset, shader_type, buffer, | 650 | |
417 | vmw_user_shader_free); | 651 | switch (entry->state) { |
652 | case VMW_COMPAT_ADD: | ||
653 | vmw_compat_shader_free(man, entry); | ||
654 | break; | ||
655 | case VMW_COMPAT_COMMITED: | ||
656 | (void) drm_ht_remove_item(&man->shaders, &entry->hash); | ||
657 | list_del(&entry->head); | ||
658 | entry->state = VMW_COMPAT_DEL; | ||
659 | list_add_tail(&entry->head, list); | ||
660 | break; | ||
661 | default: | ||
662 | BUG(); | ||
663 | break; | ||
664 | } | ||
665 | |||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | /** | ||
670 | * vmw_compat_shader_add - Create a compat shader and add the | ||
671 | * key to the manager | ||
672 | * | ||
673 | * @man: Pointer to the compat shader manager | ||
674 | * @user_key: The key that is used to identify the shader. The key is | ||
675 | * unique to the shader type. | ||
676 | * @bytecode: Pointer to the bytecode of the shader. | ||
677 | * @shader_type: Shader type. | ||
678 | * @tfile: Pointer to a struct ttm_object_file that the guest-backed shader is | ||
679 | * to be created with. | ||
680 | * @list: Caller's list of staged shader actions. | ||
681 | * | ||
682 | * Note that only the key is added to the shader manager's hash table. | ||
683 | * The shader is not yet added to the shader manager's list of shaders. | ||
684 | */ | ||
685 | int vmw_compat_shader_add(struct vmw_compat_shader_manager *man, | ||
686 | u32 user_key, const void *bytecode, | ||
687 | SVGA3dShaderType shader_type, | ||
688 | size_t size, | ||
689 | struct ttm_object_file *tfile, | ||
690 | struct list_head *list) | ||
691 | { | ||
692 | struct vmw_dma_buffer *buf; | ||
693 | struct ttm_bo_kmap_obj map; | ||
694 | bool is_iomem; | ||
695 | struct vmw_compat_shader *compat; | ||
696 | u32 handle; | ||
697 | int ret; | ||
698 | |||
699 | if (user_key > ((1 << 24) - 1) || (unsigned) shader_type > 16) | ||
700 | return -EINVAL; | ||
701 | |||
702 | /* Allocate and pin a DMA buffer */ | ||
703 | buf = kzalloc(sizeof(*buf), GFP_KERNEL); | ||
704 | if (unlikely(buf == NULL)) | ||
705 | return -ENOMEM; | ||
706 | |||
707 | ret = vmw_dmabuf_init(man->dev_priv, buf, size, &vmw_sys_ne_placement, | ||
708 | true, vmw_dmabuf_bo_free); | ||
418 | if (unlikely(ret != 0)) | 709 | if (unlikely(ret != 0)) |
419 | goto out_unlock; | 710 | goto out; |
420 | 711 | ||
421 | tmp = vmw_resource_reference(res); | 712 | ret = ttm_bo_reserve(&buf->base, false, true, false, NULL); |
422 | ret = ttm_base_object_init(tfile, &ushader->base, false, | 713 | if (unlikely(ret != 0)) |
423 | VMW_RES_SHADER, | 714 | goto no_reserve; |
424 | &vmw_user_shader_base_release, NULL); | ||
425 | 715 | ||
716 | /* Map and copy shader bytecode. */ | ||
717 | ret = ttm_bo_kmap(&buf->base, 0, PAGE_ALIGN(size) >> PAGE_SHIFT, | ||
718 | &map); | ||
426 | if (unlikely(ret != 0)) { | 719 | if (unlikely(ret != 0)) { |
427 | vmw_resource_unreference(&tmp); | 720 | ttm_bo_unreserve(&buf->base); |
428 | goto out_err; | 721 | goto no_reserve; |
429 | } | 722 | } |
430 | 723 | ||
431 | arg->shader_handle = ushader->base.hash.key; | 724 | memcpy(ttm_kmap_obj_virtual(&map, &is_iomem), bytecode, size); |
432 | out_err: | 725 | WARN_ON(is_iomem); |
433 | vmw_resource_unreference(&res); | 726 | |
434 | out_unlock: | 727 | ttm_bo_kunmap(&map); |
435 | ttm_read_unlock(&vmaster->lock); | 728 | ret = ttm_bo_validate(&buf->base, &vmw_sys_placement, false, true); |
436 | out_bad_arg: | 729 | WARN_ON(ret != 0); |
437 | vmw_dmabuf_unreference(&buffer); | 730 | ttm_bo_unreserve(&buf->base); |
731 | |||
732 | /* Create a guest-backed shader container backed by the dma buffer */ | ||
733 | ret = vmw_shader_alloc(man->dev_priv, buf, size, 0, shader_type, | ||
734 | tfile, &handle); | ||
735 | vmw_dmabuf_unreference(&buf); | ||
736 | if (unlikely(ret != 0)) | ||
737 | goto no_reserve; | ||
738 | /* | ||
739 | * Create a compat shader structure and stage it for insertion | ||
740 | * in the manager | ||
741 | */ | ||
742 | compat = kzalloc(sizeof(*compat), GFP_KERNEL); | ||
743 | if (compat == NULL) | ||
744 | goto no_compat; | ||
745 | |||
746 | compat->hash.key = user_key | (shader_type << 24); | ||
747 | ret = drm_ht_insert_item(&man->shaders, &compat->hash); | ||
748 | if (unlikely(ret != 0)) | ||
749 | goto out_invalid_key; | ||
750 | |||
751 | compat->state = VMW_COMPAT_ADD; | ||
752 | compat->handle = handle; | ||
753 | compat->tfile = tfile; | ||
754 | list_add_tail(&compat->head, list); | ||
438 | 755 | ||
756 | return 0; | ||
757 | |||
758 | out_invalid_key: | ||
759 | kfree(compat); | ||
760 | no_compat: | ||
761 | ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE); | ||
762 | no_reserve: | ||
763 | out: | ||
439 | return ret; | 764 | return ret; |
765 | } | ||
766 | |||
767 | /** | ||
768 | * vmw_compat_shader_man_create - Create a compat shader manager | ||
769 | * | ||
770 | * @dev_priv: Pointer to a device private structure. | ||
771 | * | ||
772 | * Typically done at file open time. If successful returns a pointer to a | ||
773 | * compat shader manager. Otherwise returns an error pointer. | ||
774 | */ | ||
775 | struct vmw_compat_shader_manager * | ||
776 | vmw_compat_shader_man_create(struct vmw_private *dev_priv) | ||
777 | { | ||
778 | struct vmw_compat_shader_manager *man; | ||
779 | int ret; | ||
780 | |||
781 | man = kzalloc(sizeof(*man), GFP_KERNEL); | ||
782 | |||
783 | man->dev_priv = dev_priv; | ||
784 | INIT_LIST_HEAD(&man->list); | ||
785 | ret = drm_ht_create(&man->shaders, VMW_COMPAT_SHADER_HT_ORDER); | ||
786 | if (ret == 0) | ||
787 | return man; | ||
788 | |||
789 | kfree(man); | ||
790 | return ERR_PTR(ret); | ||
791 | } | ||
792 | |||
793 | /** | ||
794 | * vmw_compat_shader_man_destroy - Destroy a compat shader manager | ||
795 | * | ||
796 | * @man: Pointer to the shader manager to destroy. | ||
797 | * | ||
798 | * Typically done at file close time. | ||
799 | */ | ||
800 | void vmw_compat_shader_man_destroy(struct vmw_compat_shader_manager *man) | ||
801 | { | ||
802 | struct vmw_compat_shader *entry, *next; | ||
803 | |||
804 | mutex_lock(&man->dev_priv->cmdbuf_mutex); | ||
805 | list_for_each_entry_safe(entry, next, &man->list, head) | ||
806 | vmw_compat_shader_free(man, entry); | ||
440 | 807 | ||
808 | mutex_unlock(&man->dev_priv->cmdbuf_mutex); | ||
809 | kfree(man); | ||
441 | } | 810 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 979da1c246a5..82468d902915 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | |||
@@ -908,8 +908,8 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, | |||
908 | rep->size_addr; | 908 | rep->size_addr; |
909 | 909 | ||
910 | if (user_sizes) | 910 | if (user_sizes) |
911 | ret = copy_to_user(user_sizes, srf->sizes, | 911 | ret = copy_to_user(user_sizes, &srf->base_size, |
912 | srf->num_sizes * sizeof(*srf->sizes)); | 912 | sizeof(srf->base_size)); |
913 | if (unlikely(ret != 0)) { | 913 | if (unlikely(ret != 0)) { |
914 | DRM_ERROR("copy_to_user failed %p %u\n", | 914 | DRM_ERROR("copy_to_user failed %p %u\n", |
915 | user_sizes, srf->num_sizes); | 915 | user_sizes, srf->num_sizes); |
@@ -1111,7 +1111,7 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res) | |||
1111 | return 0; | 1111 | return 0; |
1112 | 1112 | ||
1113 | mutex_lock(&dev_priv->binding_mutex); | 1113 | mutex_lock(&dev_priv->binding_mutex); |
1114 | vmw_context_binding_res_list_kill(&res->binding_head); | 1114 | vmw_context_binding_res_list_scrub(&res->binding_head); |
1115 | 1115 | ||
1116 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | 1116 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
1117 | if (unlikely(cmd == NULL)) { | 1117 | if (unlikely(cmd == NULL)) { |
diff --git a/drivers/hwmon/da9055-hwmon.c b/drivers/hwmon/da9055-hwmon.c index 029ecabc4380..73b3865f1207 100644 --- a/drivers/hwmon/da9055-hwmon.c +++ b/drivers/hwmon/da9055-hwmon.c | |||
@@ -278,10 +278,6 @@ static int da9055_hwmon_probe(struct platform_device *pdev) | |||
278 | if (hwmon_irq < 0) | 278 | if (hwmon_irq < 0) |
279 | return hwmon_irq; | 279 | return hwmon_irq; |
280 | 280 | ||
281 | hwmon_irq = regmap_irq_get_virq(hwmon->da9055->irq_data, hwmon_irq); | ||
282 | if (hwmon_irq < 0) | ||
283 | return hwmon_irq; | ||
284 | |||
285 | ret = devm_request_threaded_irq(&pdev->dev, hwmon_irq, | 281 | ret = devm_request_threaded_irq(&pdev->dev, hwmon_irq, |
286 | NULL, da9055_auxadc_irq, | 282 | NULL, da9055_auxadc_irq, |
287 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | 283 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, |
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 3cbf66e9d861..291d11fe93e7 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
@@ -90,7 +90,8 @@ struct pmbus_data { | |||
90 | 90 | ||
91 | u32 flags; /* from platform data */ | 91 | u32 flags; /* from platform data */ |
92 | 92 | ||
93 | int exponent; /* linear mode: exponent for output voltages */ | 93 | int exponent[PMBUS_PAGES]; |
94 | /* linear mode: exponent for output voltages */ | ||
94 | 95 | ||
95 | const struct pmbus_driver_info *info; | 96 | const struct pmbus_driver_info *info; |
96 | 97 | ||
@@ -410,7 +411,7 @@ static long pmbus_reg2data_linear(struct pmbus_data *data, | |||
410 | long val; | 411 | long val; |
411 | 412 | ||
412 | if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ | 413 | if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ |
413 | exponent = data->exponent; | 414 | exponent = data->exponent[sensor->page]; |
414 | mantissa = (u16) sensor->data; | 415 | mantissa = (u16) sensor->data; |
415 | } else { /* LINEAR11 */ | 416 | } else { /* LINEAR11 */ |
416 | exponent = ((s16)sensor->data) >> 11; | 417 | exponent = ((s16)sensor->data) >> 11; |
@@ -516,7 +517,7 @@ static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) | |||
516 | #define MIN_MANTISSA (511 * 1000) | 517 | #define MIN_MANTISSA (511 * 1000) |
517 | 518 | ||
518 | static u16 pmbus_data2reg_linear(struct pmbus_data *data, | 519 | static u16 pmbus_data2reg_linear(struct pmbus_data *data, |
519 | enum pmbus_sensor_classes class, long val) | 520 | struct pmbus_sensor *sensor, long val) |
520 | { | 521 | { |
521 | s16 exponent = 0, mantissa; | 522 | s16 exponent = 0, mantissa; |
522 | bool negative = false; | 523 | bool negative = false; |
@@ -525,7 +526,7 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
525 | if (val == 0) | 526 | if (val == 0) |
526 | return 0; | 527 | return 0; |
527 | 528 | ||
528 | if (class == PSC_VOLTAGE_OUT) { | 529 | if (sensor->class == PSC_VOLTAGE_OUT) { |
529 | /* LINEAR16 does not support negative voltages */ | 530 | /* LINEAR16 does not support negative voltages */ |
530 | if (val < 0) | 531 | if (val < 0) |
531 | return 0; | 532 | return 0; |
@@ -534,10 +535,10 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
534 | * For a static exponents, we don't have a choice | 535 | * For a static exponents, we don't have a choice |
535 | * but to adjust the value to it. | 536 | * but to adjust the value to it. |
536 | */ | 537 | */ |
537 | if (data->exponent < 0) | 538 | if (data->exponent[sensor->page] < 0) |
538 | val <<= -data->exponent; | 539 | val <<= -data->exponent[sensor->page]; |
539 | else | 540 | else |
540 | val >>= data->exponent; | 541 | val >>= data->exponent[sensor->page]; |
541 | val = DIV_ROUND_CLOSEST(val, 1000); | 542 | val = DIV_ROUND_CLOSEST(val, 1000); |
542 | return val & 0xffff; | 543 | return val & 0xffff; |
543 | } | 544 | } |
@@ -548,14 +549,14 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
548 | } | 549 | } |
549 | 550 | ||
550 | /* Power is in uW. Convert to mW before converting. */ | 551 | /* Power is in uW. Convert to mW before converting. */ |
551 | if (class == PSC_POWER) | 552 | if (sensor->class == PSC_POWER) |
552 | val = DIV_ROUND_CLOSEST(val, 1000L); | 553 | val = DIV_ROUND_CLOSEST(val, 1000L); |
553 | 554 | ||
554 | /* | 555 | /* |
555 | * For simplicity, convert fan data to milli-units | 556 | * For simplicity, convert fan data to milli-units |
556 | * before calculating the exponent. | 557 | * before calculating the exponent. |
557 | */ | 558 | */ |
558 | if (class == PSC_FAN) | 559 | if (sensor->class == PSC_FAN) |
559 | val = val * 1000; | 560 | val = val * 1000; |
560 | 561 | ||
561 | /* Reduce large mantissa until it fits into 10 bit */ | 562 | /* Reduce large mantissa until it fits into 10 bit */ |
@@ -585,22 +586,22 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
585 | } | 586 | } |
586 | 587 | ||
587 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, | 588 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, |
588 | enum pmbus_sensor_classes class, long val) | 589 | struct pmbus_sensor *sensor, long val) |
589 | { | 590 | { |
590 | long m, b, R; | 591 | long m, b, R; |
591 | 592 | ||
592 | m = data->info->m[class]; | 593 | m = data->info->m[sensor->class]; |
593 | b = data->info->b[class]; | 594 | b = data->info->b[sensor->class]; |
594 | R = data->info->R[class]; | 595 | R = data->info->R[sensor->class]; |
595 | 596 | ||
596 | /* Power is in uW. Adjust R and b. */ | 597 | /* Power is in uW. Adjust R and b. */ |
597 | if (class == PSC_POWER) { | 598 | if (sensor->class == PSC_POWER) { |
598 | R -= 3; | 599 | R -= 3; |
599 | b *= 1000; | 600 | b *= 1000; |
600 | } | 601 | } |
601 | 602 | ||
602 | /* Calculate Y = (m * X + b) * 10^R */ | 603 | /* Calculate Y = (m * X + b) * 10^R */ |
603 | if (class != PSC_FAN) { | 604 | if (sensor->class != PSC_FAN) { |
604 | R -= 3; /* Adjust R and b for data in milli-units */ | 605 | R -= 3; /* Adjust R and b for data in milli-units */ |
605 | b *= 1000; | 606 | b *= 1000; |
606 | } | 607 | } |
@@ -619,7 +620,7 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data, | |||
619 | } | 620 | } |
620 | 621 | ||
621 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, | 622 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, |
622 | enum pmbus_sensor_classes class, long val) | 623 | struct pmbus_sensor *sensor, long val) |
623 | { | 624 | { |
624 | val = clamp_val(val, 500, 1600); | 625 | val = clamp_val(val, 500, 1600); |
625 | 626 | ||
@@ -627,20 +628,20 @@ static u16 pmbus_data2reg_vid(struct pmbus_data *data, | |||
627 | } | 628 | } |
628 | 629 | ||
629 | static u16 pmbus_data2reg(struct pmbus_data *data, | 630 | static u16 pmbus_data2reg(struct pmbus_data *data, |
630 | enum pmbus_sensor_classes class, long val) | 631 | struct pmbus_sensor *sensor, long val) |
631 | { | 632 | { |
632 | u16 regval; | 633 | u16 regval; |
633 | 634 | ||
634 | switch (data->info->format[class]) { | 635 | switch (data->info->format[sensor->class]) { |
635 | case direct: | 636 | case direct: |
636 | regval = pmbus_data2reg_direct(data, class, val); | 637 | regval = pmbus_data2reg_direct(data, sensor, val); |
637 | break; | 638 | break; |
638 | case vid: | 639 | case vid: |
639 | regval = pmbus_data2reg_vid(data, class, val); | 640 | regval = pmbus_data2reg_vid(data, sensor, val); |
640 | break; | 641 | break; |
641 | case linear: | 642 | case linear: |
642 | default: | 643 | default: |
643 | regval = pmbus_data2reg_linear(data, class, val); | 644 | regval = pmbus_data2reg_linear(data, sensor, val); |
644 | break; | 645 | break; |
645 | } | 646 | } |
646 | return regval; | 647 | return regval; |
@@ -746,7 +747,7 @@ static ssize_t pmbus_set_sensor(struct device *dev, | |||
746 | return -EINVAL; | 747 | return -EINVAL; |
747 | 748 | ||
748 | mutex_lock(&data->update_lock); | 749 | mutex_lock(&data->update_lock); |
749 | regval = pmbus_data2reg(data, sensor->class, val); | 750 | regval = pmbus_data2reg(data, sensor, val); |
750 | ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); | 751 | ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); |
751 | if (ret < 0) | 752 | if (ret < 0) |
752 | rv = ret; | 753 | rv = ret; |
@@ -1643,12 +1644,13 @@ static int pmbus_find_attributes(struct i2c_client *client, | |||
1643 | * This function is called for all chips. | 1644 | * This function is called for all chips. |
1644 | */ | 1645 | */ |
1645 | static int pmbus_identify_common(struct i2c_client *client, | 1646 | static int pmbus_identify_common(struct i2c_client *client, |
1646 | struct pmbus_data *data) | 1647 | struct pmbus_data *data, int page) |
1647 | { | 1648 | { |
1648 | int vout_mode = -1; | 1649 | int vout_mode = -1; |
1649 | 1650 | ||
1650 | if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) | 1651 | if (pmbus_check_byte_register(client, page, PMBUS_VOUT_MODE)) |
1651 | vout_mode = _pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); | 1652 | vout_mode = _pmbus_read_byte_data(client, page, |
1653 | PMBUS_VOUT_MODE); | ||
1652 | if (vout_mode >= 0 && vout_mode != 0xff) { | 1654 | if (vout_mode >= 0 && vout_mode != 0xff) { |
1653 | /* | 1655 | /* |
1654 | * Not all chips support the VOUT_MODE command, | 1656 | * Not all chips support the VOUT_MODE command, |
@@ -1659,7 +1661,7 @@ static int pmbus_identify_common(struct i2c_client *client, | |||
1659 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) | 1661 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) |
1660 | return -ENODEV; | 1662 | return -ENODEV; |
1661 | 1663 | ||
1662 | data->exponent = ((s8)(vout_mode << 3)) >> 3; | 1664 | data->exponent[page] = ((s8)(vout_mode << 3)) >> 3; |
1663 | break; | 1665 | break; |
1664 | case 1: /* VID mode */ | 1666 | case 1: /* VID mode */ |
1665 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) | 1667 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) |
@@ -1674,7 +1676,7 @@ static int pmbus_identify_common(struct i2c_client *client, | |||
1674 | } | 1676 | } |
1675 | } | 1677 | } |
1676 | 1678 | ||
1677 | pmbus_clear_fault_page(client, 0); | 1679 | pmbus_clear_fault_page(client, page); |
1678 | return 0; | 1680 | return 0; |
1679 | } | 1681 | } |
1680 | 1682 | ||
@@ -1682,7 +1684,7 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, | |||
1682 | struct pmbus_driver_info *info) | 1684 | struct pmbus_driver_info *info) |
1683 | { | 1685 | { |
1684 | struct device *dev = &client->dev; | 1686 | struct device *dev = &client->dev; |
1685 | int ret; | 1687 | int page, ret; |
1686 | 1688 | ||
1687 | /* | 1689 | /* |
1688 | * Some PMBus chips don't support PMBUS_STATUS_BYTE, so try | 1690 | * Some PMBus chips don't support PMBUS_STATUS_BYTE, so try |
@@ -1715,10 +1717,12 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, | |||
1715 | return -ENODEV; | 1717 | return -ENODEV; |
1716 | } | 1718 | } |
1717 | 1719 | ||
1718 | ret = pmbus_identify_common(client, data); | 1720 | for (page = 0; page < info->pages; page++) { |
1719 | if (ret < 0) { | 1721 | ret = pmbus_identify_common(client, data, page); |
1720 | dev_err(dev, "Failed to identify chip capabilities\n"); | 1722 | if (ret < 0) { |
1721 | return ret; | 1723 | dev_err(dev, "Failed to identify chip capabilities\n"); |
1724 | return ret; | ||
1725 | } | ||
1722 | } | 1726 | } |
1723 | return 0; | 1727 | return 0; |
1724 | } | 1728 | } |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 86b484cb3ec2..5194afb39e78 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o | |||
21 | obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o | 21 | obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o |
22 | obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o | 22 | obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o |
23 | obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o | 23 | obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o |
24 | obj-$(CONFIG_ARCH_NSPIRE) += irq-zevio.o | ||
24 | obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o | 25 | obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o |
25 | obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o | 26 | obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o |
26 | obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o | 27 | obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o |
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 9300bc32784e..540956465ed2 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c | |||
@@ -381,7 +381,7 @@ armada_370_xp_handle_irq(struct pt_regs *regs) | |||
381 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) | 381 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) |
382 | & PCI_MSI_DOORBELL_MASK; | 382 | & PCI_MSI_DOORBELL_MASK; |
383 | 383 | ||
384 | writel(~PCI_MSI_DOORBELL_MASK, per_cpu_int_base + | 384 | writel(~msimask, per_cpu_int_base + |
385 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); | 385 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); |
386 | 386 | ||
387 | for (msinr = PCI_MSI_DOORBELL_START; | 387 | for (msinr = PCI_MSI_DOORBELL_START; |
@@ -407,7 +407,7 @@ armada_370_xp_handle_irq(struct pt_regs *regs) | |||
407 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) | 407 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) |
408 | & IPI_DOORBELL_MASK; | 408 | & IPI_DOORBELL_MASK; |
409 | 409 | ||
410 | writel(~IPI_DOORBELL_MASK, per_cpu_int_base + | 410 | writel(~ipimask, per_cpu_int_base + |
411 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); | 411 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); |
412 | 412 | ||
413 | /* Handle all pending doorbells */ | 413 | /* Handle all pending doorbells */ |
diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c new file mode 100644 index 000000000000..8ed04c4a43ee --- /dev/null +++ b/drivers/irqchip/irq-zevio.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * linux/drivers/irqchip/irq-zevio.c | ||
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 | #include <linux/io.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | |||
18 | #include <asm/mach/irq.h> | ||
19 | #include <asm/exception.h> | ||
20 | |||
21 | #include "irqchip.h" | ||
22 | |||
23 | #define IO_STATUS 0x000 | ||
24 | #define IO_RAW_STATUS 0x004 | ||
25 | #define IO_ENABLE 0x008 | ||
26 | #define IO_DISABLE 0x00C | ||
27 | #define IO_CURRENT 0x020 | ||
28 | #define IO_RESET 0x028 | ||
29 | #define IO_MAX_PRIOTY 0x02C | ||
30 | |||
31 | #define IO_IRQ_BASE 0x000 | ||
32 | #define IO_FIQ_BASE 0x100 | ||
33 | |||
34 | #define IO_INVERT_SEL 0x200 | ||
35 | #define IO_STICKY_SEL 0x204 | ||
36 | #define IO_PRIORITY_SEL 0x300 | ||
37 | |||
38 | #define MAX_INTRS 32 | ||
39 | #define FIQ_START MAX_INTRS | ||
40 | |||
41 | static struct irq_domain *zevio_irq_domain; | ||
42 | static void __iomem *zevio_irq_io; | ||
43 | |||
44 | static void zevio_irq_ack(struct irq_data *irqd) | ||
45 | { | ||
46 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(irqd); | ||
47 | struct irq_chip_regs *regs = | ||
48 | &container_of(irqd->chip, struct irq_chip_type, chip)->regs; | ||
49 | |||
50 | readl(gc->reg_base + regs->ack); | ||
51 | } | ||
52 | |||
53 | static asmlinkage void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs) | ||
54 | { | ||
55 | int irqnr; | ||
56 | |||
57 | while (readl(zevio_irq_io + IO_STATUS)) { | ||
58 | irqnr = readl(zevio_irq_io + IO_CURRENT); | ||
59 | irqnr = irq_find_mapping(zevio_irq_domain, irqnr); | ||
60 | handle_IRQ(irqnr, regs); | ||
61 | }; | ||
62 | } | ||
63 | |||
64 | static void __init zevio_init_irq_base(void __iomem *base) | ||
65 | { | ||
66 | /* Disable all interrupts */ | ||
67 | writel(~0, base + IO_DISABLE); | ||
68 | |||
69 | /* Accept interrupts of all priorities */ | ||
70 | writel(0xF, base + IO_MAX_PRIOTY); | ||
71 | |||
72 | /* Reset existing interrupts */ | ||
73 | readl(base + IO_RESET); | ||
74 | } | ||
75 | |||
76 | static int __init zevio_of_init(struct device_node *node, | ||
77 | struct device_node *parent) | ||
78 | { | ||
79 | unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | ||
80 | struct irq_chip_generic *gc; | ||
81 | int ret; | ||
82 | |||
83 | if (WARN_ON(zevio_irq_io || zevio_irq_domain)) | ||
84 | return -EBUSY; | ||
85 | |||
86 | zevio_irq_io = of_iomap(node, 0); | ||
87 | BUG_ON(!zevio_irq_io); | ||
88 | |||
89 | /* Do not invert interrupt status bits */ | ||
90 | writel(~0, zevio_irq_io + IO_INVERT_SEL); | ||
91 | |||
92 | /* Disable sticky interrupts */ | ||
93 | writel(0, zevio_irq_io + IO_STICKY_SEL); | ||
94 | |||
95 | /* We don't use IRQ priorities. Set each IRQ to highest priority. */ | ||
96 | memset_io(zevio_irq_io + IO_PRIORITY_SEL, 0, MAX_INTRS * sizeof(u32)); | ||
97 | |||
98 | /* Init IRQ and FIQ */ | ||
99 | zevio_init_irq_base(zevio_irq_io + IO_IRQ_BASE); | ||
100 | zevio_init_irq_base(zevio_irq_io + IO_FIQ_BASE); | ||
101 | |||
102 | zevio_irq_domain = irq_domain_add_linear(node, MAX_INTRS, | ||
103 | &irq_generic_chip_ops, NULL); | ||
104 | BUG_ON(!zevio_irq_domain); | ||
105 | |||
106 | ret = irq_alloc_domain_generic_chips(zevio_irq_domain, MAX_INTRS, 1, | ||
107 | "zevio_intc", handle_level_irq, | ||
108 | clr, 0, IRQ_GC_INIT_MASK_CACHE); | ||
109 | BUG_ON(ret); | ||
110 | |||
111 | gc = irq_get_domain_generic_chip(zevio_irq_domain, 0); | ||
112 | gc->reg_base = zevio_irq_io; | ||
113 | gc->chip_types[0].chip.irq_ack = zevio_irq_ack; | ||
114 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg; | ||
115 | gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg; | ||
116 | gc->chip_types[0].regs.mask = IO_IRQ_BASE + IO_ENABLE; | ||
117 | gc->chip_types[0].regs.enable = IO_IRQ_BASE + IO_ENABLE; | ||
118 | gc->chip_types[0].regs.disable = IO_IRQ_BASE + IO_DISABLE; | ||
119 | gc->chip_types[0].regs.ack = IO_IRQ_BASE + IO_RESET; | ||
120 | |||
121 | set_handle_irq(zevio_handle_irq); | ||
122 | |||
123 | pr_info("TI-NSPIRE classic IRQ controller\n"); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | IRQCHIP_DECLARE(zevio_irq, "lsi,zevio-intc", zevio_of_init); | ||
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c index 68f768a5422d..a6c3c9e2e897 100644 --- a/drivers/media/dvb-frontends/cx24117.c +++ b/drivers/media/dvb-frontends/cx24117.c | |||
@@ -1176,7 +1176,7 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, | |||
1176 | 1176 | ||
1177 | switch (demod) { | 1177 | switch (demod) { |
1178 | case 0: | 1178 | case 0: |
1179 | dev_err(&state->priv->i2c->dev, | 1179 | dev_err(&i2c->dev, |
1180 | "%s: Error attaching frontend %d\n", | 1180 | "%s: Error attaching frontend %d\n", |
1181 | KBUILD_MODNAME, demod); | 1181 | KBUILD_MODNAME, demod); |
1182 | goto error1; | 1182 | goto error1; |
@@ -1200,12 +1200,6 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, | |||
1200 | state->demod = demod - 1; | 1200 | state->demod = demod - 1; |
1201 | state->priv = priv; | 1201 | state->priv = priv; |
1202 | 1202 | ||
1203 | /* test i2c bus for ack */ | ||
1204 | if (demod == 0) { | ||
1205 | if (cx24117_readreg(state, 0x00) < 0) | ||
1206 | goto error3; | ||
1207 | } | ||
1208 | |||
1209 | dev_info(&state->priv->i2c->dev, | 1203 | dev_info(&state->priv->i2c->dev, |
1210 | "%s: Attaching frontend %d\n", | 1204 | "%s: Attaching frontend %d\n", |
1211 | KBUILD_MODNAME, state->demod); | 1205 | KBUILD_MODNAME, state->demod); |
@@ -1216,8 +1210,6 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, | |||
1216 | state->frontend.demodulator_priv = state; | 1210 | state->frontend.demodulator_priv = state; |
1217 | return &state->frontend; | 1211 | return &state->frontend; |
1218 | 1212 | ||
1219 | error3: | ||
1220 | kfree(state); | ||
1221 | error2: | 1213 | error2: |
1222 | cx24117_release_priv(priv); | 1214 | cx24117_release_priv(priv); |
1223 | error1: | 1215 | error1: |
diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c index 4bf057544607..8a8e1ecb762d 100644 --- a/drivers/media/dvb-frontends/nxt200x.c +++ b/drivers/media/dvb-frontends/nxt200x.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Support for NXT2002 and NXT2004 - VSB/QAM | 2 | * Support for NXT2002 and NXT2004 - VSB/QAM |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com> | 4 | * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com> |
5 | * Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net> | 5 | * Copyright (C) 2006-2014 Michael Krufky <mkrufky@linuxtv.org> |
6 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> | 6 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> |
7 | * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com> | 7 | * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com> |
8 | * | 8 | * |
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 1effc21e1cdd..9bbd6656fb8f 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c | |||
@@ -2554,7 +2554,7 @@ static int adv7842_core_init(struct v4l2_subdev *sd) | |||
2554 | sdp_write_and_or(sd, 0xdd, 0xf0, pdata->sdp_free_run_force | | 2554 | sdp_write_and_or(sd, 0xdd, 0xf0, pdata->sdp_free_run_force | |
2555 | (pdata->sdp_free_run_cbar_en << 1) | | 2555 | (pdata->sdp_free_run_cbar_en << 1) | |
2556 | (pdata->sdp_free_run_man_col_en << 2) | | 2556 | (pdata->sdp_free_run_man_col_en << 2) | |
2557 | (pdata->sdp_free_run_force << 3)); | 2557 | (pdata->sdp_free_run_auto << 3)); |
2558 | 2558 | ||
2559 | /* TODO from platform data */ | 2559 | /* TODO from platform data */ |
2560 | cp_write(sd, 0x69, 0x14); /* Enable CP CSC */ | 2560 | cp_write(sd, 0x69, 0x14); /* Enable CP CSC */ |
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 4b8381111cbd..77e10e0fd8d6 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c | |||
@@ -478,25 +478,33 @@ static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr, | |||
478 | u16 count, const u16 *seq) | 478 | u16 count, const u16 *seq) |
479 | { | 479 | { |
480 | struct i2c_client *c = v4l2_get_subdevdata(&state->sd); | 480 | struct i2c_client *c = v4l2_get_subdevdata(&state->sd); |
481 | __be16 buf[count + 1]; | 481 | __be16 buf[65]; |
482 | int ret, n; | ||
483 | 482 | ||
484 | s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr); | 483 | s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr); |
485 | if (state->error) | 484 | if (state->error) |
486 | return; | 485 | return; |
487 | 486 | ||
487 | v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count, | ||
488 | min(2 * count, 64), seq); | ||
489 | |||
488 | buf[0] = __constant_cpu_to_be16(REG_CMD_BUF); | 490 | buf[0] = __constant_cpu_to_be16(REG_CMD_BUF); |
489 | for (n = 1; n <= count; ++n) | ||
490 | buf[n] = cpu_to_be16(*seq++); | ||
491 | 491 | ||
492 | n *= 2; | 492 | while (count > 0) { |
493 | ret = i2c_master_send(c, (char *)buf, n); | 493 | int n = min_t(int, count, ARRAY_SIZE(buf) - 1); |
494 | v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count, | 494 | int ret, i; |
495 | min(2 * count, 64), seq - count); | ||
496 | 495 | ||
497 | if (ret != n) { | 496 | for (i = 1; i <= n; ++i) |
498 | v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret); | 497 | buf[i] = cpu_to_be16(*seq++); |
499 | state->error = ret; | 498 | |
499 | i *= 2; | ||
500 | ret = i2c_master_send(c, (char *)buf, i); | ||
501 | if (ret != i) { | ||
502 | v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret); | ||
503 | state->error = ret; | ||
504 | break; | ||
505 | } | ||
506 | |||
507 | count -= n; | ||
500 | } | 508 | } |
501 | } | 509 | } |
502 | 510 | ||
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index d85cb0ace4dc..6662b495b22c 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c | |||
@@ -2426,7 +2426,7 @@ struct tvcard bttv_tvcards[] = { | |||
2426 | }, | 2426 | }, |
2427 | /* ---- card 0x87---------------------------------- */ | 2427 | /* ---- card 0x87---------------------------------- */ |
2428 | [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { | 2428 | [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { |
2429 | /* Michael Krufky <mkrufky@m1k.net> */ | 2429 | /* Michael Krufky <mkrufky@linuxtv.org> */ |
2430 | .name = "DViCO FusionHDTV 5 Lite", | 2430 | .name = "DViCO FusionHDTV 5 Lite", |
2431 | .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ | 2431 | .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ |
2432 | .tuner_addr = ADDR_UNSET, | 2432 | .tuner_addr = ADDR_UNSET, |
diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c index 922e8233fd0b..3f364b7062b9 100644 --- a/drivers/media/pci/bt8xx/bttv-gpio.c +++ b/drivers/media/pci/bt8xx/bttv-gpio.c | |||
@@ -98,7 +98,7 @@ int bttv_sub_add_device(struct bttv_core *core, char *name) | |||
98 | 98 | ||
99 | err = device_register(&sub->dev); | 99 | err = device_register(&sub->dev); |
100 | if (0 != err) { | 100 | if (0 != err) { |
101 | kfree(sub); | 101 | put_device(&sub->dev); |
102 | return err; | 102 | return err; |
103 | } | 103 | } |
104 | pr_info("%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev)); | 104 | pr_info("%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev)); |
diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index d45e7f6ff332..c9b2350e92c8 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c | |||
@@ -2590,7 +2590,7 @@ struct saa7134_board saa7134_boards[] = { | |||
2590 | }}, | 2590 | }}, |
2591 | }, | 2591 | }, |
2592 | [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = { | 2592 | [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = { |
2593 | /* Michael Krufky <mkrufky@m1k.net> | 2593 | /* Michael Krufky <mkrufky@linuxtv.org> |
2594 | * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder | 2594 | * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder |
2595 | * AFAIK, there is no analog demod, thus, | 2595 | * AFAIK, there is no analog demod, thus, |
2596 | * no support for analog television. | 2596 | * no support for analog television. |
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index a7dfd07e8389..da2fc86cc524 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c | |||
@@ -1027,7 +1027,8 @@ static int fimc_probe(struct platform_device *pdev) | |||
1027 | return 0; | 1027 | return 0; |
1028 | 1028 | ||
1029 | err_gclk: | 1029 | err_gclk: |
1030 | clk_disable(fimc->clock[CLK_GATE]); | 1030 | if (!pm_runtime_enabled(dev)) |
1031 | clk_disable(fimc->clock[CLK_GATE]); | ||
1031 | err_sd: | 1032 | err_sd: |
1032 | fimc_unregister_capture_subdev(fimc); | 1033 | fimc_unregister_capture_subdev(fimc); |
1033 | err_sclk: | 1034 | err_sclk: |
@@ -1036,6 +1037,7 @@ err_sclk: | |||
1036 | return ret; | 1037 | return ret; |
1037 | } | 1038 | } |
1038 | 1039 | ||
1040 | #ifdef CONFIG_PM_RUNTIME | ||
1039 | static int fimc_runtime_resume(struct device *dev) | 1041 | static int fimc_runtime_resume(struct device *dev) |
1040 | { | 1042 | { |
1041 | struct fimc_dev *fimc = dev_get_drvdata(dev); | 1043 | struct fimc_dev *fimc = dev_get_drvdata(dev); |
@@ -1068,6 +1070,7 @@ static int fimc_runtime_suspend(struct device *dev) | |||
1068 | dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state); | 1070 | dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state); |
1069 | return ret; | 1071 | return ret; |
1070 | } | 1072 | } |
1073 | #endif | ||
1071 | 1074 | ||
1072 | #ifdef CONFIG_PM_SLEEP | 1075 | #ifdef CONFIG_PM_SLEEP |
1073 | static int fimc_resume(struct device *dev) | 1076 | static int fimc_resume(struct device *dev) |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 1234734bccf4..779ec3cd259d 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c | |||
@@ -1563,7 +1563,7 @@ static int fimc_lite_probe(struct platform_device *pdev) | |||
1563 | if (!pm_runtime_enabled(dev)) { | 1563 | if (!pm_runtime_enabled(dev)) { |
1564 | ret = clk_enable(fimc->clock); | 1564 | ret = clk_enable(fimc->clock); |
1565 | if (ret < 0) | 1565 | if (ret < 0) |
1566 | goto err_clk_put; | 1566 | goto err_sd; |
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); | 1569 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); |
@@ -1579,7 +1579,8 @@ static int fimc_lite_probe(struct platform_device *pdev) | |||
1579 | return 0; | 1579 | return 0; |
1580 | 1580 | ||
1581 | err_clk_dis: | 1581 | err_clk_dis: |
1582 | clk_disable(fimc->clock); | 1582 | if (!pm_runtime_enabled(dev)) |
1583 | clk_disable(fimc->clock); | ||
1583 | err_sd: | 1584 | err_sd: |
1584 | fimc_lite_unregister_capture_subdev(fimc); | 1585 | fimc_lite_unregister_capture_subdev(fimc); |
1585 | err_clk_put: | 1586 | err_clk_put: |
@@ -1587,6 +1588,7 @@ err_clk_put: | |||
1587 | return ret; | 1588 | return ret; |
1588 | } | 1589 | } |
1589 | 1590 | ||
1591 | #ifdef CONFIG_PM_RUNTIME | ||
1590 | static int fimc_lite_runtime_resume(struct device *dev) | 1592 | static int fimc_lite_runtime_resume(struct device *dev) |
1591 | { | 1593 | { |
1592 | struct fimc_lite *fimc = dev_get_drvdata(dev); | 1594 | struct fimc_lite *fimc = dev_get_drvdata(dev); |
@@ -1602,6 +1604,7 @@ static int fimc_lite_runtime_suspend(struct device *dev) | |||
1602 | clk_disable(fimc->clock); | 1604 | clk_disable(fimc->clock); |
1603 | return 0; | 1605 | return 0; |
1604 | } | 1606 | } |
1607 | #endif | ||
1605 | 1608 | ||
1606 | #ifdef CONFIG_PM_SLEEP | 1609 | #ifdef CONFIG_PM_SLEEP |
1607 | static int fimc_lite_resume(struct device *dev) | 1610 | static int fimc_lite_resume(struct device *dev) |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index a1c78c870b68..7d68d0b9966a 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c | |||
@@ -175,7 +175,7 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
175 | { | 175 | { |
176 | .name = "YUV 4:2:0 planar, Y/CbCr", | 176 | .name = "YUV 4:2:0 planar, Y/CbCr", |
177 | .fourcc = V4L2_PIX_FMT_NV12, | 177 | .fourcc = V4L2_PIX_FMT_NV12, |
178 | .depth = 16, | 178 | .depth = 12, |
179 | .colplanes = 2, | 179 | .colplanes = 2, |
180 | .h_align = 1, | 180 | .h_align = 1, |
181 | .v_align = 1, | 181 | .v_align = 1, |
@@ -188,10 +188,10 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
188 | { | 188 | { |
189 | .name = "YUV 4:2:0 planar, Y/CbCr", | 189 | .name = "YUV 4:2:0 planar, Y/CbCr", |
190 | .fourcc = V4L2_PIX_FMT_NV12, | 190 | .fourcc = V4L2_PIX_FMT_NV12, |
191 | .depth = 16, | 191 | .depth = 12, |
192 | .colplanes = 4, | 192 | .colplanes = 2, |
193 | .h_align = 4, | 193 | .h_align = 4, |
194 | .v_align = 1, | 194 | .v_align = 4, |
195 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | 195 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | |
196 | SJPEG_FMT_FLAG_DEC_CAPTURE | | 196 | SJPEG_FMT_FLAG_DEC_CAPTURE | |
197 | SJPEG_FMT_FLAG_S5P | | 197 | SJPEG_FMT_FLAG_S5P | |
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 8f9b2cea88f0..8ede8ea762e6 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c | |||
@@ -1539,6 +1539,8 @@ static const struct usb_device_id af9035_id_table[] = { | |||
1539 | &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) }, | 1539 | &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) }, |
1540 | { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05, | 1540 | { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05, |
1541 | &af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) }, | 1541 | &af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) }, |
1542 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xf900, | ||
1543 | &af9035_props, "Hauppauge WinTV-MiniStick 2", NULL) }, | ||
1542 | { } | 1544 | { } |
1543 | }; | 1545 | }; |
1544 | MODULE_DEVICE_TABLE(usb, af9035_id_table); | 1546 | MODULE_DEVICE_TABLE(usb, af9035_id_table); |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c index d83df4bb72d3..0a98d04c53e4 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator | 2 | * mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -601,7 +601,7 @@ struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state, | |||
601 | EXPORT_SYMBOL_GPL(mxl111sf_demod_attach); | 601 | EXPORT_SYMBOL_GPL(mxl111sf_demod_attach); |
602 | 602 | ||
603 | MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver"); | 603 | MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver"); |
604 | MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); | 604 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
605 | MODULE_LICENSE("GPL"); | 605 | MODULE_LICENSE("GPL"); |
606 | MODULE_VERSION("0.1"); | 606 | MODULE_VERSION("0.1"); |
607 | 607 | ||
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h index 3f3f8bfd190b..2d4530f5be54 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator | 2 | * mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c index e4121cb8f5ef..a619410adde4 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-gpio.c - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-gpio.c - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h index 0220f54299a5..b85a5772d771 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-gpio.h - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-gpio.h - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c index 34434557ef65..a101d06eb143 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-i2c.c - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-i2c.c - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h index a57a45ffb9e4..465762145ad2 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-i2c.h - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-i2c.h - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c index b741b3a7a325..f6b348024bec 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-phy.c - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-phy.c - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h index f0756071d347..0643738de7de 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-phy.h - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-phy.h - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h index 17831b0fb9db..89bf115e927e 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-reg.h - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-reg.h - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c index 879c529640f7..a8d2c7053674 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner | 2 | * mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -512,7 +512,7 @@ struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, | |||
512 | EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach); | 512 | EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach); |
513 | 513 | ||
514 | MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver"); | 514 | MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver"); |
515 | MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); | 515 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
516 | MODULE_LICENSE("GPL"); | 516 | MODULE_LICENSE("GPL"); |
517 | MODULE_VERSION("0.1"); | 517 | MODULE_VERSION("0.1"); |
518 | 518 | ||
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h index 90f583e5d6a6..2046db22519e 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner | 2 | * mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -68,7 +68,7 @@ struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, | |||
68 | #else | 68 | #else |
69 | static inline | 69 | static inline |
70 | struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, | 70 | struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, |
71 | struct mxl111sf_state *mxl_state | 71 | struct mxl111sf_state *mxl_state, |
72 | struct mxl111sf_tuner_config *cfg) | 72 | struct mxl111sf_tuner_config *cfg) |
73 | { | 73 | { |
74 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 74 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c index 08240e498451..c7304fa8ab73 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com) | 2 | * Copyright (C) 2010-2014 Michael Krufky (mkrufky@linuxtv.org) |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the Free | 5 | * under the terms of the GNU General Public License as published by the Free |
@@ -105,7 +105,7 @@ int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data) | |||
105 | ret = -EINVAL; | 105 | ret = -EINVAL; |
106 | } | 106 | } |
107 | 107 | ||
108 | pr_debug("R: (0x%02x, 0x%02x)\n", addr, *data); | 108 | pr_debug("R: (0x%02x, 0x%02x)\n", addr, buf[1]); |
109 | fail: | 109 | fail: |
110 | return ret; | 110 | return ret; |
111 | } | 111 | } |
@@ -1421,7 +1421,7 @@ static struct usb_driver mxl111sf_usb_driver = { | |||
1421 | 1421 | ||
1422 | module_usb_driver(mxl111sf_usb_driver); | 1422 | module_usb_driver(mxl111sf_usb_driver); |
1423 | 1423 | ||
1424 | MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); | 1424 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
1425 | MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF"); | 1425 | MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF"); |
1426 | MODULE_VERSION("1.0"); | 1426 | MODULE_VERSION("1.0"); |
1427 | MODULE_LICENSE("GPL"); | 1427 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.h b/drivers/media/usb/dvb-usb-v2/mxl111sf.h index 9816de86e48c..8516c011b7cc 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com) | 2 | * Copyright (C) 2010-2014 Michael Krufky (mkrufky@linuxtv.org) |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the Free | 5 | * under the terms of the GNU General Public License as published by the Free |
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 2f0c89cbac76..c5638964c3f2 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c | |||
@@ -198,7 +198,6 @@ static int device_authorization(struct hdpvr_device *dev) | |||
198 | hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); | 198 | hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); |
199 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", | 199 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", |
200 | print_buf); | 200 | print_buf); |
201 | kfree(print_buf); | ||
202 | #endif | 201 | #endif |
203 | 202 | ||
204 | msleep(100); | 203 | msleep(100); |
@@ -214,6 +213,9 @@ static int device_authorization(struct hdpvr_device *dev) | |||
214 | retval = ret != 8; | 213 | retval = ret != 8; |
215 | unlock: | 214 | unlock: |
216 | mutex_unlock(&dev->usbc_mutex); | 215 | mutex_unlock(&dev->usbc_mutex); |
216 | #ifdef HDPVR_DEBUG | ||
217 | kfree(print_buf); | ||
218 | #endif | ||
217 | return retval; | 219 | return retval; |
218 | } | 220 | } |
219 | 221 | ||
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index ee52b9f4a944..f7902fe8a526 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c | |||
@@ -515,6 +515,7 @@ bool v4l2_detect_gtf(unsigned frame_height, | |||
515 | aspect.denominator = 9; | 515 | aspect.denominator = 9; |
516 | } | 516 | } |
517 | image_width = ((image_height * aspect.numerator) / aspect.denominator); | 517 | image_width = ((image_height * aspect.numerator) / aspect.denominator); |
518 | image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1); | ||
518 | 519 | ||
519 | /* Horizontal */ | 520 | /* Horizontal */ |
520 | if (default_gtf) | 521 | if (default_gtf) |
diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c index 65411adcd0ea..7e6b209b7002 100644 --- a/drivers/media/v4l2-core/videobuf-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c | |||
@@ -66,14 +66,11 @@ static void __videobuf_dc_free(struct device *dev, | |||
66 | static void videobuf_vm_open(struct vm_area_struct *vma) | 66 | static void videobuf_vm_open(struct vm_area_struct *vma) |
67 | { | 67 | { |
68 | struct videobuf_mapping *map = vma->vm_private_data; | 68 | struct videobuf_mapping *map = vma->vm_private_data; |
69 | struct videobuf_queue *q = map->q; | ||
70 | 69 | ||
71 | dev_dbg(q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", | 70 | dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", |
72 | map, map->count, vma->vm_start, vma->vm_end); | 71 | map, map->count, vma->vm_start, vma->vm_end); |
73 | 72 | ||
74 | videobuf_queue_lock(q); | ||
75 | map->count++; | 73 | map->count++; |
76 | videobuf_queue_unlock(q); | ||
77 | } | 74 | } |
78 | 75 | ||
79 | static void videobuf_vm_close(struct vm_area_struct *vma) | 76 | static void videobuf_vm_close(struct vm_area_struct *vma) |
@@ -85,11 +82,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
85 | dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", | 82 | dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", |
86 | map, map->count, vma->vm_start, vma->vm_end); | 83 | map, map->count, vma->vm_start, vma->vm_end); |
87 | 84 | ||
88 | videobuf_queue_lock(q); | 85 | map->count--; |
89 | if (!--map->count) { | 86 | if (0 == map->count) { |
90 | struct videobuf_dma_contig_memory *mem; | 87 | struct videobuf_dma_contig_memory *mem; |
91 | 88 | ||
92 | dev_dbg(q->dev, "munmap %p q=%p\n", map, q); | 89 | dev_dbg(q->dev, "munmap %p q=%p\n", map, q); |
90 | videobuf_queue_lock(q); | ||
93 | 91 | ||
94 | /* We need first to cancel streams, before unmapping */ | 92 | /* We need first to cancel streams, before unmapping */ |
95 | if (q->streaming) | 93 | if (q->streaming) |
@@ -128,8 +126,8 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
128 | 126 | ||
129 | kfree(map); | 127 | kfree(map); |
130 | 128 | ||
129 | videobuf_queue_unlock(q); | ||
131 | } | 130 | } |
132 | videobuf_queue_unlock(q); | ||
133 | } | 131 | } |
134 | 132 | ||
135 | static const struct vm_operations_struct videobuf_vm_ops = { | 133 | static const struct vm_operations_struct videobuf_vm_ops = { |
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c index 9db674ccdc68..828e7c10bd70 100644 --- a/drivers/media/v4l2-core/videobuf-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c | |||
@@ -338,14 +338,11 @@ EXPORT_SYMBOL_GPL(videobuf_dma_free); | |||
338 | static void videobuf_vm_open(struct vm_area_struct *vma) | 338 | static void videobuf_vm_open(struct vm_area_struct *vma) |
339 | { | 339 | { |
340 | struct videobuf_mapping *map = vma->vm_private_data; | 340 | struct videobuf_mapping *map = vma->vm_private_data; |
341 | struct videobuf_queue *q = map->q; | ||
342 | 341 | ||
343 | dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map, | 342 | dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map, |
344 | map->count, vma->vm_start, vma->vm_end); | 343 | map->count, vma->vm_start, vma->vm_end); |
345 | 344 | ||
346 | videobuf_queue_lock(q); | ||
347 | map->count++; | 345 | map->count++; |
348 | videobuf_queue_unlock(q); | ||
349 | } | 346 | } |
350 | 347 | ||
351 | static void videobuf_vm_close(struct vm_area_struct *vma) | 348 | static void videobuf_vm_close(struct vm_area_struct *vma) |
@@ -358,9 +355,10 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
358 | dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map, | 355 | dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map, |
359 | map->count, vma->vm_start, vma->vm_end); | 356 | map->count, vma->vm_start, vma->vm_end); |
360 | 357 | ||
361 | videobuf_queue_lock(q); | 358 | map->count--; |
362 | if (!--map->count) { | 359 | if (0 == map->count) { |
363 | dprintk(1, "munmap %p q=%p\n", map, q); | 360 | dprintk(1, "munmap %p q=%p\n", map, q); |
361 | videobuf_queue_lock(q); | ||
364 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 362 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
365 | if (NULL == q->bufs[i]) | 363 | if (NULL == q->bufs[i]) |
366 | continue; | 364 | continue; |
@@ -376,9 +374,9 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
376 | q->bufs[i]->baddr = 0; | 374 | q->bufs[i]->baddr = 0; |
377 | q->ops->buf_release(q, q->bufs[i]); | 375 | q->ops->buf_release(q, q->bufs[i]); |
378 | } | 376 | } |
377 | videobuf_queue_unlock(q); | ||
379 | kfree(map); | 378 | kfree(map); |
380 | } | 379 | } |
381 | videobuf_queue_unlock(q); | ||
382 | return; | 380 | return; |
383 | } | 381 | } |
384 | 382 | ||
diff --git a/drivers/media/v4l2-core/videobuf-vmalloc.c b/drivers/media/v4l2-core/videobuf-vmalloc.c index 1365c651c177..2ff7fcc77b11 100644 --- a/drivers/media/v4l2-core/videobuf-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf-vmalloc.c | |||
@@ -54,14 +54,11 @@ MODULE_LICENSE("GPL"); | |||
54 | static void videobuf_vm_open(struct vm_area_struct *vma) | 54 | static void videobuf_vm_open(struct vm_area_struct *vma) |
55 | { | 55 | { |
56 | struct videobuf_mapping *map = vma->vm_private_data; | 56 | struct videobuf_mapping *map = vma->vm_private_data; |
57 | struct videobuf_queue *q = map->q; | ||
58 | 57 | ||
59 | dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map, | 58 | dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map, |
60 | map->count, vma->vm_start, vma->vm_end); | 59 | map->count, vma->vm_start, vma->vm_end); |
61 | 60 | ||
62 | videobuf_queue_lock(q); | ||
63 | map->count++; | 61 | map->count++; |
64 | videobuf_queue_unlock(q); | ||
65 | } | 62 | } |
66 | 63 | ||
67 | static void videobuf_vm_close(struct vm_area_struct *vma) | 64 | static void videobuf_vm_close(struct vm_area_struct *vma) |
@@ -73,11 +70,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
73 | dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, | 70 | dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, |
74 | map->count, vma->vm_start, vma->vm_end); | 71 | map->count, vma->vm_start, vma->vm_end); |
75 | 72 | ||
76 | videobuf_queue_lock(q); | 73 | map->count--; |
77 | if (!--map->count) { | 74 | if (0 == map->count) { |
78 | struct videobuf_vmalloc_memory *mem; | 75 | struct videobuf_vmalloc_memory *mem; |
79 | 76 | ||
80 | dprintk(1, "munmap %p q=%p\n", map, q); | 77 | dprintk(1, "munmap %p q=%p\n", map, q); |
78 | videobuf_queue_lock(q); | ||
81 | 79 | ||
82 | /* We need first to cancel streams, before unmapping */ | 80 | /* We need first to cancel streams, before unmapping */ |
83 | if (q->streaming) | 81 | if (q->streaming) |
@@ -116,8 +114,8 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
116 | 114 | ||
117 | kfree(map); | 115 | kfree(map); |
118 | 116 | ||
117 | videobuf_queue_unlock(q); | ||
119 | } | 118 | } |
120 | videobuf_queue_unlock(q); | ||
121 | 119 | ||
122 | return; | 120 | return; |
123 | } | 121 | } |
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 5a5fb7f09b7b..a127925c9d61 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
@@ -1776,6 +1776,11 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type) | |||
1776 | return 0; | 1776 | return 0; |
1777 | } | 1777 | } |
1778 | 1778 | ||
1779 | if (!q->num_buffers) { | ||
1780 | dprintk(1, "streamon: no buffers have been allocated\n"); | ||
1781 | return -EINVAL; | ||
1782 | } | ||
1783 | |||
1779 | /* | 1784 | /* |
1780 | * If any buffers were queued before streamon, | 1785 | * If any buffers were queued before streamon, |
1781 | * we can now pass them to driver for processing. | 1786 | * we can now pass them to driver for processing. |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cd929aed3613..e2a783fdb98f 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -210,10 +210,29 @@ static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | static void dock_event(acpi_handle handle, u32 type, void *data) | ||
214 | { | ||
215 | struct acpiphp_context *context; | ||
216 | |||
217 | mutex_lock(&acpiphp_context_lock); | ||
218 | context = acpiphp_get_context(handle); | ||
219 | if (!context || WARN_ON(context->handle != handle) | ||
220 | || context->func.parent->is_going_away) { | ||
221 | mutex_unlock(&acpiphp_context_lock); | ||
222 | return; | ||
223 | } | ||
224 | get_bridge(context->func.parent); | ||
225 | acpiphp_put_context(context); | ||
226 | mutex_unlock(&acpiphp_context_lock); | ||
227 | |||
228 | hotplug_event(handle, type, data); | ||
229 | |||
230 | put_bridge(context->func.parent); | ||
231 | } | ||
213 | 232 | ||
214 | static const struct acpi_dock_ops acpiphp_dock_ops = { | 233 | static const struct acpi_dock_ops acpiphp_dock_ops = { |
215 | .fixup = post_dock_fixups, | 234 | .fixup = post_dock_fixups, |
216 | .handler = hotplug_event, | 235 | .handler = dock_event, |
217 | }; | 236 | }; |
218 | 237 | ||
219 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ | 238 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ |
@@ -441,7 +460,9 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
441 | list_del(&bridge->list); | 460 | list_del(&bridge->list); |
442 | mutex_unlock(&bridge_mutex); | 461 | mutex_unlock(&bridge_mutex); |
443 | 462 | ||
463 | mutex_lock(&acpiphp_context_lock); | ||
444 | bridge->is_going_away = true; | 464 | bridge->is_going_away = true; |
465 | mutex_unlock(&acpiphp_context_lock); | ||
445 | } | 466 | } |
446 | 467 | ||
447 | /** | 468 | /** |
@@ -742,7 +763,7 @@ static void trim_stale_devices(struct pci_dev *dev) | |||
742 | 763 | ||
743 | /* The device is a bridge. so check the bus below it. */ | 764 | /* The device is a bridge. so check the bus below it. */ |
744 | pm_runtime_get_sync(&dev->dev); | 765 | pm_runtime_get_sync(&dev->dev); |
745 | list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) | 766 | list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list) |
746 | trim_stale_devices(child); | 767 | trim_stale_devices(child); |
747 | 768 | ||
748 | pm_runtime_put(&dev->dev); | 769 | pm_runtime_put(&dev->dev); |
@@ -773,8 +794,8 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
773 | ; /* do nothing */ | 794 | ; /* do nothing */ |
774 | } else if (get_slot_status(slot) == ACPI_STA_ALL) { | 795 | } else if (get_slot_status(slot) == ACPI_STA_ALL) { |
775 | /* remove stale devices if any */ | 796 | /* remove stale devices if any */ |
776 | list_for_each_entry_safe(dev, tmp, &bus->devices, | 797 | list_for_each_entry_safe_reverse(dev, tmp, |
777 | bus_list) | 798 | &bus->devices, bus_list) |
778 | if (PCI_SLOT(dev->devfn) == slot->device) | 799 | if (PCI_SLOT(dev->devfn) == slot->device) |
779 | trim_stale_devices(dev); | 800 | trim_stale_devices(dev); |
780 | 801 | ||
@@ -805,7 +826,7 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
805 | int i; | 826 | int i; |
806 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 827 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
807 | 828 | ||
808 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { | 829 | list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) { |
809 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { | 830 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { |
810 | struct resource *res = &dev->resource[i]; | 831 | struct resource *res = &dev->resource[i]; |
811 | if ((res->flags & type_mask) && !res->start && | 832 | if ((res->flags & type_mask) && !res->start && |
@@ -829,7 +850,11 @@ void acpiphp_check_host_bridge(acpi_handle handle) | |||
829 | 850 | ||
830 | bridge = acpiphp_handle_to_bridge(handle); | 851 | bridge = acpiphp_handle_to_bridge(handle); |
831 | if (bridge) { | 852 | if (bridge) { |
853 | pci_lock_rescan_remove(); | ||
854 | |||
832 | acpiphp_check_bridge(bridge); | 855 | acpiphp_check_bridge(bridge); |
856 | |||
857 | pci_unlock_rescan_remove(); | ||
833 | put_bridge(bridge); | 858 | put_bridge(bridge); |
834 | } | 859 | } |
835 | } | 860 | } |
@@ -852,6 +877,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) | |||
852 | 877 | ||
853 | mutex_unlock(&acpiphp_context_lock); | 878 | mutex_unlock(&acpiphp_context_lock); |
854 | 879 | ||
880 | pci_lock_rescan_remove(); | ||
855 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 881 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
856 | 882 | ||
857 | switch (type) { | 883 | switch (type) { |
@@ -905,6 +931,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) | |||
905 | break; | 931 | break; |
906 | } | 932 | } |
907 | 933 | ||
934 | pci_unlock_rescan_remove(); | ||
908 | if (bridge) | 935 | if (bridge) |
909 | put_bridge(bridge); | 936 | put_bridge(bridge); |
910 | } | 937 | } |
@@ -915,11 +942,9 @@ static void hotplug_event_work(void *data, u32 type) | |||
915 | acpi_handle handle = context->handle; | 942 | acpi_handle handle = context->handle; |
916 | 943 | ||
917 | acpi_scan_lock_acquire(); | 944 | acpi_scan_lock_acquire(); |
918 | pci_lock_rescan_remove(); | ||
919 | 945 | ||
920 | hotplug_event(handle, type, context); | 946 | hotplug_event(handle, type, context); |
921 | 947 | ||
922 | pci_unlock_rescan_remove(); | ||
923 | acpi_scan_lock_release(); | 948 | acpi_scan_lock_release(); |
924 | acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); | 949 | acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); |
925 | put_bridge(context->func.parent); | 950 | put_bridge(context->func.parent); |
@@ -937,6 +962,7 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) | |||
937 | { | 962 | { |
938 | struct acpiphp_context *context; | 963 | struct acpiphp_context *context; |
939 | u32 ost_code = ACPI_OST_SC_SUCCESS; | 964 | u32 ost_code = ACPI_OST_SC_SUCCESS; |
965 | acpi_status status; | ||
940 | 966 | ||
941 | switch (type) { | 967 | switch (type) { |
942 | case ACPI_NOTIFY_BUS_CHECK: | 968 | case ACPI_NOTIFY_BUS_CHECK: |
@@ -972,13 +998,20 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) | |||
972 | 998 | ||
973 | mutex_lock(&acpiphp_context_lock); | 999 | mutex_lock(&acpiphp_context_lock); |
974 | context = acpiphp_get_context(handle); | 1000 | context = acpiphp_get_context(handle); |
975 | if (context && !WARN_ON(context->handle != handle)) { | 1001 | if (!context || WARN_ON(context->handle != handle) |
976 | get_bridge(context->func.parent); | 1002 | || context->func.parent->is_going_away) |
977 | acpiphp_put_context(context); | 1003 | goto err_out; |
978 | acpi_hotplug_execute(hotplug_event_work, context, type); | 1004 | |
1005 | get_bridge(context->func.parent); | ||
1006 | acpiphp_put_context(context); | ||
1007 | status = acpi_hotplug_execute(hotplug_event_work, context, type); | ||
1008 | if (ACPI_SUCCESS(status)) { | ||
979 | mutex_unlock(&acpiphp_context_lock); | 1009 | mutex_unlock(&acpiphp_context_lock); |
980 | return; | 1010 | return; |
981 | } | 1011 | } |
1012 | put_bridge(context->func.parent); | ||
1013 | |||
1014 | err_out: | ||
982 | mutex_unlock(&acpiphp_context_lock); | 1015 | mutex_unlock(&acpiphp_context_lock); |
983 | ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 1016 | ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
984 | 1017 | ||
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 77b46d0b37a6..e10febe9ec34 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
@@ -498,7 +498,7 @@ static int ab3100_regulator_register(struct platform_device *pdev, | |||
498 | struct ab3100_platform_data *plfdata, | 498 | struct ab3100_platform_data *plfdata, |
499 | struct regulator_init_data *init_data, | 499 | struct regulator_init_data *init_data, |
500 | struct device_node *np, | 500 | struct device_node *np, |
501 | int id) | 501 | unsigned long id) |
502 | { | 502 | { |
503 | struct regulator_desc *desc; | 503 | struct regulator_desc *desc; |
504 | struct ab3100_regulator *reg; | 504 | struct ab3100_regulator *reg; |
@@ -646,7 +646,7 @@ ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np) | |||
646 | err = ab3100_regulator_register( | 646 | err = ab3100_regulator_register( |
647 | pdev, NULL, ab3100_regulator_matches[i].init_data, | 647 | pdev, NULL, ab3100_regulator_matches[i].init_data, |
648 | ab3100_regulator_matches[i].of_node, | 648 | ab3100_regulator_matches[i].of_node, |
649 | (int) ab3100_regulator_matches[i].driver_data); | 649 | (unsigned long)ab3100_regulator_matches[i].driver_data); |
650 | if (err) { | 650 | if (err) { |
651 | ab3100_regulators_remove(pdev); | 651 | ab3100_regulators_remove(pdev); |
652 | return err; | 652 | return err; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b38a6b669e8c..16a309e5c024 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -1272,6 +1272,8 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, | |||
1272 | if (r->dev.parent && | 1272 | if (r->dev.parent && |
1273 | node == r->dev.of_node) | 1273 | node == r->dev.of_node) |
1274 | return r; | 1274 | return r; |
1275 | *ret = -EPROBE_DEFER; | ||
1276 | return NULL; | ||
1275 | } else { | 1277 | } else { |
1276 | /* | 1278 | /* |
1277 | * If we couldn't even get the node then it's | 1279 | * If we couldn't even get the node then it's |
@@ -1312,7 +1314,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1312 | struct regulator_dev *rdev; | 1314 | struct regulator_dev *rdev; |
1313 | struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); | 1315 | struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); |
1314 | const char *devname = NULL; | 1316 | const char *devname = NULL; |
1315 | int ret = -EPROBE_DEFER; | 1317 | int ret; |
1316 | 1318 | ||
1317 | if (id == NULL) { | 1319 | if (id == NULL) { |
1318 | pr_err("get() with no identifier\n"); | 1320 | pr_err("get() with no identifier\n"); |
@@ -1322,6 +1324,11 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1322 | if (dev) | 1324 | if (dev) |
1323 | devname = dev_name(dev); | 1325 | devname = dev_name(dev); |
1324 | 1326 | ||
1327 | if (have_full_constraints()) | ||
1328 | ret = -ENODEV; | ||
1329 | else | ||
1330 | ret = -EPROBE_DEFER; | ||
1331 | |||
1325 | mutex_lock(®ulator_list_mutex); | 1332 | mutex_lock(®ulator_list_mutex); |
1326 | 1333 | ||
1327 | rdev = regulator_dev_lookup(dev, id, &ret); | 1334 | rdev = regulator_dev_lookup(dev, id, &ret); |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index d9e557990577..cd0b9e35a56d 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -441,6 +441,7 @@ common_reg: | |||
441 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) { | 441 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) { |
442 | if (!reg_np) { | 442 | if (!reg_np) { |
443 | config.init_data = pdata->regulators[i].initdata; | 443 | config.init_data = pdata->regulators[i].initdata; |
444 | config.of_node = pdata->regulators[i].reg_node; | ||
444 | } else { | 445 | } else { |
445 | config.init_data = rdata[i].init_data; | 446 | config.init_data = rdata[i].init_data; |
446 | config.of_node = rdata[i].of_node; | 447 | config.of_node = rdata[i].of_node; |
diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/staging/media/go7007/go7007-loader.c index 10bb41c2fb6d..eecb1f2a5574 100644 --- a/drivers/staging/media/go7007/go7007-loader.c +++ b/drivers/staging/media/go7007/go7007-loader.c | |||
@@ -59,7 +59,7 @@ static int go7007_loader_probe(struct usb_interface *interface, | |||
59 | 59 | ||
60 | if (usbdev->descriptor.bNumConfigurations != 1) { | 60 | if (usbdev->descriptor.bNumConfigurations != 1) { |
61 | dev_err(&interface->dev, "can't handle multiple config\n"); | 61 | dev_err(&interface->dev, "can't handle multiple config\n"); |
62 | return -ENODEV; | 62 | goto failed2; |
63 | } | 63 | } |
64 | 64 | ||
65 | vendor = le16_to_cpu(usbdev->descriptor.idVendor); | 65 | vendor = le16_to_cpu(usbdev->descriptor.idVendor); |
@@ -108,6 +108,7 @@ static int go7007_loader_probe(struct usb_interface *interface, | |||
108 | return 0; | 108 | return 0; |
109 | 109 | ||
110 | failed2: | 110 | failed2: |
111 | usb_put_dev(usbdev); | ||
111 | dev_err(&interface->dev, "probe failed\n"); | 112 | dev_err(&interface->dev, "probe failed\n"); |
112 | return -ENODEV; | 113 | return -ENODEV; |
113 | } | 114 | } |
@@ -115,6 +116,7 @@ failed2: | |||
115 | static void go7007_loader_disconnect(struct usb_interface *interface) | 116 | static void go7007_loader_disconnect(struct usb_interface *interface) |
116 | { | 117 | { |
117 | dev_info(&interface->dev, "disconnect\n"); | 118 | dev_info(&interface->dev, "disconnect\n"); |
119 | usb_put_dev(interface_to_usbdev(interface)); | ||
118 | usb_set_intfdata(interface, NULL); | 120 | usb_set_intfdata(interface, NULL); |
119 | } | 121 | } |
120 | 122 | ||
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 34a2704fbc88..073b4a19a8b0 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -284,10 +284,8 @@ static int map_grant_pages(struct grant_map *map) | |||
284 | } | 284 | } |
285 | 285 | ||
286 | pr_debug("map %d+%d\n", map->index, map->count); | 286 | pr_debug("map %d+%d\n", map->index, map->count); |
287 | err = gnttab_map_refs_userspace(map->map_ops, | 287 | err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, |
288 | use_ptemod ? map->kmap_ops : NULL, | 288 | map->pages, map->count); |
289 | map->pages, | ||
290 | map->count); | ||
291 | if (err) | 289 | if (err) |
292 | return err; | 290 | return err; |
293 | 291 | ||
@@ -317,10 +315,9 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) | |||
317 | } | 315 | } |
318 | } | 316 | } |
319 | 317 | ||
320 | err = gnttab_unmap_refs_userspace(map->unmap_ops + offset, | 318 | err = gnttab_unmap_refs(map->unmap_ops + offset, |
321 | use_ptemod ? map->kmap_ops + offset : NULL, | 319 | use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, |
322 | map->pages + offset, | 320 | pages); |
323 | pages); | ||
324 | if (err) | 321 | if (err) |
325 | return err; | 322 | return err; |
326 | 323 | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 8ee13e2e45e2..b84e3ab839aa 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -928,17 +928,15 @@ void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count) | |||
928 | } | 928 | } |
929 | EXPORT_SYMBOL_GPL(gnttab_batch_copy); | 929 | EXPORT_SYMBOL_GPL(gnttab_batch_copy); |
930 | 930 | ||
931 | int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | 931 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, |
932 | struct gnttab_map_grant_ref *kmap_ops, | 932 | struct gnttab_map_grant_ref *kmap_ops, |
933 | struct page **pages, unsigned int count, | 933 | struct page **pages, unsigned int count) |
934 | bool m2p_override) | ||
935 | { | 934 | { |
936 | int i, ret; | 935 | int i, ret; |
937 | bool lazy = false; | 936 | bool lazy = false; |
938 | pte_t *pte; | 937 | pte_t *pte; |
939 | unsigned long mfn, pfn; | 938 | unsigned long mfn; |
940 | 939 | ||
941 | BUG_ON(kmap_ops && !m2p_override); | ||
942 | ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); | 940 | ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); |
943 | if (ret) | 941 | if (ret) |
944 | return ret; | 942 | return ret; |
@@ -957,12 +955,10 @@ int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
957 | set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT, | 955 | set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT, |
958 | map_ops[i].dev_bus_addr >> PAGE_SHIFT); | 956 | map_ops[i].dev_bus_addr >> PAGE_SHIFT); |
959 | } | 957 | } |
960 | return 0; | 958 | return ret; |
961 | } | 959 | } |
962 | 960 | ||
963 | if (m2p_override && | 961 | if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { |
964 | !in_interrupt() && | ||
965 | paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { | ||
966 | arch_enter_lazy_mmu_mode(); | 962 | arch_enter_lazy_mmu_mode(); |
967 | lazy = true; | 963 | lazy = true; |
968 | } | 964 | } |
@@ -979,20 +975,8 @@ int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
979 | } else { | 975 | } else { |
980 | mfn = PFN_DOWN(map_ops[i].dev_bus_addr); | 976 | mfn = PFN_DOWN(map_ops[i].dev_bus_addr); |
981 | } | 977 | } |
982 | pfn = page_to_pfn(pages[i]); | 978 | ret = m2p_add_override(mfn, pages[i], kmap_ops ? |
983 | 979 | &kmap_ops[i] : NULL); | |
984 | WARN_ON(PagePrivate(pages[i])); | ||
985 | SetPagePrivate(pages[i]); | ||
986 | set_page_private(pages[i], mfn); | ||
987 | |||
988 | pages[i]->index = pfn_to_mfn(pfn); | ||
989 | if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) { | ||
990 | ret = -ENOMEM; | ||
991 | goto out; | ||
992 | } | ||
993 | if (m2p_override) | ||
994 | ret = m2p_add_override(mfn, pages[i], kmap_ops ? | ||
995 | &kmap_ops[i] : NULL); | ||
996 | if (ret) | 980 | if (ret) |
997 | goto out; | 981 | goto out; |
998 | } | 982 | } |
@@ -1003,32 +987,15 @@ int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
1003 | 987 | ||
1004 | return ret; | 988 | return ret; |
1005 | } | 989 | } |
1006 | |||
1007 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | ||
1008 | struct page **pages, unsigned int count) | ||
1009 | { | ||
1010 | return __gnttab_map_refs(map_ops, NULL, pages, count, false); | ||
1011 | } | ||
1012 | EXPORT_SYMBOL_GPL(gnttab_map_refs); | 990 | EXPORT_SYMBOL_GPL(gnttab_map_refs); |
1013 | 991 | ||
1014 | int gnttab_map_refs_userspace(struct gnttab_map_grant_ref *map_ops, | 992 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, |
1015 | struct gnttab_map_grant_ref *kmap_ops, | ||
1016 | struct page **pages, unsigned int count) | ||
1017 | { | ||
1018 | return __gnttab_map_refs(map_ops, kmap_ops, pages, count, true); | ||
1019 | } | ||
1020 | EXPORT_SYMBOL_GPL(gnttab_map_refs_userspace); | ||
1021 | |||
1022 | int __gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | ||
1023 | struct gnttab_map_grant_ref *kmap_ops, | 993 | struct gnttab_map_grant_ref *kmap_ops, |
1024 | struct page **pages, unsigned int count, | 994 | struct page **pages, unsigned int count) |
1025 | bool m2p_override) | ||
1026 | { | 995 | { |
1027 | int i, ret; | 996 | int i, ret; |
1028 | bool lazy = false; | 997 | bool lazy = false; |
1029 | unsigned long pfn, mfn; | ||
1030 | 998 | ||
1031 | BUG_ON(kmap_ops && !m2p_override); | ||
1032 | ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); | 999 | ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); |
1033 | if (ret) | 1000 | if (ret) |
1034 | return ret; | 1001 | return ret; |
@@ -1039,33 +1006,17 @@ int __gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | |||
1039 | set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT, | 1006 | set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT, |
1040 | INVALID_P2M_ENTRY); | 1007 | INVALID_P2M_ENTRY); |
1041 | } | 1008 | } |
1042 | return 0; | 1009 | return ret; |
1043 | } | 1010 | } |
1044 | 1011 | ||
1045 | if (m2p_override && | 1012 | if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { |
1046 | !in_interrupt() && | ||
1047 | paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { | ||
1048 | arch_enter_lazy_mmu_mode(); | 1013 | arch_enter_lazy_mmu_mode(); |
1049 | lazy = true; | 1014 | lazy = true; |
1050 | } | 1015 | } |
1051 | 1016 | ||
1052 | for (i = 0; i < count; i++) { | 1017 | for (i = 0; i < count; i++) { |
1053 | pfn = page_to_pfn(pages[i]); | 1018 | ret = m2p_remove_override(pages[i], kmap_ops ? |
1054 | mfn = get_phys_to_machine(pfn); | 1019 | &kmap_ops[i] : NULL); |
1055 | if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) { | ||
1056 | ret = -EINVAL; | ||
1057 | goto out; | ||
1058 | } | ||
1059 | |||
1060 | set_page_private(pages[i], INVALID_P2M_ENTRY); | ||
1061 | WARN_ON(!PagePrivate(pages[i])); | ||
1062 | ClearPagePrivate(pages[i]); | ||
1063 | set_phys_to_machine(pfn, pages[i]->index); | ||
1064 | if (m2p_override) | ||
1065 | ret = m2p_remove_override(pages[i], | ||
1066 | kmap_ops ? | ||
1067 | &kmap_ops[i] : NULL, | ||
1068 | mfn); | ||
1069 | if (ret) | 1020 | if (ret) |
1070 | goto out; | 1021 | goto out; |
1071 | } | 1022 | } |
@@ -1076,22 +1027,8 @@ int __gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | |||
1076 | 1027 | ||
1077 | return ret; | 1028 | return ret; |
1078 | } | 1029 | } |
1079 | |||
1080 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *map_ops, | ||
1081 | struct page **pages, unsigned int count) | ||
1082 | { | ||
1083 | return __gnttab_unmap_refs(map_ops, NULL, pages, count, false); | ||
1084 | } | ||
1085 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); | 1030 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); |
1086 | 1031 | ||
1087 | int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *map_ops, | ||
1088 | struct gnttab_map_grant_ref *kmap_ops, | ||
1089 | struct page **pages, unsigned int count) | ||
1090 | { | ||
1091 | return __gnttab_unmap_refs(map_ops, kmap_ops, pages, count, true); | ||
1092 | } | ||
1093 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs_userspace); | ||
1094 | |||
1095 | static unsigned nr_status_frames(unsigned nr_grant_frames) | 1032 | static unsigned nr_status_frames(unsigned nr_grant_frames) |
1096 | { | 1033 | { |
1097 | BUG_ON(grefs_per_grant_frame == 0); | 1034 | BUG_ON(grefs_per_grant_frame == 0); |
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 49a62b4dda3b..0e8388e72d8d 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c | |||
@@ -92,11 +92,11 @@ | |||
92 | #include <linux/slab.h> | 92 | #include <linux/slab.h> |
93 | #include <linux/buffer_head.h> | 93 | #include <linux/buffer_head.h> |
94 | #include <linux/mutex.h> | 94 | #include <linux/mutex.h> |
95 | #include <linux/crc32c.h> | ||
96 | #include <linux/genhd.h> | 95 | #include <linux/genhd.h> |
97 | #include <linux/blkdev.h> | 96 | #include <linux/blkdev.h> |
98 | #include "ctree.h" | 97 | #include "ctree.h" |
99 | #include "disk-io.h" | 98 | #include "disk-io.h" |
99 | #include "hash.h" | ||
100 | #include "transaction.h" | 100 | #include "transaction.h" |
101 | #include "extent_io.h" | 101 | #include "extent_io.h" |
102 | #include "volumes.h" | 102 | #include "volumes.h" |
@@ -1823,7 +1823,7 @@ static int btrfsic_test_for_metadata(struct btrfsic_state *state, | |||
1823 | size_t sublen = i ? PAGE_CACHE_SIZE : | 1823 | size_t sublen = i ? PAGE_CACHE_SIZE : |
1824 | (PAGE_CACHE_SIZE - BTRFS_CSUM_SIZE); | 1824 | (PAGE_CACHE_SIZE - BTRFS_CSUM_SIZE); |
1825 | 1825 | ||
1826 | crc = crc32c(crc, data, sublen); | 1826 | crc = btrfs_crc32c(crc, data, sublen); |
1827 | } | 1827 | } |
1828 | btrfs_csum_final(crc, csum); | 1828 | btrfs_csum_final(crc, csum); |
1829 | if (memcmp(csum, h->csum, state->csum_size)) | 1829 | if (memcmp(csum, h->csum, state->csum_size)) |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0e69295d0031..5215f04260b2 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
27 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
28 | #include <linux/freezer.h> | 28 | #include <linux/freezer.h> |
29 | #include <linux/crc32c.h> | ||
30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
31 | #include <linux/migrate.h> | 30 | #include <linux/migrate.h> |
32 | #include <linux/ratelimit.h> | 31 | #include <linux/ratelimit.h> |
@@ -35,6 +34,7 @@ | |||
35 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
36 | #include "ctree.h" | 35 | #include "ctree.h" |
37 | #include "disk-io.h" | 36 | #include "disk-io.h" |
37 | #include "hash.h" | ||
38 | #include "transaction.h" | 38 | #include "transaction.h" |
39 | #include "btrfs_inode.h" | 39 | #include "btrfs_inode.h" |
40 | #include "volumes.h" | 40 | #include "volumes.h" |
@@ -244,7 +244,7 @@ out: | |||
244 | 244 | ||
245 | u32 btrfs_csum_data(char *data, u32 seed, size_t len) | 245 | u32 btrfs_csum_data(char *data, u32 seed, size_t len) |
246 | { | 246 | { |
247 | return crc32c(seed, data, len); | 247 | return btrfs_crc32c(seed, data, len); |
248 | } | 248 | } |
249 | 249 | ||
250 | void btrfs_csum_final(u32 crc, char *result) | 250 | void btrfs_csum_final(u32 crc, char *result) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5c4ab9c18940..184e9cb39647 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2629,7 +2629,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) | |||
2629 | EXTENT_DEFRAG, 1, cached_state); | 2629 | EXTENT_DEFRAG, 1, cached_state); |
2630 | if (ret) { | 2630 | if (ret) { |
2631 | u64 last_snapshot = btrfs_root_last_snapshot(&root->root_item); | 2631 | u64 last_snapshot = btrfs_root_last_snapshot(&root->root_item); |
2632 | if (last_snapshot >= BTRFS_I(inode)->generation) | 2632 | if (0 && last_snapshot >= BTRFS_I(inode)->generation) |
2633 | /* the inode is shared */ | 2633 | /* the inode is shared */ |
2634 | new = record_old_file_extents(inode, ordered_extent); | 2634 | new = record_old_file_extents(inode, ordered_extent); |
2635 | 2635 | ||
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 730dce395858..cf9107a64204 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -24,12 +24,12 @@ | |||
24 | #include <linux/xattr.h> | 24 | #include <linux/xattr.h> |
25 | #include <linux/posix_acl_xattr.h> | 25 | #include <linux/posix_acl_xattr.h> |
26 | #include <linux/radix-tree.h> | 26 | #include <linux/radix-tree.h> |
27 | #include <linux/crc32c.h> | ||
28 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
29 | #include <linux/string.h> | 28 | #include <linux/string.h> |
30 | 29 | ||
31 | #include "send.h" | 30 | #include "send.h" |
32 | #include "backref.h" | 31 | #include "backref.h" |
32 | #include "hash.h" | ||
33 | #include "locking.h" | 33 | #include "locking.h" |
34 | #include "disk-io.h" | 34 | #include "disk-io.h" |
35 | #include "btrfs_inode.h" | 35 | #include "btrfs_inode.h" |
@@ -620,7 +620,7 @@ static int send_cmd(struct send_ctx *sctx) | |||
620 | hdr->len = cpu_to_le32(sctx->send_size - sizeof(*hdr)); | 620 | hdr->len = cpu_to_le32(sctx->send_size - sizeof(*hdr)); |
621 | hdr->crc = 0; | 621 | hdr->crc = 0; |
622 | 622 | ||
623 | crc = crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size); | 623 | crc = btrfs_crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size); |
624 | hdr->crc = cpu_to_le32(crc); | 624 | hdr->crc = cpu_to_le32(crc); |
625 | 625 | ||
626 | ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size, | 626 | ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size, |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index c02f63356895..97cc24198554 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1996,7 +1996,7 @@ static void __exit exit_btrfs_fs(void) | |||
1996 | btrfs_hash_exit(); | 1996 | btrfs_hash_exit(); |
1997 | } | 1997 | } |
1998 | 1998 | ||
1999 | module_init(init_btrfs_fs) | 1999 | late_initcall(init_btrfs_fs); |
2000 | module_exit(exit_btrfs_fs) | 2000 | module_exit(exit_btrfs_fs) |
2001 | 2001 | ||
2002 | MODULE_LICENSE("GPL"); | 2002 | MODULE_LICENSE("GPL"); |
diff --git a/fs/buffer.c b/fs/buffer.c index 651dba10b9c2..27265a8b43c1 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -654,14 +654,16 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode); | |||
654 | static void __set_page_dirty(struct page *page, | 654 | static void __set_page_dirty(struct page *page, |
655 | struct address_space *mapping, int warn) | 655 | struct address_space *mapping, int warn) |
656 | { | 656 | { |
657 | spin_lock_irq(&mapping->tree_lock); | 657 | unsigned long flags; |
658 | |||
659 | spin_lock_irqsave(&mapping->tree_lock, flags); | ||
658 | if (page->mapping) { /* Race with truncate? */ | 660 | if (page->mapping) { /* Race with truncate? */ |
659 | WARN_ON_ONCE(warn && !PageUptodate(page)); | 661 | WARN_ON_ONCE(warn && !PageUptodate(page)); |
660 | account_page_dirtied(page, mapping); | 662 | account_page_dirtied(page, mapping); |
661 | radix_tree_tag_set(&mapping->page_tree, | 663 | radix_tree_tag_set(&mapping->page_tree, |
662 | page_index(page), PAGECACHE_TAG_DIRTY); | 664 | page_index(page), PAGECACHE_TAG_DIRTY); |
663 | } | 665 | } |
664 | spin_unlock_irq(&mapping->tree_lock); | 666 | spin_unlock_irqrestore(&mapping->tree_lock, flags); |
665 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | 667 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); |
666 | } | 668 | } |
667 | 669 | ||
@@ -748,11 +748,10 @@ EXPORT_SYMBOL(setup_arg_pages); | |||
748 | 748 | ||
749 | #endif /* CONFIG_MMU */ | 749 | #endif /* CONFIG_MMU */ |
750 | 750 | ||
751 | struct file *open_exec(const char *name) | 751 | static struct file *do_open_exec(struct filename *name) |
752 | { | 752 | { |
753 | struct file *file; | 753 | struct file *file; |
754 | int err; | 754 | int err; |
755 | struct filename tmp = { .name = name }; | ||
756 | static const struct open_flags open_exec_flags = { | 755 | static const struct open_flags open_exec_flags = { |
757 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, | 756 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, |
758 | .acc_mode = MAY_EXEC | MAY_OPEN, | 757 | .acc_mode = MAY_EXEC | MAY_OPEN, |
@@ -760,7 +759,7 @@ struct file *open_exec(const char *name) | |||
760 | .lookup_flags = LOOKUP_FOLLOW, | 759 | .lookup_flags = LOOKUP_FOLLOW, |
761 | }; | 760 | }; |
762 | 761 | ||
763 | file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags); | 762 | file = do_filp_open(AT_FDCWD, name, &open_exec_flags); |
764 | if (IS_ERR(file)) | 763 | if (IS_ERR(file)) |
765 | goto out; | 764 | goto out; |
766 | 765 | ||
@@ -784,6 +783,12 @@ exit: | |||
784 | fput(file); | 783 | fput(file); |
785 | return ERR_PTR(err); | 784 | return ERR_PTR(err); |
786 | } | 785 | } |
786 | |||
787 | struct file *open_exec(const char *name) | ||
788 | { | ||
789 | struct filename tmp = { .name = name }; | ||
790 | return do_open_exec(&tmp); | ||
791 | } | ||
787 | EXPORT_SYMBOL(open_exec); | 792 | EXPORT_SYMBOL(open_exec); |
788 | 793 | ||
789 | int kernel_read(struct file *file, loff_t offset, | 794 | int kernel_read(struct file *file, loff_t offset, |
@@ -1162,7 +1167,7 @@ int prepare_bprm_creds(struct linux_binprm *bprm) | |||
1162 | return -ENOMEM; | 1167 | return -ENOMEM; |
1163 | } | 1168 | } |
1164 | 1169 | ||
1165 | void free_bprm(struct linux_binprm *bprm) | 1170 | static void free_bprm(struct linux_binprm *bprm) |
1166 | { | 1171 | { |
1167 | free_arg_pages(bprm); | 1172 | free_arg_pages(bprm); |
1168 | if (bprm->cred) { | 1173 | if (bprm->cred) { |
@@ -1432,7 +1437,7 @@ static int exec_binprm(struct linux_binprm *bprm) | |||
1432 | /* | 1437 | /* |
1433 | * sys_execve() executes a new program. | 1438 | * sys_execve() executes a new program. |
1434 | */ | 1439 | */ |
1435 | static int do_execve_common(const char *filename, | 1440 | static int do_execve_common(struct filename *filename, |
1436 | struct user_arg_ptr argv, | 1441 | struct user_arg_ptr argv, |
1437 | struct user_arg_ptr envp) | 1442 | struct user_arg_ptr envp) |
1438 | { | 1443 | { |
@@ -1441,6 +1446,9 @@ static int do_execve_common(const char *filename, | |||
1441 | struct files_struct *displaced; | 1446 | struct files_struct *displaced; |
1442 | int retval; | 1447 | int retval; |
1443 | 1448 | ||
1449 | if (IS_ERR(filename)) | ||
1450 | return PTR_ERR(filename); | ||
1451 | |||
1444 | /* | 1452 | /* |
1445 | * We move the actual failure in case of RLIMIT_NPROC excess from | 1453 | * We move the actual failure in case of RLIMIT_NPROC excess from |
1446 | * set*uid() to execve() because too many poorly written programs | 1454 | * set*uid() to execve() because too many poorly written programs |
@@ -1473,7 +1481,7 @@ static int do_execve_common(const char *filename, | |||
1473 | check_unsafe_exec(bprm); | 1481 | check_unsafe_exec(bprm); |
1474 | current->in_execve = 1; | 1482 | current->in_execve = 1; |
1475 | 1483 | ||
1476 | file = open_exec(filename); | 1484 | file = do_open_exec(filename); |
1477 | retval = PTR_ERR(file); | 1485 | retval = PTR_ERR(file); |
1478 | if (IS_ERR(file)) | 1486 | if (IS_ERR(file)) |
1479 | goto out_unmark; | 1487 | goto out_unmark; |
@@ -1481,8 +1489,7 @@ static int do_execve_common(const char *filename, | |||
1481 | sched_exec(); | 1489 | sched_exec(); |
1482 | 1490 | ||
1483 | bprm->file = file; | 1491 | bprm->file = file; |
1484 | bprm->filename = filename; | 1492 | bprm->filename = bprm->interp = filename->name; |
1485 | bprm->interp = filename; | ||
1486 | 1493 | ||
1487 | retval = bprm_mm_init(bprm); | 1494 | retval = bprm_mm_init(bprm); |
1488 | if (retval) | 1495 | if (retval) |
@@ -1523,6 +1530,7 @@ static int do_execve_common(const char *filename, | |||
1523 | acct_update_integrals(current); | 1530 | acct_update_integrals(current); |
1524 | task_numa_free(current); | 1531 | task_numa_free(current); |
1525 | free_bprm(bprm); | 1532 | free_bprm(bprm); |
1533 | putname(filename); | ||
1526 | if (displaced) | 1534 | if (displaced) |
1527 | put_files_struct(displaced); | 1535 | put_files_struct(displaced); |
1528 | return retval; | 1536 | return retval; |
@@ -1544,10 +1552,11 @@ out_files: | |||
1544 | if (displaced) | 1552 | if (displaced) |
1545 | reset_files_struct(displaced); | 1553 | reset_files_struct(displaced); |
1546 | out_ret: | 1554 | out_ret: |
1555 | putname(filename); | ||
1547 | return retval; | 1556 | return retval; |
1548 | } | 1557 | } |
1549 | 1558 | ||
1550 | int do_execve(const char *filename, | 1559 | int do_execve(struct filename *filename, |
1551 | const char __user *const __user *__argv, | 1560 | const char __user *const __user *__argv, |
1552 | const char __user *const __user *__envp) | 1561 | const char __user *const __user *__envp) |
1553 | { | 1562 | { |
@@ -1557,7 +1566,7 @@ int do_execve(const char *filename, | |||
1557 | } | 1566 | } |
1558 | 1567 | ||
1559 | #ifdef CONFIG_COMPAT | 1568 | #ifdef CONFIG_COMPAT |
1560 | static int compat_do_execve(const char *filename, | 1569 | static int compat_do_execve(struct filename *filename, |
1561 | const compat_uptr_t __user *__argv, | 1570 | const compat_uptr_t __user *__argv, |
1562 | const compat_uptr_t __user *__envp) | 1571 | const compat_uptr_t __user *__envp) |
1563 | { | 1572 | { |
@@ -1607,25 +1616,13 @@ SYSCALL_DEFINE3(execve, | |||
1607 | const char __user *const __user *, argv, | 1616 | const char __user *const __user *, argv, |
1608 | const char __user *const __user *, envp) | 1617 | const char __user *const __user *, envp) |
1609 | { | 1618 | { |
1610 | struct filename *path = getname(filename); | 1619 | return do_execve(getname(filename), argv, envp); |
1611 | int error = PTR_ERR(path); | ||
1612 | if (!IS_ERR(path)) { | ||
1613 | error = do_execve(path->name, argv, envp); | ||
1614 | putname(path); | ||
1615 | } | ||
1616 | return error; | ||
1617 | } | 1620 | } |
1618 | #ifdef CONFIG_COMPAT | 1621 | #ifdef CONFIG_COMPAT |
1619 | asmlinkage long compat_sys_execve(const char __user * filename, | 1622 | asmlinkage long compat_sys_execve(const char __user * filename, |
1620 | const compat_uptr_t __user * argv, | 1623 | const compat_uptr_t __user * argv, |
1621 | const compat_uptr_t __user * envp) | 1624 | const compat_uptr_t __user * envp) |
1622 | { | 1625 | { |
1623 | struct filename *path = getname(filename); | 1626 | return compat_do_execve(getname(filename), argv, envp); |
1624 | int error = PTR_ERR(path); | ||
1625 | if (!IS_ERR(path)) { | ||
1626 | error = compat_do_execve(path->name, argv, envp); | ||
1627 | putname(path); | ||
1628 | } | ||
1629 | return error; | ||
1630 | } | 1627 | } |
1631 | #endif | 1628 | #endif |
diff --git a/fs/namei.c b/fs/namei.c index d580df2e6804..385f7817bfcc 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -196,6 +196,7 @@ recopy: | |||
196 | goto error; | 196 | goto error; |
197 | 197 | ||
198 | result->uptr = filename; | 198 | result->uptr = filename; |
199 | result->aname = NULL; | ||
199 | audit_getname(result); | 200 | audit_getname(result); |
200 | return result; | 201 | return result; |
201 | 202 | ||
@@ -210,6 +211,35 @@ getname(const char __user * filename) | |||
210 | return getname_flags(filename, 0, NULL); | 211 | return getname_flags(filename, 0, NULL); |
211 | } | 212 | } |
212 | 213 | ||
214 | /* | ||
215 | * The "getname_kernel()" interface doesn't do pathnames longer | ||
216 | * than EMBEDDED_NAME_MAX. Deal with it - you're a kernel user. | ||
217 | */ | ||
218 | struct filename * | ||
219 | getname_kernel(const char * filename) | ||
220 | { | ||
221 | struct filename *result; | ||
222 | char *kname; | ||
223 | int len; | ||
224 | |||
225 | len = strlen(filename); | ||
226 | if (len >= EMBEDDED_NAME_MAX) | ||
227 | return ERR_PTR(-ENAMETOOLONG); | ||
228 | |||
229 | result = __getname(); | ||
230 | if (unlikely(!result)) | ||
231 | return ERR_PTR(-ENOMEM); | ||
232 | |||
233 | kname = (char *)result + sizeof(*result); | ||
234 | result->name = kname; | ||
235 | result->uptr = NULL; | ||
236 | result->aname = NULL; | ||
237 | result->separate = false; | ||
238 | |||
239 | strlcpy(kname, filename, EMBEDDED_NAME_MAX); | ||
240 | return result; | ||
241 | } | ||
242 | |||
213 | #ifdef CONFIG_AUDITSYSCALL | 243 | #ifdef CONFIG_AUDITSYSCALL |
214 | void putname(struct filename *name) | 244 | void putname(struct filename *name) |
215 | { | 245 | { |
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index 9a5ca03fa539..871d6eda8dba 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
@@ -80,7 +80,7 @@ struct posix_acl *nfs3_get_acl(struct inode *inode, int type) | |||
80 | } | 80 | } |
81 | 81 | ||
82 | if (res.acl_access != NULL) { | 82 | if (res.acl_access != NULL) { |
83 | if (posix_acl_equiv_mode(res.acl_access, NULL) || | 83 | if ((posix_acl_equiv_mode(res.acl_access, NULL) == 0) || |
84 | res.acl_access->a_count == 0) { | 84 | res.acl_access->a_count == 0) { |
85 | posix_acl_release(res.acl_access); | 85 | posix_acl_release(res.acl_access); |
86 | res.acl_access = NULL; | 86 | res.acl_access = NULL; |
@@ -113,7 +113,7 @@ getout: | |||
113 | return ERR_PTR(status); | 113 | return ERR_PTR(status); |
114 | } | 114 | } |
115 | 115 | ||
116 | int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | 116 | static int __nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, |
117 | struct posix_acl *dfacl) | 117 | struct posix_acl *dfacl) |
118 | { | 118 | { |
119 | struct nfs_server *server = NFS_SERVER(inode); | 119 | struct nfs_server *server = NFS_SERVER(inode); |
@@ -198,6 +198,15 @@ out: | |||
198 | return status; | 198 | return status; |
199 | } | 199 | } |
200 | 200 | ||
201 | int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | ||
202 | struct posix_acl *dfacl) | ||
203 | { | ||
204 | int ret; | ||
205 | ret = __nfs3_proc_setacls(inode, acl, dfacl); | ||
206 | return (ret == -EOPNOTSUPP) ? 0 : ret; | ||
207 | |||
208 | } | ||
209 | |||
201 | int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) | 210 | int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) |
202 | { | 211 | { |
203 | struct posix_acl *alloc = NULL, *dfacl = NULL; | 212 | struct posix_acl *alloc = NULL, *dfacl = NULL; |
@@ -225,7 +234,7 @@ int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) | |||
225 | if (IS_ERR(alloc)) | 234 | if (IS_ERR(alloc)) |
226 | goto fail; | 235 | goto fail; |
227 | } | 236 | } |
228 | status = nfs3_proc_setacls(inode, acl, dfacl); | 237 | status = __nfs3_proc_setacls(inode, acl, dfacl); |
229 | posix_acl_release(alloc); | 238 | posix_acl_release(alloc); |
230 | return status; | 239 | return status; |
231 | 240 | ||
@@ -233,25 +242,6 @@ fail: | |||
233 | return PTR_ERR(alloc); | 242 | return PTR_ERR(alloc); |
234 | } | 243 | } |
235 | 244 | ||
236 | int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, | ||
237 | umode_t mode) | ||
238 | { | ||
239 | struct posix_acl *default_acl, *acl; | ||
240 | int error; | ||
241 | |||
242 | error = posix_acl_create(dir, &mode, &default_acl, &acl); | ||
243 | if (error) | ||
244 | return (error == -EOPNOTSUPP) ? 0 : error; | ||
245 | |||
246 | error = nfs3_proc_setacls(inode, acl, default_acl); | ||
247 | |||
248 | if (acl) | ||
249 | posix_acl_release(acl); | ||
250 | if (default_acl) | ||
251 | posix_acl_release(default_acl); | ||
252 | return error; | ||
253 | } | ||
254 | |||
255 | const struct xattr_handler *nfs3_xattr_handlers[] = { | 245 | const struct xattr_handler *nfs3_xattr_handlers[] = { |
256 | &posix_acl_access_xattr_handler, | 246 | &posix_acl_access_xattr_handler, |
257 | &posix_acl_default_xattr_handler, | 247 | &posix_acl_default_xattr_handler, |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index dbb3e1f30c68..860ad26a5590 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -170,7 +170,7 @@ void nfs41_shutdown_client(struct nfs_client *clp) | |||
170 | void nfs40_shutdown_client(struct nfs_client *clp) | 170 | void nfs40_shutdown_client(struct nfs_client *clp) |
171 | { | 171 | { |
172 | if (clp->cl_slot_tbl) { | 172 | if (clp->cl_slot_tbl) { |
173 | nfs4_release_slot_table(clp->cl_slot_tbl); | 173 | nfs4_shutdown_slot_table(clp->cl_slot_tbl); |
174 | kfree(clp->cl_slot_tbl); | 174 | kfree(clp->cl_slot_tbl); |
175 | } | 175 | } |
176 | } | 176 | } |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 42da6af77587..2da6a698b8f7 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1620,15 +1620,15 @@ static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata) | |||
1620 | { | 1620 | { |
1621 | struct nfs4_opendata *data = calldata; | 1621 | struct nfs4_opendata *data = calldata; |
1622 | 1622 | ||
1623 | nfs40_setup_sequence(data->o_arg.server, &data->o_arg.seq_args, | 1623 | nfs40_setup_sequence(data->o_arg.server, &data->c_arg.seq_args, |
1624 | &data->o_res.seq_res, task); | 1624 | &data->c_res.seq_res, task); |
1625 | } | 1625 | } |
1626 | 1626 | ||
1627 | static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) | 1627 | static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) |
1628 | { | 1628 | { |
1629 | struct nfs4_opendata *data = calldata; | 1629 | struct nfs4_opendata *data = calldata; |
1630 | 1630 | ||
1631 | nfs40_sequence_done(task, &data->o_res.seq_res); | 1631 | nfs40_sequence_done(task, &data->c_res.seq_res); |
1632 | 1632 | ||
1633 | data->rpc_status = task->tk_status; | 1633 | data->rpc_status = task->tk_status; |
1634 | if (data->rpc_status == 0) { | 1634 | if (data->rpc_status == 0) { |
@@ -1686,7 +1686,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) | |||
1686 | }; | 1686 | }; |
1687 | int status; | 1687 | int status; |
1688 | 1688 | ||
1689 | nfs4_init_sequence(&data->o_arg.seq_args, &data->o_res.seq_res, 1); | 1689 | nfs4_init_sequence(&data->c_arg.seq_args, &data->c_res.seq_res, 1); |
1690 | kref_get(&data->kref); | 1690 | kref_get(&data->kref); |
1691 | data->rpc_done = 0; | 1691 | data->rpc_done = 0; |
1692 | data->rpc_status = 0; | 1692 | data->rpc_status = 0; |
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c index cf883c7ae053..e799dc3c3b1d 100644 --- a/fs/nfs/nfs4session.c +++ b/fs/nfs/nfs4session.c | |||
@@ -231,14 +231,23 @@ out: | |||
231 | return ret; | 231 | return ret; |
232 | } | 232 | } |
233 | 233 | ||
234 | /* | ||
235 | * nfs4_release_slot_table - release all slot table entries | ||
236 | */ | ||
237 | static void nfs4_release_slot_table(struct nfs4_slot_table *tbl) | ||
238 | { | ||
239 | nfs4_shrink_slot_table(tbl, 0); | ||
240 | } | ||
241 | |||
234 | /** | 242 | /** |
235 | * nfs4_release_slot_table - release resources attached to a slot table | 243 | * nfs4_shutdown_slot_table - release resources attached to a slot table |
236 | * @tbl: slot table to shut down | 244 | * @tbl: slot table to shut down |
237 | * | 245 | * |
238 | */ | 246 | */ |
239 | void nfs4_release_slot_table(struct nfs4_slot_table *tbl) | 247 | void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl) |
240 | { | 248 | { |
241 | nfs4_shrink_slot_table(tbl, 0); | 249 | nfs4_release_slot_table(tbl); |
250 | rpc_destroy_wait_queue(&tbl->slot_tbl_waitq); | ||
242 | } | 251 | } |
243 | 252 | ||
244 | /** | 253 | /** |
@@ -422,7 +431,7 @@ void nfs41_update_target_slotid(struct nfs4_slot_table *tbl, | |||
422 | spin_unlock(&tbl->slot_tbl_lock); | 431 | spin_unlock(&tbl->slot_tbl_lock); |
423 | } | 432 | } |
424 | 433 | ||
425 | static void nfs4_destroy_session_slot_tables(struct nfs4_session *session) | 434 | static void nfs4_release_session_slot_tables(struct nfs4_session *session) |
426 | { | 435 | { |
427 | nfs4_release_slot_table(&session->fc_slot_table); | 436 | nfs4_release_slot_table(&session->fc_slot_table); |
428 | nfs4_release_slot_table(&session->bc_slot_table); | 437 | nfs4_release_slot_table(&session->bc_slot_table); |
@@ -450,7 +459,7 @@ int nfs4_setup_session_slot_tables(struct nfs4_session *ses) | |||
450 | if (status && tbl->slots == NULL) | 459 | if (status && tbl->slots == NULL) |
451 | /* Fore and back channel share a connection so get | 460 | /* Fore and back channel share a connection so get |
452 | * both slot tables or neither */ | 461 | * both slot tables or neither */ |
453 | nfs4_destroy_session_slot_tables(ses); | 462 | nfs4_release_session_slot_tables(ses); |
454 | return status; | 463 | return status; |
455 | } | 464 | } |
456 | 465 | ||
@@ -470,6 +479,12 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) | |||
470 | return session; | 479 | return session; |
471 | } | 480 | } |
472 | 481 | ||
482 | static void nfs4_destroy_session_slot_tables(struct nfs4_session *session) | ||
483 | { | ||
484 | nfs4_shutdown_slot_table(&session->fc_slot_table); | ||
485 | nfs4_shutdown_slot_table(&session->bc_slot_table); | ||
486 | } | ||
487 | |||
473 | void nfs4_destroy_session(struct nfs4_session *session) | 488 | void nfs4_destroy_session(struct nfs4_session *session) |
474 | { | 489 | { |
475 | struct rpc_xprt *xprt; | 490 | struct rpc_xprt *xprt; |
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index 232306100651..b34ada9bc6a2 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h | |||
@@ -74,7 +74,7 @@ enum nfs4_session_state { | |||
74 | 74 | ||
75 | extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, | 75 | extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, |
76 | unsigned int max_reqs, const char *queue); | 76 | unsigned int max_reqs, const char *queue); |
77 | extern void nfs4_release_slot_table(struct nfs4_slot_table *tbl); | 77 | extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl); |
78 | extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); | 78 | extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); |
79 | extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); | 79 | extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); |
80 | extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); | 80 | extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 8750ae1b8636..aada5801567a 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -4742,6 +4742,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
4742 | enum ocfs2_alloc_restarted *reason_ret) | 4742 | enum ocfs2_alloc_restarted *reason_ret) |
4743 | { | 4743 | { |
4744 | int status = 0, err = 0; | 4744 | int status = 0, err = 0; |
4745 | int need_free = 0; | ||
4745 | int free_extents; | 4746 | int free_extents; |
4746 | enum ocfs2_alloc_restarted reason = RESTART_NONE; | 4747 | enum ocfs2_alloc_restarted reason = RESTART_NONE; |
4747 | u32 bit_off, num_bits; | 4748 | u32 bit_off, num_bits; |
@@ -4796,7 +4797,8 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
4796 | OCFS2_JOURNAL_ACCESS_WRITE); | 4797 | OCFS2_JOURNAL_ACCESS_WRITE); |
4797 | if (status < 0) { | 4798 | if (status < 0) { |
4798 | mlog_errno(status); | 4799 | mlog_errno(status); |
4799 | goto leave; | 4800 | need_free = 1; |
4801 | goto bail; | ||
4800 | } | 4802 | } |
4801 | 4803 | ||
4802 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); | 4804 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); |
@@ -4807,7 +4809,8 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
4807 | num_bits, flags, meta_ac); | 4809 | num_bits, flags, meta_ac); |
4808 | if (status < 0) { | 4810 | if (status < 0) { |
4809 | mlog_errno(status); | 4811 | mlog_errno(status); |
4810 | goto leave; | 4812 | need_free = 1; |
4813 | goto bail; | ||
4811 | } | 4814 | } |
4812 | 4815 | ||
4813 | ocfs2_journal_dirty(handle, et->et_root_bh); | 4816 | ocfs2_journal_dirty(handle, et->et_root_bh); |
@@ -4821,6 +4824,19 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
4821 | reason = RESTART_TRANS; | 4824 | reason = RESTART_TRANS; |
4822 | } | 4825 | } |
4823 | 4826 | ||
4827 | bail: | ||
4828 | if (need_free) { | ||
4829 | if (data_ac->ac_which == OCFS2_AC_USE_LOCAL) | ||
4830 | ocfs2_free_local_alloc_bits(osb, handle, data_ac, | ||
4831 | bit_off, num_bits); | ||
4832 | else | ||
4833 | ocfs2_free_clusters(handle, | ||
4834 | data_ac->ac_inode, | ||
4835 | data_ac->ac_bh, | ||
4836 | ocfs2_clusters_to_blocks(osb->sb, bit_off), | ||
4837 | num_bits); | ||
4838 | } | ||
4839 | |||
4824 | leave: | 4840 | leave: |
4825 | if (reason_ret) | 4841 | if (reason_ret) |
4826 | *reason_ret = reason; | 4842 | *reason_ret = reason; |
@@ -6805,6 +6821,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6805 | struct buffer_head *di_bh) | 6821 | struct buffer_head *di_bh) |
6806 | { | 6822 | { |
6807 | int ret, i, has_data, num_pages = 0; | 6823 | int ret, i, has_data, num_pages = 0; |
6824 | int need_free = 0; | ||
6825 | u32 bit_off, num; | ||
6808 | handle_t *handle; | 6826 | handle_t *handle; |
6809 | u64 uninitialized_var(block); | 6827 | u64 uninitialized_var(block); |
6810 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 6828 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
@@ -6850,7 +6868,6 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6850 | } | 6868 | } |
6851 | 6869 | ||
6852 | if (has_data) { | 6870 | if (has_data) { |
6853 | u32 bit_off, num; | ||
6854 | unsigned int page_end; | 6871 | unsigned int page_end; |
6855 | u64 phys; | 6872 | u64 phys; |
6856 | 6873 | ||
@@ -6886,6 +6903,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6886 | ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages); | 6903 | ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages); |
6887 | if (ret) { | 6904 | if (ret) { |
6888 | mlog_errno(ret); | 6905 | mlog_errno(ret); |
6906 | need_free = 1; | ||
6889 | goto out_commit; | 6907 | goto out_commit; |
6890 | } | 6908 | } |
6891 | 6909 | ||
@@ -6896,6 +6914,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6896 | ret = ocfs2_read_inline_data(inode, pages[0], di_bh); | 6914 | ret = ocfs2_read_inline_data(inode, pages[0], di_bh); |
6897 | if (ret) { | 6915 | if (ret) { |
6898 | mlog_errno(ret); | 6916 | mlog_errno(ret); |
6917 | need_free = 1; | ||
6899 | goto out_commit; | 6918 | goto out_commit; |
6900 | } | 6919 | } |
6901 | 6920 | ||
@@ -6927,6 +6946,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
6927 | ret = ocfs2_insert_extent(handle, &et, 0, block, 1, 0, NULL); | 6946 | ret = ocfs2_insert_extent(handle, &et, 0, block, 1, 0, NULL); |
6928 | if (ret) { | 6947 | if (ret) { |
6929 | mlog_errno(ret); | 6948 | mlog_errno(ret); |
6949 | need_free = 1; | ||
6930 | goto out_commit; | 6950 | goto out_commit; |
6931 | } | 6951 | } |
6932 | 6952 | ||
@@ -6938,6 +6958,18 @@ out_commit: | |||
6938 | dquot_free_space_nodirty(inode, | 6958 | dquot_free_space_nodirty(inode, |
6939 | ocfs2_clusters_to_bytes(osb->sb, 1)); | 6959 | ocfs2_clusters_to_bytes(osb->sb, 1)); |
6940 | 6960 | ||
6961 | if (need_free) { | ||
6962 | if (data_ac->ac_which == OCFS2_AC_USE_LOCAL) | ||
6963 | ocfs2_free_local_alloc_bits(osb, handle, data_ac, | ||
6964 | bit_off, num); | ||
6965 | else | ||
6966 | ocfs2_free_clusters(handle, | ||
6967 | data_ac->ac_inode, | ||
6968 | data_ac->ac_bh, | ||
6969 | ocfs2_clusters_to_blocks(osb->sb, bit_off), | ||
6970 | num); | ||
6971 | } | ||
6972 | |||
6941 | ocfs2_commit_trans(osb, handle); | 6973 | ocfs2_commit_trans(osb, handle); |
6942 | 6974 | ||
6943 | out_unlock: | 6975 | out_unlock: |
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index cd5496b7a0a3..044013455621 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
@@ -781,6 +781,48 @@ bail: | |||
781 | return status; | 781 | return status; |
782 | } | 782 | } |
783 | 783 | ||
784 | int ocfs2_free_local_alloc_bits(struct ocfs2_super *osb, | ||
785 | handle_t *handle, | ||
786 | struct ocfs2_alloc_context *ac, | ||
787 | u32 bit_off, | ||
788 | u32 num_bits) | ||
789 | { | ||
790 | int status, start; | ||
791 | u32 clear_bits; | ||
792 | struct inode *local_alloc_inode; | ||
793 | void *bitmap; | ||
794 | struct ocfs2_dinode *alloc; | ||
795 | struct ocfs2_local_alloc *la; | ||
796 | |||
797 | BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL); | ||
798 | |||
799 | local_alloc_inode = ac->ac_inode; | ||
800 | alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; | ||
801 | la = OCFS2_LOCAL_ALLOC(alloc); | ||
802 | |||
803 | bitmap = la->la_bitmap; | ||
804 | start = bit_off - le32_to_cpu(la->la_bm_off); | ||
805 | clear_bits = num_bits; | ||
806 | |||
807 | status = ocfs2_journal_access_di(handle, | ||
808 | INODE_CACHE(local_alloc_inode), | ||
809 | osb->local_alloc_bh, | ||
810 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
811 | if (status < 0) { | ||
812 | mlog_errno(status); | ||
813 | goto bail; | ||
814 | } | ||
815 | |||
816 | while (clear_bits--) | ||
817 | ocfs2_clear_bit(start++, bitmap); | ||
818 | |||
819 | le32_add_cpu(&alloc->id1.bitmap1.i_used, -num_bits); | ||
820 | ocfs2_journal_dirty(handle, osb->local_alloc_bh); | ||
821 | |||
822 | bail: | ||
823 | return status; | ||
824 | } | ||
825 | |||
784 | static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc) | 826 | static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc) |
785 | { | 827 | { |
786 | u32 count; | 828 | u32 count; |
diff --git a/fs/ocfs2/localalloc.h b/fs/ocfs2/localalloc.h index 1be9b5864460..44a7d1fb2dec 100644 --- a/fs/ocfs2/localalloc.h +++ b/fs/ocfs2/localalloc.h | |||
@@ -55,6 +55,12 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | |||
55 | u32 *bit_off, | 55 | u32 *bit_off, |
56 | u32 *num_bits); | 56 | u32 *num_bits); |
57 | 57 | ||
58 | int ocfs2_free_local_alloc_bits(struct ocfs2_super *osb, | ||
59 | handle_t *handle, | ||
60 | struct ocfs2_alloc_context *ac, | ||
61 | u32 bit_off, | ||
62 | u32 num_bits); | ||
63 | |||
58 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, | 64 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, |
59 | unsigned int num_clusters); | 65 | unsigned int num_clusters); |
60 | void ocfs2_la_enable_worker(struct work_struct *work); | 66 | void ocfs2_la_enable_worker(struct work_struct *work); |
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 38bae5a0ea25..11c54fd51e16 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -521,8 +521,11 @@ posix_acl_chmod(struct inode *inode, umode_t mode) | |||
521 | return -EOPNOTSUPP; | 521 | return -EOPNOTSUPP; |
522 | 522 | ||
523 | acl = get_acl(inode, ACL_TYPE_ACCESS); | 523 | acl = get_acl(inode, ACL_TYPE_ACCESS); |
524 | if (IS_ERR_OR_NULL(acl)) | 524 | if (IS_ERR_OR_NULL(acl)) { |
525 | if (acl == ERR_PTR(-EOPNOTSUPP)) | ||
526 | return 0; | ||
525 | return PTR_ERR(acl); | 527 | return PTR_ERR(acl); |
528 | } | ||
526 | 529 | ||
527 | ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode); | 530 | ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode); |
528 | if (ret) | 531 | if (ret) |
@@ -544,14 +547,15 @@ posix_acl_create(struct inode *dir, umode_t *mode, | |||
544 | goto no_acl; | 547 | goto no_acl; |
545 | 548 | ||
546 | p = get_acl(dir, ACL_TYPE_DEFAULT); | 549 | p = get_acl(dir, ACL_TYPE_DEFAULT); |
547 | if (IS_ERR(p)) | 550 | if (IS_ERR(p)) { |
551 | if (p == ERR_PTR(-EOPNOTSUPP)) | ||
552 | goto apply_umask; | ||
548 | return PTR_ERR(p); | 553 | return PTR_ERR(p); |
549 | |||
550 | if (!p) { | ||
551 | *mode &= ~current_umask(); | ||
552 | goto no_acl; | ||
553 | } | 554 | } |
554 | 555 | ||
556 | if (!p) | ||
557 | goto apply_umask; | ||
558 | |||
555 | *acl = posix_acl_clone(p, GFP_NOFS); | 559 | *acl = posix_acl_clone(p, GFP_NOFS); |
556 | if (!*acl) | 560 | if (!*acl) |
557 | return -ENOMEM; | 561 | return -ENOMEM; |
@@ -575,6 +579,8 @@ posix_acl_create(struct inode *dir, umode_t *mode, | |||
575 | } | 579 | } |
576 | return 0; | 580 | return 0; |
577 | 581 | ||
582 | apply_umask: | ||
583 | *mode &= ~current_umask(); | ||
578 | no_acl: | 584 | no_acl: |
579 | *default_acl = NULL; | 585 | *default_acl = NULL; |
580 | *acl = NULL; | 586 | *acl = NULL; |
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index fd8bf3219ef7..b4a745d7d9a9 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h | |||
@@ -115,7 +115,6 @@ extern int copy_strings_kernel(int argc, const char *const *argv, | |||
115 | extern int prepare_bprm_creds(struct linux_binprm *bprm); | 115 | extern int prepare_bprm_creds(struct linux_binprm *bprm); |
116 | extern void install_exec_creds(struct linux_binprm *bprm); | 116 | extern void install_exec_creds(struct linux_binprm *bprm); |
117 | extern void set_binfmt(struct linux_binfmt *new); | 117 | extern void set_binfmt(struct linux_binfmt *new); |
118 | extern void free_bprm(struct linux_binprm *); | ||
119 | extern ssize_t read_code(struct file *, unsigned long, loff_t, size_t); | 118 | extern ssize_t read_code(struct file *, unsigned long, loff_t, size_t); |
120 | 119 | ||
121 | #endif /* _LINUX_BINFMTS_H */ | 120 | #endif /* _LINUX_BINFMTS_H */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 09f553c59813..d79678c188ad 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2079,6 +2079,7 @@ extern struct file * dentry_open(const struct path *, int, const struct cred *); | |||
2079 | extern int filp_close(struct file *, fl_owner_t id); | 2079 | extern int filp_close(struct file *, fl_owner_t id); |
2080 | 2080 | ||
2081 | extern struct filename *getname(const char __user *); | 2081 | extern struct filename *getname(const char __user *); |
2082 | extern struct filename *getname_kernel(const char *); | ||
2082 | 2083 | ||
2083 | enum { | 2084 | enum { |
2084 | FILE_CREATED = 1, | 2085 | FILE_CREATED = 1, |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 3ccfcecf8999..b2fb167b2e6d 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -379,12 +379,14 @@ struct nfs_openres { | |||
379 | * Arguments to the open_confirm call. | 379 | * Arguments to the open_confirm call. |
380 | */ | 380 | */ |
381 | struct nfs_open_confirmargs { | 381 | struct nfs_open_confirmargs { |
382 | struct nfs4_sequence_args seq_args; | ||
382 | const struct nfs_fh * fh; | 383 | const struct nfs_fh * fh; |
383 | nfs4_stateid * stateid; | 384 | nfs4_stateid * stateid; |
384 | struct nfs_seqid * seqid; | 385 | struct nfs_seqid * seqid; |
385 | }; | 386 | }; |
386 | 387 | ||
387 | struct nfs_open_confirmres { | 388 | struct nfs_open_confirmres { |
389 | struct nfs4_sequence_res seq_res; | ||
388 | nfs4_stateid stateid; | 390 | nfs4_stateid stateid; |
389 | struct nfs_seqid * seqid; | 391 | struct nfs_seqid * seqid; |
390 | }; | 392 | }; |
diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 26ebcf41c213..69ae03f6eb15 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h | |||
@@ -80,13 +80,14 @@ struct nvme_dev { | |||
80 | struct dma_pool *prp_small_pool; | 80 | struct dma_pool *prp_small_pool; |
81 | int instance; | 81 | int instance; |
82 | int queue_count; | 82 | int queue_count; |
83 | int db_stride; | 83 | u32 db_stride; |
84 | u32 ctrl_config; | 84 | u32 ctrl_config; |
85 | struct msix_entry *entry; | 85 | struct msix_entry *entry; |
86 | struct nvme_bar __iomem *bar; | 86 | struct nvme_bar __iomem *bar; |
87 | struct list_head namespaces; | 87 | struct list_head namespaces; |
88 | struct kref kref; | 88 | struct kref kref; |
89 | struct miscdevice miscdev; | 89 | struct miscdevice miscdev; |
90 | struct work_struct reset_work; | ||
90 | char name[12]; | 91 | char name[12]; |
91 | char serial[20]; | 92 | char serial[20]; |
92 | char model[40]; | 93 | char model[40]; |
@@ -94,6 +95,8 @@ struct nvme_dev { | |||
94 | u32 max_hw_sectors; | 95 | u32 max_hw_sectors; |
95 | u32 stripe_size; | 96 | u32 stripe_size; |
96 | u16 oncs; | 97 | u16 oncs; |
98 | u16 abort_limit; | ||
99 | u8 initialized; | ||
97 | }; | 100 | }; |
98 | 101 | ||
99 | /* | 102 | /* |
@@ -165,6 +168,7 @@ int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, | |||
165 | struct sg_io_hdr; | 168 | struct sg_io_hdr; |
166 | 169 | ||
167 | int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr); | 170 | int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr); |
171 | int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg); | ||
168 | int nvme_sg_get_version_num(int __user *ip); | 172 | int nvme_sg_get_version_num(int __user *ip); |
169 | 173 | ||
170 | #endif /* _LINUX_NVME_H */ | 174 | #endif /* _LINUX_NVME_H */ |
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index e464b4e987e8..d1fe1a761047 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
@@ -228,9 +228,9 @@ PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1) | |||
228 | TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback) | 228 | TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback) |
229 | PAGEFLAG(MappedToDisk, mappedtodisk) | 229 | PAGEFLAG(MappedToDisk, mappedtodisk) |
230 | 230 | ||
231 | /* PG_readahead is only used for file reads; PG_reclaim is only for writes */ | 231 | /* PG_readahead is only used for reads; PG_reclaim is only for writes */ |
232 | PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim) | 232 | PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim) |
233 | PAGEFLAG(Readahead, reclaim) /* Reminder to do async read-ahead */ | 233 | PAGEFLAG(Readahead, reclaim) TESTCLEARFLAG(Readahead, reclaim) |
234 | 234 | ||
235 | #ifdef CONFIG_HIGHMEM | 235 | #ifdef CONFIG_HIGHMEM |
236 | /* | 236 | /* |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 68a0e84463a0..a781dec1cd0b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -128,6 +128,7 @@ struct bio_list; | |||
128 | struct fs_struct; | 128 | struct fs_struct; |
129 | struct perf_event_context; | 129 | struct perf_event_context; |
130 | struct blk_plug; | 130 | struct blk_plug; |
131 | struct filename; | ||
131 | 132 | ||
132 | /* | 133 | /* |
133 | * List of flags we want to share for kernel threads, | 134 | * List of flags we want to share for kernel threads, |
@@ -2311,7 +2312,7 @@ extern void do_group_exit(int); | |||
2311 | extern int allow_signal(int); | 2312 | extern int allow_signal(int); |
2312 | extern int disallow_signal(int); | 2313 | extern int disallow_signal(int); |
2313 | 2314 | ||
2314 | extern int do_execve(const char *, | 2315 | extern int do_execve(struct filename *, |
2315 | const char __user * const __user *, | 2316 | const char __user * const __user *, |
2316 | const char __user * const __user *); | 2317 | const char __user * const __user *); |
2317 | extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *); | 2318 | extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *); |
diff --git a/include/uapi/linux/nvme.h b/include/uapi/linux/nvme.h index 989c04e0c563..e5ab62201119 100644 --- a/include/uapi/linux/nvme.h +++ b/include/uapi/linux/nvme.h | |||
@@ -350,6 +350,16 @@ struct nvme_delete_queue { | |||
350 | __u32 rsvd11[5]; | 350 | __u32 rsvd11[5]; |
351 | }; | 351 | }; |
352 | 352 | ||
353 | struct nvme_abort_cmd { | ||
354 | __u8 opcode; | ||
355 | __u8 flags; | ||
356 | __u16 command_id; | ||
357 | __u32 rsvd1[9]; | ||
358 | __le16 sqid; | ||
359 | __u16 cid; | ||
360 | __u32 rsvd11[5]; | ||
361 | }; | ||
362 | |||
353 | struct nvme_download_firmware { | 363 | struct nvme_download_firmware { |
354 | __u8 opcode; | 364 | __u8 opcode; |
355 | __u8 flags; | 365 | __u8 flags; |
@@ -384,6 +394,7 @@ struct nvme_command { | |||
384 | struct nvme_download_firmware dlfw; | 394 | struct nvme_download_firmware dlfw; |
385 | struct nvme_format_cmd format; | 395 | struct nvme_format_cmd format; |
386 | struct nvme_dsm_cmd dsm; | 396 | struct nvme_dsm_cmd dsm; |
397 | struct nvme_abort_cmd abort; | ||
387 | }; | 398 | }; |
388 | }; | 399 | }; |
389 | 400 | ||
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index 7ad033dbc845..a5af2a26d94f 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h | |||
@@ -191,15 +191,11 @@ void gnttab_free_auto_xlat_frames(void); | |||
191 | #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) | 191 | #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) |
192 | 192 | ||
193 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | 193 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, |
194 | struct gnttab_map_grant_ref *kmap_ops, | ||
194 | struct page **pages, unsigned int count); | 195 | struct page **pages, unsigned int count); |
195 | int gnttab_map_refs_userspace(struct gnttab_map_grant_ref *map_ops, | ||
196 | struct gnttab_map_grant_ref *kmap_ops, | ||
197 | struct page **pages, unsigned int count); | ||
198 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | 196 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, |
197 | struct gnttab_map_grant_ref *kunmap_ops, | ||
199 | struct page **pages, unsigned int count); | 198 | struct page **pages, unsigned int count); |
200 | int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *unmap_ops, | ||
201 | struct gnttab_map_grant_ref *kunmap_ops, | ||
202 | struct page **pages, unsigned int count); | ||
203 | 199 | ||
204 | /* Perform a batch of grant map/copy operations. Retry every batch slot | 200 | /* Perform a batch of grant map/copy operations. Retry every batch slot |
205 | * for which the hypervisor returns GNTST_eagain. This is typically due | 201 | * for which the hypervisor returns GNTST_eagain. This is typically due |
diff --git a/init/main.c b/init/main.c index 2fd9cef70ee8..eb03090cdced 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -812,7 +812,7 @@ void __init load_default_modules(void) | |||
812 | static int run_init_process(const char *init_filename) | 812 | static int run_init_process(const char *init_filename) |
813 | { | 813 | { |
814 | argv_init[0] = init_filename; | 814 | argv_init[0] = init_filename; |
815 | return do_execve(init_filename, | 815 | return do_execve(getname_kernel(init_filename), |
816 | (const char __user *const __user *)argv_init, | 816 | (const char __user *const __user *)argv_init, |
817 | (const char __user *const __user *)envp_init); | 817 | (const char __user *const __user *)envp_init); |
818 | } | 818 | } |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 10176cd5956a..7aef2f4b6c64 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1719,7 +1719,7 @@ void audit_putname(struct filename *name) | |||
1719 | struct audit_context *context = current->audit_context; | 1719 | struct audit_context *context = current->audit_context; |
1720 | 1720 | ||
1721 | BUG_ON(!context); | 1721 | BUG_ON(!context); |
1722 | if (!context->in_syscall) { | 1722 | if (!name->aname || !context->in_syscall) { |
1723 | #if AUDIT_DEBUG == 2 | 1723 | #if AUDIT_DEBUG == 2 |
1724 | printk(KERN_ERR "%s:%d(:%d): final_putname(%p)\n", | 1724 | printk(KERN_ERR "%s:%d(:%d): final_putname(%p)\n", |
1725 | __FILE__, __LINE__, context->serial, name); | 1725 | __FILE__, __LINE__, context->serial, name); |
diff --git a/kernel/kmod.c b/kernel/kmod.c index b086006c59e7..6b375af4958d 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -239,7 +239,7 @@ static int ____call_usermodehelper(void *data) | |||
239 | 239 | ||
240 | commit_creds(new); | 240 | commit_creds(new); |
241 | 241 | ||
242 | retval = do_execve(sub_info->path, | 242 | retval = do_execve(getname_kernel(sub_info->path), |
243 | (const char __user *const __user *)sub_info->argv, | 243 | (const char __user *const __user *)sub_info->argv, |
244 | (const char __user *const __user *)sub_info->envp); | 244 | (const char __user *const __user *)sub_info->envp); |
245 | if (!retval) | 245 | if (!retval) |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index dbf94a7d25a8..a48abeac753f 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -119,7 +119,7 @@ menu "Compile-time checks and compiler options" | |||
119 | 119 | ||
120 | config DEBUG_INFO | 120 | config DEBUG_INFO |
121 | bool "Compile the kernel with debug info" | 121 | bool "Compile the kernel with debug info" |
122 | depends on DEBUG_KERNEL | 122 | depends on DEBUG_KERNEL && !COMPILE_TEST |
123 | help | 123 | help |
124 | If you say Y here the resulting kernel image will include | 124 | If you say Y here the resulting kernel image will include |
125 | debugging info resulting in a larger kernel image. | 125 | debugging info resulting in a larger kernel image. |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 2d30e2cfe804..7106cb1aca8e 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -2173,11 +2173,12 @@ int __set_page_dirty_nobuffers(struct page *page) | |||
2173 | if (!TestSetPageDirty(page)) { | 2173 | if (!TestSetPageDirty(page)) { |
2174 | struct address_space *mapping = page_mapping(page); | 2174 | struct address_space *mapping = page_mapping(page); |
2175 | struct address_space *mapping2; | 2175 | struct address_space *mapping2; |
2176 | unsigned long flags; | ||
2176 | 2177 | ||
2177 | if (!mapping) | 2178 | if (!mapping) |
2178 | return 1; | 2179 | return 1; |
2179 | 2180 | ||
2180 | spin_lock_irq(&mapping->tree_lock); | 2181 | spin_lock_irqsave(&mapping->tree_lock, flags); |
2181 | mapping2 = page_mapping(page); | 2182 | mapping2 = page_mapping(page); |
2182 | if (mapping2) { /* Race with truncate? */ | 2183 | if (mapping2) { /* Race with truncate? */ |
2183 | BUG_ON(mapping2 != mapping); | 2184 | BUG_ON(mapping2 != mapping); |
@@ -2186,7 +2187,7 @@ int __set_page_dirty_nobuffers(struct page *page) | |||
2186 | radix_tree_tag_set(&mapping->page_tree, | 2187 | radix_tree_tag_set(&mapping->page_tree, |
2187 | page_index(page), PAGECACHE_TAG_DIRTY); | 2188 | page_index(page), PAGECACHE_TAG_DIRTY); |
2188 | } | 2189 | } |
2189 | spin_unlock_irq(&mapping->tree_lock); | 2190 | spin_unlock_irqrestore(&mapping->tree_lock, flags); |
2190 | if (mapping->host) { | 2191 | if (mapping->host) { |
2191 | /* !PageAnon && !swapper_space */ | 2192 | /* !PageAnon && !swapper_space */ |
2192 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | 2193 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); |
diff --git a/mm/swap_state.c b/mm/swap_state.c index 98e85e9c2b2d..e76ace30d436 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c | |||
@@ -63,6 +63,8 @@ unsigned long total_swapcache_pages(void) | |||
63 | return ret; | 63 | return ret; |
64 | } | 64 | } |
65 | 65 | ||
66 | static atomic_t swapin_readahead_hits = ATOMIC_INIT(4); | ||
67 | |||
66 | void show_swap_cache_info(void) | 68 | void show_swap_cache_info(void) |
67 | { | 69 | { |
68 | printk("%lu pages in swap cache\n", total_swapcache_pages()); | 70 | printk("%lu pages in swap cache\n", total_swapcache_pages()); |
@@ -286,8 +288,11 @@ struct page * lookup_swap_cache(swp_entry_t entry) | |||
286 | 288 | ||
287 | page = find_get_page(swap_address_space(entry), entry.val); | 289 | page = find_get_page(swap_address_space(entry), entry.val); |
288 | 290 | ||
289 | if (page) | 291 | if (page) { |
290 | INC_CACHE_INFO(find_success); | 292 | INC_CACHE_INFO(find_success); |
293 | if (TestClearPageReadahead(page)) | ||
294 | atomic_inc(&swapin_readahead_hits); | ||
295 | } | ||
291 | 296 | ||
292 | INC_CACHE_INFO(find_total); | 297 | INC_CACHE_INFO(find_total); |
293 | return page; | 298 | return page; |
@@ -389,6 +394,50 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, | |||
389 | return found_page; | 394 | return found_page; |
390 | } | 395 | } |
391 | 396 | ||
397 | static unsigned long swapin_nr_pages(unsigned long offset) | ||
398 | { | ||
399 | static unsigned long prev_offset; | ||
400 | unsigned int pages, max_pages, last_ra; | ||
401 | static atomic_t last_readahead_pages; | ||
402 | |||
403 | max_pages = 1 << ACCESS_ONCE(page_cluster); | ||
404 | if (max_pages <= 1) | ||
405 | return 1; | ||
406 | |||
407 | /* | ||
408 | * This heuristic has been found to work well on both sequential and | ||
409 | * random loads, swapping to hard disk or to SSD: please don't ask | ||
410 | * what the "+ 2" means, it just happens to work well, that's all. | ||
411 | */ | ||
412 | pages = atomic_xchg(&swapin_readahead_hits, 0) + 2; | ||
413 | if (pages == 2) { | ||
414 | /* | ||
415 | * We can have no readahead hits to judge by: but must not get | ||
416 | * stuck here forever, so check for an adjacent offset instead | ||
417 | * (and don't even bother to check whether swap type is same). | ||
418 | */ | ||
419 | if (offset != prev_offset + 1 && offset != prev_offset - 1) | ||
420 | pages = 1; | ||
421 | prev_offset = offset; | ||
422 | } else { | ||
423 | unsigned int roundup = 4; | ||
424 | while (roundup < pages) | ||
425 | roundup <<= 1; | ||
426 | pages = roundup; | ||
427 | } | ||
428 | |||
429 | if (pages > max_pages) | ||
430 | pages = max_pages; | ||
431 | |||
432 | /* Don't shrink readahead too fast */ | ||
433 | last_ra = atomic_read(&last_readahead_pages) / 2; | ||
434 | if (pages < last_ra) | ||
435 | pages = last_ra; | ||
436 | atomic_set(&last_readahead_pages, pages); | ||
437 | |||
438 | return pages; | ||
439 | } | ||
440 | |||
392 | /** | 441 | /** |
393 | * swapin_readahead - swap in pages in hope we need them soon | 442 | * swapin_readahead - swap in pages in hope we need them soon |
394 | * @entry: swap entry of this memory | 443 | * @entry: swap entry of this memory |
@@ -412,11 +461,16 @@ struct page *swapin_readahead(swp_entry_t entry, gfp_t gfp_mask, | |||
412 | struct vm_area_struct *vma, unsigned long addr) | 461 | struct vm_area_struct *vma, unsigned long addr) |
413 | { | 462 | { |
414 | struct page *page; | 463 | struct page *page; |
415 | unsigned long offset = swp_offset(entry); | 464 | unsigned long entry_offset = swp_offset(entry); |
465 | unsigned long offset = entry_offset; | ||
416 | unsigned long start_offset, end_offset; | 466 | unsigned long start_offset, end_offset; |
417 | unsigned long mask = (1UL << page_cluster) - 1; | 467 | unsigned long mask; |
418 | struct blk_plug plug; | 468 | struct blk_plug plug; |
419 | 469 | ||
470 | mask = swapin_nr_pages(offset) - 1; | ||
471 | if (!mask) | ||
472 | goto skip; | ||
473 | |||
420 | /* Read a page_cluster sized and aligned cluster around offset. */ | 474 | /* Read a page_cluster sized and aligned cluster around offset. */ |
421 | start_offset = offset & ~mask; | 475 | start_offset = offset & ~mask; |
422 | end_offset = offset | mask; | 476 | end_offset = offset | mask; |
@@ -430,10 +484,13 @@ struct page *swapin_readahead(swp_entry_t entry, gfp_t gfp_mask, | |||
430 | gfp_mask, vma, addr); | 484 | gfp_mask, vma, addr); |
431 | if (!page) | 485 | if (!page) |
432 | continue; | 486 | continue; |
487 | if (offset != entry_offset) | ||
488 | SetPageReadahead(page); | ||
433 | page_cache_release(page); | 489 | page_cache_release(page); |
434 | } | 490 | } |
435 | blk_finish_plug(&plug); | 491 | blk_finish_plug(&plug); |
436 | 492 | ||
437 | lru_add_drain(); /* Push any new pages onto the LRU now */ | 493 | lru_add_drain(); /* Push any new pages onto the LRU now */ |
494 | skip: | ||
438 | return read_swap_cache_async(entry, gfp_mask, vma, addr); | 495 | return read_swap_cache_async(entry, gfp_mask, vma, addr); |
439 | } | 496 | } |
diff --git a/mm/swapfile.c b/mm/swapfile.c index c6c13b050a58..4a7f7e6992b6 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -1923,7 +1923,6 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) | |||
1923 | p->swap_map = NULL; | 1923 | p->swap_map = NULL; |
1924 | cluster_info = p->cluster_info; | 1924 | cluster_info = p->cluster_info; |
1925 | p->cluster_info = NULL; | 1925 | p->cluster_info = NULL; |
1926 | p->flags = 0; | ||
1927 | frontswap_map = frontswap_map_get(p); | 1926 | frontswap_map = frontswap_map_get(p); |
1928 | spin_unlock(&p->lock); | 1927 | spin_unlock(&p->lock); |
1929 | spin_unlock(&swap_lock); | 1928 | spin_unlock(&swap_lock); |
@@ -1949,6 +1948,16 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) | |||
1949 | mutex_unlock(&inode->i_mutex); | 1948 | mutex_unlock(&inode->i_mutex); |
1950 | } | 1949 | } |
1951 | filp_close(swap_file, NULL); | 1950 | filp_close(swap_file, NULL); |
1951 | |||
1952 | /* | ||
1953 | * Clear the SWP_USED flag after all resources are freed so that swapon | ||
1954 | * can reuse this swap_info in alloc_swap_info() safely. It is ok to | ||
1955 | * not hold p->lock after we cleared its SWP_WRITEOK. | ||
1956 | */ | ||
1957 | spin_lock(&swap_lock); | ||
1958 | p->flags = 0; | ||
1959 | spin_unlock(&swap_lock); | ||
1960 | |||
1952 | err = 0; | 1961 | err = 0; |
1953 | atomic_inc(&proc_poll_event); | 1962 | atomic_inc(&proc_poll_event); |
1954 | wake_up_interruptible(&proc_poll_wait); | 1963 | wake_up_interruptible(&proc_poll_wait); |
diff --git a/security/Kconfig b/security/Kconfig index e9c6ac724fef..beb86b500adf 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -103,7 +103,7 @@ config INTEL_TXT | |||
103 | config LSM_MMAP_MIN_ADDR | 103 | config LSM_MMAP_MIN_ADDR |
104 | int "Low address space for LSM to protect from user allocation" | 104 | int "Low address space for LSM to protect from user allocation" |
105 | depends on SECURITY && SECURITY_SELINUX | 105 | depends on SECURITY && SECURITY_SELINUX |
106 | default 32768 if ARM | 106 | default 32768 if ARM || (ARM64 && COMPAT) |
107 | default 65536 | 107 | default 65536 |
108 | help | 108 | help |
109 | This is the portion of low virtual memory which should be protected | 109 | This is the portion of low virtual memory which should be protected |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 7a426ed491f2..df3652ad15ef 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -244,6 +244,19 @@ static void ad_fixup_inv_jack_detect(struct hda_codec *codec, | |||
244 | } | 244 | } |
245 | } | 245 | } |
246 | 246 | ||
247 | /* Toshiba Satellite L40 implements EAPD in a standard way unlike others */ | ||
248 | static void ad1986a_fixup_eapd(struct hda_codec *codec, | ||
249 | const struct hda_fixup *fix, int action) | ||
250 | { | ||
251 | struct ad198x_spec *spec = codec->spec; | ||
252 | |||
253 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
254 | codec->inv_eapd = 0; | ||
255 | spec->gen.keep_eapd_on = 1; | ||
256 | spec->eapd_nid = 0x1b; | ||
257 | } | ||
258 | } | ||
259 | |||
247 | enum { | 260 | enum { |
248 | AD1986A_FIXUP_INV_JACK_DETECT, | 261 | AD1986A_FIXUP_INV_JACK_DETECT, |
249 | AD1986A_FIXUP_ULTRA, | 262 | AD1986A_FIXUP_ULTRA, |
@@ -251,6 +264,7 @@ enum { | |||
251 | AD1986A_FIXUP_3STACK, | 264 | AD1986A_FIXUP_3STACK, |
252 | AD1986A_FIXUP_LAPTOP, | 265 | AD1986A_FIXUP_LAPTOP, |
253 | AD1986A_FIXUP_LAPTOP_IMIC, | 266 | AD1986A_FIXUP_LAPTOP_IMIC, |
267 | AD1986A_FIXUP_EAPD, | ||
254 | }; | 268 | }; |
255 | 269 | ||
256 | static const struct hda_fixup ad1986a_fixups[] = { | 270 | static const struct hda_fixup ad1986a_fixups[] = { |
@@ -311,6 +325,10 @@ static const struct hda_fixup ad1986a_fixups[] = { | |||
311 | .chained_before = 1, | 325 | .chained_before = 1, |
312 | .chain_id = AD1986A_FIXUP_LAPTOP, | 326 | .chain_id = AD1986A_FIXUP_LAPTOP, |
313 | }, | 327 | }, |
328 | [AD1986A_FIXUP_EAPD] = { | ||
329 | .type = HDA_FIXUP_FUNC, | ||
330 | .v.func = ad1986a_fixup_eapd, | ||
331 | }, | ||
314 | }; | 332 | }; |
315 | 333 | ||
316 | static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { | 334 | static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { |
@@ -318,6 +336,7 @@ static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { | |||
318 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), | 336 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), |
319 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), | 337 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), |
320 | SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), | 338 | SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), |
339 | SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40", AD1986A_FIXUP_EAPD), | ||
321 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), | 340 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), |
322 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), | 341 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), |
323 | SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), | 342 | SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), |
@@ -472,6 +491,8 @@ static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec) | |||
472 | static int patch_ad1983(struct hda_codec *codec) | 491 | static int patch_ad1983(struct hda_codec *codec) |
473 | { | 492 | { |
474 | struct ad198x_spec *spec; | 493 | struct ad198x_spec *spec; |
494 | static hda_nid_t conn_0c[] = { 0x08 }; | ||
495 | static hda_nid_t conn_0d[] = { 0x09 }; | ||
475 | int err; | 496 | int err; |
476 | 497 | ||
477 | err = alloc_ad_spec(codec); | 498 | err = alloc_ad_spec(codec); |
@@ -479,8 +500,14 @@ static int patch_ad1983(struct hda_codec *codec) | |||
479 | return err; | 500 | return err; |
480 | spec = codec->spec; | 501 | spec = codec->spec; |
481 | 502 | ||
503 | spec->gen.mixer_nid = 0x0e; | ||
482 | spec->gen.beep_nid = 0x10; | 504 | spec->gen.beep_nid = 0x10; |
483 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 505 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
506 | |||
507 | /* limit the loopback routes not to confuse the parser */ | ||
508 | snd_hda_override_conn_list(codec, 0x0c, ARRAY_SIZE(conn_0c), conn_0c); | ||
509 | snd_hda_override_conn_list(codec, 0x0d, ARRAY_SIZE(conn_0d), conn_0d); | ||
510 | |||
484 | err = ad198x_parse_auto_config(codec, false); | 511 | err = ad198x_parse_auto_config(codec, false); |
485 | if (err < 0) | 512 | if (err < 0) |
486 | goto error; | 513 | goto error; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 56a8f1876603..d9693ca9546f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1821,6 +1821,7 @@ enum { | |||
1821 | ALC889_FIXUP_IMAC91_VREF, | 1821 | ALC889_FIXUP_IMAC91_VREF, |
1822 | ALC889_FIXUP_MBA11_VREF, | 1822 | ALC889_FIXUP_MBA11_VREF, |
1823 | ALC889_FIXUP_MBA21_VREF, | 1823 | ALC889_FIXUP_MBA21_VREF, |
1824 | ALC889_FIXUP_MP11_VREF, | ||
1824 | ALC882_FIXUP_INV_DMIC, | 1825 | ALC882_FIXUP_INV_DMIC, |
1825 | ALC882_FIXUP_NO_PRIMARY_HP, | 1826 | ALC882_FIXUP_NO_PRIMARY_HP, |
1826 | ALC887_FIXUP_ASUS_BASS, | 1827 | ALC887_FIXUP_ASUS_BASS, |
@@ -2190,6 +2191,12 @@ static const struct hda_fixup alc882_fixups[] = { | |||
2190 | .chained = true, | 2191 | .chained = true, |
2191 | .chain_id = ALC889_FIXUP_MBP_VREF, | 2192 | .chain_id = ALC889_FIXUP_MBP_VREF, |
2192 | }, | 2193 | }, |
2194 | [ALC889_FIXUP_MP11_VREF] = { | ||
2195 | .type = HDA_FIXUP_FUNC, | ||
2196 | .v.func = alc889_fixup_mba11_vref, | ||
2197 | .chained = true, | ||
2198 | .chain_id = ALC885_FIXUP_MACPRO_GPIO, | ||
2199 | }, | ||
2193 | [ALC882_FIXUP_INV_DMIC] = { | 2200 | [ALC882_FIXUP_INV_DMIC] = { |
2194 | .type = HDA_FIXUP_FUNC, | 2201 | .type = HDA_FIXUP_FUNC, |
2195 | .v.func = alc_fixup_inv_dmic_0x12, | 2202 | .v.func = alc_fixup_inv_dmic_0x12, |
@@ -2253,7 +2260,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
2253 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), | 2260 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), |
2254 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), | 2261 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), |
2255 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | 2262 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), |
2256 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), | 2263 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), |
2257 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), | 2264 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), |
2258 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), | 2265 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), |
2259 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), | 2266 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), |
@@ -4427,6 +4434,9 @@ static void alc269_fill_coef(struct hda_codec *codec) | |||
4427 | 4434 | ||
4428 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) | 4435 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) |
4429 | return; | 4436 | return; |
4437 | /* ALC271X doesn't seem to support these COEFs (bko#52181) */ | ||
4438 | if (!strcmp(codec->chip_name, "ALC271X")) | ||
4439 | return; | ||
4430 | 4440 | ||
4431 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { | 4441 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { |
4432 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4442 | alc_write_coef_idx(codec, 0xf, 0x960b); |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index de9408b83f75..e05a86b7c0da 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -14,6 +14,7 @@ config SND_USB_AUDIO | |||
14 | select SND_HWDEP | 14 | select SND_HWDEP |
15 | select SND_RAWMIDI | 15 | select SND_RAWMIDI |
16 | select SND_PCM | 16 | select SND_PCM |
17 | select BITREVERSE | ||
17 | help | 18 | help |
18 | Say Y here to include support for USB audio and USB MIDI | 19 | Say Y here to include support for USB audio and USB MIDI |
19 | devices. | 20 | devices. |