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. |
