diff options
author | David S. Miller <davem@davemloft.net> | 2017-12-29 15:14:27 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-12-29 15:42:26 -0500 |
commit | 6bb8824732f69de0f233ae6b1a8158e149627b38 (patch) | |
tree | 78642311a28f42df9042da41eb98652c39d51327 | |
parent | d367341b25bd5aef3bf5524baa6f73e16ceced85 (diff) | |
parent | 2758b3e3e630ba304fc4aca434d591e70e528298 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
net/ipv6/ip6_gre.c is a case of parallel adds.
include/trace/events/tcp.h is a little bit more tricky. The removal
of in-trace-macro ifdefs in 'net' paralleled with moving
show_tcp_state_name and friends over to include/trace/events/sock.h
in 'net-next'.
Signed-off-by: David S. Miller <davem@davemloft.net>
212 files changed, 2378 insertions, 1204 deletions
diff --git a/Documentation/devicetree/bindings/sound/da7218.txt b/Documentation/devicetree/bindings/sound/da7218.txt index 5ca5a709b6aa..3ab9dfef38d1 100644 --- a/Documentation/devicetree/bindings/sound/da7218.txt +++ b/Documentation/devicetree/bindings/sound/da7218.txt | |||
@@ -73,7 +73,7 @@ Example: | |||
73 | compatible = "dlg,da7218"; | 73 | compatible = "dlg,da7218"; |
74 | reg = <0x1a>; | 74 | reg = <0x1a>; |
75 | interrupt-parent = <&gpio6>; | 75 | interrupt-parent = <&gpio6>; |
76 | interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; | 76 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; |
77 | wakeup-source; | 77 | wakeup-source; |
78 | 78 | ||
79 | VDD-supply = <®_audio>; | 79 | VDD-supply = <®_audio>; |
diff --git a/Documentation/devicetree/bindings/sound/da7219.txt b/Documentation/devicetree/bindings/sound/da7219.txt index cf61681826b6..5b54d2d045c3 100644 --- a/Documentation/devicetree/bindings/sound/da7219.txt +++ b/Documentation/devicetree/bindings/sound/da7219.txt | |||
@@ -77,7 +77,7 @@ Example: | |||
77 | reg = <0x1a>; | 77 | reg = <0x1a>; |
78 | 78 | ||
79 | interrupt-parent = <&gpio6>; | 79 | interrupt-parent = <&gpio6>; |
80 | interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; | 80 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; |
81 | 81 | ||
82 | VDD-supply = <®_audio>; | 82 | VDD-supply = <®_audio>; |
83 | VDDMIC-supply = <®_audio>; | 83 | VDDMIC-supply = <®_audio>; |
diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index 3448e675b462..51101708a03a 100644 --- a/Documentation/x86/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt | |||
@@ -1,6 +1,4 @@ | |||
1 | 1 | ||
2 | <previous description obsolete, deleted> | ||
3 | |||
4 | Virtual memory map with 4 level page tables: | 2 | Virtual memory map with 4 level page tables: |
5 | 3 | ||
6 | 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm | 4 | 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm |
@@ -14,13 +12,15 @@ ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB) | |||
14 | ... unused hole ... | 12 | ... unused hole ... |
15 | ffffec0000000000 - fffffbffffffffff (=44 bits) kasan shadow memory (16TB) | 13 | ffffec0000000000 - fffffbffffffffff (=44 bits) kasan shadow memory (16TB) |
16 | ... unused hole ... | 14 | ... unused hole ... |
15 | fffffe8000000000 - fffffeffffffffff (=39 bits) cpu_entry_area mapping | ||
17 | ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks | 16 | ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks |
18 | ... unused hole ... | 17 | ... unused hole ... |
19 | ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space | 18 | ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space |
20 | ... unused hole ... | 19 | ... unused hole ... |
21 | ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 | 20 | ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 |
22 | ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space (variable) | 21 | ffffffffa0000000 - [fixmap start] (~1526 MB) module mapping space (variable) |
23 | ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls | 22 | [fixmap start] - ffffffffff5fffff kernel-internal fixmap range |
23 | ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI | ||
24 | ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole | 24 | ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole |
25 | 25 | ||
26 | Virtual memory map with 5 level page tables: | 26 | Virtual memory map with 5 level page tables: |
@@ -36,19 +36,22 @@ ffd4000000000000 - ffd5ffffffffffff (=49 bits) virtual memory map (512TB) | |||
36 | ... unused hole ... | 36 | ... unused hole ... |
37 | ffdf000000000000 - fffffc0000000000 (=53 bits) kasan shadow memory (8PB) | 37 | ffdf000000000000 - fffffc0000000000 (=53 bits) kasan shadow memory (8PB) |
38 | ... unused hole ... | 38 | ... unused hole ... |
39 | fffffe8000000000 - fffffeffffffffff (=39 bits) cpu_entry_area mapping | ||
39 | ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks | 40 | ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks |
40 | ... unused hole ... | 41 | ... unused hole ... |
41 | ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space | 42 | ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space |
42 | ... unused hole ... | 43 | ... unused hole ... |
43 | ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 | 44 | ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 |
44 | ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space | 45 | ffffffffa0000000 - [fixmap start] (~1526 MB) module mapping space |
45 | ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls | 46 | [fixmap start] - ffffffffff5fffff kernel-internal fixmap range |
47 | ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI | ||
46 | ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole | 48 | ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole |
47 | 49 | ||
48 | Architecture defines a 64-bit virtual address. Implementations can support | 50 | Architecture defines a 64-bit virtual address. Implementations can support |
49 | less. Currently supported are 48- and 57-bit virtual addresses. Bits 63 | 51 | less. Currently supported are 48- and 57-bit virtual addresses. Bits 63 |
50 | through to the most-significant implemented bit are set to either all ones | 52 | through to the most-significant implemented bit are sign extended. |
51 | or all zero. This causes hole between user space and kernel addresses. | 53 | This causes hole between user space and kernel addresses if you interpret them |
54 | as unsigned. | ||
52 | 55 | ||
53 | The direct mapping covers all memory in the system up to the highest | 56 | The direct mapping covers all memory in the system up to the highest |
54 | memory address (this means in some cases it can also include PCI memory | 57 | memory address (this means in some cases it can also include PCI memory |
@@ -58,9 +61,6 @@ vmalloc space is lazily synchronized into the different PML4/PML5 pages of | |||
58 | the processes using the page fault handler, with init_top_pgt as | 61 | the processes using the page fault handler, with init_top_pgt as |
59 | reference. | 62 | reference. |
60 | 63 | ||
61 | Current X86-64 implementations support up to 46 bits of address space (64 TB), | ||
62 | which is our current limit. This expands into MBZ space in the page tables. | ||
63 | |||
64 | We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual | 64 | We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual |
65 | memory window (this size is arbitrary, it can be raised later if needed). | 65 | memory window (this size is arbitrary, it can be raised later if needed). |
66 | The mappings are not part of any other kernel PGD and are only available | 66 | The mappings are not part of any other kernel PGD and are only available |
@@ -72,5 +72,3 @@ following fixmap section. | |||
72 | Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all | 72 | Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all |
73 | physical memory, vmalloc/ioremap space and virtual memory map are randomized. | 73 | physical memory, vmalloc/ioremap space and virtual memory map are randomized. |
74 | Their order is preserved but their base will be offset early at boot time. | 74 | Their order is preserved but their base will be offset early at boot time. |
75 | |||
76 | -Andi Kleen, Jul 2004 | ||
@@ -2,7 +2,7 @@ | |||
2 | VERSION = 4 | 2 | VERSION = 4 |
3 | PATCHLEVEL = 15 | 3 | PATCHLEVEL = 15 |
4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
5 | EXTRAVERSION = -rc4 | 5 | EXTRAVERSION = -rc5 |
6 | NAME = Fearless Coyote | 6 | NAME = Fearless Coyote |
7 | 7 | ||
8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 6177d43f0ce8..e2a2b8400490 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h | |||
@@ -160,9 +160,10 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, | |||
160 | #endif | 160 | #endif |
161 | } | 161 | } |
162 | 162 | ||
163 | static inline void arch_dup_mmap(struct mm_struct *oldmm, | 163 | static inline int arch_dup_mmap(struct mm_struct *oldmm, |
164 | struct mm_struct *mm) | 164 | struct mm_struct *mm) |
165 | { | 165 | { |
166 | return 0; | ||
166 | } | 167 | } |
167 | 168 | ||
168 | #ifndef CONFIG_PPC_BOOK3S_64 | 169 | #ifndef CONFIG_PPC_BOOK3S_64 |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 5acb5a176dbe..72be0c32e902 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -1403,7 +1403,7 @@ void show_regs(struct pt_regs * regs) | |||
1403 | 1403 | ||
1404 | printk("NIP: "REG" LR: "REG" CTR: "REG"\n", | 1404 | printk("NIP: "REG" LR: "REG" CTR: "REG"\n", |
1405 | regs->nip, regs->link, regs->ctr); | 1405 | regs->nip, regs->link, regs->ctr); |
1406 | printk("REGS: %p TRAP: %04lx %s (%s)\n", | 1406 | printk("REGS: %px TRAP: %04lx %s (%s)\n", |
1407 | regs, regs->trap, print_tainted(), init_utsname()->release); | 1407 | regs, regs->trap, print_tainted(), init_utsname()->release); |
1408 | printk("MSR: "REG" ", regs->msr); | 1408 | printk("MSR: "REG" ", regs->msr); |
1409 | print_msr_bits(regs->msr); | 1409 | print_msr_bits(regs->msr); |
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index bf457843e032..0d750d274c4e 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c | |||
@@ -725,7 +725,8 @@ u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu) | |||
725 | 725 | ||
726 | /* Return the per-cpu state for state saving/migration */ | 726 | /* Return the per-cpu state for state saving/migration */ |
727 | return (u64)xc->cppr << KVM_REG_PPC_ICP_CPPR_SHIFT | | 727 | return (u64)xc->cppr << KVM_REG_PPC_ICP_CPPR_SHIFT | |
728 | (u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT; | 728 | (u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT | |
729 | (u64)0xff << KVM_REG_PPC_ICP_PPRI_SHIFT; | ||
729 | } | 730 | } |
730 | 731 | ||
731 | int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) | 732 | int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) |
@@ -1558,7 +1559,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) | |||
1558 | 1559 | ||
1559 | /* | 1560 | /* |
1560 | * Restore P and Q. If the interrupt was pending, we | 1561 | * Restore P and Q. If the interrupt was pending, we |
1561 | * force both P and Q, which will trigger a resend. | 1562 | * force Q and !P, which will trigger a resend. |
1562 | * | 1563 | * |
1563 | * That means that a guest that had both an interrupt | 1564 | * That means that a guest that had both an interrupt |
1564 | * pending (queued) and Q set will restore with only | 1565 | * pending (queued) and Q set will restore with only |
@@ -1566,7 +1567,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) | |||
1566 | * is perfectly fine as coalescing interrupts that haven't | 1567 | * is perfectly fine as coalescing interrupts that haven't |
1567 | * been presented yet is always allowed. | 1568 | * been presented yet is always allowed. |
1568 | */ | 1569 | */ |
1569 | if (val & KVM_XICS_PRESENTED || val & KVM_XICS_PENDING) | 1570 | if (val & KVM_XICS_PRESENTED && !(val & KVM_XICS_PENDING)) |
1570 | state->old_p = true; | 1571 | state->old_p = true; |
1571 | if (val & KVM_XICS_QUEUED || val & KVM_XICS_PENDING) | 1572 | if (val & KVM_XICS_QUEUED || val & KVM_XICS_PENDING) |
1572 | state->old_q = true; | 1573 | state->old_q = true; |
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 153812966365..fce545774d50 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
@@ -410,8 +410,12 @@ static __u64 power_pmu_bhrb_to(u64 addr) | |||
410 | int ret; | 410 | int ret; |
411 | __u64 target; | 411 | __u64 target; |
412 | 412 | ||
413 | if (is_kernel_addr(addr)) | 413 | if (is_kernel_addr(addr)) { |
414 | return branch_target((unsigned int *)addr); | 414 | if (probe_kernel_read(&instr, (void *)addr, sizeof(instr))) |
415 | return 0; | ||
416 | |||
417 | return branch_target(&instr); | ||
418 | } | ||
415 | 419 | ||
416 | /* Userspace: need copy instruction here then translate it */ | 420 | /* Userspace: need copy instruction here then translate it */ |
417 | pagefault_disable(); | 421 | pagefault_disable(); |
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 0ead3cd73caa..be4e7f84f70a 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c | |||
@@ -310,6 +310,19 @@ static int ppc_nest_imc_cpu_offline(unsigned int cpu) | |||
310 | return 0; | 310 | return 0; |
311 | 311 | ||
312 | /* | 312 | /* |
313 | * Check whether nest_imc is registered. We could end up here if the | ||
314 | * cpuhotplug callback registration fails. i.e, callback invokes the | ||
315 | * offline path for all successfully registered nodes. At this stage, | ||
316 | * nest_imc pmu will not be registered and we should return here. | ||
317 | * | ||
318 | * We return with a zero since this is not an offline failure. And | ||
319 | * cpuhp_setup_state() returns the actual failure reason to the caller, | ||
320 | * which in turn will call the cleanup routine. | ||
321 | */ | ||
322 | if (!nest_pmus) | ||
323 | return 0; | ||
324 | |||
325 | /* | ||
313 | * Now that this cpu is one of the designated, | 326 | * Now that this cpu is one of the designated, |
314 | * find a next cpu a) which is online and b) in same chip. | 327 | * find a next cpu a) which is online and b) in same chip. |
315 | */ | 328 | */ |
@@ -1171,6 +1184,7 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr) | |||
1171 | if (nest_pmus == 1) { | 1184 | if (nest_pmus == 1) { |
1172 | cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE); | 1185 | cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE); |
1173 | kfree(nest_imc_refc); | 1186 | kfree(nest_imc_refc); |
1187 | kfree(per_nest_pmu_arr); | ||
1174 | } | 1188 | } |
1175 | 1189 | ||
1176 | if (nest_pmus > 0) | 1190 | if (nest_pmus > 0) |
@@ -1195,7 +1209,6 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr) | |||
1195 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs); | 1209 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs); |
1196 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]); | 1210 | kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]); |
1197 | kfree(pmu_ptr); | 1211 | kfree(pmu_ptr); |
1198 | kfree(per_nest_pmu_arr); | ||
1199 | return; | 1212 | return; |
1200 | } | 1213 | } |
1201 | 1214 | ||
@@ -1309,6 +1322,8 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id | |||
1309 | ret = nest_pmu_cpumask_init(); | 1322 | ret = nest_pmu_cpumask_init(); |
1310 | if (ret) { | 1323 | if (ret) { |
1311 | mutex_unlock(&nest_init_lock); | 1324 | mutex_unlock(&nest_init_lock); |
1325 | kfree(nest_imc_refc); | ||
1326 | kfree(per_nest_pmu_arr); | ||
1312 | goto err_free; | 1327 | goto err_free; |
1313 | } | 1328 | } |
1314 | } | 1329 | } |
diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index b668e351fd6c..fca34b2177e2 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h | |||
@@ -15,9 +15,10 @@ extern void uml_setup_stubs(struct mm_struct *mm); | |||
15 | /* | 15 | /* |
16 | * Needed since we do not use the asm-generic/mm_hooks.h: | 16 | * Needed since we do not use the asm-generic/mm_hooks.h: |
17 | */ | 17 | */ |
18 | static inline void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) | 18 | static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) |
19 | { | 19 | { |
20 | uml_setup_stubs(mm); | 20 | uml_setup_stubs(mm); |
21 | return 0; | ||
21 | } | 22 | } |
22 | extern void arch_exit_mmap(struct mm_struct *mm); | 23 | extern void arch_exit_mmap(struct mm_struct *mm); |
23 | static inline void arch_unmap(struct mm_struct *mm, | 24 | static inline void arch_unmap(struct mm_struct *mm, |
diff --git a/arch/unicore32/include/asm/mmu_context.h b/arch/unicore32/include/asm/mmu_context.h index 59b06b48f27d..5c205a9cb5a6 100644 --- a/arch/unicore32/include/asm/mmu_context.h +++ b/arch/unicore32/include/asm/mmu_context.h | |||
@@ -81,9 +81,10 @@ do { \ | |||
81 | } \ | 81 | } \ |
82 | } while (0) | 82 | } while (0) |
83 | 83 | ||
84 | static inline void arch_dup_mmap(struct mm_struct *oldmm, | 84 | static inline int arch_dup_mmap(struct mm_struct *oldmm, |
85 | struct mm_struct *mm) | 85 | struct mm_struct *mm) |
86 | { | 86 | { |
87 | return 0; | ||
87 | } | 88 | } |
88 | 89 | ||
89 | static inline void arch_unmap(struct mm_struct *mm, | 90 | static inline void arch_unmap(struct mm_struct *mm, |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 04d66e6fa447..45dc6233f2b9 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -927,7 +927,8 @@ config MAXSMP | |||
927 | config NR_CPUS | 927 | config NR_CPUS |
928 | int "Maximum number of CPUs" if SMP && !MAXSMP | 928 | int "Maximum number of CPUs" if SMP && !MAXSMP |
929 | range 2 8 if SMP && X86_32 && !X86_BIGSMP | 929 | range 2 8 if SMP && X86_32 && !X86_BIGSMP |
930 | range 2 512 if SMP && !MAXSMP && !CPUMASK_OFFSTACK | 930 | range 2 64 if SMP && X86_32 && X86_BIGSMP |
931 | range 2 512 if SMP && !MAXSMP && !CPUMASK_OFFSTACK && X86_64 | ||
931 | range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64 | 932 | range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64 |
932 | default "1" if !SMP | 933 | default "1" if !SMP |
933 | default "8192" if MAXSMP | 934 | default "8192" if MAXSMP |
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index bd8b57a5c874..ace8f321a5a1 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S | |||
@@ -942,9 +942,9 @@ ENTRY(debug) | |||
942 | 942 | ||
943 | /* Are we currently on the SYSENTER stack? */ | 943 | /* Are we currently on the SYSENTER stack? */ |
944 | movl PER_CPU_VAR(cpu_entry_area), %ecx | 944 | movl PER_CPU_VAR(cpu_entry_area), %ecx |
945 | addl $CPU_ENTRY_AREA_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx | 945 | addl $CPU_ENTRY_AREA_entry_stack + SIZEOF_entry_stack, %ecx |
946 | subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ | 946 | subl %eax, %ecx /* ecx = (end of entry_stack) - esp */ |
947 | cmpl $SIZEOF_SYSENTER_stack, %ecx | 947 | cmpl $SIZEOF_entry_stack, %ecx |
948 | jb .Ldebug_from_sysenter_stack | 948 | jb .Ldebug_from_sysenter_stack |
949 | 949 | ||
950 | TRACE_IRQS_OFF | 950 | TRACE_IRQS_OFF |
@@ -986,9 +986,9 @@ ENTRY(nmi) | |||
986 | 986 | ||
987 | /* Are we currently on the SYSENTER stack? */ | 987 | /* Are we currently on the SYSENTER stack? */ |
988 | movl PER_CPU_VAR(cpu_entry_area), %ecx | 988 | movl PER_CPU_VAR(cpu_entry_area), %ecx |
989 | addl $CPU_ENTRY_AREA_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx | 989 | addl $CPU_ENTRY_AREA_entry_stack + SIZEOF_entry_stack, %ecx |
990 | subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ | 990 | subl %eax, %ecx /* ecx = (end of entry_stack) - esp */ |
991 | cmpl $SIZEOF_SYSENTER_stack, %ecx | 991 | cmpl $SIZEOF_entry_stack, %ecx |
992 | jb .Lnmi_from_sysenter_stack | 992 | jb .Lnmi_from_sysenter_stack |
993 | 993 | ||
994 | /* Not on SYSENTER stack. */ | 994 | /* Not on SYSENTER stack. */ |
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 423885bee398..3d19c830e1b1 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S | |||
@@ -158,8 +158,8 @@ END(native_usergs_sysret64) | |||
158 | _entry_trampoline - CPU_ENTRY_AREA_entry_trampoline(%rip) | 158 | _entry_trampoline - CPU_ENTRY_AREA_entry_trampoline(%rip) |
159 | 159 | ||
160 | /* The top word of the SYSENTER stack is hot and is usable as scratch space. */ | 160 | /* The top word of the SYSENTER stack is hot and is usable as scratch space. */ |
161 | #define RSP_SCRATCH CPU_ENTRY_AREA_SYSENTER_stack + \ | 161 | #define RSP_SCRATCH CPU_ENTRY_AREA_entry_stack + \ |
162 | SIZEOF_SYSENTER_stack - 8 + CPU_ENTRY_AREA | 162 | SIZEOF_entry_stack - 8 + CPU_ENTRY_AREA |
163 | 163 | ||
164 | ENTRY(entry_SYSCALL_64_trampoline) | 164 | ENTRY(entry_SYSCALL_64_trampoline) |
165 | UNWIND_HINT_EMPTY | 165 | UNWIND_HINT_EMPTY |
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c index f279ba2643dc..1faf40f2dda9 100644 --- a/arch/x86/entry/vsyscall/vsyscall_64.c +++ b/arch/x86/entry/vsyscall/vsyscall_64.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/unistd.h> | 37 | #include <asm/unistd.h> |
38 | #include <asm/fixmap.h> | 38 | #include <asm/fixmap.h> |
39 | #include <asm/traps.h> | 39 | #include <asm/traps.h> |
40 | #include <asm/paravirt.h> | ||
40 | 41 | ||
41 | #define CREATE_TRACE_POINTS | 42 | #define CREATE_TRACE_POINTS |
42 | #include "vsyscall_trace.h" | 43 | #include "vsyscall_trace.h" |
@@ -138,6 +139,10 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) | |||
138 | 139 | ||
139 | WARN_ON_ONCE(address != regs->ip); | 140 | WARN_ON_ONCE(address != regs->ip); |
140 | 141 | ||
142 | /* This should be unreachable in NATIVE mode. */ | ||
143 | if (WARN_ON(vsyscall_mode == NATIVE)) | ||
144 | return false; | ||
145 | |||
141 | if (vsyscall_mode == NONE) { | 146 | if (vsyscall_mode == NONE) { |
142 | warn_bad_vsyscall(KERN_INFO, regs, | 147 | warn_bad_vsyscall(KERN_INFO, regs, |
143 | "vsyscall attempted with vsyscall=none"); | 148 | "vsyscall attempted with vsyscall=none"); |
@@ -329,16 +334,47 @@ int in_gate_area_no_mm(unsigned long addr) | |||
329 | return vsyscall_mode != NONE && (addr & PAGE_MASK) == VSYSCALL_ADDR; | 334 | return vsyscall_mode != NONE && (addr & PAGE_MASK) == VSYSCALL_ADDR; |
330 | } | 335 | } |
331 | 336 | ||
337 | /* | ||
338 | * The VSYSCALL page is the only user-accessible page in the kernel address | ||
339 | * range. Normally, the kernel page tables can have _PAGE_USER clear, but | ||
340 | * the tables covering VSYSCALL_ADDR need _PAGE_USER set if vsyscalls | ||
341 | * are enabled. | ||
342 | * | ||
343 | * Some day we may create a "minimal" vsyscall mode in which we emulate | ||
344 | * vsyscalls but leave the page not present. If so, we skip calling | ||
345 | * this. | ||
346 | */ | ||
347 | static void __init set_vsyscall_pgtable_user_bits(void) | ||
348 | { | ||
349 | pgd_t *pgd; | ||
350 | p4d_t *p4d; | ||
351 | pud_t *pud; | ||
352 | pmd_t *pmd; | ||
353 | |||
354 | pgd = pgd_offset_k(VSYSCALL_ADDR); | ||
355 | set_pgd(pgd, __pgd(pgd_val(*pgd) | _PAGE_USER)); | ||
356 | p4d = p4d_offset(pgd, VSYSCALL_ADDR); | ||
357 | #if CONFIG_PGTABLE_LEVELS >= 5 | ||
358 | p4d->p4d |= _PAGE_USER; | ||
359 | #endif | ||
360 | pud = pud_offset(p4d, VSYSCALL_ADDR); | ||
361 | set_pud(pud, __pud(pud_val(*pud) | _PAGE_USER)); | ||
362 | pmd = pmd_offset(pud, VSYSCALL_ADDR); | ||
363 | set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_USER)); | ||
364 | } | ||
365 | |||
332 | void __init map_vsyscall(void) | 366 | void __init map_vsyscall(void) |
333 | { | 367 | { |
334 | extern char __vsyscall_page; | 368 | extern char __vsyscall_page; |
335 | unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); | 369 | unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); |
336 | 370 | ||
337 | if (vsyscall_mode != NONE) | 371 | if (vsyscall_mode != NONE) { |
338 | __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall, | 372 | __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall, |
339 | vsyscall_mode == NATIVE | 373 | vsyscall_mode == NATIVE |
340 | ? PAGE_KERNEL_VSYSCALL | 374 | ? PAGE_KERNEL_VSYSCALL |
341 | : PAGE_KERNEL_VVAR); | 375 | : PAGE_KERNEL_VVAR); |
376 | set_vsyscall_pgtable_user_bits(); | ||
377 | } | ||
342 | 378 | ||
343 | BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) != | 379 | BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) != |
344 | (unsigned long)VSYSCALL_ADDR); | 380 | (unsigned long)VSYSCALL_ADDR); |
diff --git a/arch/x86/include/asm/cpu_entry_area.h b/arch/x86/include/asm/cpu_entry_area.h new file mode 100644 index 000000000000..2fbc69a0916e --- /dev/null +++ b/arch/x86/include/asm/cpu_entry_area.h | |||
@@ -0,0 +1,68 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | #ifndef _ASM_X86_CPU_ENTRY_AREA_H | ||
4 | #define _ASM_X86_CPU_ENTRY_AREA_H | ||
5 | |||
6 | #include <linux/percpu-defs.h> | ||
7 | #include <asm/processor.h> | ||
8 | |||
9 | /* | ||
10 | * cpu_entry_area is a percpu region that contains things needed by the CPU | ||
11 | * and early entry/exit code. Real types aren't used for all fields here | ||
12 | * to avoid circular header dependencies. | ||
13 | * | ||
14 | * Every field is a virtual alias of some other allocated backing store. | ||
15 | * There is no direct allocation of a struct cpu_entry_area. | ||
16 | */ | ||
17 | struct cpu_entry_area { | ||
18 | char gdt[PAGE_SIZE]; | ||
19 | |||
20 | /* | ||
21 | * The GDT is just below entry_stack and thus serves (on x86_64) as | ||
22 | * a a read-only guard page. | ||
23 | */ | ||
24 | struct entry_stack_page entry_stack_page; | ||
25 | |||
26 | /* | ||
27 | * On x86_64, the TSS is mapped RO. On x86_32, it's mapped RW because | ||
28 | * we need task switches to work, and task switches write to the TSS. | ||
29 | */ | ||
30 | struct tss_struct tss; | ||
31 | |||
32 | char entry_trampoline[PAGE_SIZE]; | ||
33 | |||
34 | #ifdef CONFIG_X86_64 | ||
35 | /* | ||
36 | * Exception stacks used for IST entries. | ||
37 | * | ||
38 | * In the future, this should have a separate slot for each stack | ||
39 | * with guard pages between them. | ||
40 | */ | ||
41 | char exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]; | ||
42 | #endif | ||
43 | }; | ||
44 | |||
45 | #define CPU_ENTRY_AREA_SIZE (sizeof(struct cpu_entry_area)) | ||
46 | #define CPU_ENTRY_AREA_TOT_SIZE (CPU_ENTRY_AREA_SIZE * NR_CPUS) | ||
47 | |||
48 | DECLARE_PER_CPU(struct cpu_entry_area *, cpu_entry_area); | ||
49 | |||
50 | extern void setup_cpu_entry_areas(void); | ||
51 | extern void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags); | ||
52 | |||
53 | #define CPU_ENTRY_AREA_RO_IDT CPU_ENTRY_AREA_BASE | ||
54 | #define CPU_ENTRY_AREA_PER_CPU (CPU_ENTRY_AREA_RO_IDT + PAGE_SIZE) | ||
55 | |||
56 | #define CPU_ENTRY_AREA_RO_IDT_VADDR ((void *)CPU_ENTRY_AREA_RO_IDT) | ||
57 | |||
58 | #define CPU_ENTRY_AREA_MAP_SIZE \ | ||
59 | (CPU_ENTRY_AREA_PER_CPU + CPU_ENTRY_AREA_TOT_SIZE - CPU_ENTRY_AREA_BASE) | ||
60 | |||
61 | extern struct cpu_entry_area *get_cpu_entry_area(int cpu); | ||
62 | |||
63 | static inline struct entry_stack *cpu_entry_stack(int cpu) | ||
64 | { | ||
65 | return &get_cpu_entry_area(cpu)->entry_stack_page.stack; | ||
66 | } | ||
67 | |||
68 | #endif | ||
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index aab4fe9f49f8..ec8be07c0cda 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <asm/mmu.h> | 7 | #include <asm/mmu.h> |
8 | #include <asm/fixmap.h> | 8 | #include <asm/fixmap.h> |
9 | #include <asm/irq_vectors.h> | 9 | #include <asm/irq_vectors.h> |
10 | #include <asm/cpu_entry_area.h> | ||
10 | 11 | ||
11 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
12 | #include <linux/percpu.h> | 13 | #include <linux/percpu.h> |
diff --git a/arch/x86/include/asm/espfix.h b/arch/x86/include/asm/espfix.h index 0211029076ea..6777480d8a42 100644 --- a/arch/x86/include/asm/espfix.h +++ b/arch/x86/include/asm/espfix.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #ifndef _ASM_X86_ESPFIX_H | 2 | #ifndef _ASM_X86_ESPFIX_H |
3 | #define _ASM_X86_ESPFIX_H | 3 | #define _ASM_X86_ESPFIX_H |
4 | 4 | ||
5 | #ifdef CONFIG_X86_64 | 5 | #ifdef CONFIG_X86_ESPFIX64 |
6 | 6 | ||
7 | #include <asm/percpu.h> | 7 | #include <asm/percpu.h> |
8 | 8 | ||
@@ -11,7 +11,8 @@ DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr); | |||
11 | 11 | ||
12 | extern void init_espfix_bsp(void); | 12 | extern void init_espfix_bsp(void); |
13 | extern void init_espfix_ap(int cpu); | 13 | extern void init_espfix_ap(int cpu); |
14 | 14 | #else | |
15 | #endif /* CONFIG_X86_64 */ | 15 | static inline void init_espfix_ap(int cpu) { } |
16 | #endif | ||
16 | 17 | ||
17 | #endif /* _ASM_X86_ESPFIX_H */ | 18 | #endif /* _ASM_X86_ESPFIX_H */ |
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 94fc4fa14127..64c4a30e0d39 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h | |||
@@ -45,46 +45,6 @@ extern unsigned long __FIXADDR_TOP; | |||
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * cpu_entry_area is a percpu region in the fixmap that contains things | ||
49 | * needed by the CPU and early entry/exit code. Real types aren't used | ||
50 | * for all fields here to avoid circular header dependencies. | ||
51 | * | ||
52 | * Every field is a virtual alias of some other allocated backing store. | ||
53 | * There is no direct allocation of a struct cpu_entry_area. | ||
54 | */ | ||
55 | struct cpu_entry_area { | ||
56 | char gdt[PAGE_SIZE]; | ||
57 | |||
58 | /* | ||
59 | * The GDT is just below SYSENTER_stack and thus serves (on x86_64) as | ||
60 | * a a read-only guard page. | ||
61 | */ | ||
62 | struct SYSENTER_stack_page SYSENTER_stack_page; | ||
63 | |||
64 | /* | ||
65 | * On x86_64, the TSS is mapped RO. On x86_32, it's mapped RW because | ||
66 | * we need task switches to work, and task switches write to the TSS. | ||
67 | */ | ||
68 | struct tss_struct tss; | ||
69 | |||
70 | char entry_trampoline[PAGE_SIZE]; | ||
71 | |||
72 | #ifdef CONFIG_X86_64 | ||
73 | /* | ||
74 | * Exception stacks used for IST entries. | ||
75 | * | ||
76 | * In the future, this should have a separate slot for each stack | ||
77 | * with guard pages between them. | ||
78 | */ | ||
79 | char exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]; | ||
80 | #endif | ||
81 | }; | ||
82 | |||
83 | #define CPU_ENTRY_AREA_PAGES (sizeof(struct cpu_entry_area) / PAGE_SIZE) | ||
84 | |||
85 | extern void setup_cpu_entry_areas(void); | ||
86 | |||
87 | /* | ||
88 | * Here we define all the compile-time 'special' virtual | 48 | * Here we define all the compile-time 'special' virtual |
89 | * addresses. The point is to have a constant address at | 49 | * addresses. The point is to have a constant address at |
90 | * compile time, but to set the physical address only | 50 | * compile time, but to set the physical address only |
@@ -123,7 +83,6 @@ enum fixed_addresses { | |||
123 | FIX_IO_APIC_BASE_0, | 83 | FIX_IO_APIC_BASE_0, |
124 | FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, | 84 | FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, |
125 | #endif | 85 | #endif |
126 | FIX_RO_IDT, /* Virtual mapping for read-only IDT */ | ||
127 | #ifdef CONFIG_X86_32 | 86 | #ifdef CONFIG_X86_32 |
128 | FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ | 87 | FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ |
129 | FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, | 88 | FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, |
@@ -139,9 +98,6 @@ enum fixed_addresses { | |||
139 | #ifdef CONFIG_X86_INTEL_MID | 98 | #ifdef CONFIG_X86_INTEL_MID |
140 | FIX_LNW_VRTC, | 99 | FIX_LNW_VRTC, |
141 | #endif | 100 | #endif |
142 | /* Fixmap entries to remap the GDTs, one per processor. */ | ||
143 | FIX_CPU_ENTRY_AREA_TOP, | ||
144 | FIX_CPU_ENTRY_AREA_BOTTOM = FIX_CPU_ENTRY_AREA_TOP + (CPU_ENTRY_AREA_PAGES * NR_CPUS) - 1, | ||
145 | 101 | ||
146 | #ifdef CONFIG_ACPI_APEI_GHES | 102 | #ifdef CONFIG_ACPI_APEI_GHES |
147 | /* Used for GHES mapping from assorted contexts */ | 103 | /* Used for GHES mapping from assorted contexts */ |
@@ -182,7 +138,7 @@ enum fixed_addresses { | |||
182 | extern void reserve_top_address(unsigned long reserve); | 138 | extern void reserve_top_address(unsigned long reserve); |
183 | 139 | ||
184 | #define FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) | 140 | #define FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) |
185 | #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) | 141 | #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) |
186 | 142 | ||
187 | extern int fixmaps_set; | 143 | extern int fixmaps_set; |
188 | 144 | ||
@@ -230,30 +186,5 @@ void __init *early_memremap_decrypted_wp(resource_size_t phys_addr, | |||
230 | void __early_set_fixmap(enum fixed_addresses idx, | 186 | void __early_set_fixmap(enum fixed_addresses idx, |
231 | phys_addr_t phys, pgprot_t flags); | 187 | phys_addr_t phys, pgprot_t flags); |
232 | 188 | ||
233 | static inline unsigned int __get_cpu_entry_area_page_index(int cpu, int page) | ||
234 | { | ||
235 | BUILD_BUG_ON(sizeof(struct cpu_entry_area) % PAGE_SIZE != 0); | ||
236 | |||
237 | return FIX_CPU_ENTRY_AREA_BOTTOM - cpu*CPU_ENTRY_AREA_PAGES - page; | ||
238 | } | ||
239 | |||
240 | #define __get_cpu_entry_area_offset_index(cpu, offset) ({ \ | ||
241 | BUILD_BUG_ON(offset % PAGE_SIZE != 0); \ | ||
242 | __get_cpu_entry_area_page_index(cpu, offset / PAGE_SIZE); \ | ||
243 | }) | ||
244 | |||
245 | #define get_cpu_entry_area_index(cpu, field) \ | ||
246 | __get_cpu_entry_area_offset_index((cpu), offsetof(struct cpu_entry_area, field)) | ||
247 | |||
248 | static inline struct cpu_entry_area *get_cpu_entry_area(int cpu) | ||
249 | { | ||
250 | return (struct cpu_entry_area *)__fix_to_virt(__get_cpu_entry_area_page_index(cpu, 0)); | ||
251 | } | ||
252 | |||
253 | static inline struct SYSENTER_stack *cpu_SYSENTER_stack(int cpu) | ||
254 | { | ||
255 | return &get_cpu_entry_area(cpu)->SYSENTER_stack_page.stack; | ||
256 | } | ||
257 | |||
258 | #endif /* !__ASSEMBLY__ */ | 189 | #endif /* !__ASSEMBLY__ */ |
259 | #endif /* _ASM_X86_FIXMAP_H */ | 190 | #endif /* _ASM_X86_FIXMAP_H */ |
diff --git a/arch/x86/include/asm/invpcid.h b/arch/x86/include/asm/invpcid.h new file mode 100644 index 000000000000..989cfa86de85 --- /dev/null +++ b/arch/x86/include/asm/invpcid.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #ifndef _ASM_X86_INVPCID | ||
3 | #define _ASM_X86_INVPCID | ||
4 | |||
5 | static inline void __invpcid(unsigned long pcid, unsigned long addr, | ||
6 | unsigned long type) | ||
7 | { | ||
8 | struct { u64 d[2]; } desc = { { pcid, addr } }; | ||
9 | |||
10 | /* | ||
11 | * The memory clobber is because the whole point is to invalidate | ||
12 | * stale TLB entries and, especially if we're flushing global | ||
13 | * mappings, we don't want the compiler to reorder any subsequent | ||
14 | * memory accesses before the TLB flush. | ||
15 | * | ||
16 | * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and | ||
17 | * invpcid (%rcx), %rax in long mode. | ||
18 | */ | ||
19 | asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" | ||
20 | : : "m" (desc), "a" (type), "c" (&desc) : "memory"); | ||
21 | } | ||
22 | |||
23 | #define INVPCID_TYPE_INDIV_ADDR 0 | ||
24 | #define INVPCID_TYPE_SINGLE_CTXT 1 | ||
25 | #define INVPCID_TYPE_ALL_INCL_GLOBAL 2 | ||
26 | #define INVPCID_TYPE_ALL_NON_GLOBAL 3 | ||
27 | |||
28 | /* Flush all mappings for a given pcid and addr, not including globals. */ | ||
29 | static inline void invpcid_flush_one(unsigned long pcid, | ||
30 | unsigned long addr) | ||
31 | { | ||
32 | __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); | ||
33 | } | ||
34 | |||
35 | /* Flush all mappings for a given PCID, not including globals. */ | ||
36 | static inline void invpcid_flush_single_context(unsigned long pcid) | ||
37 | { | ||
38 | __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); | ||
39 | } | ||
40 | |||
41 | /* Flush all mappings, including globals, for all PCIDs. */ | ||
42 | static inline void invpcid_flush_all(void) | ||
43 | { | ||
44 | __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); | ||
45 | } | ||
46 | |||
47 | /* Flush all mappings for all PCIDs except globals. */ | ||
48 | static inline void invpcid_flush_all_nonglobals(void) | ||
49 | { | ||
50 | __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); | ||
51 | } | ||
52 | |||
53 | #endif /* _ASM_X86_INVPCID */ | ||
diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 9ea26f167497..5ff3e8af2c20 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h | |||
@@ -3,6 +3,7 @@ | |||
3 | #define _ASM_X86_MMU_H | 3 | #define _ASM_X86_MMU_H |
4 | 4 | ||
5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
6 | #include <linux/rwsem.h> | ||
6 | #include <linux/mutex.h> | 7 | #include <linux/mutex.h> |
7 | #include <linux/atomic.h> | 8 | #include <linux/atomic.h> |
8 | 9 | ||
@@ -27,7 +28,8 @@ typedef struct { | |||
27 | atomic64_t tlb_gen; | 28 | atomic64_t tlb_gen; |
28 | 29 | ||
29 | #ifdef CONFIG_MODIFY_LDT_SYSCALL | 30 | #ifdef CONFIG_MODIFY_LDT_SYSCALL |
30 | struct ldt_struct *ldt; | 31 | struct rw_semaphore ldt_usr_sem; |
32 | struct ldt_struct *ldt; | ||
31 | #endif | 33 | #endif |
32 | 34 | ||
33 | #ifdef CONFIG_X86_64 | 35 | #ifdef CONFIG_X86_64 |
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 6d16d15d09a0..5ede7cae1d67 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h | |||
@@ -57,11 +57,17 @@ struct ldt_struct { | |||
57 | /* | 57 | /* |
58 | * Used for LDT copy/destruction. | 58 | * Used for LDT copy/destruction. |
59 | */ | 59 | */ |
60 | int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm); | 60 | static inline void init_new_context_ldt(struct mm_struct *mm) |
61 | { | ||
62 | mm->context.ldt = NULL; | ||
63 | init_rwsem(&mm->context.ldt_usr_sem); | ||
64 | } | ||
65 | int ldt_dup_context(struct mm_struct *oldmm, struct mm_struct *mm); | ||
61 | void destroy_context_ldt(struct mm_struct *mm); | 66 | void destroy_context_ldt(struct mm_struct *mm); |
62 | #else /* CONFIG_MODIFY_LDT_SYSCALL */ | 67 | #else /* CONFIG_MODIFY_LDT_SYSCALL */ |
63 | static inline int init_new_context_ldt(struct task_struct *tsk, | 68 | static inline void init_new_context_ldt(struct mm_struct *mm) { } |
64 | struct mm_struct *mm) | 69 | static inline int ldt_dup_context(struct mm_struct *oldmm, |
70 | struct mm_struct *mm) | ||
65 | { | 71 | { |
66 | return 0; | 72 | return 0; |
67 | } | 73 | } |
@@ -132,18 +138,21 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk); | |||
132 | static inline int init_new_context(struct task_struct *tsk, | 138 | static inline int init_new_context(struct task_struct *tsk, |
133 | struct mm_struct *mm) | 139 | struct mm_struct *mm) |
134 | { | 140 | { |
141 | mutex_init(&mm->context.lock); | ||
142 | |||
135 | mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); | 143 | mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); |
136 | atomic64_set(&mm->context.tlb_gen, 0); | 144 | atomic64_set(&mm->context.tlb_gen, 0); |
137 | 145 | ||
138 | #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS | 146 | #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS |
139 | if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { | 147 | if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { |
140 | /* pkey 0 is the default and always allocated */ | 148 | /* pkey 0 is the default and always allocated */ |
141 | mm->context.pkey_allocation_map = 0x1; | 149 | mm->context.pkey_allocation_map = 0x1; |
142 | /* -1 means unallocated or invalid */ | 150 | /* -1 means unallocated or invalid */ |
143 | mm->context.execute_only_pkey = -1; | 151 | mm->context.execute_only_pkey = -1; |
144 | } | 152 | } |
145 | #endif | 153 | #endif |
146 | return init_new_context_ldt(tsk, mm); | 154 | init_new_context_ldt(mm); |
155 | return 0; | ||
147 | } | 156 | } |
148 | static inline void destroy_context(struct mm_struct *mm) | 157 | static inline void destroy_context(struct mm_struct *mm) |
149 | { | 158 | { |
@@ -176,10 +185,10 @@ do { \ | |||
176 | } while (0) | 185 | } while (0) |
177 | #endif | 186 | #endif |
178 | 187 | ||
179 | static inline void arch_dup_mmap(struct mm_struct *oldmm, | 188 | static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) |
180 | struct mm_struct *mm) | ||
181 | { | 189 | { |
182 | paravirt_arch_dup_mmap(oldmm, mm); | 190 | paravirt_arch_dup_mmap(oldmm, mm); |
191 | return ldt_dup_context(oldmm, mm); | ||
183 | } | 192 | } |
184 | 193 | ||
185 | static inline void arch_exit_mmap(struct mm_struct *mm) | 194 | static inline void arch_exit_mmap(struct mm_struct *mm) |
@@ -282,33 +291,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, | |||
282 | } | 291 | } |
283 | 292 | ||
284 | /* | 293 | /* |
285 | * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID | ||
286 | * bits. This serves two purposes. It prevents a nasty situation in | ||
287 | * which PCID-unaware code saves CR3, loads some other value (with PCID | ||
288 | * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if | ||
289 | * the saved ASID was nonzero. It also means that any bugs involving | ||
290 | * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger | ||
291 | * deterministically. | ||
292 | */ | ||
293 | |||
294 | static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid) | ||
295 | { | ||
296 | if (static_cpu_has(X86_FEATURE_PCID)) { | ||
297 | VM_WARN_ON_ONCE(asid > 4094); | ||
298 | return __sme_pa(mm->pgd) | (asid + 1); | ||
299 | } else { | ||
300 | VM_WARN_ON_ONCE(asid != 0); | ||
301 | return __sme_pa(mm->pgd); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) | ||
306 | { | ||
307 | VM_WARN_ON_ONCE(asid > 4094); | ||
308 | return __sme_pa(mm->pgd) | (asid + 1) | CR3_NOFLUSH; | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | * This can be used from process context to figure out what the value of | 294 | * This can be used from process context to figure out what the value of |
313 | * CR3 is without needing to do a (slow) __read_cr3(). | 295 | * CR3 is without needing to do a (slow) __read_cr3(). |
314 | * | 296 | * |
@@ -317,7 +299,7 @@ static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) | |||
317 | */ | 299 | */ |
318 | static inline unsigned long __get_current_cr3_fast(void) | 300 | static inline unsigned long __get_current_cr3_fast(void) |
319 | { | 301 | { |
320 | unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm), | 302 | unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd, |
321 | this_cpu_read(cpu_tlbstate.loaded_mm_asid)); | 303 | this_cpu_read(cpu_tlbstate.loaded_mm_asid)); |
322 | 304 | ||
323 | /* For now, be very restrictive about when this can be called. */ | 305 | /* For now, be very restrictive about when this can be called. */ |
diff --git a/arch/x86/include/asm/pgtable_32_types.h b/arch/x86/include/asm/pgtable_32_types.h index f2ca9b28fd68..ce245b0cdfca 100644 --- a/arch/x86/include/asm/pgtable_32_types.h +++ b/arch/x86/include/asm/pgtable_32_types.h | |||
@@ -38,13 +38,22 @@ extern bool __vmalloc_start_set; /* set once high_memory is set */ | |||
38 | #define LAST_PKMAP 1024 | 38 | #define LAST_PKMAP 1024 |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE * (LAST_PKMAP + 1)) \ | 41 | /* |
42 | & PMD_MASK) | 42 | * Define this here and validate with BUILD_BUG_ON() in pgtable_32.c |
43 | * to avoid include recursion hell | ||
44 | */ | ||
45 | #define CPU_ENTRY_AREA_PAGES (NR_CPUS * 40) | ||
46 | |||
47 | #define CPU_ENTRY_AREA_BASE \ | ||
48 | ((FIXADDR_START - PAGE_SIZE * (CPU_ENTRY_AREA_PAGES + 1)) & PMD_MASK) | ||
49 | |||
50 | #define PKMAP_BASE \ | ||
51 | ((CPU_ENTRY_AREA_BASE - PAGE_SIZE) & PMD_MASK) | ||
43 | 52 | ||
44 | #ifdef CONFIG_HIGHMEM | 53 | #ifdef CONFIG_HIGHMEM |
45 | # define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE) | 54 | # define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE) |
46 | #else | 55 | #else |
47 | # define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE) | 56 | # define VMALLOC_END (CPU_ENTRY_AREA_BASE - 2 * PAGE_SIZE) |
48 | #endif | 57 | #endif |
49 | 58 | ||
50 | #define MODULES_VADDR VMALLOC_START | 59 | #define MODULES_VADDR VMALLOC_START |
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index 6d5f45dcd4a1..3d27831bc58d 100644 --- a/arch/x86/include/asm/pgtable_64_types.h +++ b/arch/x86/include/asm/pgtable_64_types.h | |||
@@ -76,32 +76,41 @@ typedef struct { pteval_t pte; } pte_t; | |||
76 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) | 76 | #define PGDIR_MASK (~(PGDIR_SIZE - 1)) |
77 | 77 | ||
78 | /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */ | 78 | /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */ |
79 | #define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL) | 79 | #define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL) |
80 | |||
80 | #ifdef CONFIG_X86_5LEVEL | 81 | #ifdef CONFIG_X86_5LEVEL |
81 | #define VMALLOC_SIZE_TB _AC(16384, UL) | 82 | # define VMALLOC_SIZE_TB _AC(16384, UL) |
82 | #define __VMALLOC_BASE _AC(0xff92000000000000, UL) | 83 | # define __VMALLOC_BASE _AC(0xff92000000000000, UL) |
83 | #define __VMEMMAP_BASE _AC(0xffd4000000000000, UL) | 84 | # define __VMEMMAP_BASE _AC(0xffd4000000000000, UL) |
84 | #else | 85 | #else |
85 | #define VMALLOC_SIZE_TB _AC(32, UL) | 86 | # define VMALLOC_SIZE_TB _AC(32, UL) |
86 | #define __VMALLOC_BASE _AC(0xffffc90000000000, UL) | 87 | # define __VMALLOC_BASE _AC(0xffffc90000000000, UL) |
87 | #define __VMEMMAP_BASE _AC(0xffffea0000000000, UL) | 88 | # define __VMEMMAP_BASE _AC(0xffffea0000000000, UL) |
88 | #endif | 89 | #endif |
90 | |||
89 | #ifdef CONFIG_RANDOMIZE_MEMORY | 91 | #ifdef CONFIG_RANDOMIZE_MEMORY |
90 | #define VMALLOC_START vmalloc_base | 92 | # define VMALLOC_START vmalloc_base |
91 | #define VMEMMAP_START vmemmap_base | 93 | # define VMEMMAP_START vmemmap_base |
92 | #else | 94 | #else |
93 | #define VMALLOC_START __VMALLOC_BASE | 95 | # define VMALLOC_START __VMALLOC_BASE |
94 | #define VMEMMAP_START __VMEMMAP_BASE | 96 | # define VMEMMAP_START __VMEMMAP_BASE |
95 | #endif /* CONFIG_RANDOMIZE_MEMORY */ | 97 | #endif /* CONFIG_RANDOMIZE_MEMORY */ |
96 | #define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL)) | 98 | |
97 | #define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE) | 99 | #define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL)) |
100 | |||
101 | #define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE) | ||
98 | /* The module sections ends with the start of the fixmap */ | 102 | /* The module sections ends with the start of the fixmap */ |
99 | #define MODULES_END __fix_to_virt(__end_of_fixed_addresses + 1) | 103 | #define MODULES_END __fix_to_virt(__end_of_fixed_addresses + 1) |
100 | #define MODULES_LEN (MODULES_END - MODULES_VADDR) | 104 | #define MODULES_LEN (MODULES_END - MODULES_VADDR) |
101 | #define ESPFIX_PGD_ENTRY _AC(-2, UL) | 105 | |
102 | #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << P4D_SHIFT) | 106 | #define ESPFIX_PGD_ENTRY _AC(-2, UL) |
103 | #define EFI_VA_START ( -4 * (_AC(1, UL) << 30)) | 107 | #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << P4D_SHIFT) |
104 | #define EFI_VA_END (-68 * (_AC(1, UL) << 30)) | 108 | |
109 | #define CPU_ENTRY_AREA_PGD _AC(-3, UL) | ||
110 | #define CPU_ENTRY_AREA_BASE (CPU_ENTRY_AREA_PGD << P4D_SHIFT) | ||
111 | |||
112 | #define EFI_VA_START ( -4 * (_AC(1, UL) << 30)) | ||
113 | #define EFI_VA_END (-68 * (_AC(1, UL) << 30)) | ||
105 | 114 | ||
106 | #define EARLY_DYNAMIC_PAGE_TABLES 64 | 115 | #define EARLY_DYNAMIC_PAGE_TABLES 64 |
107 | 116 | ||
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 1f2434ee9f80..cad8dab266bc 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -337,12 +337,12 @@ struct x86_hw_tss { | |||
337 | #define IO_BITMAP_OFFSET (offsetof(struct tss_struct, io_bitmap) - offsetof(struct tss_struct, x86_tss)) | 337 | #define IO_BITMAP_OFFSET (offsetof(struct tss_struct, io_bitmap) - offsetof(struct tss_struct, x86_tss)) |
338 | #define INVALID_IO_BITMAP_OFFSET 0x8000 | 338 | #define INVALID_IO_BITMAP_OFFSET 0x8000 |
339 | 339 | ||
340 | struct SYSENTER_stack { | 340 | struct entry_stack { |
341 | unsigned long words[64]; | 341 | unsigned long words[64]; |
342 | }; | 342 | }; |
343 | 343 | ||
344 | struct SYSENTER_stack_page { | 344 | struct entry_stack_page { |
345 | struct SYSENTER_stack stack; | 345 | struct entry_stack stack; |
346 | } __aligned(PAGE_SIZE); | 346 | } __aligned(PAGE_SIZE); |
347 | 347 | ||
348 | struct tss_struct { | 348 | struct tss_struct { |
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index f8062bfd43a0..f73706878772 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h | |||
@@ -16,7 +16,7 @@ enum stack_type { | |||
16 | STACK_TYPE_TASK, | 16 | STACK_TYPE_TASK, |
17 | STACK_TYPE_IRQ, | 17 | STACK_TYPE_IRQ, |
18 | STACK_TYPE_SOFTIRQ, | 18 | STACK_TYPE_SOFTIRQ, |
19 | STACK_TYPE_SYSENTER, | 19 | STACK_TYPE_ENTRY, |
20 | STACK_TYPE_EXCEPTION, | 20 | STACK_TYPE_EXCEPTION, |
21 | STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1, | 21 | STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1, |
22 | }; | 22 | }; |
@@ -29,7 +29,7 @@ struct stack_info { | |||
29 | bool in_task_stack(unsigned long *stack, struct task_struct *task, | 29 | bool in_task_stack(unsigned long *stack, struct task_struct *task, |
30 | struct stack_info *info); | 30 | struct stack_info *info); |
31 | 31 | ||
32 | bool in_sysenter_stack(unsigned long *stack, struct stack_info *info); | 32 | bool in_entry_stack(unsigned long *stack, struct stack_info *info); |
33 | 33 | ||
34 | int get_stack_info(unsigned long *stack, struct task_struct *task, | 34 | int get_stack_info(unsigned long *stack, struct task_struct *task, |
35 | struct stack_info *info, unsigned long *visit_mask); | 35 | struct stack_info *info, unsigned long *visit_mask); |
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 877b5c1a1b12..e1884cf35257 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
@@ -9,70 +9,66 @@ | |||
9 | #include <asm/cpufeature.h> | 9 | #include <asm/cpufeature.h> |
10 | #include <asm/special_insns.h> | 10 | #include <asm/special_insns.h> |
11 | #include <asm/smp.h> | 11 | #include <asm/smp.h> |
12 | #include <asm/invpcid.h> | ||
12 | 13 | ||
13 | static inline void __invpcid(unsigned long pcid, unsigned long addr, | 14 | static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) |
14 | unsigned long type) | ||
15 | { | 15 | { |
16 | struct { u64 d[2]; } desc = { { pcid, addr } }; | ||
17 | |||
18 | /* | 16 | /* |
19 | * The memory clobber is because the whole point is to invalidate | 17 | * Bump the generation count. This also serves as a full barrier |
20 | * stale TLB entries and, especially if we're flushing global | 18 | * that synchronizes with switch_mm(): callers are required to order |
21 | * mappings, we don't want the compiler to reorder any subsequent | 19 | * their read of mm_cpumask after their writes to the paging |
22 | * memory accesses before the TLB flush. | 20 | * structures. |
23 | * | ||
24 | * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and | ||
25 | * invpcid (%rcx), %rax in long mode. | ||
26 | */ | 21 | */ |
27 | asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01" | 22 | return atomic64_inc_return(&mm->context.tlb_gen); |
28 | : : "m" (desc), "a" (type), "c" (&desc) : "memory"); | ||
29 | } | 23 | } |
30 | 24 | ||
31 | #define INVPCID_TYPE_INDIV_ADDR 0 | 25 | /* There are 12 bits of space for ASIDS in CR3 */ |
32 | #define INVPCID_TYPE_SINGLE_CTXT 1 | 26 | #define CR3_HW_ASID_BITS 12 |
33 | #define INVPCID_TYPE_ALL_INCL_GLOBAL 2 | 27 | /* |
34 | #define INVPCID_TYPE_ALL_NON_GLOBAL 3 | 28 | * When enabled, PAGE_TABLE_ISOLATION consumes a single bit for |
29 | * user/kernel switches | ||
30 | */ | ||
31 | #define PTI_CONSUMED_ASID_BITS 0 | ||
35 | 32 | ||
36 | /* Flush all mappings for a given pcid and addr, not including globals. */ | 33 | #define CR3_AVAIL_ASID_BITS (CR3_HW_ASID_BITS - PTI_CONSUMED_ASID_BITS) |
37 | static inline void invpcid_flush_one(unsigned long pcid, | 34 | /* |
38 | unsigned long addr) | 35 | * ASIDs are zero-based: 0->MAX_AVAIL_ASID are valid. -1 below to account |
39 | { | 36 | * for them being zero-based. Another -1 is because ASID 0 is reserved for |
40 | __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); | 37 | * use by non-PCID-aware users. |
41 | } | 38 | */ |
39 | #define MAX_ASID_AVAILABLE ((1 << CR3_AVAIL_ASID_BITS) - 2) | ||
42 | 40 | ||
43 | /* Flush all mappings for a given PCID, not including globals. */ | 41 | static inline u16 kern_pcid(u16 asid) |
44 | static inline void invpcid_flush_single_context(unsigned long pcid) | ||
45 | { | 42 | { |
46 | __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); | 43 | VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE); |
44 | /* | ||
45 | * If PCID is on, ASID-aware code paths put the ASID+1 into the | ||
46 | * PCID bits. This serves two purposes. It prevents a nasty | ||
47 | * situation in which PCID-unaware code saves CR3, loads some other | ||
48 | * value (with PCID == 0), and then restores CR3, thus corrupting | ||
49 | * the TLB for ASID 0 if the saved ASID was nonzero. It also means | ||
50 | * that any bugs involving loading a PCID-enabled CR3 with | ||
51 | * CR4.PCIDE off will trigger deterministically. | ||
52 | */ | ||
53 | return asid + 1; | ||
47 | } | 54 | } |
48 | 55 | ||
49 | /* Flush all mappings, including globals, for all PCIDs. */ | 56 | struct pgd_t; |
50 | static inline void invpcid_flush_all(void) | 57 | static inline unsigned long build_cr3(pgd_t *pgd, u16 asid) |
51 | { | 58 | { |
52 | __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); | 59 | if (static_cpu_has(X86_FEATURE_PCID)) { |
60 | return __sme_pa(pgd) | kern_pcid(asid); | ||
61 | } else { | ||
62 | VM_WARN_ON_ONCE(asid != 0); | ||
63 | return __sme_pa(pgd); | ||
64 | } | ||
53 | } | 65 | } |
54 | 66 | ||
55 | /* Flush all mappings for all PCIDs except globals. */ | 67 | static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid) |
56 | static inline void invpcid_flush_all_nonglobals(void) | ||
57 | { | 68 | { |
58 | __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); | 69 | VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE); |
59 | } | 70 | VM_WARN_ON_ONCE(!this_cpu_has(X86_FEATURE_PCID)); |
60 | 71 | return __sme_pa(pgd) | kern_pcid(asid) | CR3_NOFLUSH; | |
61 | static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) | ||
62 | { | ||
63 | u64 new_tlb_gen; | ||
64 | |||
65 | /* | ||
66 | * Bump the generation count. This also serves as a full barrier | ||
67 | * that synchronizes with switch_mm(): callers are required to order | ||
68 | * their read of mm_cpumask after their writes to the paging | ||
69 | * structures. | ||
70 | */ | ||
71 | smp_mb__before_atomic(); | ||
72 | new_tlb_gen = atomic64_inc_return(&mm->context.tlb_gen); | ||
73 | smp_mb__after_atomic(); | ||
74 | |||
75 | return new_tlb_gen; | ||
76 | } | 72 | } |
77 | 73 | ||
78 | #ifdef CONFIG_PARAVIRT | 74 | #ifdef CONFIG_PARAVIRT |
@@ -237,6 +233,9 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask) | |||
237 | 233 | ||
238 | extern void initialize_tlbstate_and_flush(void); | 234 | extern void initialize_tlbstate_and_flush(void); |
239 | 235 | ||
236 | /* | ||
237 | * flush the entire current user mapping | ||
238 | */ | ||
240 | static inline void __native_flush_tlb(void) | 239 | static inline void __native_flush_tlb(void) |
241 | { | 240 | { |
242 | /* | 241 | /* |
@@ -249,20 +248,12 @@ static inline void __native_flush_tlb(void) | |||
249 | preempt_enable(); | 248 | preempt_enable(); |
250 | } | 249 | } |
251 | 250 | ||
252 | static inline void __native_flush_tlb_global_irq_disabled(void) | 251 | /* |
253 | { | 252 | * flush everything |
254 | unsigned long cr4; | 253 | */ |
255 | |||
256 | cr4 = this_cpu_read(cpu_tlbstate.cr4); | ||
257 | /* clear PGE */ | ||
258 | native_write_cr4(cr4 & ~X86_CR4_PGE); | ||
259 | /* write old PGE again and flush TLBs */ | ||
260 | native_write_cr4(cr4); | ||
261 | } | ||
262 | |||
263 | static inline void __native_flush_tlb_global(void) | 254 | static inline void __native_flush_tlb_global(void) |
264 | { | 255 | { |
265 | unsigned long flags; | 256 | unsigned long cr4, flags; |
266 | 257 | ||
267 | if (static_cpu_has(X86_FEATURE_INVPCID)) { | 258 | if (static_cpu_has(X86_FEATURE_INVPCID)) { |
268 | /* | 259 | /* |
@@ -280,22 +271,36 @@ static inline void __native_flush_tlb_global(void) | |||
280 | */ | 271 | */ |
281 | raw_local_irq_save(flags); | 272 | raw_local_irq_save(flags); |
282 | 273 | ||
283 | __native_flush_tlb_global_irq_disabled(); | 274 | cr4 = this_cpu_read(cpu_tlbstate.cr4); |
275 | /* toggle PGE */ | ||
276 | native_write_cr4(cr4 ^ X86_CR4_PGE); | ||
277 | /* write old PGE again and flush TLBs */ | ||
278 | native_write_cr4(cr4); | ||
284 | 279 | ||
285 | raw_local_irq_restore(flags); | 280 | raw_local_irq_restore(flags); |
286 | } | 281 | } |
287 | 282 | ||
283 | /* | ||
284 | * flush one page in the user mapping | ||
285 | */ | ||
288 | static inline void __native_flush_tlb_single(unsigned long addr) | 286 | static inline void __native_flush_tlb_single(unsigned long addr) |
289 | { | 287 | { |
290 | asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); | 288 | asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); |
291 | } | 289 | } |
292 | 290 | ||
291 | /* | ||
292 | * flush everything | ||
293 | */ | ||
293 | static inline void __flush_tlb_all(void) | 294 | static inline void __flush_tlb_all(void) |
294 | { | 295 | { |
295 | if (boot_cpu_has(X86_FEATURE_PGE)) | 296 | if (boot_cpu_has(X86_FEATURE_PGE)) { |
296 | __flush_tlb_global(); | 297 | __flush_tlb_global(); |
297 | else | 298 | } else { |
299 | /* | ||
300 | * !PGE -> !PCID (setup_pcid()), thus every flush is total. | ||
301 | */ | ||
298 | __flush_tlb(); | 302 | __flush_tlb(); |
303 | } | ||
299 | 304 | ||
300 | /* | 305 | /* |
301 | * Note: if we somehow had PCID but not PGE, then this wouldn't work -- | 306 | * Note: if we somehow had PCID but not PGE, then this wouldn't work -- |
@@ -306,6 +311,9 @@ static inline void __flush_tlb_all(void) | |||
306 | */ | 311 | */ |
307 | } | 312 | } |
308 | 313 | ||
314 | /* | ||
315 | * flush one page in the kernel mapping | ||
316 | */ | ||
309 | static inline void __flush_tlb_one(unsigned long addr) | 317 | static inline void __flush_tlb_one(unsigned long addr) |
310 | { | 318 | { |
311 | count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE); | 319 | count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE); |
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index cd360a5e0dca..676b7cf4b62b 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c | |||
@@ -97,6 +97,6 @@ void common(void) { | |||
97 | /* Layout info for cpu_entry_area */ | 97 | /* Layout info for cpu_entry_area */ |
98 | OFFSET(CPU_ENTRY_AREA_tss, cpu_entry_area, tss); | 98 | OFFSET(CPU_ENTRY_AREA_tss, cpu_entry_area, tss); |
99 | OFFSET(CPU_ENTRY_AREA_entry_trampoline, cpu_entry_area, entry_trampoline); | 99 | OFFSET(CPU_ENTRY_AREA_entry_trampoline, cpu_entry_area, entry_trampoline); |
100 | OFFSET(CPU_ENTRY_AREA_SYSENTER_stack, cpu_entry_area, SYSENTER_stack_page); | 100 | OFFSET(CPU_ENTRY_AREA_entry_stack, cpu_entry_area, entry_stack_page); |
101 | DEFINE(SIZEOF_SYSENTER_stack, sizeof(struct SYSENTER_stack)); | 101 | DEFINE(SIZEOF_entry_stack, sizeof(struct entry_stack)); |
102 | } | 102 | } |
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index 7d20d9c0b3d6..fa1261eefa16 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c | |||
@@ -48,7 +48,7 @@ void foo(void) | |||
48 | 48 | ||
49 | /* Offset from the sysenter stack to tss.sp0 */ | 49 | /* Offset from the sysenter stack to tss.sp0 */ |
50 | DEFINE(TSS_sysenter_sp0, offsetof(struct cpu_entry_area, tss.x86_tss.sp0) - | 50 | DEFINE(TSS_sysenter_sp0, offsetof(struct cpu_entry_area, tss.x86_tss.sp0) - |
51 | offsetofend(struct cpu_entry_area, SYSENTER_stack_page.stack)); | 51 | offsetofend(struct cpu_entry_area, entry_stack_page.stack)); |
52 | 52 | ||
53 | #ifdef CONFIG_CC_STACKPROTECTOR | 53 | #ifdef CONFIG_CC_STACKPROTECTOR |
54 | BLANK(); | 54 | BLANK(); |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 7416da3ec4df..c9757f07d738 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -506,102 +506,8 @@ static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { | |||
506 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, | 506 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, |
507 | [DEBUG_STACK - 1] = DEBUG_STKSZ | 507 | [DEBUG_STACK - 1] = DEBUG_STKSZ |
508 | }; | 508 | }; |
509 | |||
510 | static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks | ||
511 | [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); | ||
512 | #endif | ||
513 | |||
514 | static DEFINE_PER_CPU_PAGE_ALIGNED(struct SYSENTER_stack_page, | ||
515 | SYSENTER_stack_storage); | ||
516 | |||
517 | static void __init | ||
518 | set_percpu_fixmap_pages(int idx, void *ptr, int pages, pgprot_t prot) | ||
519 | { | ||
520 | for ( ; pages; pages--, idx--, ptr += PAGE_SIZE) | ||
521 | __set_fixmap(idx, per_cpu_ptr_to_phys(ptr), prot); | ||
522 | } | ||
523 | |||
524 | /* Setup the fixmap mappings only once per-processor */ | ||
525 | static void __init setup_cpu_entry_area(int cpu) | ||
526 | { | ||
527 | #ifdef CONFIG_X86_64 | ||
528 | extern char _entry_trampoline[]; | ||
529 | |||
530 | /* On 64-bit systems, we use a read-only fixmap GDT and TSS. */ | ||
531 | pgprot_t gdt_prot = PAGE_KERNEL_RO; | ||
532 | pgprot_t tss_prot = PAGE_KERNEL_RO; | ||
533 | #else | ||
534 | /* | ||
535 | * On native 32-bit systems, the GDT cannot be read-only because | ||
536 | * our double fault handler uses a task gate, and entering through | ||
537 | * a task gate needs to change an available TSS to busy. If the | ||
538 | * GDT is read-only, that will triple fault. The TSS cannot be | ||
539 | * read-only because the CPU writes to it on task switches. | ||
540 | * | ||
541 | * On Xen PV, the GDT must be read-only because the hypervisor | ||
542 | * requires it. | ||
543 | */ | ||
544 | pgprot_t gdt_prot = boot_cpu_has(X86_FEATURE_XENPV) ? | ||
545 | PAGE_KERNEL_RO : PAGE_KERNEL; | ||
546 | pgprot_t tss_prot = PAGE_KERNEL; | ||
547 | #endif | ||
548 | |||
549 | __set_fixmap(get_cpu_entry_area_index(cpu, gdt), get_cpu_gdt_paddr(cpu), gdt_prot); | ||
550 | set_percpu_fixmap_pages(get_cpu_entry_area_index(cpu, SYSENTER_stack_page), | ||
551 | per_cpu_ptr(&SYSENTER_stack_storage, cpu), 1, | ||
552 | PAGE_KERNEL); | ||
553 | |||
554 | /* | ||
555 | * The Intel SDM says (Volume 3, 7.2.1): | ||
556 | * | ||
557 | * Avoid placing a page boundary in the part of the TSS that the | ||
558 | * processor reads during a task switch (the first 104 bytes). The | ||
559 | * processor may not correctly perform address translations if a | ||
560 | * boundary occurs in this area. During a task switch, the processor | ||
561 | * reads and writes into the first 104 bytes of each TSS (using | ||
562 | * contiguous physical addresses beginning with the physical address | ||
563 | * of the first byte of the TSS). So, after TSS access begins, if | ||
564 | * part of the 104 bytes is not physically contiguous, the processor | ||
565 | * will access incorrect information without generating a page-fault | ||
566 | * exception. | ||
567 | * | ||
568 | * There are also a lot of errata involving the TSS spanning a page | ||
569 | * boundary. Assert that we're not doing that. | ||
570 | */ | ||
571 | BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^ | ||
572 | offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK); | ||
573 | BUILD_BUG_ON(sizeof(struct tss_struct) % PAGE_SIZE != 0); | ||
574 | set_percpu_fixmap_pages(get_cpu_entry_area_index(cpu, tss), | ||
575 | &per_cpu(cpu_tss_rw, cpu), | ||
576 | sizeof(struct tss_struct) / PAGE_SIZE, | ||
577 | tss_prot); | ||
578 | |||
579 | #ifdef CONFIG_X86_32 | ||
580 | per_cpu(cpu_entry_area, cpu) = get_cpu_entry_area(cpu); | ||
581 | #endif | 509 | #endif |
582 | 510 | ||
583 | #ifdef CONFIG_X86_64 | ||
584 | BUILD_BUG_ON(sizeof(exception_stacks) % PAGE_SIZE != 0); | ||
585 | BUILD_BUG_ON(sizeof(exception_stacks) != | ||
586 | sizeof(((struct cpu_entry_area *)0)->exception_stacks)); | ||
587 | set_percpu_fixmap_pages(get_cpu_entry_area_index(cpu, exception_stacks), | ||
588 | &per_cpu(exception_stacks, cpu), | ||
589 | sizeof(exception_stacks) / PAGE_SIZE, | ||
590 | PAGE_KERNEL); | ||
591 | |||
592 | __set_fixmap(get_cpu_entry_area_index(cpu, entry_trampoline), | ||
593 | __pa_symbol(_entry_trampoline), PAGE_KERNEL_RX); | ||
594 | #endif | ||
595 | } | ||
596 | |||
597 | void __init setup_cpu_entry_areas(void) | ||
598 | { | ||
599 | unsigned int cpu; | ||
600 | |||
601 | for_each_possible_cpu(cpu) | ||
602 | setup_cpu_entry_area(cpu); | ||
603 | } | ||
604 | |||
605 | /* Load the original GDT from the per-cpu structure */ | 511 | /* Load the original GDT from the per-cpu structure */ |
606 | void load_direct_gdt(int cpu) | 512 | void load_direct_gdt(int cpu) |
607 | { | 513 | { |
@@ -1348,7 +1254,7 @@ void enable_sep_cpu(void) | |||
1348 | 1254 | ||
1349 | tss->x86_tss.ss1 = __KERNEL_CS; | 1255 | tss->x86_tss.ss1 = __KERNEL_CS; |
1350 | wrmsr(MSR_IA32_SYSENTER_CS, tss->x86_tss.ss1, 0); | 1256 | wrmsr(MSR_IA32_SYSENTER_CS, tss->x86_tss.ss1, 0); |
1351 | wrmsr(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_SYSENTER_stack(cpu) + 1), 0); | 1257 | wrmsr(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_entry_stack(cpu) + 1), 0); |
1352 | wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long)entry_SYSENTER_32, 0); | 1258 | wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long)entry_SYSENTER_32, 0); |
1353 | 1259 | ||
1354 | put_cpu(); | 1260 | put_cpu(); |
@@ -1465,7 +1371,7 @@ void syscall_init(void) | |||
1465 | * AMD doesn't allow SYSENTER in long mode (either 32- or 64-bit). | 1371 | * AMD doesn't allow SYSENTER in long mode (either 32- or 64-bit). |
1466 | */ | 1372 | */ |
1467 | wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); | 1373 | wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); |
1468 | wrmsrl_safe(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_SYSENTER_stack(cpu) + 1)); | 1374 | wrmsrl_safe(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_entry_stack(cpu) + 1)); |
1469 | wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)entry_SYSENTER_compat); | 1375 | wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)entry_SYSENTER_compat); |
1470 | #else | 1376 | #else |
1471 | wrmsrl(MSR_CSTAR, (unsigned long)ignore_sysret); | 1377 | wrmsrl(MSR_CSTAR, (unsigned long)ignore_sysret); |
@@ -1680,7 +1586,7 @@ void cpu_init(void) | |||
1680 | */ | 1586 | */ |
1681 | set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss); | 1587 | set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss); |
1682 | load_TR_desc(); | 1588 | load_TR_desc(); |
1683 | load_sp0((unsigned long)(cpu_SYSENTER_stack(cpu) + 1)); | 1589 | load_sp0((unsigned long)(cpu_entry_stack(cpu) + 1)); |
1684 | 1590 | ||
1685 | load_mm_ldt(&init_mm); | 1591 | load_mm_ldt(&init_mm); |
1686 | 1592 | ||
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 7dbcb7adf797..8ccdca6d3f9e 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c | |||
@@ -565,15 +565,6 @@ static void print_ucode(struct ucode_cpu_info *uci) | |||
565 | } | 565 | } |
566 | #else | 566 | #else |
567 | 567 | ||
568 | /* | ||
569 | * Flush global tlb. We only do this in x86_64 where paging has been enabled | ||
570 | * already and PGE should be enabled as well. | ||
571 | */ | ||
572 | static inline void flush_tlb_early(void) | ||
573 | { | ||
574 | __native_flush_tlb_global_irq_disabled(); | ||
575 | } | ||
576 | |||
577 | static inline void print_ucode(struct ucode_cpu_info *uci) | 568 | static inline void print_ucode(struct ucode_cpu_info *uci) |
578 | { | 569 | { |
579 | struct microcode_intel *mc; | 570 | struct microcode_intel *mc; |
@@ -602,10 +593,6 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early) | |||
602 | if (rev != mc->hdr.rev) | 593 | if (rev != mc->hdr.rev) |
603 | return -1; | 594 | return -1; |
604 | 595 | ||
605 | #ifdef CONFIG_X86_64 | ||
606 | /* Flush global tlb. This is precaution. */ | ||
607 | flush_tlb_early(); | ||
608 | #endif | ||
609 | uci->cpu_sig.rev = rev; | 596 | uci->cpu_sig.rev = rev; |
610 | 597 | ||
611 | if (early) | 598 | if (early) |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index bbd6d986e2d0..36b17e0febe8 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/nmi.h> | 18 | #include <linux/nmi.h> |
19 | #include <linux/sysfs.h> | 19 | #include <linux/sysfs.h> |
20 | 20 | ||
21 | #include <asm/cpu_entry_area.h> | ||
21 | #include <asm/stacktrace.h> | 22 | #include <asm/stacktrace.h> |
22 | #include <asm/unwind.h> | 23 | #include <asm/unwind.h> |
23 | 24 | ||
@@ -43,9 +44,9 @@ bool in_task_stack(unsigned long *stack, struct task_struct *task, | |||
43 | return true; | 44 | return true; |
44 | } | 45 | } |
45 | 46 | ||
46 | bool in_sysenter_stack(unsigned long *stack, struct stack_info *info) | 47 | bool in_entry_stack(unsigned long *stack, struct stack_info *info) |
47 | { | 48 | { |
48 | struct SYSENTER_stack *ss = cpu_SYSENTER_stack(smp_processor_id()); | 49 | struct entry_stack *ss = cpu_entry_stack(smp_processor_id()); |
49 | 50 | ||
50 | void *begin = ss; | 51 | void *begin = ss; |
51 | void *end = ss + 1; | 52 | void *end = ss + 1; |
@@ -53,7 +54,7 @@ bool in_sysenter_stack(unsigned long *stack, struct stack_info *info) | |||
53 | if ((void *)stack < begin || (void *)stack >= end) | 54 | if ((void *)stack < begin || (void *)stack >= end) |
54 | return false; | 55 | return false; |
55 | 56 | ||
56 | info->type = STACK_TYPE_SYSENTER; | 57 | info->type = STACK_TYPE_ENTRY; |
57 | info->begin = begin; | 58 | info->begin = begin; |
58 | info->end = end; | 59 | info->end = end; |
59 | info->next_sp = NULL; | 60 | info->next_sp = NULL; |
@@ -111,13 +112,13 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
111 | * - task stack | 112 | * - task stack |
112 | * - interrupt stack | 113 | * - interrupt stack |
113 | * - HW exception stacks (double fault, nmi, debug, mce) | 114 | * - HW exception stacks (double fault, nmi, debug, mce) |
114 | * - SYSENTER stack | 115 | * - entry stack |
115 | * | 116 | * |
116 | * x86-32 can have up to four stacks: | 117 | * x86-32 can have up to four stacks: |
117 | * - task stack | 118 | * - task stack |
118 | * - softirq stack | 119 | * - softirq stack |
119 | * - hardirq stack | 120 | * - hardirq stack |
120 | * - SYSENTER stack | 121 | * - entry stack |
121 | */ | 122 | */ |
122 | for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { | 123 | for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { |
123 | const char *stack_name; | 124 | const char *stack_name; |
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 5ff13a6b3680..04170f63e3a1 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -26,8 +26,8 @@ const char *stack_type_name(enum stack_type type) | |||
26 | if (type == STACK_TYPE_SOFTIRQ) | 26 | if (type == STACK_TYPE_SOFTIRQ) |
27 | return "SOFTIRQ"; | 27 | return "SOFTIRQ"; |
28 | 28 | ||
29 | if (type == STACK_TYPE_SYSENTER) | 29 | if (type == STACK_TYPE_ENTRY) |
30 | return "SYSENTER"; | 30 | return "ENTRY_TRAMPOLINE"; |
31 | 31 | ||
32 | return NULL; | 32 | return NULL; |
33 | } | 33 | } |
@@ -96,7 +96,7 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, | |||
96 | if (task != current) | 96 | if (task != current) |
97 | goto unknown; | 97 | goto unknown; |
98 | 98 | ||
99 | if (in_sysenter_stack(stack, info)) | 99 | if (in_entry_stack(stack, info)) |
100 | goto recursion_check; | 100 | goto recursion_check; |
101 | 101 | ||
102 | if (in_hardirq_stack(stack, info)) | 102 | if (in_hardirq_stack(stack, info)) |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index abc828f8c297..563e28d14f2c 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -37,8 +37,14 @@ const char *stack_type_name(enum stack_type type) | |||
37 | if (type == STACK_TYPE_IRQ) | 37 | if (type == STACK_TYPE_IRQ) |
38 | return "IRQ"; | 38 | return "IRQ"; |
39 | 39 | ||
40 | if (type == STACK_TYPE_SYSENTER) | 40 | if (type == STACK_TYPE_ENTRY) { |
41 | return "SYSENTER"; | 41 | /* |
42 | * On 64-bit, we have a generic entry stack that we | ||
43 | * use for all the kernel entry points, including | ||
44 | * SYSENTER. | ||
45 | */ | ||
46 | return "ENTRY_TRAMPOLINE"; | ||
47 | } | ||
42 | 48 | ||
43 | if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST) | 49 | if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST) |
44 | return exception_stack_names[type - STACK_TYPE_EXCEPTION]; | 50 | return exception_stack_names[type - STACK_TYPE_EXCEPTION]; |
@@ -118,7 +124,7 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, | |||
118 | if (in_irq_stack(stack, info)) | 124 | if (in_irq_stack(stack, info)) |
119 | goto recursion_check; | 125 | goto recursion_check; |
120 | 126 | ||
121 | if (in_sysenter_stack(stack, info)) | 127 | if (in_entry_stack(stack, info)) |
122 | goto recursion_check; | 128 | goto recursion_check; |
123 | 129 | ||
124 | goto unknown; | 130 | goto unknown; |
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 1c1eae961340..a6b5d62f45a7 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
@@ -5,6 +5,11 @@ | |||
5 | * Copyright (C) 2002 Andi Kleen | 5 | * Copyright (C) 2002 Andi Kleen |
6 | * | 6 | * |
7 | * This handles calls from both 32bit and 64bit mode. | 7 | * This handles calls from both 32bit and 64bit mode. |
8 | * | ||
9 | * Lock order: | ||
10 | * contex.ldt_usr_sem | ||
11 | * mmap_sem | ||
12 | * context.lock | ||
8 | */ | 13 | */ |
9 | 14 | ||
10 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
@@ -42,7 +47,7 @@ static void refresh_ldt_segments(void) | |||
42 | #endif | 47 | #endif |
43 | } | 48 | } |
44 | 49 | ||
45 | /* context.lock is held for us, so we don't need any locking. */ | 50 | /* context.lock is held by the task which issued the smp function call */ |
46 | static void flush_ldt(void *__mm) | 51 | static void flush_ldt(void *__mm) |
47 | { | 52 | { |
48 | struct mm_struct *mm = __mm; | 53 | struct mm_struct *mm = __mm; |
@@ -99,15 +104,17 @@ static void finalize_ldt_struct(struct ldt_struct *ldt) | |||
99 | paravirt_alloc_ldt(ldt->entries, ldt->nr_entries); | 104 | paravirt_alloc_ldt(ldt->entries, ldt->nr_entries); |
100 | } | 105 | } |
101 | 106 | ||
102 | /* context.lock is held */ | 107 | static void install_ldt(struct mm_struct *mm, struct ldt_struct *ldt) |
103 | static void install_ldt(struct mm_struct *current_mm, | ||
104 | struct ldt_struct *ldt) | ||
105 | { | 108 | { |
109 | mutex_lock(&mm->context.lock); | ||
110 | |||
106 | /* Synchronizes with READ_ONCE in load_mm_ldt. */ | 111 | /* Synchronizes with READ_ONCE in load_mm_ldt. */ |
107 | smp_store_release(¤t_mm->context.ldt, ldt); | 112 | smp_store_release(&mm->context.ldt, ldt); |
108 | 113 | ||
109 | /* Activate the LDT for all CPUs using current_mm. */ | 114 | /* Activate the LDT for all CPUs using currents mm. */ |
110 | on_each_cpu_mask(mm_cpumask(current_mm), flush_ldt, current_mm, true); | 115 | on_each_cpu_mask(mm_cpumask(mm), flush_ldt, mm, true); |
116 | |||
117 | mutex_unlock(&mm->context.lock); | ||
111 | } | 118 | } |
112 | 119 | ||
113 | static void free_ldt_struct(struct ldt_struct *ldt) | 120 | static void free_ldt_struct(struct ldt_struct *ldt) |
@@ -124,27 +131,20 @@ static void free_ldt_struct(struct ldt_struct *ldt) | |||
124 | } | 131 | } |
125 | 132 | ||
126 | /* | 133 | /* |
127 | * we do not have to muck with descriptors here, that is | 134 | * Called on fork from arch_dup_mmap(). Just copy the current LDT state, |
128 | * done in switch_mm() as needed. | 135 | * the new task is not running, so nothing can be installed. |
129 | */ | 136 | */ |
130 | int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm) | 137 | int ldt_dup_context(struct mm_struct *old_mm, struct mm_struct *mm) |
131 | { | 138 | { |
132 | struct ldt_struct *new_ldt; | 139 | struct ldt_struct *new_ldt; |
133 | struct mm_struct *old_mm; | ||
134 | int retval = 0; | 140 | int retval = 0; |
135 | 141 | ||
136 | mutex_init(&mm->context.lock); | 142 | if (!old_mm) |
137 | old_mm = current->mm; | ||
138 | if (!old_mm) { | ||
139 | mm->context.ldt = NULL; | ||
140 | return 0; | 143 | return 0; |
141 | } | ||
142 | 144 | ||
143 | mutex_lock(&old_mm->context.lock); | 145 | mutex_lock(&old_mm->context.lock); |
144 | if (!old_mm->context.ldt) { | 146 | if (!old_mm->context.ldt) |
145 | mm->context.ldt = NULL; | ||
146 | goto out_unlock; | 147 | goto out_unlock; |
147 | } | ||
148 | 148 | ||
149 | new_ldt = alloc_ldt_struct(old_mm->context.ldt->nr_entries); | 149 | new_ldt = alloc_ldt_struct(old_mm->context.ldt->nr_entries); |
150 | if (!new_ldt) { | 150 | if (!new_ldt) { |
@@ -180,7 +180,7 @@ static int read_ldt(void __user *ptr, unsigned long bytecount) | |||
180 | unsigned long entries_size; | 180 | unsigned long entries_size; |
181 | int retval; | 181 | int retval; |
182 | 182 | ||
183 | mutex_lock(&mm->context.lock); | 183 | down_read(&mm->context.ldt_usr_sem); |
184 | 184 | ||
185 | if (!mm->context.ldt) { | 185 | if (!mm->context.ldt) { |
186 | retval = 0; | 186 | retval = 0; |
@@ -209,7 +209,7 @@ static int read_ldt(void __user *ptr, unsigned long bytecount) | |||
209 | retval = bytecount; | 209 | retval = bytecount; |
210 | 210 | ||
211 | out_unlock: | 211 | out_unlock: |
212 | mutex_unlock(&mm->context.lock); | 212 | up_read(&mm->context.ldt_usr_sem); |
213 | return retval; | 213 | return retval; |
214 | } | 214 | } |
215 | 215 | ||
@@ -269,7 +269,8 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) | |||
269 | ldt.avl = 0; | 269 | ldt.avl = 0; |
270 | } | 270 | } |
271 | 271 | ||
272 | mutex_lock(&mm->context.lock); | 272 | if (down_write_killable(&mm->context.ldt_usr_sem)) |
273 | return -EINTR; | ||
273 | 274 | ||
274 | old_ldt = mm->context.ldt; | 275 | old_ldt = mm->context.ldt; |
275 | old_nr_entries = old_ldt ? old_ldt->nr_entries : 0; | 276 | old_nr_entries = old_ldt ? old_ldt->nr_entries : 0; |
@@ -291,7 +292,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) | |||
291 | error = 0; | 292 | error = 0; |
292 | 293 | ||
293 | out_unlock: | 294 | out_unlock: |
294 | mutex_unlock(&mm->context.lock); | 295 | up_write(&mm->context.ldt_usr_sem); |
295 | out: | 296 | out: |
296 | return error; | 297 | return error; |
297 | } | 298 | } |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 35cb20994e32..c5970efa8557 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -932,12 +932,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, | |||
932 | initial_code = (unsigned long)start_secondary; | 932 | initial_code = (unsigned long)start_secondary; |
933 | initial_stack = idle->thread.sp; | 933 | initial_stack = idle->thread.sp; |
934 | 934 | ||
935 | /* | 935 | /* Enable the espfix hack for this CPU */ |
936 | * Enable the espfix hack for this CPU | ||
937 | */ | ||
938 | #ifdef CONFIG_X86_ESPFIX64 | ||
939 | init_espfix_ap(cpu); | 936 | init_espfix_ap(cpu); |
940 | #endif | ||
941 | 937 | ||
942 | /* So we see what's up */ | 938 | /* So we see what's up */ |
943 | announce_cpu(cpu, apicid); | 939 | announce_cpu(cpu, apicid); |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index e98f8b66a460..f69dbd47d733 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <asm/traps.h> | 51 | #include <asm/traps.h> |
52 | #include <asm/desc.h> | 52 | #include <asm/desc.h> |
53 | #include <asm/fpu/internal.h> | 53 | #include <asm/fpu/internal.h> |
54 | #include <asm/cpu_entry_area.h> | ||
54 | #include <asm/mce.h> | 55 | #include <asm/mce.h> |
55 | #include <asm/fixmap.h> | 56 | #include <asm/fixmap.h> |
56 | #include <asm/mach_traps.h> | 57 | #include <asm/mach_traps.h> |
@@ -951,8 +952,9 @@ void __init trap_init(void) | |||
951 | * "sidt" instruction will not leak the location of the kernel, and | 952 | * "sidt" instruction will not leak the location of the kernel, and |
952 | * to defend the IDT against arbitrary memory write vulnerabilities. | 953 | * to defend the IDT against arbitrary memory write vulnerabilities. |
953 | * It will be reloaded in cpu_init() */ | 954 | * It will be reloaded in cpu_init() */ |
954 | __set_fixmap(FIX_RO_IDT, __pa_symbol(idt_table), PAGE_KERNEL_RO); | 955 | cea_set_pte(CPU_ENTRY_AREA_RO_IDT_VADDR, __pa_symbol(idt_table), |
955 | idt_descr.address = fix_to_virt(FIX_RO_IDT); | 956 | PAGE_KERNEL_RO); |
957 | idt_descr.address = CPU_ENTRY_AREA_RO_IDT; | ||
956 | 958 | ||
957 | /* | 959 | /* |
958 | * Should be a barrier for any external CPU state: | 960 | * Should be a barrier for any external CPU state: |
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 8e13b8cc6bed..52195ee3f6d5 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile | |||
@@ -10,7 +10,7 @@ CFLAGS_REMOVE_mem_encrypt.o = -pg | |||
10 | endif | 10 | endif |
11 | 11 | ||
12 | obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ | 12 | obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ |
13 | pat.o pgtable.o physaddr.o setup_nx.o tlb.o | 13 | pat.o pgtable.o physaddr.o setup_nx.o tlb.o cpu_entry_area.o |
14 | 14 | ||
15 | # Make sure __phys_addr has no stackprotector | 15 | # Make sure __phys_addr has no stackprotector |
16 | nostackp := $(call cc-option, -fno-stack-protector) | 16 | nostackp := $(call cc-option, -fno-stack-protector) |
diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c new file mode 100644 index 000000000000..fe814fd5e014 --- /dev/null +++ b/arch/x86/mm/cpu_entry_area.c | |||
@@ -0,0 +1,139 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | #include <linux/spinlock.h> | ||
4 | #include <linux/percpu.h> | ||
5 | |||
6 | #include <asm/cpu_entry_area.h> | ||
7 | #include <asm/pgtable.h> | ||
8 | #include <asm/fixmap.h> | ||
9 | #include <asm/desc.h> | ||
10 | |||
11 | static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage); | ||
12 | |||
13 | #ifdef CONFIG_X86_64 | ||
14 | static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks | ||
15 | [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); | ||
16 | #endif | ||
17 | |||
18 | struct cpu_entry_area *get_cpu_entry_area(int cpu) | ||
19 | { | ||
20 | unsigned long va = CPU_ENTRY_AREA_PER_CPU + cpu * CPU_ENTRY_AREA_SIZE; | ||
21 | BUILD_BUG_ON(sizeof(struct cpu_entry_area) % PAGE_SIZE != 0); | ||
22 | |||
23 | return (struct cpu_entry_area *) va; | ||
24 | } | ||
25 | EXPORT_SYMBOL(get_cpu_entry_area); | ||
26 | |||
27 | void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags) | ||
28 | { | ||
29 | unsigned long va = (unsigned long) cea_vaddr; | ||
30 | |||
31 | set_pte_vaddr(va, pfn_pte(pa >> PAGE_SHIFT, flags)); | ||
32 | } | ||
33 | |||
34 | static void __init | ||
35 | cea_map_percpu_pages(void *cea_vaddr, void *ptr, int pages, pgprot_t prot) | ||
36 | { | ||
37 | for ( ; pages; pages--, cea_vaddr+= PAGE_SIZE, ptr += PAGE_SIZE) | ||
38 | cea_set_pte(cea_vaddr, per_cpu_ptr_to_phys(ptr), prot); | ||
39 | } | ||
40 | |||
41 | /* Setup the fixmap mappings only once per-processor */ | ||
42 | static void __init setup_cpu_entry_area(int cpu) | ||
43 | { | ||
44 | #ifdef CONFIG_X86_64 | ||
45 | extern char _entry_trampoline[]; | ||
46 | |||
47 | /* On 64-bit systems, we use a read-only fixmap GDT and TSS. */ | ||
48 | pgprot_t gdt_prot = PAGE_KERNEL_RO; | ||
49 | pgprot_t tss_prot = PAGE_KERNEL_RO; | ||
50 | #else | ||
51 | /* | ||
52 | * On native 32-bit systems, the GDT cannot be read-only because | ||
53 | * our double fault handler uses a task gate, and entering through | ||
54 | * a task gate needs to change an available TSS to busy. If the | ||
55 | * GDT is read-only, that will triple fault. The TSS cannot be | ||
56 | * read-only because the CPU writes to it on task switches. | ||
57 | * | ||
58 | * On Xen PV, the GDT must be read-only because the hypervisor | ||
59 | * requires it. | ||
60 | */ | ||
61 | pgprot_t gdt_prot = boot_cpu_has(X86_FEATURE_XENPV) ? | ||
62 | PAGE_KERNEL_RO : PAGE_KERNEL; | ||
63 | pgprot_t tss_prot = PAGE_KERNEL; | ||
64 | #endif | ||
65 | |||
66 | cea_set_pte(&get_cpu_entry_area(cpu)->gdt, get_cpu_gdt_paddr(cpu), | ||
67 | gdt_prot); | ||
68 | |||
69 | cea_map_percpu_pages(&get_cpu_entry_area(cpu)->entry_stack_page, | ||
70 | per_cpu_ptr(&entry_stack_storage, cpu), 1, | ||
71 | PAGE_KERNEL); | ||
72 | |||
73 | /* | ||
74 | * The Intel SDM says (Volume 3, 7.2.1): | ||
75 | * | ||
76 | * Avoid placing a page boundary in the part of the TSS that the | ||
77 | * processor reads during a task switch (the first 104 bytes). The | ||
78 | * processor may not correctly perform address translations if a | ||
79 | * boundary occurs in this area. During a task switch, the processor | ||
80 | * reads and writes into the first 104 bytes of each TSS (using | ||
81 | * contiguous physical addresses beginning with the physical address | ||
82 | * of the first byte of the TSS). So, after TSS access begins, if | ||
83 | * part of the 104 bytes is not physically contiguous, the processor | ||
84 | * will access incorrect information without generating a page-fault | ||
85 | * exception. | ||
86 | * | ||
87 | * There are also a lot of errata involving the TSS spanning a page | ||
88 | * boundary. Assert that we're not doing that. | ||
89 | */ | ||
90 | BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^ | ||
91 | offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK); | ||
92 | BUILD_BUG_ON(sizeof(struct tss_struct) % PAGE_SIZE != 0); | ||
93 | cea_map_percpu_pages(&get_cpu_entry_area(cpu)->tss, | ||
94 | &per_cpu(cpu_tss_rw, cpu), | ||
95 | sizeof(struct tss_struct) / PAGE_SIZE, tss_prot); | ||
96 | |||
97 | #ifdef CONFIG_X86_32 | ||
98 | per_cpu(cpu_entry_area, cpu) = get_cpu_entry_area(cpu); | ||
99 | #endif | ||
100 | |||
101 | #ifdef CONFIG_X86_64 | ||
102 | BUILD_BUG_ON(sizeof(exception_stacks) % PAGE_SIZE != 0); | ||
103 | BUILD_BUG_ON(sizeof(exception_stacks) != | ||
104 | sizeof(((struct cpu_entry_area *)0)->exception_stacks)); | ||
105 | cea_map_percpu_pages(&get_cpu_entry_area(cpu)->exception_stacks, | ||
106 | &per_cpu(exception_stacks, cpu), | ||
107 | sizeof(exception_stacks) / PAGE_SIZE, PAGE_KERNEL); | ||
108 | |||
109 | cea_set_pte(&get_cpu_entry_area(cpu)->entry_trampoline, | ||
110 | __pa_symbol(_entry_trampoline), PAGE_KERNEL_RX); | ||
111 | #endif | ||
112 | } | ||
113 | |||
114 | static __init void setup_cpu_entry_area_ptes(void) | ||
115 | { | ||
116 | #ifdef CONFIG_X86_32 | ||
117 | unsigned long start, end; | ||
118 | |||
119 | BUILD_BUG_ON(CPU_ENTRY_AREA_PAGES * PAGE_SIZE < CPU_ENTRY_AREA_MAP_SIZE); | ||
120 | BUG_ON(CPU_ENTRY_AREA_BASE & ~PMD_MASK); | ||
121 | |||
122 | start = CPU_ENTRY_AREA_BASE; | ||
123 | end = start + CPU_ENTRY_AREA_MAP_SIZE; | ||
124 | |||
125 | /* Careful here: start + PMD_SIZE might wrap around */ | ||
126 | for (; start < end && start >= CPU_ENTRY_AREA_BASE; start += PMD_SIZE) | ||
127 | populate_extra_pte(start); | ||
128 | #endif | ||
129 | } | ||
130 | |||
131 | void __init setup_cpu_entry_areas(void) | ||
132 | { | ||
133 | unsigned int cpu; | ||
134 | |||
135 | setup_cpu_entry_area_ptes(); | ||
136 | |||
137 | for_each_possible_cpu(cpu) | ||
138 | setup_cpu_entry_area(cpu); | ||
139 | } | ||
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c index 5e3ac6fe6c9e..43dedbfb7257 100644 --- a/arch/x86/mm/dump_pagetables.c +++ b/arch/x86/mm/dump_pagetables.c | |||
@@ -44,10 +44,12 @@ struct addr_marker { | |||
44 | unsigned long max_lines; | 44 | unsigned long max_lines; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | /* indices for address_markers; keep sync'd w/ address_markers below */ | 47 | /* Address space markers hints */ |
48 | |||
49 | #ifdef CONFIG_X86_64 | ||
50 | |||
48 | enum address_markers_idx { | 51 | enum address_markers_idx { |
49 | USER_SPACE_NR = 0, | 52 | USER_SPACE_NR = 0, |
50 | #ifdef CONFIG_X86_64 | ||
51 | KERNEL_SPACE_NR, | 53 | KERNEL_SPACE_NR, |
52 | LOW_KERNEL_NR, | 54 | LOW_KERNEL_NR, |
53 | VMALLOC_START_NR, | 55 | VMALLOC_START_NR, |
@@ -56,56 +58,74 @@ enum address_markers_idx { | |||
56 | KASAN_SHADOW_START_NR, | 58 | KASAN_SHADOW_START_NR, |
57 | KASAN_SHADOW_END_NR, | 59 | KASAN_SHADOW_END_NR, |
58 | #endif | 60 | #endif |
59 | # ifdef CONFIG_X86_ESPFIX64 | 61 | CPU_ENTRY_AREA_NR, |
62 | #ifdef CONFIG_X86_ESPFIX64 | ||
60 | ESPFIX_START_NR, | 63 | ESPFIX_START_NR, |
61 | # endif | 64 | #endif |
65 | #ifdef CONFIG_EFI | ||
66 | EFI_END_NR, | ||
67 | #endif | ||
62 | HIGH_KERNEL_NR, | 68 | HIGH_KERNEL_NR, |
63 | MODULES_VADDR_NR, | 69 | MODULES_VADDR_NR, |
64 | MODULES_END_NR, | 70 | MODULES_END_NR, |
65 | #else | 71 | FIXADDR_START_NR, |
72 | END_OF_SPACE_NR, | ||
73 | }; | ||
74 | |||
75 | static struct addr_marker address_markers[] = { | ||
76 | [USER_SPACE_NR] = { 0, "User Space" }, | ||
77 | [KERNEL_SPACE_NR] = { (1UL << 63), "Kernel Space" }, | ||
78 | [LOW_KERNEL_NR] = { 0UL, "Low Kernel Mapping" }, | ||
79 | [VMALLOC_START_NR] = { 0UL, "vmalloc() Area" }, | ||
80 | [VMEMMAP_START_NR] = { 0UL, "Vmemmap" }, | ||
81 | #ifdef CONFIG_KASAN | ||
82 | [KASAN_SHADOW_START_NR] = { KASAN_SHADOW_START, "KASAN shadow" }, | ||
83 | [KASAN_SHADOW_END_NR] = { KASAN_SHADOW_END, "KASAN shadow end" }, | ||
84 | #endif | ||
85 | [CPU_ENTRY_AREA_NR] = { CPU_ENTRY_AREA_BASE,"CPU entry Area" }, | ||
86 | #ifdef CONFIG_X86_ESPFIX64 | ||
87 | [ESPFIX_START_NR] = { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, | ||
88 | #endif | ||
89 | #ifdef CONFIG_EFI | ||
90 | [EFI_END_NR] = { EFI_VA_END, "EFI Runtime Services" }, | ||
91 | #endif | ||
92 | [HIGH_KERNEL_NR] = { __START_KERNEL_map, "High Kernel Mapping" }, | ||
93 | [MODULES_VADDR_NR] = { MODULES_VADDR, "Modules" }, | ||
94 | [MODULES_END_NR] = { MODULES_END, "End Modules" }, | ||
95 | [FIXADDR_START_NR] = { FIXADDR_START, "Fixmap Area" }, | ||
96 | [END_OF_SPACE_NR] = { -1, NULL } | ||
97 | }; | ||
98 | |||
99 | #else /* CONFIG_X86_64 */ | ||
100 | |||
101 | enum address_markers_idx { | ||
102 | USER_SPACE_NR = 0, | ||
66 | KERNEL_SPACE_NR, | 103 | KERNEL_SPACE_NR, |
67 | VMALLOC_START_NR, | 104 | VMALLOC_START_NR, |
68 | VMALLOC_END_NR, | 105 | VMALLOC_END_NR, |
69 | # ifdef CONFIG_HIGHMEM | 106 | #ifdef CONFIG_HIGHMEM |
70 | PKMAP_BASE_NR, | 107 | PKMAP_BASE_NR, |
71 | # endif | ||
72 | FIXADDR_START_NR, | ||
73 | #endif | 108 | #endif |
109 | CPU_ENTRY_AREA_NR, | ||
110 | FIXADDR_START_NR, | ||
111 | END_OF_SPACE_NR, | ||
74 | }; | 112 | }; |
75 | 113 | ||
76 | /* Address space markers hints */ | ||
77 | static struct addr_marker address_markers[] = { | 114 | static struct addr_marker address_markers[] = { |
78 | { 0, "User Space" }, | 115 | [USER_SPACE_NR] = { 0, "User Space" }, |
79 | #ifdef CONFIG_X86_64 | 116 | [KERNEL_SPACE_NR] = { PAGE_OFFSET, "Kernel Mapping" }, |
80 | { 0x8000000000000000UL, "Kernel Space" }, | 117 | [VMALLOC_START_NR] = { 0UL, "vmalloc() Area" }, |
81 | { 0/* PAGE_OFFSET */, "Low Kernel Mapping" }, | 118 | [VMALLOC_END_NR] = { 0UL, "vmalloc() End" }, |
82 | { 0/* VMALLOC_START */, "vmalloc() Area" }, | 119 | #ifdef CONFIG_HIGHMEM |
83 | { 0/* VMEMMAP_START */, "Vmemmap" }, | 120 | [PKMAP_BASE_NR] = { 0UL, "Persistent kmap() Area" }, |
84 | #ifdef CONFIG_KASAN | ||
85 | { KASAN_SHADOW_START, "KASAN shadow" }, | ||
86 | { KASAN_SHADOW_END, "KASAN shadow end" }, | ||
87 | #endif | 121 | #endif |
88 | # ifdef CONFIG_X86_ESPFIX64 | 122 | [CPU_ENTRY_AREA_NR] = { 0UL, "CPU entry area" }, |
89 | { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, | 123 | [FIXADDR_START_NR] = { 0UL, "Fixmap area" }, |
90 | # endif | 124 | [END_OF_SPACE_NR] = { -1, NULL } |
91 | # ifdef CONFIG_EFI | ||
92 | { EFI_VA_END, "EFI Runtime Services" }, | ||
93 | # endif | ||
94 | { __START_KERNEL_map, "High Kernel Mapping" }, | ||
95 | { MODULES_VADDR, "Modules" }, | ||
96 | { MODULES_END, "End Modules" }, | ||
97 | #else | ||
98 | { PAGE_OFFSET, "Kernel Mapping" }, | ||
99 | { 0/* VMALLOC_START */, "vmalloc() Area" }, | ||
100 | { 0/*VMALLOC_END*/, "vmalloc() End" }, | ||
101 | # ifdef CONFIG_HIGHMEM | ||
102 | { 0/*PKMAP_BASE*/, "Persistent kmap() Area" }, | ||
103 | # endif | ||
104 | { 0/*FIXADDR_START*/, "Fixmap Area" }, | ||
105 | #endif | ||
106 | { -1, NULL } /* End of list */ | ||
107 | }; | 125 | }; |
108 | 126 | ||
127 | #endif /* !CONFIG_X86_64 */ | ||
128 | |||
109 | /* Multipliers for offsets within the PTEs */ | 129 | /* Multipliers for offsets within the PTEs */ |
110 | #define PTE_LEVEL_MULT (PAGE_SIZE) | 130 | #define PTE_LEVEL_MULT (PAGE_SIZE) |
111 | #define PMD_LEVEL_MULT (PTRS_PER_PTE * PTE_LEVEL_MULT) | 131 | #define PMD_LEVEL_MULT (PTRS_PER_PTE * PTE_LEVEL_MULT) |
@@ -140,7 +160,7 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg) | |||
140 | static const char * const level_name[] = | 160 | static const char * const level_name[] = |
141 | { "cr3", "pgd", "p4d", "pud", "pmd", "pte" }; | 161 | { "cr3", "pgd", "p4d", "pud", "pmd", "pte" }; |
142 | 162 | ||
143 | if (!pgprot_val(prot)) { | 163 | if (!(pr & _PAGE_PRESENT)) { |
144 | /* Not present */ | 164 | /* Not present */ |
145 | pt_dump_cont_printf(m, dmsg, " "); | 165 | pt_dump_cont_printf(m, dmsg, " "); |
146 | } else { | 166 | } else { |
@@ -525,8 +545,8 @@ static int __init pt_dump_init(void) | |||
525 | address_markers[PKMAP_BASE_NR].start_address = PKMAP_BASE; | 545 | address_markers[PKMAP_BASE_NR].start_address = PKMAP_BASE; |
526 | # endif | 546 | # endif |
527 | address_markers[FIXADDR_START_NR].start_address = FIXADDR_START; | 547 | address_markers[FIXADDR_START_NR].start_address = FIXADDR_START; |
548 | address_markers[CPU_ENTRY_AREA_NR].start_address = CPU_ENTRY_AREA_BASE; | ||
528 | #endif | 549 | #endif |
529 | |||
530 | return 0; | 550 | return 0; |
531 | } | 551 | } |
532 | __initcall(pt_dump_init); | 552 | __initcall(pt_dump_init); |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 8a64a6f2848d..135c9a7898c7 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <asm/setup.h> | 50 | #include <asm/setup.h> |
51 | #include <asm/set_memory.h> | 51 | #include <asm/set_memory.h> |
52 | #include <asm/page_types.h> | 52 | #include <asm/page_types.h> |
53 | #include <asm/cpu_entry_area.h> | ||
53 | #include <asm/init.h> | 54 | #include <asm/init.h> |
54 | 55 | ||
55 | #include "mm_internal.h" | 56 | #include "mm_internal.h" |
@@ -766,6 +767,7 @@ void __init mem_init(void) | |||
766 | mem_init_print_info(NULL); | 767 | mem_init_print_info(NULL); |
767 | printk(KERN_INFO "virtual kernel memory layout:\n" | 768 | printk(KERN_INFO "virtual kernel memory layout:\n" |
768 | " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" | 769 | " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" |
770 | " cpu_entry : 0x%08lx - 0x%08lx (%4ld kB)\n" | ||
769 | #ifdef CONFIG_HIGHMEM | 771 | #ifdef CONFIG_HIGHMEM |
770 | " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" | 772 | " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" |
771 | #endif | 773 | #endif |
@@ -777,6 +779,10 @@ void __init mem_init(void) | |||
777 | FIXADDR_START, FIXADDR_TOP, | 779 | FIXADDR_START, FIXADDR_TOP, |
778 | (FIXADDR_TOP - FIXADDR_START) >> 10, | 780 | (FIXADDR_TOP - FIXADDR_START) >> 10, |
779 | 781 | ||
782 | CPU_ENTRY_AREA_BASE, | ||
783 | CPU_ENTRY_AREA_BASE + CPU_ENTRY_AREA_MAP_SIZE, | ||
784 | CPU_ENTRY_AREA_MAP_SIZE >> 10, | ||
785 | |||
780 | #ifdef CONFIG_HIGHMEM | 786 | #ifdef CONFIG_HIGHMEM |
781 | PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, | 787 | PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, |
782 | (LAST_PKMAP*PAGE_SIZE) >> 10, | 788 | (LAST_PKMAP*PAGE_SIZE) >> 10, |
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c index 9ec70d780f1f..47388f0c0e59 100644 --- a/arch/x86/mm/kasan_init_64.c +++ b/arch/x86/mm/kasan_init_64.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/tlbflush.h> | 15 | #include <asm/tlbflush.h> |
16 | #include <asm/sections.h> | 16 | #include <asm/sections.h> |
17 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
18 | #include <asm/cpu_entry_area.h> | ||
18 | 19 | ||
19 | extern struct range pfn_mapped[E820_MAX_ENTRIES]; | 20 | extern struct range pfn_mapped[E820_MAX_ENTRIES]; |
20 | 21 | ||
@@ -322,31 +323,33 @@ void __init kasan_init(void) | |||
322 | map_range(&pfn_mapped[i]); | 323 | map_range(&pfn_mapped[i]); |
323 | } | 324 | } |
324 | 325 | ||
325 | kasan_populate_zero_shadow( | 326 | shadow_cpu_entry_begin = (void *)CPU_ENTRY_AREA_BASE; |
326 | kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM), | ||
327 | kasan_mem_to_shadow((void *)__START_KERNEL_map)); | ||
328 | |||
329 | kasan_populate_shadow((unsigned long)kasan_mem_to_shadow(_stext), | ||
330 | (unsigned long)kasan_mem_to_shadow(_end), | ||
331 | early_pfn_to_nid(__pa(_stext))); | ||
332 | |||
333 | shadow_cpu_entry_begin = (void *)__fix_to_virt(FIX_CPU_ENTRY_AREA_BOTTOM); | ||
334 | shadow_cpu_entry_begin = kasan_mem_to_shadow(shadow_cpu_entry_begin); | 327 | shadow_cpu_entry_begin = kasan_mem_to_shadow(shadow_cpu_entry_begin); |
335 | shadow_cpu_entry_begin = (void *)round_down((unsigned long)shadow_cpu_entry_begin, | 328 | shadow_cpu_entry_begin = (void *)round_down((unsigned long)shadow_cpu_entry_begin, |
336 | PAGE_SIZE); | 329 | PAGE_SIZE); |
337 | 330 | ||
338 | shadow_cpu_entry_end = (void *)(__fix_to_virt(FIX_CPU_ENTRY_AREA_TOP) + PAGE_SIZE); | 331 | shadow_cpu_entry_end = (void *)(CPU_ENTRY_AREA_BASE + |
332 | CPU_ENTRY_AREA_MAP_SIZE); | ||
339 | shadow_cpu_entry_end = kasan_mem_to_shadow(shadow_cpu_entry_end); | 333 | shadow_cpu_entry_end = kasan_mem_to_shadow(shadow_cpu_entry_end); |
340 | shadow_cpu_entry_end = (void *)round_up((unsigned long)shadow_cpu_entry_end, | 334 | shadow_cpu_entry_end = (void *)round_up((unsigned long)shadow_cpu_entry_end, |
341 | PAGE_SIZE); | 335 | PAGE_SIZE); |
342 | 336 | ||
343 | kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END), | 337 | kasan_populate_zero_shadow( |
344 | shadow_cpu_entry_begin); | 338 | kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM), |
339 | shadow_cpu_entry_begin); | ||
345 | 340 | ||
346 | kasan_populate_shadow((unsigned long)shadow_cpu_entry_begin, | 341 | kasan_populate_shadow((unsigned long)shadow_cpu_entry_begin, |
347 | (unsigned long)shadow_cpu_entry_end, 0); | 342 | (unsigned long)shadow_cpu_entry_end, 0); |
348 | 343 | ||
349 | kasan_populate_zero_shadow(shadow_cpu_entry_end, (void *)KASAN_SHADOW_END); | 344 | kasan_populate_zero_shadow(shadow_cpu_entry_end, |
345 | kasan_mem_to_shadow((void *)__START_KERNEL_map)); | ||
346 | |||
347 | kasan_populate_shadow((unsigned long)kasan_mem_to_shadow(_stext), | ||
348 | (unsigned long)kasan_mem_to_shadow(_end), | ||
349 | early_pfn_to_nid(__pa(_stext))); | ||
350 | |||
351 | kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END), | ||
352 | (void *)KASAN_SHADOW_END); | ||
350 | 353 | ||
351 | load_cr3(init_top_pgt); | 354 | load_cr3(init_top_pgt); |
352 | __flush_tlb_all(); | 355 | __flush_tlb_all(); |
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 6b9bf023a700..c3c5274410a9 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/pagemap.h> | 10 | #include <linux/pagemap.h> |
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | 12 | ||
13 | #include <asm/cpu_entry_area.h> | ||
13 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
14 | #include <asm/pgalloc.h> | 15 | #include <asm/pgalloc.h> |
15 | #include <asm/fixmap.h> | 16 | #include <asm/fixmap.h> |
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 3118392cdf75..0a1be3adc97e 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c | |||
@@ -128,7 +128,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, | |||
128 | * isn't free. | 128 | * isn't free. |
129 | */ | 129 | */ |
130 | #ifdef CONFIG_DEBUG_VM | 130 | #ifdef CONFIG_DEBUG_VM |
131 | if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev, prev_asid))) { | 131 | if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev->pgd, prev_asid))) { |
132 | /* | 132 | /* |
133 | * If we were to BUG here, we'd be very likely to kill | 133 | * If we were to BUG here, we'd be very likely to kill |
134 | * the system so hard that we don't see the call trace. | 134 | * the system so hard that we don't see the call trace. |
@@ -195,7 +195,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, | |||
195 | if (need_flush) { | 195 | if (need_flush) { |
196 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id); | 196 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id); |
197 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); | 197 | this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); |
198 | write_cr3(build_cr3(next, new_asid)); | 198 | write_cr3(build_cr3(next->pgd, new_asid)); |
199 | 199 | ||
200 | /* | 200 | /* |
201 | * NB: This gets called via leave_mm() in the idle path | 201 | * NB: This gets called via leave_mm() in the idle path |
@@ -208,7 +208,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, | |||
208 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL); | 208 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL); |
209 | } else { | 209 | } else { |
210 | /* The new ASID is already up to date. */ | 210 | /* The new ASID is already up to date. */ |
211 | write_cr3(build_cr3_noflush(next, new_asid)); | 211 | write_cr3(build_cr3_noflush(next->pgd, new_asid)); |
212 | 212 | ||
213 | /* See above wrt _rcuidle. */ | 213 | /* See above wrt _rcuidle. */ |
214 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0); | 214 | trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0); |
@@ -288,7 +288,7 @@ void initialize_tlbstate_and_flush(void) | |||
288 | !(cr4_read_shadow() & X86_CR4_PCIDE)); | 288 | !(cr4_read_shadow() & X86_CR4_PCIDE)); |
289 | 289 | ||
290 | /* Force ASID 0 and force a TLB flush. */ | 290 | /* Force ASID 0 and force a TLB flush. */ |
291 | write_cr3(build_cr3(mm, 0)); | 291 | write_cr3(build_cr3(mm->pgd, 0)); |
292 | 292 | ||
293 | /* Reinitialize tlbstate. */ | 293 | /* Reinitialize tlbstate. */ |
294 | this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0); | 294 | this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0); |
@@ -551,7 +551,7 @@ static void do_kernel_range_flush(void *info) | |||
551 | 551 | ||
552 | /* flush range by one by one 'invlpg' */ | 552 | /* flush range by one by one 'invlpg' */ |
553 | for (addr = f->start; addr < f->end; addr += PAGE_SIZE) | 553 | for (addr = f->start; addr < f->end; addr += PAGE_SIZE) |
554 | __flush_tlb_single(addr); | 554 | __flush_tlb_one(addr); |
555 | } | 555 | } |
556 | 556 | ||
557 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | 557 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) |
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index f44c0bc95aa2..8538a6723171 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
@@ -299,7 +299,7 @@ static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp, | |||
299 | local_flush_tlb(); | 299 | local_flush_tlb(); |
300 | stat->d_alltlb++; | 300 | stat->d_alltlb++; |
301 | } else { | 301 | } else { |
302 | __flush_tlb_one(msg->address); | 302 | __flush_tlb_single(msg->address); |
303 | stat->d_onetlb++; | 303 | stat->d_onetlb++; |
304 | } | 304 | } |
305 | stat->d_requestee++; | 305 | stat->d_requestee++; |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index d669e9d89001..c9081c6671f0 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1,8 +1,12 @@ | |||
1 | #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG | ||
2 | #include <linux/bootmem.h> | ||
3 | #endif | ||
1 | #include <linux/cpu.h> | 4 | #include <linux/cpu.h> |
2 | #include <linux/kexec.h> | 5 | #include <linux/kexec.h> |
3 | 6 | ||
4 | #include <xen/features.h> | 7 | #include <xen/features.h> |
5 | #include <xen/page.h> | 8 | #include <xen/page.h> |
9 | #include <xen/interface/memory.h> | ||
6 | 10 | ||
7 | #include <asm/xen/hypercall.h> | 11 | #include <asm/xen/hypercall.h> |
8 | #include <asm/xen/hypervisor.h> | 12 | #include <asm/xen/hypervisor.h> |
@@ -331,3 +335,80 @@ void xen_arch_unregister_cpu(int num) | |||
331 | } | 335 | } |
332 | EXPORT_SYMBOL(xen_arch_unregister_cpu); | 336 | EXPORT_SYMBOL(xen_arch_unregister_cpu); |
333 | #endif | 337 | #endif |
338 | |||
339 | #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG | ||
340 | void __init arch_xen_balloon_init(struct resource *hostmem_resource) | ||
341 | { | ||
342 | struct xen_memory_map memmap; | ||
343 | int rc; | ||
344 | unsigned int i, last_guest_ram; | ||
345 | phys_addr_t max_addr = PFN_PHYS(max_pfn); | ||
346 | struct e820_table *xen_e820_table; | ||
347 | const struct e820_entry *entry; | ||
348 | struct resource *res; | ||
349 | |||
350 | if (!xen_initial_domain()) | ||
351 | return; | ||
352 | |||
353 | xen_e820_table = kmalloc(sizeof(*xen_e820_table), GFP_KERNEL); | ||
354 | if (!xen_e820_table) | ||
355 | return; | ||
356 | |||
357 | memmap.nr_entries = ARRAY_SIZE(xen_e820_table->entries); | ||
358 | set_xen_guest_handle(memmap.buffer, xen_e820_table->entries); | ||
359 | rc = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap); | ||
360 | if (rc) { | ||
361 | pr_warn("%s: Can't read host e820 (%d)\n", __func__, rc); | ||
362 | goto out; | ||
363 | } | ||
364 | |||
365 | last_guest_ram = 0; | ||
366 | for (i = 0; i < memmap.nr_entries; i++) { | ||
367 | if (xen_e820_table->entries[i].addr >= max_addr) | ||
368 | break; | ||
369 | if (xen_e820_table->entries[i].type == E820_TYPE_RAM) | ||
370 | last_guest_ram = i; | ||
371 | } | ||
372 | |||
373 | entry = &xen_e820_table->entries[last_guest_ram]; | ||
374 | if (max_addr >= entry->addr + entry->size) | ||
375 | goto out; /* No unallocated host RAM. */ | ||
376 | |||
377 | hostmem_resource->start = max_addr; | ||
378 | hostmem_resource->end = entry->addr + entry->size; | ||
379 | |||
380 | /* | ||
381 | * Mark non-RAM regions between the end of dom0 RAM and end of host RAM | ||
382 | * as unavailable. The rest of that region can be used for hotplug-based | ||
383 | * ballooning. | ||
384 | */ | ||
385 | for (; i < memmap.nr_entries; i++) { | ||
386 | entry = &xen_e820_table->entries[i]; | ||
387 | |||
388 | if (entry->type == E820_TYPE_RAM) | ||
389 | continue; | ||
390 | |||
391 | if (entry->addr >= hostmem_resource->end) | ||
392 | break; | ||
393 | |||
394 | res = kzalloc(sizeof(*res), GFP_KERNEL); | ||
395 | if (!res) | ||
396 | goto out; | ||
397 | |||
398 | res->name = "Unavailable host RAM"; | ||
399 | res->start = entry->addr; | ||
400 | res->end = (entry->addr + entry->size < hostmem_resource->end) ? | ||
401 | entry->addr + entry->size : hostmem_resource->end; | ||
402 | rc = insert_resource(hostmem_resource, res); | ||
403 | if (rc) { | ||
404 | pr_warn("%s: Can't insert [%llx - %llx) (%d)\n", | ||
405 | __func__, res->start, res->end, rc); | ||
406 | kfree(res); | ||
407 | goto out; | ||
408 | } | ||
409 | } | ||
410 | |||
411 | out: | ||
412 | kfree(xen_e820_table); | ||
413 | } | ||
414 | #endif /* CONFIG_XEN_BALLOON_MEMORY_HOTPLUG */ | ||
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 7beeee1443b3..c047f42552e1 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c | |||
@@ -88,6 +88,8 @@ | |||
88 | #include "multicalls.h" | 88 | #include "multicalls.h" |
89 | #include "pmu.h" | 89 | #include "pmu.h" |
90 | 90 | ||
91 | #include "../kernel/cpu/cpu.h" /* get_cpu_cap() */ | ||
92 | |||
91 | void *xen_initial_gdt; | 93 | void *xen_initial_gdt; |
92 | 94 | ||
93 | static int xen_cpu_up_prepare_pv(unsigned int cpu); | 95 | static int xen_cpu_up_prepare_pv(unsigned int cpu); |
@@ -1258,6 +1260,7 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1258 | __userpte_alloc_gfp &= ~__GFP_HIGHMEM; | 1260 | __userpte_alloc_gfp &= ~__GFP_HIGHMEM; |
1259 | 1261 | ||
1260 | /* Work out if we support NX */ | 1262 | /* Work out if we support NX */ |
1263 | get_cpu_cap(&boot_cpu_data); | ||
1261 | x86_configure_nx(); | 1264 | x86_configure_nx(); |
1262 | 1265 | ||
1263 | /* Get mfn list */ | 1266 | /* Get mfn list */ |
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 6cf801ca1142..4d62c071b166 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c | |||
@@ -1902,6 +1902,18 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) | |||
1902 | /* Graft it onto L4[511][510] */ | 1902 | /* Graft it onto L4[511][510] */ |
1903 | copy_page(level2_kernel_pgt, l2); | 1903 | copy_page(level2_kernel_pgt, l2); |
1904 | 1904 | ||
1905 | /* | ||
1906 | * Zap execute permission from the ident map. Due to the sharing of | ||
1907 | * L1 entries we need to do this in the L2. | ||
1908 | */ | ||
1909 | if (__supported_pte_mask & _PAGE_NX) { | ||
1910 | for (i = 0; i < PTRS_PER_PMD; ++i) { | ||
1911 | if (pmd_none(level2_ident_pgt[i])) | ||
1912 | continue; | ||
1913 | level2_ident_pgt[i] = pmd_set_flags(level2_ident_pgt[i], _PAGE_NX); | ||
1914 | } | ||
1915 | } | ||
1916 | |||
1905 | /* Copy the initial P->M table mappings if necessary. */ | 1917 | /* Copy the initial P->M table mappings if necessary. */ |
1906 | i = pgd_index(xen_start_info->mfn_list); | 1918 | i = pgd_index(xen_start_info->mfn_list); |
1907 | if (i && i < pgd_index(__START_KERNEL_map)) | 1919 | if (i && i < pgd_index(__START_KERNEL_map)) |
@@ -2261,7 +2273,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) | |||
2261 | 2273 | ||
2262 | switch (idx) { | 2274 | switch (idx) { |
2263 | case FIX_BTMAP_END ... FIX_BTMAP_BEGIN: | 2275 | case FIX_BTMAP_END ... FIX_BTMAP_BEGIN: |
2264 | case FIX_RO_IDT: | ||
2265 | #ifdef CONFIG_X86_32 | 2276 | #ifdef CONFIG_X86_32 |
2266 | case FIX_WP_TEST: | 2277 | case FIX_WP_TEST: |
2267 | # ifdef CONFIG_HIGHMEM | 2278 | # ifdef CONFIG_HIGHMEM |
@@ -2272,7 +2283,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) | |||
2272 | #endif | 2283 | #endif |
2273 | case FIX_TEXT_POKE0: | 2284 | case FIX_TEXT_POKE0: |
2274 | case FIX_TEXT_POKE1: | 2285 | case FIX_TEXT_POKE1: |
2275 | case FIX_CPU_ENTRY_AREA_TOP ... FIX_CPU_ENTRY_AREA_BOTTOM: | ||
2276 | /* All local page mappings */ | 2286 | /* All local page mappings */ |
2277 | pte = pfn_pte(phys, prot); | 2287 | pte = pfn_pte(phys, prot); |
2278 | break; | 2288 | break; |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index c114ca767b3b..6e0d2086eacb 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -808,7 +808,6 @@ char * __init xen_memory_setup(void) | |||
808 | addr = xen_e820_table.entries[0].addr; | 808 | addr = xen_e820_table.entries[0].addr; |
809 | size = xen_e820_table.entries[0].size; | 809 | size = xen_e820_table.entries[0].size; |
810 | while (i < xen_e820_table.nr_entries) { | 810 | while (i < xen_e820_table.nr_entries) { |
811 | bool discard = false; | ||
812 | 811 | ||
813 | chunk_size = size; | 812 | chunk_size = size; |
814 | type = xen_e820_table.entries[i].type; | 813 | type = xen_e820_table.entries[i].type; |
@@ -824,11 +823,10 @@ char * __init xen_memory_setup(void) | |||
824 | xen_add_extra_mem(pfn_s, n_pfns); | 823 | xen_add_extra_mem(pfn_s, n_pfns); |
825 | xen_max_p2m_pfn = pfn_s + n_pfns; | 824 | xen_max_p2m_pfn = pfn_s + n_pfns; |
826 | } else | 825 | } else |
827 | discard = true; | 826 | type = E820_TYPE_UNUSABLE; |
828 | } | 827 | } |
829 | 828 | ||
830 | if (!discard) | 829 | xen_align_and_add_e820_region(addr, chunk_size, type); |
831 | xen_align_and_add_e820_region(addr, chunk_size, type); | ||
832 | 830 | ||
833 | addr += chunk_size; | 831 | addr += chunk_size; |
834 | size -= chunk_size; | 832 | size -= chunk_size; |
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 415a54ced4d6..444a387df219 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c | |||
@@ -1138,12 +1138,6 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags, | |||
1138 | if (!af_alg_readable(sk)) | 1138 | if (!af_alg_readable(sk)) |
1139 | break; | 1139 | break; |
1140 | 1140 | ||
1141 | if (!ctx->used) { | ||
1142 | err = af_alg_wait_for_data(sk, flags); | ||
1143 | if (err) | ||
1144 | return err; | ||
1145 | } | ||
1146 | |||
1147 | seglen = min_t(size_t, (maxsize - len), | 1141 | seglen = min_t(size_t, (maxsize - len), |
1148 | msg_data_left(msg)); | 1142 | msg_data_left(msg)); |
1149 | 1143 | ||
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index 48b34e9c6834..ddcc45f77edd 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c | |||
@@ -111,6 +111,12 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, | |||
111 | size_t usedpages = 0; /* [in] RX bufs to be used from user */ | 111 | size_t usedpages = 0; /* [in] RX bufs to be used from user */ |
112 | size_t processed = 0; /* [in] TX bufs to be consumed */ | 112 | size_t processed = 0; /* [in] TX bufs to be consumed */ |
113 | 113 | ||
114 | if (!ctx->used) { | ||
115 | err = af_alg_wait_for_data(sk, flags); | ||
116 | if (err) | ||
117 | return err; | ||
118 | } | ||
119 | |||
114 | /* | 120 | /* |
115 | * Data length provided by caller via sendmsg/sendpage that has not | 121 | * Data length provided by caller via sendmsg/sendpage that has not |
116 | * yet been processed. | 122 | * yet been processed. |
@@ -285,6 +291,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, | |||
285 | /* AIO operation */ | 291 | /* AIO operation */ |
286 | sock_hold(sk); | 292 | sock_hold(sk); |
287 | areq->iocb = msg->msg_iocb; | 293 | areq->iocb = msg->msg_iocb; |
294 | |||
295 | /* Remember output size that will be generated. */ | ||
296 | areq->outlen = outlen; | ||
297 | |||
288 | aead_request_set_callback(&areq->cra_u.aead_req, | 298 | aead_request_set_callback(&areq->cra_u.aead_req, |
289 | CRYPTO_TFM_REQ_MAY_BACKLOG, | 299 | CRYPTO_TFM_REQ_MAY_BACKLOG, |
290 | af_alg_async_cb, areq); | 300 | af_alg_async_cb, areq); |
@@ -292,12 +302,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, | |||
292 | crypto_aead_decrypt(&areq->cra_u.aead_req); | 302 | crypto_aead_decrypt(&areq->cra_u.aead_req); |
293 | 303 | ||
294 | /* AIO operation in progress */ | 304 | /* AIO operation in progress */ |
295 | if (err == -EINPROGRESS || err == -EBUSY) { | 305 | if (err == -EINPROGRESS || err == -EBUSY) |
296 | /* Remember output size that will be generated. */ | ||
297 | areq->outlen = outlen; | ||
298 | |||
299 | return -EIOCBQUEUED; | 306 | return -EIOCBQUEUED; |
300 | } | ||
301 | 307 | ||
302 | sock_put(sk); | 308 | sock_put(sk); |
303 | } else { | 309 | } else { |
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 30cff827dd8f..baef9bfccdda 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c | |||
@@ -72,6 +72,12 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, | |||
72 | int err = 0; | 72 | int err = 0; |
73 | size_t len = 0; | 73 | size_t len = 0; |
74 | 74 | ||
75 | if (!ctx->used) { | ||
76 | err = af_alg_wait_for_data(sk, flags); | ||
77 | if (err) | ||
78 | return err; | ||
79 | } | ||
80 | |||
75 | /* Allocate cipher request for current operation. */ | 81 | /* Allocate cipher request for current operation. */ |
76 | areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) + | 82 | areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) + |
77 | crypto_skcipher_reqsize(tfm)); | 83 | crypto_skcipher_reqsize(tfm)); |
@@ -119,6 +125,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, | |||
119 | /* AIO operation */ | 125 | /* AIO operation */ |
120 | sock_hold(sk); | 126 | sock_hold(sk); |
121 | areq->iocb = msg->msg_iocb; | 127 | areq->iocb = msg->msg_iocb; |
128 | |||
129 | /* Remember output size that will be generated. */ | ||
130 | areq->outlen = len; | ||
131 | |||
122 | skcipher_request_set_callback(&areq->cra_u.skcipher_req, | 132 | skcipher_request_set_callback(&areq->cra_u.skcipher_req, |
123 | CRYPTO_TFM_REQ_MAY_SLEEP, | 133 | CRYPTO_TFM_REQ_MAY_SLEEP, |
124 | af_alg_async_cb, areq); | 134 | af_alg_async_cb, areq); |
@@ -127,12 +137,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, | |||
127 | crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); | 137 | crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); |
128 | 138 | ||
129 | /* AIO operation in progress */ | 139 | /* AIO operation in progress */ |
130 | if (err == -EINPROGRESS || err == -EBUSY) { | 140 | if (err == -EINPROGRESS || err == -EBUSY) |
131 | /* Remember output size that will be generated. */ | ||
132 | areq->outlen = len; | ||
133 | |||
134 | return -EIOCBQUEUED; | 141 | return -EIOCBQUEUED; |
135 | } | ||
136 | 142 | ||
137 | sock_put(sk); | 143 | sock_put(sk); |
138 | } else { | 144 | } else { |
diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c index 4e6472658852..eca04d3729b3 100644 --- a/crypto/mcryptd.c +++ b/crypto/mcryptd.c | |||
@@ -81,6 +81,7 @@ static int mcryptd_init_queue(struct mcryptd_queue *queue, | |||
81 | pr_debug("cpu_queue #%d %p\n", cpu, queue->cpu_queue); | 81 | pr_debug("cpu_queue #%d %p\n", cpu, queue->cpu_queue); |
82 | crypto_init_queue(&cpu_queue->queue, max_cpu_qlen); | 82 | crypto_init_queue(&cpu_queue->queue, max_cpu_qlen); |
83 | INIT_WORK(&cpu_queue->work, mcryptd_queue_worker); | 83 | INIT_WORK(&cpu_queue->work, mcryptd_queue_worker); |
84 | spin_lock_init(&cpu_queue->q_lock); | ||
84 | } | 85 | } |
85 | return 0; | 86 | return 0; |
86 | } | 87 | } |
@@ -104,15 +105,16 @@ static int mcryptd_enqueue_request(struct mcryptd_queue *queue, | |||
104 | int cpu, err; | 105 | int cpu, err; |
105 | struct mcryptd_cpu_queue *cpu_queue; | 106 | struct mcryptd_cpu_queue *cpu_queue; |
106 | 107 | ||
107 | cpu = get_cpu(); | 108 | cpu_queue = raw_cpu_ptr(queue->cpu_queue); |
108 | cpu_queue = this_cpu_ptr(queue->cpu_queue); | 109 | spin_lock(&cpu_queue->q_lock); |
109 | rctx->tag.cpu = cpu; | 110 | cpu = smp_processor_id(); |
111 | rctx->tag.cpu = smp_processor_id(); | ||
110 | 112 | ||
111 | err = crypto_enqueue_request(&cpu_queue->queue, request); | 113 | err = crypto_enqueue_request(&cpu_queue->queue, request); |
112 | pr_debug("enqueue request: cpu %d cpu_queue %p request %p\n", | 114 | pr_debug("enqueue request: cpu %d cpu_queue %p request %p\n", |
113 | cpu, cpu_queue, request); | 115 | cpu, cpu_queue, request); |
116 | spin_unlock(&cpu_queue->q_lock); | ||
114 | queue_work_on(cpu, kcrypto_wq, &cpu_queue->work); | 117 | queue_work_on(cpu, kcrypto_wq, &cpu_queue->work); |
115 | put_cpu(); | ||
116 | 118 | ||
117 | return err; | 119 | return err; |
118 | } | 120 | } |
@@ -161,16 +163,11 @@ static void mcryptd_queue_worker(struct work_struct *work) | |||
161 | cpu_queue = container_of(work, struct mcryptd_cpu_queue, work); | 163 | cpu_queue = container_of(work, struct mcryptd_cpu_queue, work); |
162 | i = 0; | 164 | i = 0; |
163 | while (i < MCRYPTD_BATCH || single_task_running()) { | 165 | while (i < MCRYPTD_BATCH || single_task_running()) { |
164 | /* | 166 | |
165 | * preempt_disable/enable is used to prevent | 167 | spin_lock_bh(&cpu_queue->q_lock); |
166 | * being preempted by mcryptd_enqueue_request() | ||
167 | */ | ||
168 | local_bh_disable(); | ||
169 | preempt_disable(); | ||
170 | backlog = crypto_get_backlog(&cpu_queue->queue); | 168 | backlog = crypto_get_backlog(&cpu_queue->queue); |
171 | req = crypto_dequeue_request(&cpu_queue->queue); | 169 | req = crypto_dequeue_request(&cpu_queue->queue); |
172 | preempt_enable(); | 170 | spin_unlock_bh(&cpu_queue->q_lock); |
173 | local_bh_enable(); | ||
174 | 171 | ||
175 | if (!req) { | 172 | if (!req) { |
176 | mcryptd_opportunistic_flush(); | 173 | mcryptd_opportunistic_flush(); |
@@ -185,7 +182,7 @@ static void mcryptd_queue_worker(struct work_struct *work) | |||
185 | ++i; | 182 | ++i; |
186 | } | 183 | } |
187 | if (cpu_queue->queue.qlen) | 184 | if (cpu_queue->queue.qlen) |
188 | queue_work(kcrypto_wq, &cpu_queue->work); | 185 | queue_work_on(smp_processor_id(), kcrypto_wq, &cpu_queue->work); |
189 | } | 186 | } |
190 | 187 | ||
191 | void mcryptd_flusher(struct work_struct *__work) | 188 | void mcryptd_flusher(struct work_struct *__work) |
diff --git a/crypto/skcipher.c b/crypto/skcipher.c index 778e0ff42bfa..11af5fd6a443 100644 --- a/crypto/skcipher.c +++ b/crypto/skcipher.c | |||
@@ -449,6 +449,8 @@ static int skcipher_walk_skcipher(struct skcipher_walk *walk, | |||
449 | 449 | ||
450 | walk->total = req->cryptlen; | 450 | walk->total = req->cryptlen; |
451 | walk->nbytes = 0; | 451 | walk->nbytes = 0; |
452 | walk->iv = req->iv; | ||
453 | walk->oiv = req->iv; | ||
452 | 454 | ||
453 | if (unlikely(!walk->total)) | 455 | if (unlikely(!walk->total)) |
454 | return 0; | 456 | return 0; |
@@ -456,9 +458,6 @@ static int skcipher_walk_skcipher(struct skcipher_walk *walk, | |||
456 | scatterwalk_start(&walk->in, req->src); | 458 | scatterwalk_start(&walk->in, req->src); |
457 | scatterwalk_start(&walk->out, req->dst); | 459 | scatterwalk_start(&walk->out, req->dst); |
458 | 460 | ||
459 | walk->iv = req->iv; | ||
460 | walk->oiv = req->iv; | ||
461 | |||
462 | walk->flags &= ~SKCIPHER_WALK_SLEEP; | 461 | walk->flags &= ~SKCIPHER_WALK_SLEEP; |
463 | walk->flags |= req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? | 462 | walk->flags |= req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? |
464 | SKCIPHER_WALK_SLEEP : 0; | 463 | SKCIPHER_WALK_SLEEP : 0; |
@@ -510,6 +509,8 @@ static int skcipher_walk_aead_common(struct skcipher_walk *walk, | |||
510 | int err; | 509 | int err; |
511 | 510 | ||
512 | walk->nbytes = 0; | 511 | walk->nbytes = 0; |
512 | walk->iv = req->iv; | ||
513 | walk->oiv = req->iv; | ||
513 | 514 | ||
514 | if (unlikely(!walk->total)) | 515 | if (unlikely(!walk->total)) |
515 | return 0; | 516 | return 0; |
@@ -525,9 +526,6 @@ static int skcipher_walk_aead_common(struct skcipher_walk *walk, | |||
525 | scatterwalk_done(&walk->in, 0, walk->total); | 526 | scatterwalk_done(&walk->in, 0, walk->total); |
526 | scatterwalk_done(&walk->out, 0, walk->total); | 527 | scatterwalk_done(&walk->out, 0, walk->total); |
527 | 528 | ||
528 | walk->iv = req->iv; | ||
529 | walk->oiv = req->iv; | ||
530 | |||
531 | if (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) | 529 | if (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) |
532 | walk->flags |= SKCIPHER_WALK_SLEEP; | 530 | walk->flags |= SKCIPHER_WALK_SLEEP; |
533 | else | 531 | else |
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index ff2580e7611d..abeb4df4f22e 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c | |||
@@ -1670,6 +1670,11 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, | |||
1670 | dev_name(&adev_dimm->dev)); | 1670 | dev_name(&adev_dimm->dev)); |
1671 | return -ENXIO; | 1671 | return -ENXIO; |
1672 | } | 1672 | } |
1673 | /* | ||
1674 | * Record nfit_mem for the notification path to track back to | ||
1675 | * the nfit sysfs attributes for this dimm device object. | ||
1676 | */ | ||
1677 | dev_set_drvdata(&adev_dimm->dev, nfit_mem); | ||
1673 | 1678 | ||
1674 | /* | 1679 | /* |
1675 | * Until standardization materializes we need to consider 4 | 1680 | * Until standardization materializes we need to consider 4 |
@@ -1752,9 +1757,11 @@ static void shutdown_dimm_notify(void *data) | |||
1752 | sysfs_put(nfit_mem->flags_attr); | 1757 | sysfs_put(nfit_mem->flags_attr); |
1753 | nfit_mem->flags_attr = NULL; | 1758 | nfit_mem->flags_attr = NULL; |
1754 | } | 1759 | } |
1755 | if (adev_dimm) | 1760 | if (adev_dimm) { |
1756 | acpi_remove_notify_handler(adev_dimm->handle, | 1761 | acpi_remove_notify_handler(adev_dimm->handle, |
1757 | ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify); | 1762 | ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify); |
1763 | dev_set_drvdata(&adev_dimm->dev, NULL); | ||
1764 | } | ||
1758 | } | 1765 | } |
1759 | mutex_unlock(&acpi_desc->init_mutex); | 1766 | mutex_unlock(&acpi_desc->init_mutex); |
1760 | } | 1767 | } |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 647d056df88c..b56c11f51baf 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -220,7 +220,8 @@ static bool clk_core_is_enabled(struct clk_core *core) | |||
220 | 220 | ||
221 | ret = core->ops->is_enabled(core->hw); | 221 | ret = core->ops->is_enabled(core->hw); |
222 | done: | 222 | done: |
223 | clk_pm_runtime_put(core); | 223 | if (core->dev) |
224 | pm_runtime_put(core->dev); | ||
224 | 225 | ||
225 | return ret; | 226 | return ret; |
226 | } | 227 | } |
@@ -1564,6 +1565,9 @@ static void clk_change_rate(struct clk_core *core) | |||
1564 | best_parent_rate = core->parent->rate; | 1565 | best_parent_rate = core->parent->rate; |
1565 | } | 1566 | } |
1566 | 1567 | ||
1568 | if (clk_pm_runtime_get(core)) | ||
1569 | return; | ||
1570 | |||
1567 | if (core->flags & CLK_SET_RATE_UNGATE) { | 1571 | if (core->flags & CLK_SET_RATE_UNGATE) { |
1568 | unsigned long flags; | 1572 | unsigned long flags; |
1569 | 1573 | ||
@@ -1634,6 +1638,8 @@ static void clk_change_rate(struct clk_core *core) | |||
1634 | /* handle the new child who might not be in core->children yet */ | 1638 | /* handle the new child who might not be in core->children yet */ |
1635 | if (core->new_child) | 1639 | if (core->new_child) |
1636 | clk_change_rate(core->new_child); | 1640 | clk_change_rate(core->new_child); |
1641 | |||
1642 | clk_pm_runtime_put(core); | ||
1637 | } | 1643 | } |
1638 | 1644 | ||
1639 | static int clk_core_set_rate_nolock(struct clk_core *core, | 1645 | static int clk_core_set_rate_nolock(struct clk_core *core, |
diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c index a1a634253d6f..f00d8758ba24 100644 --- a/drivers/clk/sunxi/clk-sun9i-mmc.c +++ b/drivers/clk/sunxi/clk-sun9i-mmc.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/clk-provider.h> | 18 | #include <linux/clk-provider.h> |
19 | #include <linux/delay.h> | ||
19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
20 | #include <linux/of.h> | 21 | #include <linux/of.h> |
21 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
@@ -83,9 +84,20 @@ static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev, | |||
83 | return 0; | 84 | return 0; |
84 | } | 85 | } |
85 | 86 | ||
87 | static int sun9i_mmc_reset_reset(struct reset_controller_dev *rcdev, | ||
88 | unsigned long id) | ||
89 | { | ||
90 | sun9i_mmc_reset_assert(rcdev, id); | ||
91 | udelay(10); | ||
92 | sun9i_mmc_reset_deassert(rcdev, id); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
86 | static const struct reset_control_ops sun9i_mmc_reset_ops = { | 97 | static const struct reset_control_ops sun9i_mmc_reset_ops = { |
87 | .assert = sun9i_mmc_reset_assert, | 98 | .assert = sun9i_mmc_reset_assert, |
88 | .deassert = sun9i_mmc_reset_deassert, | 99 | .deassert = sun9i_mmc_reset_deassert, |
100 | .reset = sun9i_mmc_reset_reset, | ||
89 | }; | 101 | }; |
90 | 102 | ||
91 | static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev) | 103 | static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev) |
diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c index 23e771dba4c1..e85903eddc68 100644 --- a/drivers/gpio/gpio-reg.c +++ b/drivers/gpio/gpio-reg.c | |||
@@ -103,8 +103,8 @@ static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset) | |||
103 | struct gpio_reg *r = to_gpio_reg(gc); | 103 | struct gpio_reg *r = to_gpio_reg(gc); |
104 | int irq = r->irqs[offset]; | 104 | int irq = r->irqs[offset]; |
105 | 105 | ||
106 | if (irq >= 0 && r->irq.domain) | 106 | if (irq >= 0 && r->irqdomain) |
107 | irq = irq_find_mapping(r->irq.domain, irq); | 107 | irq = irq_find_mapping(r->irqdomain, irq); |
108 | 108 | ||
109 | return irq; | 109 | return irq; |
110 | } | 110 | } |
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index eb4528c87c0b..d6f3d9ee1350 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c | |||
@@ -1074,7 +1074,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip) | |||
1074 | } | 1074 | } |
1075 | 1075 | ||
1076 | if (!chip->names) | 1076 | if (!chip->names) |
1077 | devprop_gpiochip_set_names(chip); | 1077 | devprop_gpiochip_set_names(chip, dev_fwnode(chip->parent)); |
1078 | 1078 | ||
1079 | acpi_gpiochip_request_regions(acpi_gpio); | 1079 | acpi_gpiochip_request_regions(acpi_gpio); |
1080 | acpi_gpiochip_scan_gpios(acpi_gpio); | 1080 | acpi_gpiochip_scan_gpios(acpi_gpio); |
diff --git a/drivers/gpio/gpiolib-devprop.c b/drivers/gpio/gpiolib-devprop.c index 27f383bda7d9..f748aa3e77f7 100644 --- a/drivers/gpio/gpiolib-devprop.c +++ b/drivers/gpio/gpiolib-devprop.c | |||
@@ -19,30 +19,27 @@ | |||
19 | /** | 19 | /** |
20 | * devprop_gpiochip_set_names - Set GPIO line names using device properties | 20 | * devprop_gpiochip_set_names - Set GPIO line names using device properties |
21 | * @chip: GPIO chip whose lines should be named, if possible | 21 | * @chip: GPIO chip whose lines should be named, if possible |
22 | * @fwnode: Property Node containing the gpio-line-names property | ||
22 | * | 23 | * |
23 | * Looks for device property "gpio-line-names" and if it exists assigns | 24 | * Looks for device property "gpio-line-names" and if it exists assigns |
24 | * GPIO line names for the chip. The memory allocated for the assigned | 25 | * GPIO line names for the chip. The memory allocated for the assigned |
25 | * names belong to the underlying firmware node and should not be released | 26 | * names belong to the underlying firmware node and should not be released |
26 | * by the caller. | 27 | * by the caller. |
27 | */ | 28 | */ |
28 | void devprop_gpiochip_set_names(struct gpio_chip *chip) | 29 | void devprop_gpiochip_set_names(struct gpio_chip *chip, |
30 | const struct fwnode_handle *fwnode) | ||
29 | { | 31 | { |
30 | struct gpio_device *gdev = chip->gpiodev; | 32 | struct gpio_device *gdev = chip->gpiodev; |
31 | const char **names; | 33 | const char **names; |
32 | int ret, i; | 34 | int ret, i; |
33 | 35 | ||
34 | if (!chip->parent) { | 36 | ret = fwnode_property_read_string_array(fwnode, "gpio-line-names", |
35 | dev_warn(&gdev->dev, "GPIO chip parent is NULL\n"); | ||
36 | return; | ||
37 | } | ||
38 | |||
39 | ret = device_property_read_string_array(chip->parent, "gpio-line-names", | ||
40 | NULL, 0); | 37 | NULL, 0); |
41 | if (ret < 0) | 38 | if (ret < 0) |
42 | return; | 39 | return; |
43 | 40 | ||
44 | if (ret != gdev->ngpio) { | 41 | if (ret != gdev->ngpio) { |
45 | dev_warn(chip->parent, | 42 | dev_warn(&gdev->dev, |
46 | "names %d do not match number of GPIOs %d\n", ret, | 43 | "names %d do not match number of GPIOs %d\n", ret, |
47 | gdev->ngpio); | 44 | gdev->ngpio); |
48 | return; | 45 | return; |
@@ -52,10 +49,10 @@ void devprop_gpiochip_set_names(struct gpio_chip *chip) | |||
52 | if (!names) | 49 | if (!names) |
53 | return; | 50 | return; |
54 | 51 | ||
55 | ret = device_property_read_string_array(chip->parent, "gpio-line-names", | 52 | ret = fwnode_property_read_string_array(fwnode, "gpio-line-names", |
56 | names, gdev->ngpio); | 53 | names, gdev->ngpio); |
57 | if (ret < 0) { | 54 | if (ret < 0) { |
58 | dev_warn(chip->parent, "failed to read GPIO line names\n"); | 55 | dev_warn(&gdev->dev, "failed to read GPIO line names\n"); |
59 | kfree(names); | 56 | kfree(names); |
60 | return; | 57 | return; |
61 | } | 58 | } |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index e0d59e61b52f..72a0695d2ac3 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
@@ -493,7 +493,8 @@ int of_gpiochip_add(struct gpio_chip *chip) | |||
493 | 493 | ||
494 | /* If the chip defines names itself, these take precedence */ | 494 | /* If the chip defines names itself, these take precedence */ |
495 | if (!chip->names) | 495 | if (!chip->names) |
496 | devprop_gpiochip_set_names(chip); | 496 | devprop_gpiochip_set_names(chip, |
497 | of_fwnode_handle(chip->of_node)); | ||
497 | 498 | ||
498 | of_node_get(chip->of_node); | 499 | of_node_get(chip->of_node); |
499 | 500 | ||
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index af48322839c3..6c44d1652139 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h | |||
@@ -228,7 +228,8 @@ static inline int gpio_chip_hwgpio(const struct gpio_desc *desc) | |||
228 | return desc - &desc->gdev->descs[0]; | 228 | return desc - &desc->gdev->descs[0]; |
229 | } | 229 | } |
230 | 230 | ||
231 | void devprop_gpiochip_set_names(struct gpio_chip *chip); | 231 | void devprop_gpiochip_set_names(struct gpio_chip *chip, |
232 | const struct fwnode_handle *fwnode); | ||
232 | 233 | ||
233 | /* With descriptor prefix */ | 234 | /* With descriptor prefix */ |
234 | 235 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index da43813d67a4..5aeb5f8816f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | |||
@@ -2467,7 +2467,7 @@ static int gfx_v9_0_kiq_kcq_enable(struct amdgpu_device *adev) | |||
2467 | PACKET3_MAP_QUEUES_PIPE(ring->pipe) | | 2467 | PACKET3_MAP_QUEUES_PIPE(ring->pipe) | |
2468 | PACKET3_MAP_QUEUES_ME((ring->me == 1 ? 0 : 1)) | | 2468 | PACKET3_MAP_QUEUES_ME((ring->me == 1 ? 0 : 1)) | |
2469 | PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */ | 2469 | PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */ |
2470 | PACKET3_MAP_QUEUES_ALLOC_FORMAT(1) | /* alloc format: all_on_one_pipe */ | 2470 | PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */ |
2471 | PACKET3_MAP_QUEUES_ENGINE_SEL(0) | /* engine_sel: compute */ | 2471 | PACKET3_MAP_QUEUES_ENGINE_SEL(0) | /* engine_sel: compute */ |
2472 | PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */ | 2472 | PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */ |
2473 | amdgpu_ring_write(kiq_ring, PACKET3_MAP_QUEUES_DOORBELL_OFFSET(ring->doorbell_index)); | 2473 | amdgpu_ring_write(kiq_ring, PACKET3_MAP_QUEUES_DOORBELL_OFFSET(ring->doorbell_index)); |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f71fe6d2ddda..bb5fa895fb64 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
@@ -2336,7 +2336,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
2336 | const struct dm_connector_state *dm_state) | 2336 | const struct dm_connector_state *dm_state) |
2337 | { | 2337 | { |
2338 | struct drm_display_mode *preferred_mode = NULL; | 2338 | struct drm_display_mode *preferred_mode = NULL; |
2339 | const struct drm_connector *drm_connector; | 2339 | struct drm_connector *drm_connector; |
2340 | struct dc_stream_state *stream = NULL; | 2340 | struct dc_stream_state *stream = NULL; |
2341 | struct drm_display_mode mode = *drm_mode; | 2341 | struct drm_display_mode mode = *drm_mode; |
2342 | bool native_mode_found = false; | 2342 | bool native_mode_found = false; |
@@ -2355,11 +2355,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
2355 | 2355 | ||
2356 | if (!aconnector->dc_sink) { | 2356 | if (!aconnector->dc_sink) { |
2357 | /* | 2357 | /* |
2358 | * Exclude MST from creating fake_sink | 2358 | * Create dc_sink when necessary to MST |
2359 | * TODO: need to enable MST into fake_sink feature | 2359 | * Don't apply fake_sink to MST |
2360 | */ | 2360 | */ |
2361 | if (aconnector->mst_port) | 2361 | if (aconnector->mst_port) { |
2362 | goto stream_create_fail; | 2362 | dm_dp_mst_dc_sink_create(drm_connector); |
2363 | goto mst_dc_sink_create_done; | ||
2364 | } | ||
2363 | 2365 | ||
2364 | if (create_fake_sink(aconnector)) | 2366 | if (create_fake_sink(aconnector)) |
2365 | goto stream_create_fail; | 2367 | goto stream_create_fail; |
@@ -2410,6 +2412,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
2410 | stream_create_fail: | 2412 | stream_create_fail: |
2411 | dm_state_null: | 2413 | dm_state_null: |
2412 | drm_connector_null: | 2414 | drm_connector_null: |
2415 | mst_dc_sink_create_done: | ||
2413 | return stream; | 2416 | return stream; |
2414 | } | 2417 | } |
2415 | 2418 | ||
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 117521c6a6ed..0230250a1164 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | |||
@@ -189,6 +189,8 @@ struct amdgpu_dm_connector { | |||
189 | struct mutex hpd_lock; | 189 | struct mutex hpd_lock; |
190 | 190 | ||
191 | bool fake_enable; | 191 | bool fake_enable; |
192 | |||
193 | bool mst_connected; | ||
192 | }; | 194 | }; |
193 | 195 | ||
194 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) | 196 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index f8efb98b1fa7..638c2c2b5cd7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | |||
@@ -185,6 +185,42 @@ static int dm_connector_update_modes(struct drm_connector *connector, | |||
185 | return ret; | 185 | return ret; |
186 | } | 186 | } |
187 | 187 | ||
188 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector) | ||
189 | { | ||
190 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | ||
191 | struct edid *edid; | ||
192 | struct dc_sink *dc_sink; | ||
193 | struct dc_sink_init_data init_params = { | ||
194 | .link = aconnector->dc_link, | ||
195 | .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; | ||
196 | |||
197 | edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); | ||
198 | |||
199 | if (!edid) { | ||
200 | drm_mode_connector_update_edid_property( | ||
201 | &aconnector->base, | ||
202 | NULL); | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | aconnector->edid = edid; | ||
207 | |||
208 | dc_sink = dc_link_add_remote_sink( | ||
209 | aconnector->dc_link, | ||
210 | (uint8_t *)aconnector->edid, | ||
211 | (aconnector->edid->extensions + 1) * EDID_LENGTH, | ||
212 | &init_params); | ||
213 | |||
214 | dc_sink->priv = aconnector; | ||
215 | aconnector->dc_sink = dc_sink; | ||
216 | |||
217 | amdgpu_dm_add_sink_to_freesync_module( | ||
218 | connector, aconnector->edid); | ||
219 | |||
220 | drm_mode_connector_update_edid_property( | ||
221 | &aconnector->base, aconnector->edid); | ||
222 | } | ||
223 | |||
188 | static int dm_dp_mst_get_modes(struct drm_connector *connector) | 224 | static int dm_dp_mst_get_modes(struct drm_connector *connector) |
189 | { | 225 | { |
190 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | 226 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
@@ -311,6 +347,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
311 | drm_mode_connector_set_path_property(connector, pathprop); | 347 | drm_mode_connector_set_path_property(connector, pathprop); |
312 | 348 | ||
313 | drm_connector_list_iter_end(&conn_iter); | 349 | drm_connector_list_iter_end(&conn_iter); |
350 | aconnector->mst_connected = true; | ||
314 | return &aconnector->base; | 351 | return &aconnector->base; |
315 | } | 352 | } |
316 | } | 353 | } |
@@ -363,6 +400,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
363 | */ | 400 | */ |
364 | amdgpu_dm_connector_funcs_reset(connector); | 401 | amdgpu_dm_connector_funcs_reset(connector); |
365 | 402 | ||
403 | aconnector->mst_connected = true; | ||
404 | |||
366 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", | 405 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", |
367 | aconnector, connector->base.id, aconnector->mst_port); | 406 | aconnector, connector->base.id, aconnector->mst_port); |
368 | 407 | ||
@@ -394,6 +433,8 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
394 | drm_mode_connector_update_edid_property( | 433 | drm_mode_connector_update_edid_property( |
395 | &aconnector->base, | 434 | &aconnector->base, |
396 | NULL); | 435 | NULL); |
436 | |||
437 | aconnector->mst_connected = false; | ||
397 | } | 438 | } |
398 | 439 | ||
399 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | 440 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) |
@@ -404,10 +445,18 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | |||
404 | drm_kms_helper_hotplug_event(dev); | 445 | drm_kms_helper_hotplug_event(dev); |
405 | } | 446 | } |
406 | 447 | ||
448 | static void dm_dp_mst_link_status_reset(struct drm_connector *connector) | ||
449 | { | ||
450 | mutex_lock(&connector->dev->mode_config.mutex); | ||
451 | drm_mode_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD); | ||
452 | mutex_unlock(&connector->dev->mode_config.mutex); | ||
453 | } | ||
454 | |||
407 | static void dm_dp_mst_register_connector(struct drm_connector *connector) | 455 | static void dm_dp_mst_register_connector(struct drm_connector *connector) |
408 | { | 456 | { |
409 | struct drm_device *dev = connector->dev; | 457 | struct drm_device *dev = connector->dev; |
410 | struct amdgpu_device *adev = dev->dev_private; | 458 | struct amdgpu_device *adev = dev->dev_private; |
459 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | ||
411 | 460 | ||
412 | if (adev->mode_info.rfbdev) | 461 | if (adev->mode_info.rfbdev) |
413 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); | 462 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); |
@@ -416,6 +465,8 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) | |||
416 | 465 | ||
417 | drm_connector_register(connector); | 466 | drm_connector_register(connector); |
418 | 467 | ||
468 | if (aconnector->mst_connected) | ||
469 | dm_dp_mst_link_status_reset(connector); | ||
419 | } | 470 | } |
420 | 471 | ||
421 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { | 472 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 2da851b40042..8cf51da26657 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | |||
@@ -31,5 +31,6 @@ struct amdgpu_dm_connector; | |||
31 | 31 | ||
32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, | 32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, |
33 | struct amdgpu_dm_connector *aconnector); | 33 | struct amdgpu_dm_connector *aconnector); |
34 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector); | ||
34 | 35 | ||
35 | #endif | 36 | #endif |
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 3dce35e66b09..b142629a1058 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | |||
@@ -900,6 +900,15 @@ bool dcn_validate_bandwidth( | |||
900 | v->override_vta_ps[input_idx] = pipe->plane_res.scl_data.taps.v_taps; | 900 | v->override_vta_ps[input_idx] = pipe->plane_res.scl_data.taps.v_taps; |
901 | v->override_hta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.h_taps_c; | 901 | v->override_hta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.h_taps_c; |
902 | v->override_vta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.v_taps_c; | 902 | v->override_vta_pschroma[input_idx] = pipe->plane_res.scl_data.taps.v_taps_c; |
903 | /* | ||
904 | * Spreadsheet doesn't handle taps_c is one properly, | ||
905 | * need to force Chroma to always be scaled to pass | ||
906 | * bandwidth validation. | ||
907 | */ | ||
908 | if (v->override_hta_pschroma[input_idx] == 1) | ||
909 | v->override_hta_pschroma[input_idx] = 2; | ||
910 | if (v->override_vta_pschroma[input_idx] == 1) | ||
911 | v->override_vta_pschroma[input_idx] = 2; | ||
903 | v->source_scan[input_idx] = (pipe->plane_state->rotation % 2) ? dcn_bw_vert : dcn_bw_hor; | 912 | v->source_scan[input_idx] = (pipe->plane_state->rotation % 2) ? dcn_bw_vert : dcn_bw_hor; |
904 | } | 913 | } |
905 | if (v->is_line_buffer_bpp_fixed == dcn_bw_yes) | 914 | if (v->is_line_buffer_bpp_fixed == dcn_bw_yes) |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index e27ed4a45265..42a111b9505d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c | |||
@@ -1801,7 +1801,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal) | |||
1801 | link->link_enc->funcs->disable_output(link->link_enc, signal, link); | 1801 | link->link_enc->funcs->disable_output(link->link_enc, signal, link); |
1802 | } | 1802 | } |
1803 | 1803 | ||
1804 | bool dp_active_dongle_validate_timing( | 1804 | static bool dp_active_dongle_validate_timing( |
1805 | const struct dc_crtc_timing *timing, | 1805 | const struct dc_crtc_timing *timing, |
1806 | const struct dc_dongle_caps *dongle_caps) | 1806 | const struct dc_dongle_caps *dongle_caps) |
1807 | { | 1807 | { |
@@ -1833,6 +1833,8 @@ bool dp_active_dongle_validate_timing( | |||
1833 | /* Check Color Depth and Pixel Clock */ | 1833 | /* Check Color Depth and Pixel Clock */ |
1834 | if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) | 1834 | if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
1835 | required_pix_clk /= 2; | 1835 | required_pix_clk /= 2; |
1836 | else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) | ||
1837 | required_pix_clk = required_pix_clk * 2 / 3; | ||
1836 | 1838 | ||
1837 | switch (timing->display_color_depth) { | 1839 | switch (timing->display_color_depth) { |
1838 | case COLOR_DEPTH_666: | 1840 | case COLOR_DEPTH_666: |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 07ff8d2faf3f..d844fadcd56f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
@@ -2866,16 +2866,19 @@ static void dce110_apply_ctx_for_surface( | |||
2866 | int num_planes, | 2866 | int num_planes, |
2867 | struct dc_state *context) | 2867 | struct dc_state *context) |
2868 | { | 2868 | { |
2869 | int i, be_idx; | 2869 | int i; |
2870 | 2870 | ||
2871 | if (num_planes == 0) | 2871 | if (num_planes == 0) |
2872 | return; | 2872 | return; |
2873 | 2873 | ||
2874 | be_idx = -1; | ||
2875 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 2874 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
2876 | if (stream == context->res_ctx.pipe_ctx[i].stream) { | 2875 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; |
2877 | be_idx = context->res_ctx.pipe_ctx[i].stream_res.tg->inst; | 2876 | struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; |
2878 | break; | 2877 | |
2878 | if (stream == pipe_ctx->stream) { | ||
2879 | if (!pipe_ctx->top_pipe && | ||
2880 | (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) | ||
2881 | dc->hwss.pipe_control_lock(dc, pipe_ctx, true); | ||
2879 | } | 2882 | } |
2880 | } | 2883 | } |
2881 | 2884 | ||
@@ -2895,9 +2898,22 @@ static void dce110_apply_ctx_for_surface( | |||
2895 | context->stream_count); | 2898 | context->stream_count); |
2896 | 2899 | ||
2897 | dce110_program_front_end_for_pipe(dc, pipe_ctx); | 2900 | dce110_program_front_end_for_pipe(dc, pipe_ctx); |
2901 | |||
2902 | dc->hwss.update_plane_addr(dc, pipe_ctx); | ||
2903 | |||
2898 | program_surface_visibility(dc, pipe_ctx); | 2904 | program_surface_visibility(dc, pipe_ctx); |
2899 | 2905 | ||
2900 | } | 2906 | } |
2907 | |||
2908 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
2909 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
2910 | struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; | ||
2911 | |||
2912 | if ((stream == pipe_ctx->stream) && | ||
2913 | (!pipe_ctx->top_pipe) && | ||
2914 | (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) | ||
2915 | dc->hwss.pipe_control_lock(dc, pipe_ctx, false); | ||
2916 | } | ||
2901 | } | 2917 | } |
2902 | 2918 | ||
2903 | static void dce110_power_down_fe(struct dc *dc, int fe_idx) | 2919 | static void dce110_power_down_fe(struct dc *dc, int fe_idx) |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index 74e7c82bdc76..a9d55d0dd69e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | |||
@@ -159,11 +159,10 @@ bool dpp_get_optimal_number_of_taps( | |||
159 | scl_data->taps.h_taps = 1; | 159 | scl_data->taps.h_taps = 1; |
160 | if (IDENTITY_RATIO(scl_data->ratios.vert)) | 160 | if (IDENTITY_RATIO(scl_data->ratios.vert)) |
161 | scl_data->taps.v_taps = 1; | 161 | scl_data->taps.v_taps = 1; |
162 | /* | 162 | if (IDENTITY_RATIO(scl_data->ratios.horz_c)) |
163 | * Spreadsheet doesn't handle taps_c is one properly, | 163 | scl_data->taps.h_taps_c = 1; |
164 | * need to force Chroma to always be scaled to pass | 164 | if (IDENTITY_RATIO(scl_data->ratios.vert_c)) |
165 | * bandwidth validation. | 165 | scl_data->taps.v_taps_c = 1; |
166 | */ | ||
167 | } | 166 | } |
168 | 167 | ||
169 | return true; | 168 | return true; |
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 59849f02e2ad..1402c0e71b03 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c | |||
@@ -220,17 +220,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr | |||
220 | 220 | ||
221 | mutex_lock(&dev->mode_config.idr_mutex); | 221 | mutex_lock(&dev->mode_config.idr_mutex); |
222 | 222 | ||
223 | /* Insert the new lessee into the tree */ | ||
224 | id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL); | ||
225 | if (id < 0) { | ||
226 | error = id; | ||
227 | goto out_lessee; | ||
228 | } | ||
229 | |||
230 | lessee->lessee_id = id; | ||
231 | lessee->lessor = drm_master_get(lessor); | ||
232 | list_add_tail(&lessee->lessee_list, &lessor->lessees); | ||
233 | |||
234 | idr_for_each_entry(leases, entry, object) { | 223 | idr_for_each_entry(leases, entry, object) { |
235 | error = 0; | 224 | error = 0; |
236 | if (!idr_find(&dev->mode_config.crtc_idr, object)) | 225 | if (!idr_find(&dev->mode_config.crtc_idr, object)) |
@@ -246,6 +235,17 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr | |||
246 | } | 235 | } |
247 | } | 236 | } |
248 | 237 | ||
238 | /* Insert the new lessee into the tree */ | ||
239 | id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL); | ||
240 | if (id < 0) { | ||
241 | error = id; | ||
242 | goto out_lessee; | ||
243 | } | ||
244 | |||
245 | lessee->lessee_id = id; | ||
246 | lessee->lessor = drm_master_get(lessor); | ||
247 | list_add_tail(&lessee->lessee_list, &lessor->lessees); | ||
248 | |||
249 | /* Move the leases over */ | 249 | /* Move the leases over */ |
250 | lessee->leases = *leases; | 250 | lessee->leases = *leases; |
251 | DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor); | 251 | DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor); |
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 37a93cdffb4a..2c90519576a3 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c | |||
@@ -558,11 +558,10 @@ int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) | |||
558 | } | 558 | } |
559 | 559 | ||
560 | /* | 560 | /* |
561 | * setplane_internal - setplane handler for internal callers | 561 | * __setplane_internal - setplane handler for internal callers |
562 | * | 562 | * |
563 | * Note that we assume an extra reference has already been taken on fb. If the | 563 | * This function will take a reference on the new fb for the plane |
564 | * update fails, this reference will be dropped before return; if it succeeds, | 564 | * on success. |
565 | * the previous framebuffer (if any) will be unreferenced instead. | ||
566 | * | 565 | * |
567 | * src_{x,y,w,h} are provided in 16.16 fixed point format | 566 | * src_{x,y,w,h} are provided in 16.16 fixed point format |
568 | */ | 567 | */ |
@@ -630,14 +629,12 @@ static int __setplane_internal(struct drm_plane *plane, | |||
630 | if (!ret) { | 629 | if (!ret) { |
631 | plane->crtc = crtc; | 630 | plane->crtc = crtc; |
632 | plane->fb = fb; | 631 | plane->fb = fb; |
633 | fb = NULL; | 632 | drm_framebuffer_get(plane->fb); |
634 | } else { | 633 | } else { |
635 | plane->old_fb = NULL; | 634 | plane->old_fb = NULL; |
636 | } | 635 | } |
637 | 636 | ||
638 | out: | 637 | out: |
639 | if (fb) | ||
640 | drm_framebuffer_put(fb); | ||
641 | if (plane->old_fb) | 638 | if (plane->old_fb) |
642 | drm_framebuffer_put(plane->old_fb); | 639 | drm_framebuffer_put(plane->old_fb); |
643 | plane->old_fb = NULL; | 640 | plane->old_fb = NULL; |
@@ -685,6 +682,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, | |||
685 | struct drm_plane *plane; | 682 | struct drm_plane *plane; |
686 | struct drm_crtc *crtc = NULL; | 683 | struct drm_crtc *crtc = NULL; |
687 | struct drm_framebuffer *fb = NULL; | 684 | struct drm_framebuffer *fb = NULL; |
685 | int ret; | ||
688 | 686 | ||
689 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 687 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
690 | return -EINVAL; | 688 | return -EINVAL; |
@@ -717,15 +715,16 @@ int drm_mode_setplane(struct drm_device *dev, void *data, | |||
717 | } | 715 | } |
718 | } | 716 | } |
719 | 717 | ||
720 | /* | 718 | ret = setplane_internal(plane, crtc, fb, |
721 | * setplane_internal will take care of deref'ing either the old or new | 719 | plane_req->crtc_x, plane_req->crtc_y, |
722 | * framebuffer depending on success. | 720 | plane_req->crtc_w, plane_req->crtc_h, |
723 | */ | 721 | plane_req->src_x, plane_req->src_y, |
724 | return setplane_internal(plane, crtc, fb, | 722 | plane_req->src_w, plane_req->src_h); |
725 | plane_req->crtc_x, plane_req->crtc_y, | 723 | |
726 | plane_req->crtc_w, plane_req->crtc_h, | 724 | if (fb) |
727 | plane_req->src_x, plane_req->src_y, | 725 | drm_framebuffer_put(fb); |
728 | plane_req->src_w, plane_req->src_h); | 726 | |
727 | return ret; | ||
729 | } | 728 | } |
730 | 729 | ||
731 | static int drm_mode_cursor_universal(struct drm_crtc *crtc, | 730 | static int drm_mode_cursor_universal(struct drm_crtc *crtc, |
@@ -788,13 +787,12 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, | |||
788 | src_h = fb->height << 16; | 787 | src_h = fb->height << 16; |
789 | } | 788 | } |
790 | 789 | ||
791 | /* | ||
792 | * setplane_internal will take care of deref'ing either the old or new | ||
793 | * framebuffer depending on success. | ||
794 | */ | ||
795 | ret = __setplane_internal(crtc->cursor, crtc, fb, | 790 | ret = __setplane_internal(crtc->cursor, crtc, fb, |
796 | crtc_x, crtc_y, crtc_w, crtc_h, | 791 | crtc_x, crtc_y, crtc_w, crtc_h, |
797 | 0, 0, src_w, src_h, ctx); | 792 | 0, 0, src_w, src_h, ctx); |
793 | |||
794 | if (fb) | ||
795 | drm_framebuffer_put(fb); | ||
798 | 796 | ||
799 | /* Update successful; save new cursor position, if necessary */ | 797 | /* Update successful; save new cursor position, if necessary */ |
800 | if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { | 798 | if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { |
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index f776fc1cc543..cb4d09c70fd4 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c | |||
@@ -369,40 +369,26 @@ static const struct file_operations drm_syncobj_file_fops = { | |||
369 | .release = drm_syncobj_file_release, | 369 | .release = drm_syncobj_file_release, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | static int drm_syncobj_alloc_file(struct drm_syncobj *syncobj) | ||
373 | { | ||
374 | struct file *file = anon_inode_getfile("syncobj_file", | ||
375 | &drm_syncobj_file_fops, | ||
376 | syncobj, 0); | ||
377 | if (IS_ERR(file)) | ||
378 | return PTR_ERR(file); | ||
379 | |||
380 | drm_syncobj_get(syncobj); | ||
381 | if (cmpxchg(&syncobj->file, NULL, file)) { | ||
382 | /* lost the race */ | ||
383 | fput(file); | ||
384 | } | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) | 372 | int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) |
390 | { | 373 | { |
391 | int ret; | 374 | struct file *file; |
392 | int fd; | 375 | int fd; |
393 | 376 | ||
394 | fd = get_unused_fd_flags(O_CLOEXEC); | 377 | fd = get_unused_fd_flags(O_CLOEXEC); |
395 | if (fd < 0) | 378 | if (fd < 0) |
396 | return fd; | 379 | return fd; |
397 | 380 | ||
398 | if (!syncobj->file) { | 381 | file = anon_inode_getfile("syncobj_file", |
399 | ret = drm_syncobj_alloc_file(syncobj); | 382 | &drm_syncobj_file_fops, |
400 | if (ret) { | 383 | syncobj, 0); |
401 | put_unused_fd(fd); | 384 | if (IS_ERR(file)) { |
402 | return ret; | 385 | put_unused_fd(fd); |
403 | } | 386 | return PTR_ERR(file); |
404 | } | 387 | } |
405 | fd_install(fd, syncobj->file); | 388 | |
389 | drm_syncobj_get(syncobj); | ||
390 | fd_install(fd, file); | ||
391 | |||
406 | *p_fd = fd; | 392 | *p_fd = fd; |
407 | return 0; | 393 | return 0; |
408 | } | 394 | } |
@@ -422,31 +408,24 @@ static int drm_syncobj_handle_to_fd(struct drm_file *file_private, | |||
422 | return ret; | 408 | return ret; |
423 | } | 409 | } |
424 | 410 | ||
425 | static struct drm_syncobj *drm_syncobj_fdget(int fd) | ||
426 | { | ||
427 | struct file *file = fget(fd); | ||
428 | |||
429 | if (!file) | ||
430 | return NULL; | ||
431 | if (file->f_op != &drm_syncobj_file_fops) | ||
432 | goto err; | ||
433 | |||
434 | return file->private_data; | ||
435 | err: | ||
436 | fput(file); | ||
437 | return NULL; | ||
438 | }; | ||
439 | |||
440 | static int drm_syncobj_fd_to_handle(struct drm_file *file_private, | 411 | static int drm_syncobj_fd_to_handle(struct drm_file *file_private, |
441 | int fd, u32 *handle) | 412 | int fd, u32 *handle) |
442 | { | 413 | { |
443 | struct drm_syncobj *syncobj = drm_syncobj_fdget(fd); | 414 | struct drm_syncobj *syncobj; |
415 | struct file *file; | ||
444 | int ret; | 416 | int ret; |
445 | 417 | ||
446 | if (!syncobj) | 418 | file = fget(fd); |
419 | if (!file) | ||
447 | return -EINVAL; | 420 | return -EINVAL; |
448 | 421 | ||
422 | if (file->f_op != &drm_syncobj_file_fops) { | ||
423 | fput(file); | ||
424 | return -EINVAL; | ||
425 | } | ||
426 | |||
449 | /* take a reference to put in the idr */ | 427 | /* take a reference to put in the idr */ |
428 | syncobj = file->private_data; | ||
450 | drm_syncobj_get(syncobj); | 429 | drm_syncobj_get(syncobj); |
451 | 430 | ||
452 | idr_preload(GFP_KERNEL); | 431 | idr_preload(GFP_KERNEL); |
@@ -455,12 +434,14 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private, | |||
455 | spin_unlock(&file_private->syncobj_table_lock); | 434 | spin_unlock(&file_private->syncobj_table_lock); |
456 | idr_preload_end(); | 435 | idr_preload_end(); |
457 | 436 | ||
458 | if (ret < 0) { | 437 | if (ret > 0) { |
459 | fput(syncobj->file); | 438 | *handle = ret; |
460 | return ret; | 439 | ret = 0; |
461 | } | 440 | } else |
462 | *handle = ret; | 441 | drm_syncobj_put(syncobj); |
463 | return 0; | 442 | |
443 | fput(file); | ||
444 | return ret; | ||
464 | } | 445 | } |
465 | 446 | ||
466 | static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, | 447 | static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, |
diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 355120865efd..309f3fa6794a 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c | |||
@@ -266,6 +266,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) | |||
266 | /* Clear host CRT status, so guest couldn't detect this host CRT. */ | 266 | /* Clear host CRT status, so guest couldn't detect this host CRT. */ |
267 | if (IS_BROADWELL(dev_priv)) | 267 | if (IS_BROADWELL(dev_priv)) |
268 | vgpu_vreg(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; | 268 | vgpu_vreg(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; |
269 | |||
270 | vgpu_vreg(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; | ||
269 | } | 271 | } |
270 | 272 | ||
271 | static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) | 273 | static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) |
@@ -282,7 +284,6 @@ static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) | |||
282 | static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, | 284 | static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, |
283 | int type, unsigned int resolution) | 285 | int type, unsigned int resolution) |
284 | { | 286 | { |
285 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
286 | struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num); | 287 | struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num); |
287 | 288 | ||
288 | if (WARN_ON(resolution >= GVT_EDID_NUM)) | 289 | if (WARN_ON(resolution >= GVT_EDID_NUM)) |
@@ -308,7 +309,7 @@ static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, | |||
308 | port->type = type; | 309 | port->type = type; |
309 | 310 | ||
310 | emulate_monitor_status_change(vgpu); | 311 | emulate_monitor_status_change(vgpu); |
311 | vgpu_vreg(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; | 312 | |
312 | return 0; | 313 | return 0; |
313 | } | 314 | } |
314 | 315 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ad4050f7ab3b..18de6569d04a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -330,17 +330,10 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj) | |||
330 | * must wait for all rendering to complete to the object (as unbinding | 330 | * must wait for all rendering to complete to the object (as unbinding |
331 | * must anyway), and retire the requests. | 331 | * must anyway), and retire the requests. |
332 | */ | 332 | */ |
333 | ret = i915_gem_object_wait(obj, | 333 | ret = i915_gem_object_set_to_cpu_domain(obj, false); |
334 | I915_WAIT_INTERRUPTIBLE | | ||
335 | I915_WAIT_LOCKED | | ||
336 | I915_WAIT_ALL, | ||
337 | MAX_SCHEDULE_TIMEOUT, | ||
338 | NULL); | ||
339 | if (ret) | 334 | if (ret) |
340 | return ret; | 335 | return ret; |
341 | 336 | ||
342 | i915_gem_retire_requests(to_i915(obj->base.dev)); | ||
343 | |||
344 | while ((vma = list_first_entry_or_null(&obj->vma_list, | 337 | while ((vma = list_first_entry_or_null(&obj->vma_list, |
345 | struct i915_vma, | 338 | struct i915_vma, |
346 | obj_link))) { | 339 | obj_link))) { |
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index e8ca67a129d2..ac236b88c99c 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c | |||
@@ -367,6 +367,7 @@ struct i915_sw_dma_fence_cb { | |||
367 | struct dma_fence *dma; | 367 | struct dma_fence *dma; |
368 | struct timer_list timer; | 368 | struct timer_list timer; |
369 | struct irq_work work; | 369 | struct irq_work work; |
370 | struct rcu_head rcu; | ||
370 | }; | 371 | }; |
371 | 372 | ||
372 | static void timer_i915_sw_fence_wake(struct timer_list *t) | 373 | static void timer_i915_sw_fence_wake(struct timer_list *t) |
@@ -406,7 +407,7 @@ static void irq_i915_sw_fence_work(struct irq_work *wrk) | |||
406 | del_timer_sync(&cb->timer); | 407 | del_timer_sync(&cb->timer); |
407 | dma_fence_put(cb->dma); | 408 | dma_fence_put(cb->dma); |
408 | 409 | ||
409 | kfree(cb); | 410 | kfree_rcu(cb, rcu); |
410 | } | 411 | } |
411 | 412 | ||
412 | int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, | 413 | int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, |
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 5f8b9f1f40f1..bcbc7abe6693 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c | |||
@@ -186,7 +186,7 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) | |||
186 | struct intel_wait *wait, *n, *first; | 186 | struct intel_wait *wait, *n, *first; |
187 | 187 | ||
188 | if (!b->irq_armed) | 188 | if (!b->irq_armed) |
189 | return; | 189 | goto wakeup_signaler; |
190 | 190 | ||
191 | /* We only disarm the irq when we are idle (all requests completed), | 191 | /* We only disarm the irq when we are idle (all requests completed), |
192 | * so if the bottom-half remains asleep, it missed the request | 192 | * so if the bottom-half remains asleep, it missed the request |
@@ -208,6 +208,14 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) | |||
208 | b->waiters = RB_ROOT; | 208 | b->waiters = RB_ROOT; |
209 | 209 | ||
210 | spin_unlock_irq(&b->rb_lock); | 210 | spin_unlock_irq(&b->rb_lock); |
211 | |||
212 | /* | ||
213 | * The signaling thread may be asleep holding a reference to a request, | ||
214 | * that had its signaling cancelled prior to being preempted. We need | ||
215 | * to kick the signaler, just in case, to release any such reference. | ||
216 | */ | ||
217 | wakeup_signaler: | ||
218 | wake_up_process(b->signaler); | ||
211 | } | 219 | } |
212 | 220 | ||
213 | static bool use_fake_irq(const struct intel_breadcrumbs *b) | 221 | static bool use_fake_irq(const struct intel_breadcrumbs *b) |
@@ -651,23 +659,15 @@ static int intel_breadcrumbs_signaler(void *arg) | |||
651 | } | 659 | } |
652 | 660 | ||
653 | if (unlikely(do_schedule)) { | 661 | if (unlikely(do_schedule)) { |
654 | DEFINE_WAIT(exec); | ||
655 | |||
656 | if (kthread_should_park()) | 662 | if (kthread_should_park()) |
657 | kthread_parkme(); | 663 | kthread_parkme(); |
658 | 664 | ||
659 | if (kthread_should_stop()) { | 665 | if (unlikely(kthread_should_stop())) { |
660 | GEM_BUG_ON(request); | 666 | i915_gem_request_put(request); |
661 | break; | 667 | break; |
662 | } | 668 | } |
663 | 669 | ||
664 | if (request) | ||
665 | add_wait_queue(&request->execute, &exec); | ||
666 | |||
667 | schedule(); | 670 | schedule(); |
668 | |||
669 | if (request) | ||
670 | remove_wait_queue(&request->execute, &exec); | ||
671 | } | 671 | } |
672 | i915_gem_request_put(request); | 672 | i915_gem_request_put(request); |
673 | } while (1); | 673 | } while (1); |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e0843bb99169..58a3755544b2 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -2128,6 +2128,8 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, | |||
2128 | if (WARN_ON(!pll)) | 2128 | if (WARN_ON(!pll)) |
2129 | return; | 2129 | return; |
2130 | 2130 | ||
2131 | mutex_lock(&dev_priv->dpll_lock); | ||
2132 | |||
2131 | if (IS_CANNONLAKE(dev_priv)) { | 2133 | if (IS_CANNONLAKE(dev_priv)) { |
2132 | /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */ | 2134 | /* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */ |
2133 | val = I915_READ(DPCLKA_CFGCR0); | 2135 | val = I915_READ(DPCLKA_CFGCR0); |
@@ -2157,6 +2159,8 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, | |||
2157 | } else if (INTEL_INFO(dev_priv)->gen < 9) { | 2159 | } else if (INTEL_INFO(dev_priv)->gen < 9) { |
2158 | I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); | 2160 | I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); |
2159 | } | 2161 | } |
2162 | |||
2163 | mutex_unlock(&dev_priv->dpll_lock); | ||
2160 | } | 2164 | } |
2161 | 2165 | ||
2162 | static void intel_ddi_clk_disable(struct intel_encoder *encoder) | 2166 | static void intel_ddi_clk_disable(struct intel_encoder *encoder) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e8ccf89cb17b..30cf273d57aa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -9944,11 +9944,10 @@ found: | |||
9944 | } | 9944 | } |
9945 | 9945 | ||
9946 | ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0); | 9946 | ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0); |
9947 | drm_framebuffer_put(fb); | ||
9947 | if (ret) | 9948 | if (ret) |
9948 | goto fail; | 9949 | goto fail; |
9949 | 9950 | ||
9950 | drm_framebuffer_put(fb); | ||
9951 | |||
9952 | ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); | 9951 | ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); |
9953 | if (ret) | 9952 | if (ret) |
9954 | goto fail; | 9953 | goto fail; |
@@ -13195,7 +13194,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) | |||
13195 | primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); | 13194 | primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); |
13196 | primary->check_plane = intel_check_primary_plane; | 13195 | primary->check_plane = intel_check_primary_plane; |
13197 | 13196 | ||
13198 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { | 13197 | if (INTEL_GEN(dev_priv) >= 10) { |
13199 | intel_primary_formats = skl_primary_formats; | 13198 | intel_primary_formats = skl_primary_formats; |
13200 | num_formats = ARRAY_SIZE(skl_primary_formats); | 13199 | num_formats = ARRAY_SIZE(skl_primary_formats); |
13201 | modifiers = skl_format_modifiers_ccs; | 13200 | modifiers = skl_format_modifiers_ccs; |
diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c index 3bf65288ffff..5809b29044fc 100644 --- a/drivers/gpu/drm/i915/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/intel_lpe_audio.c | |||
@@ -193,7 +193,7 @@ static bool lpe_audio_detect(struct drm_i915_private *dev_priv) | |||
193 | }; | 193 | }; |
194 | 194 | ||
195 | if (!pci_dev_present(atom_hdaudio_ids)) { | 195 | if (!pci_dev_present(atom_hdaudio_ids)) { |
196 | DRM_INFO("%s\n", "HDaudio controller not detected, using LPE audio instead\n"); | 196 | DRM_INFO("HDaudio controller not detected, using LPE audio instead\n"); |
197 | lpe_present = true; | 197 | lpe_present = true; |
198 | } | 198 | } |
199 | } | 199 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 2615912430cc..435ff8662cfa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -224,7 +224,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, | |||
224 | /* Determine if we can get a cache-coherent map, forcing | 224 | /* Determine if we can get a cache-coherent map, forcing |
225 | * uncached mapping if we can't. | 225 | * uncached mapping if we can't. |
226 | */ | 226 | */ |
227 | if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) | 227 | if (!nouveau_drm_use_coherent_gpu_mapping(drm)) |
228 | nvbo->force_coherent = true; | 228 | nvbo->force_coherent = true; |
229 | } | 229 | } |
230 | 230 | ||
@@ -262,7 +262,8 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, | |||
262 | if (cli->device.info.family > NV_DEVICE_INFO_V0_CURIE && | 262 | if (cli->device.info.family > NV_DEVICE_INFO_V0_CURIE && |
263 | (flags & TTM_PL_FLAG_VRAM) && !vmm->page[i].vram) | 263 | (flags & TTM_PL_FLAG_VRAM) && !vmm->page[i].vram) |
264 | continue; | 264 | continue; |
265 | if ((flags & TTM_PL_FLAG_TT ) && !vmm->page[i].host) | 265 | if ((flags & TTM_PL_FLAG_TT) && |
266 | (!vmm->page[i].host || vmm->page[i].shift > PAGE_SHIFT)) | ||
266 | continue; | 267 | continue; |
267 | 268 | ||
268 | /* Select this page size if it's the first that supports | 269 | /* Select this page size if it's the first that supports |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 8d4a5be3b913..56fe261b6268 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -152,9 +152,9 @@ nouveau_cli_work_queue(struct nouveau_cli *cli, struct dma_fence *fence, | |||
152 | work->cli = cli; | 152 | work->cli = cli; |
153 | mutex_lock(&cli->lock); | 153 | mutex_lock(&cli->lock); |
154 | list_add_tail(&work->head, &cli->worker); | 154 | list_add_tail(&work->head, &cli->worker); |
155 | mutex_unlock(&cli->lock); | ||
156 | if (dma_fence_add_callback(fence, &work->cb, nouveau_cli_work_fence)) | 155 | if (dma_fence_add_callback(fence, &work->cb, nouveau_cli_work_fence)) |
157 | nouveau_cli_work_fence(fence, &work->cb); | 156 | nouveau_cli_work_fence(fence, &work->cb); |
157 | mutex_unlock(&cli->lock); | ||
158 | } | 158 | } |
159 | 159 | ||
160 | static void | 160 | static void |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 3331e82ae9e7..96f6bd8aee5d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -157,8 +157,8 @@ struct nouveau_drm { | |||
157 | struct nvif_object copy; | 157 | struct nvif_object copy; |
158 | int mtrr; | 158 | int mtrr; |
159 | int type_vram; | 159 | int type_vram; |
160 | int type_host; | 160 | int type_host[2]; |
161 | int type_ncoh; | 161 | int type_ncoh[2]; |
162 | } ttm; | 162 | } ttm; |
163 | 163 | ||
164 | /* GEM interface support */ | 164 | /* GEM interface support */ |
@@ -217,6 +217,13 @@ nouveau_drm(struct drm_device *dev) | |||
217 | return dev->dev_private; | 217 | return dev->dev_private; |
218 | } | 218 | } |
219 | 219 | ||
220 | static inline bool | ||
221 | nouveau_drm_use_coherent_gpu_mapping(struct nouveau_drm *drm) | ||
222 | { | ||
223 | struct nvif_mmu *mmu = &drm->client.mmu; | ||
224 | return !(mmu->type[drm->ttm.type_host[0]].type & NVIF_MEM_UNCACHED); | ||
225 | } | ||
226 | |||
220 | int nouveau_pmops_suspend(struct device *); | 227 | int nouveau_pmops_suspend(struct device *); |
221 | int nouveau_pmops_resume(struct device *); | 228 | int nouveau_pmops_resume(struct device *); |
222 | bool nouveau_pmops_runtime(void); | 229 | bool nouveau_pmops_runtime(void); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index c533d8e04afc..be7357bf2246 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -429,7 +429,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) | |||
429 | drm_fb_helper_unregister_fbi(&fbcon->helper); | 429 | drm_fb_helper_unregister_fbi(&fbcon->helper); |
430 | drm_fb_helper_fini(&fbcon->helper); | 430 | drm_fb_helper_fini(&fbcon->helper); |
431 | 431 | ||
432 | if (nouveau_fb->nvbo) { | 432 | if (nouveau_fb && nouveau_fb->nvbo) { |
433 | nouveau_vma_del(&nouveau_fb->vma); | 433 | nouveau_vma_del(&nouveau_fb->vma); |
434 | nouveau_bo_unmap(nouveau_fb->nvbo); | 434 | nouveau_bo_unmap(nouveau_fb->nvbo); |
435 | nouveau_bo_unpin(nouveau_fb->nvbo); | 435 | nouveau_bo_unpin(nouveau_fb->nvbo); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 589a9621db76..c002f8968507 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -103,10 +103,10 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) | |||
103 | u8 type; | 103 | u8 type; |
104 | int ret; | 104 | int ret; |
105 | 105 | ||
106 | if (mmu->type[drm->ttm.type_host].type & NVIF_MEM_UNCACHED) | 106 | if (!nouveau_drm_use_coherent_gpu_mapping(drm)) |
107 | type = drm->ttm.type_ncoh; | 107 | type = drm->ttm.type_ncoh[!!mem->kind]; |
108 | else | 108 | else |
109 | type = drm->ttm.type_host; | 109 | type = drm->ttm.type_host[0]; |
110 | 110 | ||
111 | if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND)) | 111 | if (mem->kind && !(mmu->type[type].type & NVIF_MEM_KIND)) |
112 | mem->comp = mem->kind = 0; | 112 | mem->comp = mem->kind = 0; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 08b974b30482..dff51a0ee028 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c | |||
@@ -235,27 +235,46 @@ nouveau_ttm_global_release(struct nouveau_drm *drm) | |||
235 | drm->ttm.mem_global_ref.release = NULL; | 235 | drm->ttm.mem_global_ref.release = NULL; |
236 | } | 236 | } |
237 | 237 | ||
238 | int | 238 | static int |
239 | nouveau_ttm_init(struct nouveau_drm *drm) | 239 | nouveau_ttm_init_host(struct nouveau_drm *drm, u8 kind) |
240 | { | 240 | { |
241 | struct nvkm_device *device = nvxx_device(&drm->client.device); | ||
242 | struct nvkm_pci *pci = device->pci; | ||
243 | struct nvif_mmu *mmu = &drm->client.mmu; | 241 | struct nvif_mmu *mmu = &drm->client.mmu; |
244 | struct drm_device *dev = drm->dev; | 242 | int typei; |
245 | int typei, ret; | ||
246 | 243 | ||
247 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | | 244 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | |
248 | NVIF_MEM_COHERENT); | 245 | kind | NVIF_MEM_COHERENT); |
249 | if (typei < 0) | 246 | if (typei < 0) |
250 | return -ENOSYS; | 247 | return -ENOSYS; |
251 | 248 | ||
252 | drm->ttm.type_host = typei; | 249 | drm->ttm.type_host[!!kind] = typei; |
253 | 250 | ||
254 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE); | 251 | typei = nvif_mmu_type(mmu, NVIF_MEM_HOST | NVIF_MEM_MAPPABLE | kind); |
255 | if (typei < 0) | 252 | if (typei < 0) |
256 | return -ENOSYS; | 253 | return -ENOSYS; |
257 | 254 | ||
258 | drm->ttm.type_ncoh = typei; | 255 | drm->ttm.type_ncoh[!!kind] = typei; |
256 | return 0; | ||
257 | } | ||
258 | |||
259 | int | ||
260 | nouveau_ttm_init(struct nouveau_drm *drm) | ||
261 | { | ||
262 | struct nvkm_device *device = nvxx_device(&drm->client.device); | ||
263 | struct nvkm_pci *pci = device->pci; | ||
264 | struct nvif_mmu *mmu = &drm->client.mmu; | ||
265 | struct drm_device *dev = drm->dev; | ||
266 | int typei, ret; | ||
267 | |||
268 | ret = nouveau_ttm_init_host(drm, 0); | ||
269 | if (ret) | ||
270 | return ret; | ||
271 | |||
272 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA && | ||
273 | drm->client.device.info.chipset != 0x50) { | ||
274 | ret = nouveau_ttm_init_host(drm, NVIF_MEM_KIND); | ||
275 | if (ret) | ||
276 | return ret; | ||
277 | } | ||
259 | 278 | ||
260 | if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC && | 279 | if (drm->client.device.info.platform != NV_DEVICE_INFO_V0_SOC && |
261 | drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { | 280 | drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c index 9e2628dd8e4d..f5371d96b003 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c | |||
@@ -67,8 +67,8 @@ nouveau_vma_del(struct nouveau_vma **pvma) | |||
67 | nvif_vmm_put(&vma->vmm->vmm, &tmp); | 67 | nvif_vmm_put(&vma->vmm->vmm, &tmp); |
68 | } | 68 | } |
69 | list_del(&vma->head); | 69 | list_del(&vma->head); |
70 | *pvma = NULL; | ||
71 | kfree(*pvma); | 70 | kfree(*pvma); |
71 | *pvma = NULL; | ||
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index e14643615698..00eeaaffeae5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | |||
@@ -2369,7 +2369,7 @@ nv13b_chipset = { | |||
2369 | .imem = gk20a_instmem_new, | 2369 | .imem = gk20a_instmem_new, |
2370 | .ltc = gp100_ltc_new, | 2370 | .ltc = gp100_ltc_new, |
2371 | .mc = gp10b_mc_new, | 2371 | .mc = gp10b_mc_new, |
2372 | .mmu = gf100_mmu_new, | 2372 | .mmu = gp10b_mmu_new, |
2373 | .secboot = gp10b_secboot_new, | 2373 | .secboot = gp10b_secboot_new, |
2374 | .pmu = gm20b_pmu_new, | 2374 | .pmu = gm20b_pmu_new, |
2375 | .timer = gk20a_timer_new, | 2375 | .timer = gk20a_timer_new, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c index 972370ed36f0..7c7efa4ea0d0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c | |||
@@ -36,6 +36,7 @@ nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | |||
36 | if (data) { | 36 | if (data) { |
37 | *ver = nvbios_rd08(bios, data + 0x00); | 37 | *ver = nvbios_rd08(bios, data + 0x00); |
38 | switch (*ver) { | 38 | switch (*ver) { |
39 | case 0x20: | ||
39 | case 0x21: | 40 | case 0x21: |
40 | case 0x30: | 41 | case 0x30: |
41 | case 0x40: | 42 | case 0x40: |
@@ -63,6 +64,7 @@ nvbios_dpout_entry(struct nvkm_bios *bios, u8 idx, | |||
63 | if (data && idx < *cnt) { | 64 | if (data && idx < *cnt) { |
64 | u16 outp = nvbios_rd16(bios, data + *hdr + idx * *len); | 65 | u16 outp = nvbios_rd16(bios, data + *hdr + idx * *len); |
65 | switch (*ver * !!outp) { | 66 | switch (*ver * !!outp) { |
67 | case 0x20: | ||
66 | case 0x21: | 68 | case 0x21: |
67 | case 0x30: | 69 | case 0x30: |
68 | *hdr = nvbios_rd08(bios, data + 0x04); | 70 | *hdr = nvbios_rd08(bios, data + 0x04); |
@@ -96,12 +98,16 @@ nvbios_dpout_parse(struct nvkm_bios *bios, u8 idx, | |||
96 | info->type = nvbios_rd16(bios, data + 0x00); | 98 | info->type = nvbios_rd16(bios, data + 0x00); |
97 | info->mask = nvbios_rd16(bios, data + 0x02); | 99 | info->mask = nvbios_rd16(bios, data + 0x02); |
98 | switch (*ver) { | 100 | switch (*ver) { |
101 | case 0x20: | ||
102 | info->mask |= 0x00c0; /* match any link */ | ||
103 | /* fall-through */ | ||
99 | case 0x21: | 104 | case 0x21: |
100 | case 0x30: | 105 | case 0x30: |
101 | info->flags = nvbios_rd08(bios, data + 0x05); | 106 | info->flags = nvbios_rd08(bios, data + 0x05); |
102 | info->script[0] = nvbios_rd16(bios, data + 0x06); | 107 | info->script[0] = nvbios_rd16(bios, data + 0x06); |
103 | info->script[1] = nvbios_rd16(bios, data + 0x08); | 108 | info->script[1] = nvbios_rd16(bios, data + 0x08); |
104 | info->lnkcmp = nvbios_rd16(bios, data + 0x0a); | 109 | if (*len >= 0x0c) |
110 | info->lnkcmp = nvbios_rd16(bios, data + 0x0a); | ||
105 | if (*len >= 0x0f) { | 111 | if (*len >= 0x0f) { |
106 | info->script[2] = nvbios_rd16(bios, data + 0x0c); | 112 | info->script[2] = nvbios_rd16(bios, data + 0x0c); |
107 | info->script[3] = nvbios_rd16(bios, data + 0x0e); | 113 | info->script[3] = nvbios_rd16(bios, data + 0x0e); |
@@ -170,6 +176,7 @@ nvbios_dpcfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
170 | memset(info, 0x00, sizeof(*info)); | 176 | memset(info, 0x00, sizeof(*info)); |
171 | if (data) { | 177 | if (data) { |
172 | switch (*ver) { | 178 | switch (*ver) { |
179 | case 0x20: | ||
173 | case 0x21: | 180 | case 0x21: |
174 | info->dc = nvbios_rd08(bios, data + 0x02); | 181 | info->dc = nvbios_rd08(bios, data + 0x02); |
175 | info->pe = nvbios_rd08(bios, data + 0x03); | 182 | info->pe = nvbios_rd08(bios, data + 0x03); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 1ba7289684aa..db48a1daca0c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | |||
@@ -249,7 +249,7 @@ nv50_instobj_acquire(struct nvkm_memory *memory) | |||
249 | iobj->base.memory.ptrs = &nv50_instobj_fast; | 249 | iobj->base.memory.ptrs = &nv50_instobj_fast; |
250 | else | 250 | else |
251 | iobj->base.memory.ptrs = &nv50_instobj_slow; | 251 | iobj->base.memory.ptrs = &nv50_instobj_slow; |
252 | refcount_inc(&iobj->maps); | 252 | refcount_set(&iobj->maps, 1); |
253 | } | 253 | } |
254 | 254 | ||
255 | mutex_unlock(&imem->subdev.mutex); | 255 | mutex_unlock(&imem->subdev.mutex); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index b1b1f3626b96..deb96de54b00 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c | |||
@@ -136,6 +136,13 @@ nvkm_pci_init(struct nvkm_subdev *subdev) | |||
136 | return ret; | 136 | return ret; |
137 | 137 | ||
138 | pci->irq = pdev->irq; | 138 | pci->irq = pdev->irq; |
139 | |||
140 | /* Ensure MSI interrupts are armed, for the case where there are | ||
141 | * already interrupts pending (for whatever reason) at load time. | ||
142 | */ | ||
143 | if (pci->msi) | ||
144 | pci->func->msi_rearm(pci); | ||
145 | |||
139 | return ret; | 146 | return ret; |
140 | } | 147 | } |
141 | 148 | ||
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index dda904ec0534..500b6fb3e028 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | |||
@@ -175,11 +175,31 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, | |||
175 | writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); | 175 | writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); |
176 | } | 176 | } |
177 | 177 | ||
178 | static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder, | ||
179 | const struct drm_display_mode *mode) | ||
180 | { | ||
181 | struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); | ||
182 | unsigned long rate = mode->clock * 1000; | ||
183 | unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */ | ||
184 | long rounded_rate; | ||
185 | |||
186 | /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */ | ||
187 | if (rate > 165000000) | ||
188 | return MODE_CLOCK_HIGH; | ||
189 | rounded_rate = clk_round_rate(hdmi->tmds_clk, rate); | ||
190 | if (rounded_rate > 0 && | ||
191 | max_t(unsigned long, rounded_rate, rate) - | ||
192 | min_t(unsigned long, rounded_rate, rate) < diff) | ||
193 | return MODE_OK; | ||
194 | return MODE_NOCLOCK; | ||
195 | } | ||
196 | |||
178 | static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { | 197 | static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { |
179 | .atomic_check = sun4i_hdmi_atomic_check, | 198 | .atomic_check = sun4i_hdmi_atomic_check, |
180 | .disable = sun4i_hdmi_disable, | 199 | .disable = sun4i_hdmi_disable, |
181 | .enable = sun4i_hdmi_enable, | 200 | .enable = sun4i_hdmi_enable, |
182 | .mode_set = sun4i_hdmi_mode_set, | 201 | .mode_set = sun4i_hdmi_mode_set, |
202 | .mode_valid = sun4i_hdmi_mode_valid, | ||
183 | }; | 203 | }; |
184 | 204 | ||
185 | static const struct drm_encoder_funcs sun4i_hdmi_funcs = { | 205 | static const struct drm_encoder_funcs sun4i_hdmi_funcs = { |
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index e122f5b2a395..f4284b51bdca 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c | |||
@@ -724,12 +724,12 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, | |||
724 | if (IS_ERR(tcon->crtc)) { | 724 | if (IS_ERR(tcon->crtc)) { |
725 | dev_err(dev, "Couldn't create our CRTC\n"); | 725 | dev_err(dev, "Couldn't create our CRTC\n"); |
726 | ret = PTR_ERR(tcon->crtc); | 726 | ret = PTR_ERR(tcon->crtc); |
727 | goto err_free_clocks; | 727 | goto err_free_dotclock; |
728 | } | 728 | } |
729 | 729 | ||
730 | ret = sun4i_rgb_init(drm, tcon); | 730 | ret = sun4i_rgb_init(drm, tcon); |
731 | if (ret < 0) | 731 | if (ret < 0) |
732 | goto err_free_clocks; | 732 | goto err_free_dotclock; |
733 | 733 | ||
734 | if (tcon->quirks->needs_de_be_mux) { | 734 | if (tcon->quirks->needs_de_be_mux) { |
735 | /* | 735 | /* |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 44343a2bf55c..b5ba6441489f 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
@@ -455,6 +455,7 @@ ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) | |||
455 | freed += (nr_free_pool - shrink_pages) << pool->order; | 455 | freed += (nr_free_pool - shrink_pages) << pool->order; |
456 | if (freed >= sc->nr_to_scan) | 456 | if (freed >= sc->nr_to_scan) |
457 | break; | 457 | break; |
458 | shrink_pages <<= pool->order; | ||
458 | } | 459 | } |
459 | mutex_unlock(&lock); | 460 | mutex_unlock(&lock); |
460 | return freed; | 461 | return freed; |
@@ -543,7 +544,7 @@ static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, | |||
543 | int r = 0; | 544 | int r = 0; |
544 | unsigned i, j, cpages; | 545 | unsigned i, j, cpages; |
545 | unsigned npages = 1 << order; | 546 | unsigned npages = 1 << order; |
546 | unsigned max_cpages = min(count, (unsigned)NUM_PAGES_TO_ALLOC); | 547 | unsigned max_cpages = min(count << order, (unsigned)NUM_PAGES_TO_ALLOC); |
547 | 548 | ||
548 | /* allocate array for page caching change */ | 549 | /* allocate array for page caching change */ |
549 | caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); | 550 | caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index c9790e2c3440..af5123042990 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -143,6 +143,7 @@ static int hwmon_thermal_add_sensor(struct device *dev, | |||
143 | struct hwmon_device *hwdev, int index) | 143 | struct hwmon_device *hwdev, int index) |
144 | { | 144 | { |
145 | struct hwmon_thermal_data *tdata; | 145 | struct hwmon_thermal_data *tdata; |
146 | struct thermal_zone_device *tzd; | ||
146 | 147 | ||
147 | tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); | 148 | tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); |
148 | if (!tdata) | 149 | if (!tdata) |
@@ -151,8 +152,14 @@ static int hwmon_thermal_add_sensor(struct device *dev, | |||
151 | tdata->hwdev = hwdev; | 152 | tdata->hwdev = hwdev; |
152 | tdata->index = index; | 153 | tdata->index = index; |
153 | 154 | ||
154 | devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, | 155 | tzd = devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, |
155 | &hwmon_thermal_ops); | 156 | &hwmon_thermal_ops); |
157 | /* | ||
158 | * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, | ||
159 | * so ignore that error but forward any other error. | ||
160 | */ | ||
161 | if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) | ||
162 | return PTR_ERR(tzd); | ||
156 | 163 | ||
157 | return 0; | 164 | return 0; |
158 | } | 165 | } |
@@ -621,14 +628,20 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, | |||
621 | if (!chip->ops->is_visible(drvdata, hwmon_temp, | 628 | if (!chip->ops->is_visible(drvdata, hwmon_temp, |
622 | hwmon_temp_input, j)) | 629 | hwmon_temp_input, j)) |
623 | continue; | 630 | continue; |
624 | if (info[i]->config[j] & HWMON_T_INPUT) | 631 | if (info[i]->config[j] & HWMON_T_INPUT) { |
625 | hwmon_thermal_add_sensor(dev, hwdev, j); | 632 | err = hwmon_thermal_add_sensor(dev, |
633 | hwdev, j); | ||
634 | if (err) | ||
635 | goto free_device; | ||
636 | } | ||
626 | } | 637 | } |
627 | } | 638 | } |
628 | } | 639 | } |
629 | 640 | ||
630 | return hdev; | 641 | return hdev; |
631 | 642 | ||
643 | free_device: | ||
644 | device_unregister(hdev); | ||
632 | free_hwmon: | 645 | free_hwmon: |
633 | kfree(hwdev); | 646 | kfree(hwdev); |
634 | ida_remove: | 647 | ida_remove: |
diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c index feafdb961c48..59b2f96d986a 100644 --- a/drivers/infiniband/core/security.c +++ b/drivers/infiniband/core/security.c | |||
@@ -386,6 +386,9 @@ int ib_open_shared_qp_security(struct ib_qp *qp, struct ib_device *dev) | |||
386 | if (ret) | 386 | if (ret) |
387 | return ret; | 387 | return ret; |
388 | 388 | ||
389 | if (!qp->qp_sec) | ||
390 | return 0; | ||
391 | |||
389 | mutex_lock(&real_qp->qp_sec->mutex); | 392 | mutex_lock(&real_qp->qp_sec->mutex); |
390 | ret = check_qp_port_pkey_settings(real_qp->qp_sec->ports_pkeys, | 393 | ret = check_qp_port_pkey_settings(real_qp->qp_sec->ports_pkeys, |
391 | qp->qp_sec); | 394 | qp->qp_sec); |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index d0202bb176a4..840b24096690 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -2074,8 +2074,8 @@ int ib_uverbs_ex_modify_qp(struct ib_uverbs_file *file, | |||
2074 | return -EOPNOTSUPP; | 2074 | return -EOPNOTSUPP; |
2075 | 2075 | ||
2076 | if (ucore->inlen > sizeof(cmd)) { | 2076 | if (ucore->inlen > sizeof(cmd)) { |
2077 | if (ib_is_udata_cleared(ucore, sizeof(cmd), | 2077 | if (!ib_is_udata_cleared(ucore, sizeof(cmd), |
2078 | ucore->inlen - sizeof(cmd))) | 2078 | ucore->inlen - sizeof(cmd))) |
2079 | return -EOPNOTSUPP; | 2079 | return -EOPNOTSUPP; |
2080 | } | 2080 | } |
2081 | 2081 | ||
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 3fb8fb6cc824..e36d27ed4daa 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
@@ -1438,7 +1438,8 @@ int ib_close_qp(struct ib_qp *qp) | |||
1438 | spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags); | 1438 | spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags); |
1439 | 1439 | ||
1440 | atomic_dec(&real_qp->usecnt); | 1440 | atomic_dec(&real_qp->usecnt); |
1441 | ib_close_shared_qp_security(qp->qp_sec); | 1441 | if (qp->qp_sec) |
1442 | ib_close_shared_qp_security(qp->qp_sec); | ||
1442 | kfree(qp); | 1443 | kfree(qp); |
1443 | 1444 | ||
1444 | return 0; | 1445 | return 0; |
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index b7bfc536e00f..6f2b26126c64 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c | |||
@@ -395,7 +395,7 @@ next_cqe: | |||
395 | 395 | ||
396 | static int cqe_completes_wr(struct t4_cqe *cqe, struct t4_wq *wq) | 396 | static int cqe_completes_wr(struct t4_cqe *cqe, struct t4_wq *wq) |
397 | { | 397 | { |
398 | if (CQE_OPCODE(cqe) == C4IW_DRAIN_OPCODE) { | 398 | if (DRAIN_CQE(cqe)) { |
399 | WARN_ONCE(1, "Unexpected DRAIN CQE qp id %u!\n", wq->sq.qid); | 399 | WARN_ONCE(1, "Unexpected DRAIN CQE qp id %u!\n", wq->sq.qid); |
400 | return 0; | 400 | return 0; |
401 | } | 401 | } |
@@ -494,7 +494,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe, | |||
494 | /* | 494 | /* |
495 | * Special cqe for drain WR completions... | 495 | * Special cqe for drain WR completions... |
496 | */ | 496 | */ |
497 | if (CQE_OPCODE(hw_cqe) == C4IW_DRAIN_OPCODE) { | 497 | if (DRAIN_CQE(hw_cqe)) { |
498 | *cookie = CQE_DRAIN_COOKIE(hw_cqe); | 498 | *cookie = CQE_DRAIN_COOKIE(hw_cqe); |
499 | *cqe = *hw_cqe; | 499 | *cqe = *hw_cqe; |
500 | goto skip_cqe; | 500 | goto skip_cqe; |
@@ -571,10 +571,10 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe, | |||
571 | ret = -EAGAIN; | 571 | ret = -EAGAIN; |
572 | goto skip_cqe; | 572 | goto skip_cqe; |
573 | } | 573 | } |
574 | if (unlikely((CQE_WRID_MSN(hw_cqe) != (wq->rq.msn)))) { | 574 | if (unlikely(!CQE_STATUS(hw_cqe) && |
575 | CQE_WRID_MSN(hw_cqe) != wq->rq.msn)) { | ||
575 | t4_set_wq_in_error(wq); | 576 | t4_set_wq_in_error(wq); |
576 | hw_cqe->header |= htonl(CQE_STATUS_V(T4_ERR_MSN)); | 577 | hw_cqe->header |= cpu_to_be32(CQE_STATUS_V(T4_ERR_MSN)); |
577 | goto proc_cqe; | ||
578 | } | 578 | } |
579 | goto proc_cqe; | 579 | goto proc_cqe; |
580 | } | 580 | } |
@@ -748,9 +748,6 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc) | |||
748 | c4iw_invalidate_mr(qhp->rhp, | 748 | c4iw_invalidate_mr(qhp->rhp, |
749 | CQE_WRID_FR_STAG(&cqe)); | 749 | CQE_WRID_FR_STAG(&cqe)); |
750 | break; | 750 | break; |
751 | case C4IW_DRAIN_OPCODE: | ||
752 | wc->opcode = IB_WC_SEND; | ||
753 | break; | ||
754 | default: | 751 | default: |
755 | pr_err("Unexpected opcode %d in the CQE received for QPID=0x%0x\n", | 752 | pr_err("Unexpected opcode %d in the CQE received for QPID=0x%0x\n", |
756 | CQE_OPCODE(&cqe), CQE_QPID(&cqe)); | 753 | CQE_OPCODE(&cqe), CQE_QPID(&cqe)); |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 470f97a79ebb..65dd3726ca02 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
@@ -693,8 +693,6 @@ static inline int to_ib_qp_state(int c4iw_qp_state) | |||
693 | return IB_QPS_ERR; | 693 | return IB_QPS_ERR; |
694 | } | 694 | } |
695 | 695 | ||
696 | #define C4IW_DRAIN_OPCODE FW_RI_SGE_EC_CR_RETURN | ||
697 | |||
698 | static inline u32 c4iw_ib_to_tpt_access(int a) | 696 | static inline u32 c4iw_ib_to_tpt_access(int a) |
699 | { | 697 | { |
700 | return (a & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) | | 698 | return (a & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) | |
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 38bddd02a943..d5c92fc520d6 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
@@ -790,21 +790,57 @@ static int ring_kernel_rq_db(struct c4iw_qp *qhp, u16 inc) | |||
790 | return 0; | 790 | return 0; |
791 | } | 791 | } |
792 | 792 | ||
793 | static void complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) | 793 | static int ib_to_fw_opcode(int ib_opcode) |
794 | { | ||
795 | int opcode; | ||
796 | |||
797 | switch (ib_opcode) { | ||
798 | case IB_WR_SEND_WITH_INV: | ||
799 | opcode = FW_RI_SEND_WITH_INV; | ||
800 | break; | ||
801 | case IB_WR_SEND: | ||
802 | opcode = FW_RI_SEND; | ||
803 | break; | ||
804 | case IB_WR_RDMA_WRITE: | ||
805 | opcode = FW_RI_RDMA_WRITE; | ||
806 | break; | ||
807 | case IB_WR_RDMA_READ: | ||
808 | case IB_WR_RDMA_READ_WITH_INV: | ||
809 | opcode = FW_RI_READ_REQ; | ||
810 | break; | ||
811 | case IB_WR_REG_MR: | ||
812 | opcode = FW_RI_FAST_REGISTER; | ||
813 | break; | ||
814 | case IB_WR_LOCAL_INV: | ||
815 | opcode = FW_RI_LOCAL_INV; | ||
816 | break; | ||
817 | default: | ||
818 | opcode = -EINVAL; | ||
819 | } | ||
820 | return opcode; | ||
821 | } | ||
822 | |||
823 | static int complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) | ||
794 | { | 824 | { |
795 | struct t4_cqe cqe = {}; | 825 | struct t4_cqe cqe = {}; |
796 | struct c4iw_cq *schp; | 826 | struct c4iw_cq *schp; |
797 | unsigned long flag; | 827 | unsigned long flag; |
798 | struct t4_cq *cq; | 828 | struct t4_cq *cq; |
829 | int opcode; | ||
799 | 830 | ||
800 | schp = to_c4iw_cq(qhp->ibqp.send_cq); | 831 | schp = to_c4iw_cq(qhp->ibqp.send_cq); |
801 | cq = &schp->cq; | 832 | cq = &schp->cq; |
802 | 833 | ||
834 | opcode = ib_to_fw_opcode(wr->opcode); | ||
835 | if (opcode < 0) | ||
836 | return opcode; | ||
837 | |||
803 | cqe.u.drain_cookie = wr->wr_id; | 838 | cqe.u.drain_cookie = wr->wr_id; |
804 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | | 839 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | |
805 | CQE_OPCODE_V(C4IW_DRAIN_OPCODE) | | 840 | CQE_OPCODE_V(opcode) | |
806 | CQE_TYPE_V(1) | | 841 | CQE_TYPE_V(1) | |
807 | CQE_SWCQE_V(1) | | 842 | CQE_SWCQE_V(1) | |
843 | CQE_DRAIN_V(1) | | ||
808 | CQE_QPID_V(qhp->wq.sq.qid)); | 844 | CQE_QPID_V(qhp->wq.sq.qid)); |
809 | 845 | ||
810 | spin_lock_irqsave(&schp->lock, flag); | 846 | spin_lock_irqsave(&schp->lock, flag); |
@@ -819,6 +855,23 @@ static void complete_sq_drain_wr(struct c4iw_qp *qhp, struct ib_send_wr *wr) | |||
819 | schp->ibcq.cq_context); | 855 | schp->ibcq.cq_context); |
820 | spin_unlock_irqrestore(&schp->comp_handler_lock, flag); | 856 | spin_unlock_irqrestore(&schp->comp_handler_lock, flag); |
821 | } | 857 | } |
858 | return 0; | ||
859 | } | ||
860 | |||
861 | static int complete_sq_drain_wrs(struct c4iw_qp *qhp, struct ib_send_wr *wr, | ||
862 | struct ib_send_wr **bad_wr) | ||
863 | { | ||
864 | int ret = 0; | ||
865 | |||
866 | while (wr) { | ||
867 | ret = complete_sq_drain_wr(qhp, wr); | ||
868 | if (ret) { | ||
869 | *bad_wr = wr; | ||
870 | break; | ||
871 | } | ||
872 | wr = wr->next; | ||
873 | } | ||
874 | return ret; | ||
822 | } | 875 | } |
823 | 876 | ||
824 | static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | 877 | static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) |
@@ -833,9 +886,10 @@ static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | |||
833 | 886 | ||
834 | cqe.u.drain_cookie = wr->wr_id; | 887 | cqe.u.drain_cookie = wr->wr_id; |
835 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | | 888 | cqe.header = cpu_to_be32(CQE_STATUS_V(T4_ERR_SWFLUSH) | |
836 | CQE_OPCODE_V(C4IW_DRAIN_OPCODE) | | 889 | CQE_OPCODE_V(FW_RI_SEND) | |
837 | CQE_TYPE_V(0) | | 890 | CQE_TYPE_V(0) | |
838 | CQE_SWCQE_V(1) | | 891 | CQE_SWCQE_V(1) | |
892 | CQE_DRAIN_V(1) | | ||
839 | CQE_QPID_V(qhp->wq.sq.qid)); | 893 | CQE_QPID_V(qhp->wq.sq.qid)); |
840 | 894 | ||
841 | spin_lock_irqsave(&rchp->lock, flag); | 895 | spin_lock_irqsave(&rchp->lock, flag); |
@@ -852,6 +906,14 @@ static void complete_rq_drain_wr(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | |||
852 | } | 906 | } |
853 | } | 907 | } |
854 | 908 | ||
909 | static void complete_rq_drain_wrs(struct c4iw_qp *qhp, struct ib_recv_wr *wr) | ||
910 | { | ||
911 | while (wr) { | ||
912 | complete_rq_drain_wr(qhp, wr); | ||
913 | wr = wr->next; | ||
914 | } | ||
915 | } | ||
916 | |||
855 | int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | 917 | int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, |
856 | struct ib_send_wr **bad_wr) | 918 | struct ib_send_wr **bad_wr) |
857 | { | 919 | { |
@@ -875,7 +937,7 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
875 | */ | 937 | */ |
876 | if (qhp->wq.flushed) { | 938 | if (qhp->wq.flushed) { |
877 | spin_unlock_irqrestore(&qhp->lock, flag); | 939 | spin_unlock_irqrestore(&qhp->lock, flag); |
878 | complete_sq_drain_wr(qhp, wr); | 940 | err = complete_sq_drain_wrs(qhp, wr, bad_wr); |
879 | return err; | 941 | return err; |
880 | } | 942 | } |
881 | num_wrs = t4_sq_avail(&qhp->wq); | 943 | num_wrs = t4_sq_avail(&qhp->wq); |
@@ -1023,7 +1085,7 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1023 | */ | 1085 | */ |
1024 | if (qhp->wq.flushed) { | 1086 | if (qhp->wq.flushed) { |
1025 | spin_unlock_irqrestore(&qhp->lock, flag); | 1087 | spin_unlock_irqrestore(&qhp->lock, flag); |
1026 | complete_rq_drain_wr(qhp, wr); | 1088 | complete_rq_drain_wrs(qhp, wr); |
1027 | return err; | 1089 | return err; |
1028 | } | 1090 | } |
1029 | num_wrs = t4_rq_avail(&qhp->wq); | 1091 | num_wrs = t4_rq_avail(&qhp->wq); |
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index e9ea94268d51..79e8ee12c391 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h | |||
@@ -197,6 +197,11 @@ struct t4_cqe { | |||
197 | #define CQE_SWCQE_G(x) ((((x) >> CQE_SWCQE_S)) & CQE_SWCQE_M) | 197 | #define CQE_SWCQE_G(x) ((((x) >> CQE_SWCQE_S)) & CQE_SWCQE_M) |
198 | #define CQE_SWCQE_V(x) ((x)<<CQE_SWCQE_S) | 198 | #define CQE_SWCQE_V(x) ((x)<<CQE_SWCQE_S) |
199 | 199 | ||
200 | #define CQE_DRAIN_S 10 | ||
201 | #define CQE_DRAIN_M 0x1 | ||
202 | #define CQE_DRAIN_G(x) ((((x) >> CQE_DRAIN_S)) & CQE_DRAIN_M) | ||
203 | #define CQE_DRAIN_V(x) ((x)<<CQE_DRAIN_S) | ||
204 | |||
200 | #define CQE_STATUS_S 5 | 205 | #define CQE_STATUS_S 5 |
201 | #define CQE_STATUS_M 0x1F | 206 | #define CQE_STATUS_M 0x1F |
202 | #define CQE_STATUS_G(x) ((((x) >> CQE_STATUS_S)) & CQE_STATUS_M) | 207 | #define CQE_STATUS_G(x) ((((x) >> CQE_STATUS_S)) & CQE_STATUS_M) |
@@ -213,6 +218,7 @@ struct t4_cqe { | |||
213 | #define CQE_OPCODE_V(x) ((x)<<CQE_OPCODE_S) | 218 | #define CQE_OPCODE_V(x) ((x)<<CQE_OPCODE_S) |
214 | 219 | ||
215 | #define SW_CQE(x) (CQE_SWCQE_G(be32_to_cpu((x)->header))) | 220 | #define SW_CQE(x) (CQE_SWCQE_G(be32_to_cpu((x)->header))) |
221 | #define DRAIN_CQE(x) (CQE_DRAIN_G(be32_to_cpu((x)->header))) | ||
216 | #define CQE_QPID(x) (CQE_QPID_G(be32_to_cpu((x)->header))) | 222 | #define CQE_QPID(x) (CQE_QPID_G(be32_to_cpu((x)->header))) |
217 | #define CQE_TYPE(x) (CQE_TYPE_G(be32_to_cpu((x)->header))) | 223 | #define CQE_TYPE(x) (CQE_TYPE_G(be32_to_cpu((x)->header))) |
218 | #define SQ_TYPE(x) (CQE_TYPE((x))) | 224 | #define SQ_TYPE(x) (CQE_TYPE((x))) |
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 4a9b4d7efe63..8ce9118d4a7f 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h | |||
@@ -1131,7 +1131,6 @@ struct hfi1_devdata { | |||
1131 | u16 pcie_lnkctl; | 1131 | u16 pcie_lnkctl; |
1132 | u16 pcie_devctl2; | 1132 | u16 pcie_devctl2; |
1133 | u32 pci_msix0; | 1133 | u32 pci_msix0; |
1134 | u32 pci_lnkctl3; | ||
1135 | u32 pci_tph2; | 1134 | u32 pci_tph2; |
1136 | 1135 | ||
1137 | /* | 1136 | /* |
diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c index 09e50fd2a08f..8c7e7a60b715 100644 --- a/drivers/infiniband/hw/hfi1/pcie.c +++ b/drivers/infiniband/hw/hfi1/pcie.c | |||
@@ -411,15 +411,12 @@ int restore_pci_variables(struct hfi1_devdata *dd) | |||
411 | if (ret) | 411 | if (ret) |
412 | goto error; | 412 | goto error; |
413 | 413 | ||
414 | ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_SPCIE1, | 414 | if (pci_find_ext_capability(dd->pcidev, PCI_EXT_CAP_ID_TPH)) { |
415 | dd->pci_lnkctl3); | 415 | ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_TPH2, |
416 | if (ret) | 416 | dd->pci_tph2); |
417 | goto error; | 417 | if (ret) |
418 | 418 | goto error; | |
419 | ret = pci_write_config_dword(dd->pcidev, PCIE_CFG_TPH2, dd->pci_tph2); | 419 | } |
420 | if (ret) | ||
421 | goto error; | ||
422 | |||
423 | return 0; | 420 | return 0; |
424 | 421 | ||
425 | error: | 422 | error: |
@@ -469,15 +466,12 @@ int save_pci_variables(struct hfi1_devdata *dd) | |||
469 | if (ret) | 466 | if (ret) |
470 | goto error; | 467 | goto error; |
471 | 468 | ||
472 | ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_SPCIE1, | 469 | if (pci_find_ext_capability(dd->pcidev, PCI_EXT_CAP_ID_TPH)) { |
473 | &dd->pci_lnkctl3); | 470 | ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_TPH2, |
474 | if (ret) | 471 | &dd->pci_tph2); |
475 | goto error; | 472 | if (ret) |
476 | 473 | goto error; | |
477 | ret = pci_read_config_dword(dd->pcidev, PCIE_CFG_TPH2, &dd->pci_tph2); | 474 | } |
478 | if (ret) | ||
479 | goto error; | ||
480 | |||
481 | return 0; | 475 | return 0; |
482 | 476 | ||
483 | error: | 477 | error: |
diff --git a/drivers/infiniband/hw/mlx5/cmd.c b/drivers/infiniband/hw/mlx5/cmd.c index 470995fa38d2..6f6712f87a73 100644 --- a/drivers/infiniband/hw/mlx5/cmd.c +++ b/drivers/infiniband/hw/mlx5/cmd.c | |||
@@ -47,17 +47,6 @@ int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey) | |||
47 | return err; | 47 | return err; |
48 | } | 48 | } |
49 | 49 | ||
50 | int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | ||
51 | bool reset, void *out, int out_size) | ||
52 | { | ||
53 | u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = { }; | ||
54 | |||
55 | MLX5_SET(query_cong_statistics_in, in, opcode, | ||
56 | MLX5_CMD_OP_QUERY_CONG_STATISTICS); | ||
57 | MLX5_SET(query_cong_statistics_in, in, clear, reset); | ||
58 | return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size); | ||
59 | } | ||
60 | |||
61 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, | 50 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, |
62 | void *out, int out_size) | 51 | void *out, int out_size) |
63 | { | 52 | { |
diff --git a/drivers/infiniband/hw/mlx5/cmd.h b/drivers/infiniband/hw/mlx5/cmd.h index af4c24596274..78ffded7cc2c 100644 --- a/drivers/infiniband/hw/mlx5/cmd.h +++ b/drivers/infiniband/hw/mlx5/cmd.h | |||
@@ -37,8 +37,6 @@ | |||
37 | #include <linux/mlx5/driver.h> | 37 | #include <linux/mlx5/driver.h> |
38 | 38 | ||
39 | int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey); | 39 | int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey); |
40 | int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | ||
41 | bool reset, void *out, int out_size); | ||
42 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, | 40 | int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point, |
43 | void *out, int out_size); | 41 | void *out, int out_size); |
44 | int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev, | 42 | int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev, |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 543d0a4c8bf3..8ac50de2b242 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -1463,6 +1463,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, | |||
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | INIT_LIST_HEAD(&context->vma_private_list); | 1465 | INIT_LIST_HEAD(&context->vma_private_list); |
1466 | mutex_init(&context->vma_private_list_mutex); | ||
1466 | INIT_LIST_HEAD(&context->db_page_list); | 1467 | INIT_LIST_HEAD(&context->db_page_list); |
1467 | mutex_init(&context->db_page_mutex); | 1468 | mutex_init(&context->db_page_mutex); |
1468 | 1469 | ||
@@ -1624,7 +1625,9 @@ static void mlx5_ib_vma_close(struct vm_area_struct *area) | |||
1624 | * mlx5_ib_disassociate_ucontext(). | 1625 | * mlx5_ib_disassociate_ucontext(). |
1625 | */ | 1626 | */ |
1626 | mlx5_ib_vma_priv_data->vma = NULL; | 1627 | mlx5_ib_vma_priv_data->vma = NULL; |
1628 | mutex_lock(mlx5_ib_vma_priv_data->vma_private_list_mutex); | ||
1627 | list_del(&mlx5_ib_vma_priv_data->list); | 1629 | list_del(&mlx5_ib_vma_priv_data->list); |
1630 | mutex_unlock(mlx5_ib_vma_priv_data->vma_private_list_mutex); | ||
1628 | kfree(mlx5_ib_vma_priv_data); | 1631 | kfree(mlx5_ib_vma_priv_data); |
1629 | } | 1632 | } |
1630 | 1633 | ||
@@ -1644,10 +1647,13 @@ static int mlx5_ib_set_vma_data(struct vm_area_struct *vma, | |||
1644 | return -ENOMEM; | 1647 | return -ENOMEM; |
1645 | 1648 | ||
1646 | vma_prv->vma = vma; | 1649 | vma_prv->vma = vma; |
1650 | vma_prv->vma_private_list_mutex = &ctx->vma_private_list_mutex; | ||
1647 | vma->vm_private_data = vma_prv; | 1651 | vma->vm_private_data = vma_prv; |
1648 | vma->vm_ops = &mlx5_ib_vm_ops; | 1652 | vma->vm_ops = &mlx5_ib_vm_ops; |
1649 | 1653 | ||
1654 | mutex_lock(&ctx->vma_private_list_mutex); | ||
1650 | list_add(&vma_prv->list, vma_head); | 1655 | list_add(&vma_prv->list, vma_head); |
1656 | mutex_unlock(&ctx->vma_private_list_mutex); | ||
1651 | 1657 | ||
1652 | return 0; | 1658 | return 0; |
1653 | } | 1659 | } |
@@ -1690,6 +1696,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) | |||
1690 | * mlx5_ib_vma_close. | 1696 | * mlx5_ib_vma_close. |
1691 | */ | 1697 | */ |
1692 | down_write(&owning_mm->mmap_sem); | 1698 | down_write(&owning_mm->mmap_sem); |
1699 | mutex_lock(&context->vma_private_list_mutex); | ||
1693 | list_for_each_entry_safe(vma_private, n, &context->vma_private_list, | 1700 | list_for_each_entry_safe(vma_private, n, &context->vma_private_list, |
1694 | list) { | 1701 | list) { |
1695 | vma = vma_private->vma; | 1702 | vma = vma_private->vma; |
@@ -1704,6 +1711,7 @@ static void mlx5_ib_disassociate_ucontext(struct ib_ucontext *ibcontext) | |||
1704 | list_del(&vma_private->list); | 1711 | list_del(&vma_private->list); |
1705 | kfree(vma_private); | 1712 | kfree(vma_private); |
1706 | } | 1713 | } |
1714 | mutex_unlock(&context->vma_private_list_mutex); | ||
1707 | up_write(&owning_mm->mmap_sem); | 1715 | up_write(&owning_mm->mmap_sem); |
1708 | mmput(owning_mm); | 1716 | mmput(owning_mm); |
1709 | put_task_struct(owning_process); | 1717 | put_task_struct(owning_process); |
@@ -3737,34 +3745,6 @@ free: | |||
3737 | return ret; | 3745 | return ret; |
3738 | } | 3746 | } |
3739 | 3747 | ||
3740 | static int mlx5_ib_query_cong_counters(struct mlx5_ib_dev *dev, | ||
3741 | struct mlx5_ib_port *port, | ||
3742 | struct rdma_hw_stats *stats) | ||
3743 | { | ||
3744 | int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out); | ||
3745 | void *out; | ||
3746 | int ret, i; | ||
3747 | int offset = port->cnts.num_q_counters; | ||
3748 | |||
3749 | out = kvzalloc(outlen, GFP_KERNEL); | ||
3750 | if (!out) | ||
3751 | return -ENOMEM; | ||
3752 | |||
3753 | ret = mlx5_cmd_query_cong_counter(dev->mdev, false, out, outlen); | ||
3754 | if (ret) | ||
3755 | goto free; | ||
3756 | |||
3757 | for (i = 0; i < port->cnts.num_cong_counters; i++) { | ||
3758 | stats->value[i + offset] = | ||
3759 | be64_to_cpup((__be64 *)(out + | ||
3760 | port->cnts.offsets[i + offset])); | ||
3761 | } | ||
3762 | |||
3763 | free: | ||
3764 | kvfree(out); | ||
3765 | return ret; | ||
3766 | } | ||
3767 | |||
3768 | static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, | 3748 | static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, |
3769 | struct rdma_hw_stats *stats, | 3749 | struct rdma_hw_stats *stats, |
3770 | u8 port_num, int index) | 3750 | u8 port_num, int index) |
@@ -3782,7 +3762,12 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev, | |||
3782 | num_counters = port->cnts.num_q_counters; | 3762 | num_counters = port->cnts.num_q_counters; |
3783 | 3763 | ||
3784 | if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) { | 3764 | if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) { |
3785 | ret = mlx5_ib_query_cong_counters(dev, port, stats); | 3765 | ret = mlx5_lag_query_cong_counters(dev->mdev, |
3766 | stats->value + | ||
3767 | port->cnts.num_q_counters, | ||
3768 | port->cnts.num_cong_counters, | ||
3769 | port->cnts.offsets + | ||
3770 | port->cnts.num_q_counters); | ||
3786 | if (ret) | 3771 | if (ret) |
3787 | return ret; | 3772 | return ret; |
3788 | num_counters += port->cnts.num_cong_counters; | 3773 | num_counters += port->cnts.num_cong_counters; |
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 6dd8cac78de2..2c5f3533bbc9 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h | |||
@@ -115,6 +115,8 @@ enum { | |||
115 | struct mlx5_ib_vma_private_data { | 115 | struct mlx5_ib_vma_private_data { |
116 | struct list_head list; | 116 | struct list_head list; |
117 | struct vm_area_struct *vma; | 117 | struct vm_area_struct *vma; |
118 | /* protect vma_private_list add/del */ | ||
119 | struct mutex *vma_private_list_mutex; | ||
118 | }; | 120 | }; |
119 | 121 | ||
120 | struct mlx5_ib_ucontext { | 122 | struct mlx5_ib_ucontext { |
@@ -129,6 +131,8 @@ struct mlx5_ib_ucontext { | |||
129 | /* Transport Domain number */ | 131 | /* Transport Domain number */ |
130 | u32 tdn; | 132 | u32 tdn; |
131 | struct list_head vma_private_list; | 133 | struct list_head vma_private_list; |
134 | /* protect vma_private_list add/del */ | ||
135 | struct mutex vma_private_list_mutex; | ||
132 | 136 | ||
133 | unsigned long upd_xlt_page; | 137 | unsigned long upd_xlt_page; |
134 | /* protect ODP/KSM */ | 138 | /* protect ODP/KSM */ |
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index ee0ee1f9994b..d109fe8290a7 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c | |||
@@ -1637,6 +1637,7 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, | |||
1637 | MLX5_SET(mkc, mkc, access_mode, mr->access_mode); | 1637 | MLX5_SET(mkc, mkc, access_mode, mr->access_mode); |
1638 | MLX5_SET(mkc, mkc, umr_en, 1); | 1638 | MLX5_SET(mkc, mkc, umr_en, 1); |
1639 | 1639 | ||
1640 | mr->ibmr.device = pd->device; | ||
1640 | err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen); | 1641 | err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen); |
1641 | if (err) | 1642 | if (err) |
1642 | goto err_destroy_psv; | 1643 | goto err_destroy_psv; |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h index 63bc2efc34eb..4f7bd3b6a315 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h | |||
@@ -94,7 +94,7 @@ struct pvrdma_cq { | |||
94 | u32 cq_handle; | 94 | u32 cq_handle; |
95 | bool is_kernel; | 95 | bool is_kernel; |
96 | atomic_t refcnt; | 96 | atomic_t refcnt; |
97 | wait_queue_head_t wait; | 97 | struct completion free; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | struct pvrdma_id_table { | 100 | struct pvrdma_id_table { |
@@ -175,7 +175,7 @@ struct pvrdma_srq { | |||
175 | u32 srq_handle; | 175 | u32 srq_handle; |
176 | int npages; | 176 | int npages; |
177 | refcount_t refcnt; | 177 | refcount_t refcnt; |
178 | wait_queue_head_t wait; | 178 | struct completion free; |
179 | }; | 179 | }; |
180 | 180 | ||
181 | struct pvrdma_qp { | 181 | struct pvrdma_qp { |
@@ -197,7 +197,7 @@ struct pvrdma_qp { | |||
197 | bool is_kernel; | 197 | bool is_kernel; |
198 | struct mutex mutex; /* QP state mutex. */ | 198 | struct mutex mutex; /* QP state mutex. */ |
199 | atomic_t refcnt; | 199 | atomic_t refcnt; |
200 | wait_queue_head_t wait; | 200 | struct completion free; |
201 | }; | 201 | }; |
202 | 202 | ||
203 | struct pvrdma_dev { | 203 | struct pvrdma_dev { |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c index 3562c0c30492..e529622cefad 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c | |||
@@ -179,7 +179,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev, | |||
179 | pvrdma_page_dir_insert_umem(&cq->pdir, cq->umem, 0); | 179 | pvrdma_page_dir_insert_umem(&cq->pdir, cq->umem, 0); |
180 | 180 | ||
181 | atomic_set(&cq->refcnt, 1); | 181 | atomic_set(&cq->refcnt, 1); |
182 | init_waitqueue_head(&cq->wait); | 182 | init_completion(&cq->free); |
183 | spin_lock_init(&cq->cq_lock); | 183 | spin_lock_init(&cq->cq_lock); |
184 | 184 | ||
185 | memset(cmd, 0, sizeof(*cmd)); | 185 | memset(cmd, 0, sizeof(*cmd)); |
@@ -230,8 +230,9 @@ err_cq: | |||
230 | 230 | ||
231 | static void pvrdma_free_cq(struct pvrdma_dev *dev, struct pvrdma_cq *cq) | 231 | static void pvrdma_free_cq(struct pvrdma_dev *dev, struct pvrdma_cq *cq) |
232 | { | 232 | { |
233 | atomic_dec(&cq->refcnt); | 233 | if (atomic_dec_and_test(&cq->refcnt)) |
234 | wait_event(cq->wait, !atomic_read(&cq->refcnt)); | 234 | complete(&cq->free); |
235 | wait_for_completion(&cq->free); | ||
235 | 236 | ||
236 | if (!cq->is_kernel) | 237 | if (!cq->is_kernel) |
237 | ib_umem_release(cq->umem); | 238 | ib_umem_release(cq->umem); |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c index 1f4e18717a00..e92681878c93 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c | |||
@@ -346,9 +346,8 @@ static void pvrdma_qp_event(struct pvrdma_dev *dev, u32 qpn, int type) | |||
346 | ibqp->event_handler(&e, ibqp->qp_context); | 346 | ibqp->event_handler(&e, ibqp->qp_context); |
347 | } | 347 | } |
348 | if (qp) { | 348 | if (qp) { |
349 | atomic_dec(&qp->refcnt); | 349 | if (atomic_dec_and_test(&qp->refcnt)) |
350 | if (atomic_read(&qp->refcnt) == 0) | 350 | complete(&qp->free); |
351 | wake_up(&qp->wait); | ||
352 | } | 351 | } |
353 | } | 352 | } |
354 | 353 | ||
@@ -373,9 +372,8 @@ static void pvrdma_cq_event(struct pvrdma_dev *dev, u32 cqn, int type) | |||
373 | ibcq->event_handler(&e, ibcq->cq_context); | 372 | ibcq->event_handler(&e, ibcq->cq_context); |
374 | } | 373 | } |
375 | if (cq) { | 374 | if (cq) { |
376 | atomic_dec(&cq->refcnt); | 375 | if (atomic_dec_and_test(&cq->refcnt)) |
377 | if (atomic_read(&cq->refcnt) == 0) | 376 | complete(&cq->free); |
378 | wake_up(&cq->wait); | ||
379 | } | 377 | } |
380 | } | 378 | } |
381 | 379 | ||
@@ -404,7 +402,7 @@ static void pvrdma_srq_event(struct pvrdma_dev *dev, u32 srqn, int type) | |||
404 | } | 402 | } |
405 | if (srq) { | 403 | if (srq) { |
406 | if (refcount_dec_and_test(&srq->refcnt)) | 404 | if (refcount_dec_and_test(&srq->refcnt)) |
407 | wake_up(&srq->wait); | 405 | complete(&srq->free); |
408 | } | 406 | } |
409 | } | 407 | } |
410 | 408 | ||
@@ -539,9 +537,8 @@ static irqreturn_t pvrdma_intrx_handler(int irq, void *dev_id) | |||
539 | if (cq && cq->ibcq.comp_handler) | 537 | if (cq && cq->ibcq.comp_handler) |
540 | cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); | 538 | cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); |
541 | if (cq) { | 539 | if (cq) { |
542 | atomic_dec(&cq->refcnt); | 540 | if (atomic_dec_and_test(&cq->refcnt)) |
543 | if (atomic_read(&cq->refcnt)) | 541 | complete(&cq->free); |
544 | wake_up(&cq->wait); | ||
545 | } | 542 | } |
546 | pvrdma_idx_ring_inc(&ring->cons_head, ring_slots); | 543 | pvrdma_idx_ring_inc(&ring->cons_head, ring_slots); |
547 | } | 544 | } |
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c index 10420a18d02f..4059308e1454 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c | |||
@@ -246,7 +246,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, | |||
246 | spin_lock_init(&qp->rq.lock); | 246 | spin_lock_init(&qp->rq.lock); |
247 | mutex_init(&qp->mutex); | 247 | mutex_init(&qp->mutex); |
248 | atomic_set(&qp->refcnt, 1); | 248 | atomic_set(&qp->refcnt, 1); |
249 | init_waitqueue_head(&qp->wait); | 249 | init_completion(&qp->free); |
250 | 250 | ||
251 | qp->state = IB_QPS_RESET; | 251 | qp->state = IB_QPS_RESET; |
252 | 252 | ||
@@ -428,8 +428,16 @@ static void pvrdma_free_qp(struct pvrdma_qp *qp) | |||
428 | 428 | ||
429 | pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags); | 429 | pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags); |
430 | 430 | ||
431 | atomic_dec(&qp->refcnt); | 431 | if (atomic_dec_and_test(&qp->refcnt)) |
432 | wait_event(qp->wait, !atomic_read(&qp->refcnt)); | 432 | complete(&qp->free); |
433 | wait_for_completion(&qp->free); | ||
434 | |||
435 | if (!qp->is_kernel) { | ||
436 | if (qp->rumem) | ||
437 | ib_umem_release(qp->rumem); | ||
438 | if (qp->sumem) | ||
439 | ib_umem_release(qp->sumem); | ||
440 | } | ||
433 | 441 | ||
434 | pvrdma_page_dir_cleanup(dev, &qp->pdir); | 442 | pvrdma_page_dir_cleanup(dev, &qp->pdir); |
435 | 443 | ||
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c index 826ccb864596..5acebb1ef631 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c | |||
@@ -149,7 +149,7 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd, | |||
149 | 149 | ||
150 | spin_lock_init(&srq->lock); | 150 | spin_lock_init(&srq->lock); |
151 | refcount_set(&srq->refcnt, 1); | 151 | refcount_set(&srq->refcnt, 1); |
152 | init_waitqueue_head(&srq->wait); | 152 | init_completion(&srq->free); |
153 | 153 | ||
154 | dev_dbg(&dev->pdev->dev, | 154 | dev_dbg(&dev->pdev->dev, |
155 | "create shared receive queue from user space\n"); | 155 | "create shared receive queue from user space\n"); |
@@ -236,8 +236,9 @@ static void pvrdma_free_srq(struct pvrdma_dev *dev, struct pvrdma_srq *srq) | |||
236 | dev->srq_tbl[srq->srq_handle] = NULL; | 236 | dev->srq_tbl[srq->srq_handle] = NULL; |
237 | spin_unlock_irqrestore(&dev->srq_tbl_lock, flags); | 237 | spin_unlock_irqrestore(&dev->srq_tbl_lock, flags); |
238 | 238 | ||
239 | refcount_dec(&srq->refcnt); | 239 | if (refcount_dec_and_test(&srq->refcnt)) |
240 | wait_event(srq->wait, !refcount_read(&srq->refcnt)); | 240 | complete(&srq->free); |
241 | wait_for_completion(&srq->free); | ||
241 | 242 | ||
242 | /* There is no support for kernel clients, so this is safe. */ | 243 | /* There is no support for kernel clients, so this is safe. */ |
243 | ib_umem_release(srq->umem); | 244 | ib_umem_release(srq->umem); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 3b96cdaf9a83..e6151a29c412 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -1236,13 +1236,10 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
1236 | ipoib_ib_dev_down(dev); | 1236 | ipoib_ib_dev_down(dev); |
1237 | 1237 | ||
1238 | if (level == IPOIB_FLUSH_HEAVY) { | 1238 | if (level == IPOIB_FLUSH_HEAVY) { |
1239 | rtnl_lock(); | ||
1240 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | 1239 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
1241 | ipoib_ib_dev_stop(dev); | 1240 | ipoib_ib_dev_stop(dev); |
1242 | 1241 | ||
1243 | result = ipoib_ib_dev_open(dev); | 1242 | if (ipoib_ib_dev_open(dev)) |
1244 | rtnl_unlock(); | ||
1245 | if (result) | ||
1246 | return; | 1243 | return; |
1247 | 1244 | ||
1248 | if (netif_queue_stopped(dev)) | 1245 | if (netif_queue_stopped(dev)) |
@@ -1282,7 +1279,9 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work) | |||
1282 | struct ipoib_dev_priv *priv = | 1279 | struct ipoib_dev_priv *priv = |
1283 | container_of(work, struct ipoib_dev_priv, flush_heavy); | 1280 | container_of(work, struct ipoib_dev_priv, flush_heavy); |
1284 | 1281 | ||
1282 | rtnl_lock(); | ||
1285 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY, 0); | 1283 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY, 0); |
1284 | rtnl_unlock(); | ||
1286 | } | 1285 | } |
1287 | 1286 | ||
1288 | void ipoib_ib_dev_cleanup(struct net_device *dev) | 1287 | void ipoib_ib_dev_cleanup(struct net_device *dev) |
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index fd83c7f77a95..f3654fd2eaf3 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c | |||
@@ -186,7 +186,7 @@ void led_blink_set(struct led_classdev *led_cdev, | |||
186 | unsigned long *delay_on, | 186 | unsigned long *delay_on, |
187 | unsigned long *delay_off) | 187 | unsigned long *delay_off) |
188 | { | 188 | { |
189 | del_timer_sync(&led_cdev->blink_timer); | 189 | led_stop_software_blink(led_cdev); |
190 | 190 | ||
191 | clear_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags); | 191 | clear_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags); |
192 | clear_bit(LED_BLINK_ONESHOT_STOP, &led_cdev->work_flags); | 192 | clear_bit(LED_BLINK_ONESHOT_STOP, &led_cdev->work_flags); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 01b7f2fc249c..57eb26dfc059 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -3029,7 +3029,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
3029 | 3029 | ||
3030 | del_timer_sync(&bp->timer); | 3030 | del_timer_sync(&bp->timer); |
3031 | 3031 | ||
3032 | if (IS_PF(bp)) { | 3032 | if (IS_PF(bp) && !BP_NOMCP(bp)) { |
3033 | /* Set ALWAYS_ALIVE bit in shmem */ | 3033 | /* Set ALWAYS_ALIVE bit in shmem */ |
3034 | bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE; | 3034 | bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE; |
3035 | bnx2x_drv_pulse(bp); | 3035 | bnx2x_drv_pulse(bp); |
@@ -3115,7 +3115,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) | |||
3115 | bp->cnic_loaded = false; | 3115 | bp->cnic_loaded = false; |
3116 | 3116 | ||
3117 | /* Clear driver version indication in shmem */ | 3117 | /* Clear driver version indication in shmem */ |
3118 | if (IS_PF(bp)) | 3118 | if (IS_PF(bp) && !BP_NOMCP(bp)) |
3119 | bnx2x_update_mng_version(bp); | 3119 | bnx2x_update_mng_version(bp); |
3120 | 3120 | ||
3121 | /* Check if there are pending parity attentions. If there are - set | 3121 | /* Check if there are pending parity attentions. If there are - set |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 4d0654813de1..7b08323e3f3d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -9578,6 +9578,15 @@ static int bnx2x_init_shmem(struct bnx2x *bp) | |||
9578 | 9578 | ||
9579 | do { | 9579 | do { |
9580 | bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); | 9580 | bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); |
9581 | |||
9582 | /* If we read all 0xFFs, means we are in PCI error state and | ||
9583 | * should bail out to avoid crashes on adapter's FW reads. | ||
9584 | */ | ||
9585 | if (bp->common.shmem_base == 0xFFFFFFFF) { | ||
9586 | bp->flags |= NO_MCP_FLAG; | ||
9587 | return -ENODEV; | ||
9588 | } | ||
9589 | |||
9581 | if (bp->common.shmem_base) { | 9590 | if (bp->common.shmem_base) { |
9582 | val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); | 9591 | val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); |
9583 | if (val & SHR_MEM_VALIDITY_MB) | 9592 | if (val & SHR_MEM_VALIDITY_MB) |
@@ -14322,7 +14331,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev) | |||
14322 | BNX2X_ERR("IO slot reset --> driver unload\n"); | 14331 | BNX2X_ERR("IO slot reset --> driver unload\n"); |
14323 | 14332 | ||
14324 | /* MCP should have been reset; Need to wait for validity */ | 14333 | /* MCP should have been reset; Need to wait for validity */ |
14325 | bnx2x_init_shmem(bp); | 14334 | if (bnx2x_init_shmem(bp)) { |
14335 | rtnl_unlock(); | ||
14336 | return PCI_ERS_RESULT_DISCONNECT; | ||
14337 | } | ||
14326 | 14338 | ||
14327 | if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { | 14339 | if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) { |
14328 | u32 v; | 14340 | u32 v; |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index d09c5a9c53b5..8995cfefbfcf 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -4,11 +4,13 @@ | |||
4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) | 5 | * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) |
6 | * Copyright (C) 2004 Sun Microsystems Inc. | 6 | * Copyright (C) 2004 Sun Microsystems Inc. |
7 | * Copyright (C) 2005-2014 Broadcom Corporation. | 7 | * Copyright (C) 2005-2016 Broadcom Corporation. |
8 | * Copyright (C) 2016-2017 Broadcom Limited. | ||
8 | * | 9 | * |
9 | * Firmware is: | 10 | * Firmware is: |
10 | * Derived from proprietary unpublished source code, | 11 | * Derived from proprietary unpublished source code, |
11 | * Copyright (C) 2000-2003 Broadcom Corporation. | 12 | * Copyright (C) 2000-2016 Broadcom Corporation. |
13 | * Copyright (C) 2016-2017 Broadcom Ltd. | ||
12 | * | 14 | * |
13 | * Permission is hereby granted for the distribution of this firmware | 15 | * Permission is hereby granted for the distribution of this firmware |
14 | * data in hexadecimal or equivalent format, provided this copyright | 16 | * data in hexadecimal or equivalent format, provided this copyright |
@@ -10052,6 +10054,16 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) | |||
10052 | 10054 | ||
10053 | tw32(GRC_MODE, tp->grc_mode | val); | 10055 | tw32(GRC_MODE, tp->grc_mode | val); |
10054 | 10056 | ||
10057 | /* On one of the AMD platform, MRRS is restricted to 4000 because of | ||
10058 | * south bridge limitation. As a workaround, Driver is setting MRRS | ||
10059 | * to 2048 instead of default 4096. | ||
10060 | */ | ||
10061 | if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && | ||
10062 | tp->pdev->subsystem_device == TG3PCI_SUBDEVICE_ID_DELL_5762) { | ||
10063 | val = tr32(TG3PCI_DEV_STATUS_CTRL) & ~MAX_READ_REQ_MASK; | ||
10064 | tw32(TG3PCI_DEV_STATUS_CTRL, val | MAX_READ_REQ_SIZE_2048); | ||
10065 | } | ||
10066 | |||
10055 | /* Setup the timer prescalar register. Clock is always 66Mhz. */ | 10067 | /* Setup the timer prescalar register. Clock is always 66Mhz. */ |
10056 | val = tr32(GRC_MISC_CFG); | 10068 | val = tr32(GRC_MISC_CFG); |
10057 | val &= ~0xff; | 10069 | val &= ~0xff; |
@@ -14227,7 +14239,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
14227 | */ | 14239 | */ |
14228 | if (tg3_asic_rev(tp) == ASIC_REV_57766 || | 14240 | if (tg3_asic_rev(tp) == ASIC_REV_57766 || |
14229 | tg3_asic_rev(tp) == ASIC_REV_5717 || | 14241 | tg3_asic_rev(tp) == ASIC_REV_5717 || |
14230 | tg3_asic_rev(tp) == ASIC_REV_5719) | 14242 | tg3_asic_rev(tp) == ASIC_REV_5719 || |
14243 | tg3_asic_rev(tp) == ASIC_REV_5720) | ||
14231 | reset_phy = true; | 14244 | reset_phy = true; |
14232 | 14245 | ||
14233 | err = tg3_restart_hw(tp, reset_phy); | 14246 | err = tg3_restart_hw(tp, reset_phy); |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index c2d02d02d1e6..1f0271fa7c74 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
@@ -5,7 +5,8 @@ | |||
5 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) | 5 | * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) |
6 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) | 6 | * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) |
7 | * Copyright (C) 2004 Sun Microsystems Inc. | 7 | * Copyright (C) 2004 Sun Microsystems Inc. |
8 | * Copyright (C) 2007-2014 Broadcom Corporation. | 8 | * Copyright (C) 2007-2016 Broadcom Corporation. |
9 | * Copyright (C) 2016-2017 Broadcom Limited. | ||
9 | */ | 10 | */ |
10 | 11 | ||
11 | #ifndef _T3_H | 12 | #ifndef _T3_H |
@@ -96,6 +97,7 @@ | |||
96 | #define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106 | 97 | #define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106 |
97 | #define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109 | 98 | #define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109 |
98 | #define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a | 99 | #define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a |
100 | #define TG3PCI_SUBDEVICE_ID_DELL_5762 0x07f0 | ||
99 | #define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ | 101 | #define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ |
100 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c | 102 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c |
101 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a | 103 | #define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a |
@@ -281,6 +283,9 @@ | |||
281 | #define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */ | 283 | #define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */ |
282 | #define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */ | 284 | #define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */ |
283 | /* 0xa8 --> 0xb8 unused */ | 285 | /* 0xa8 --> 0xb8 unused */ |
286 | #define TG3PCI_DEV_STATUS_CTRL 0x000000b4 | ||
287 | #define MAX_READ_REQ_SIZE_2048 0x00004000 | ||
288 | #define MAX_READ_REQ_MASK 0x00007000 | ||
284 | #define TG3PCI_DUAL_MAC_CTRL 0x000000b8 | 289 | #define TG3PCI_DUAL_MAC_CTRL 0x000000b8 |
285 | #define DUAL_MAC_CTRL_CH_MASK 0x00000003 | 290 | #define DUAL_MAC_CTRL_CH_MASK 0x00000003 |
286 | #define DUAL_MAC_CTRL_ID 0x00000004 | 291 | #define DUAL_MAC_CTRL_ID 0x00000004 |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 2d1b06579c1a..e17d10b8b041 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -818,6 +818,12 @@ static void fec_enet_bd_init(struct net_device *dev) | |||
818 | for (i = 0; i < txq->bd.ring_size; i++) { | 818 | for (i = 0; i < txq->bd.ring_size; i++) { |
819 | /* Initialize the BD for every fragment in the page. */ | 819 | /* Initialize the BD for every fragment in the page. */ |
820 | bdp->cbd_sc = cpu_to_fec16(0); | 820 | bdp->cbd_sc = cpu_to_fec16(0); |
821 | if (bdp->cbd_bufaddr && | ||
822 | !IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr))) | ||
823 | dma_unmap_single(&fep->pdev->dev, | ||
824 | fec32_to_cpu(bdp->cbd_bufaddr), | ||
825 | fec16_to_cpu(bdp->cbd_datlen), | ||
826 | DMA_TO_DEVICE); | ||
821 | if (txq->tx_skbuff[i]) { | 827 | if (txq->tx_skbuff[i]) { |
822 | dev_kfree_skb_any(txq->tx_skbuff[i]); | 828 | dev_kfree_skb_any(txq->tx_skbuff[i]); |
823 | txq->tx_skbuff[i] = NULL; | 829 | txq->tx_skbuff[i] = NULL; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag.c index f26f97fe4666..582b2f18010a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag.c | |||
@@ -137,6 +137,17 @@ int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev) | |||
137 | } | 137 | } |
138 | EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag); | 138 | EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag); |
139 | 139 | ||
140 | static int mlx5_cmd_query_cong_counter(struct mlx5_core_dev *dev, | ||
141 | bool reset, void *out, int out_size) | ||
142 | { | ||
143 | u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = { }; | ||
144 | |||
145 | MLX5_SET(query_cong_statistics_in, in, opcode, | ||
146 | MLX5_CMD_OP_QUERY_CONG_STATISTICS); | ||
147 | MLX5_SET(query_cong_statistics_in, in, clear, reset); | ||
148 | return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size); | ||
149 | } | ||
150 | |||
140 | static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev) | 151 | static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev) |
141 | { | 152 | { |
142 | return dev->priv.lag; | 153 | return dev->priv.lag; |
@@ -633,3 +644,48 @@ bool mlx5_lag_intf_add(struct mlx5_interface *intf, struct mlx5_priv *priv) | |||
633 | /* If bonded, we do not add an IB device for PF1. */ | 644 | /* If bonded, we do not add an IB device for PF1. */ |
634 | return false; | 645 | return false; |
635 | } | 646 | } |
647 | |||
648 | int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, | ||
649 | u64 *values, | ||
650 | int num_counters, | ||
651 | size_t *offsets) | ||
652 | { | ||
653 | int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out); | ||
654 | struct mlx5_core_dev *mdev[MLX5_MAX_PORTS]; | ||
655 | struct mlx5_lag *ldev; | ||
656 | int num_ports; | ||
657 | int ret, i, j; | ||
658 | void *out; | ||
659 | |||
660 | out = kvzalloc(outlen, GFP_KERNEL); | ||
661 | if (!out) | ||
662 | return -ENOMEM; | ||
663 | |||
664 | memset(values, 0, sizeof(*values) * num_counters); | ||
665 | |||
666 | mutex_lock(&lag_mutex); | ||
667 | ldev = mlx5_lag_dev_get(dev); | ||
668 | if (ldev && mlx5_lag_is_bonded(ldev)) { | ||
669 | num_ports = MLX5_MAX_PORTS; | ||
670 | mdev[0] = ldev->pf[0].dev; | ||
671 | mdev[1] = ldev->pf[1].dev; | ||
672 | } else { | ||
673 | num_ports = 1; | ||
674 | mdev[0] = dev; | ||
675 | } | ||
676 | |||
677 | for (i = 0; i < num_ports; ++i) { | ||
678 | ret = mlx5_cmd_query_cong_counter(mdev[i], false, out, outlen); | ||
679 | if (ret) | ||
680 | goto unlock; | ||
681 | |||
682 | for (j = 0; j < num_counters; ++j) | ||
683 | values[j] += be64_to_cpup((__be64 *)(out + offsets[j])); | ||
684 | } | ||
685 | |||
686 | unlock: | ||
687 | mutex_unlock(&lag_mutex); | ||
688 | kvfree(out); | ||
689 | return ret; | ||
690 | } | ||
691 | EXPORT_SYMBOL(mlx5_lag_query_cong_counters); | ||
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index fd500b18e77f..0f45310300f6 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
@@ -624,6 +624,7 @@ static int ksz9031_read_status(struct phy_device *phydev) | |||
624 | phydev->link = 0; | 624 | phydev->link = 0; |
625 | if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev)) | 625 | if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev)) |
626 | phydev->drv->config_intr(phydev); | 626 | phydev->drv->config_intr(phydev); |
627 | return genphy_config_aneg(phydev); | ||
627 | } | 628 | } |
628 | 629 | ||
629 | return 0; | 630 | return 0; |
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 2ec140ec7923..82166a26f5c6 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c | |||
@@ -567,6 +567,7 @@ struct phylink *phylink_create(struct net_device *ndev, | |||
567 | pl->link_config.pause = MLO_PAUSE_AN; | 567 | pl->link_config.pause = MLO_PAUSE_AN; |
568 | pl->link_config.speed = SPEED_UNKNOWN; | 568 | pl->link_config.speed = SPEED_UNKNOWN; |
569 | pl->link_config.duplex = DUPLEX_UNKNOWN; | 569 | pl->link_config.duplex = DUPLEX_UNKNOWN; |
570 | pl->link_config.an_enabled = true; | ||
570 | pl->ops = ops; | 571 | pl->ops = ops; |
571 | __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); | 572 | __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); |
572 | 573 | ||
@@ -1139,6 +1140,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, | |||
1139 | mutex_lock(&pl->state_mutex); | 1140 | mutex_lock(&pl->state_mutex); |
1140 | /* Configure the MAC to match the new settings */ | 1141 | /* Configure the MAC to match the new settings */ |
1141 | linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising); | 1142 | linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising); |
1143 | pl->link_config.interface = config.interface; | ||
1142 | pl->link_config.speed = our_kset.base.speed; | 1144 | pl->link_config.speed = our_kset.base.speed; |
1143 | pl->link_config.duplex = our_kset.base.duplex; | 1145 | pl->link_config.duplex = our_kset.base.duplex; |
1144 | pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE; | 1146 | pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE; |
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index e949e3302af4..c586bcdb5190 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c | |||
@@ -211,12 +211,12 @@ static int btt_map_read(struct arena_info *arena, u32 lba, u32 *mapping, | |||
211 | return ret; | 211 | return ret; |
212 | } | 212 | } |
213 | 213 | ||
214 | static int btt_log_read_pair(struct arena_info *arena, u32 lane, | 214 | static int btt_log_group_read(struct arena_info *arena, u32 lane, |
215 | struct log_entry *ent) | 215 | struct log_group *log) |
216 | { | 216 | { |
217 | return arena_read_bytes(arena, | 217 | return arena_read_bytes(arena, |
218 | arena->logoff + (2 * lane * LOG_ENT_SIZE), ent, | 218 | arena->logoff + (lane * LOG_GRP_SIZE), log, |
219 | 2 * LOG_ENT_SIZE, 0); | 219 | LOG_GRP_SIZE, 0); |
220 | } | 220 | } |
221 | 221 | ||
222 | static struct dentry *debugfs_root; | 222 | static struct dentry *debugfs_root; |
@@ -256,6 +256,8 @@ static void arena_debugfs_init(struct arena_info *a, struct dentry *parent, | |||
256 | debugfs_create_x64("logoff", S_IRUGO, d, &a->logoff); | 256 | debugfs_create_x64("logoff", S_IRUGO, d, &a->logoff); |
257 | debugfs_create_x64("info2off", S_IRUGO, d, &a->info2off); | 257 | debugfs_create_x64("info2off", S_IRUGO, d, &a->info2off); |
258 | debugfs_create_x32("flags", S_IRUGO, d, &a->flags); | 258 | debugfs_create_x32("flags", S_IRUGO, d, &a->flags); |
259 | debugfs_create_u32("log_index_0", S_IRUGO, d, &a->log_index[0]); | ||
260 | debugfs_create_u32("log_index_1", S_IRUGO, d, &a->log_index[1]); | ||
259 | } | 261 | } |
260 | 262 | ||
261 | static void btt_debugfs_init(struct btt *btt) | 263 | static void btt_debugfs_init(struct btt *btt) |
@@ -274,6 +276,11 @@ static void btt_debugfs_init(struct btt *btt) | |||
274 | } | 276 | } |
275 | } | 277 | } |
276 | 278 | ||
279 | static u32 log_seq(struct log_group *log, int log_idx) | ||
280 | { | ||
281 | return le32_to_cpu(log->ent[log_idx].seq); | ||
282 | } | ||
283 | |||
277 | /* | 284 | /* |
278 | * This function accepts two log entries, and uses the | 285 | * This function accepts two log entries, and uses the |
279 | * sequence number to find the 'older' entry. | 286 | * sequence number to find the 'older' entry. |
@@ -283,8 +290,10 @@ static void btt_debugfs_init(struct btt *btt) | |||
283 | * | 290 | * |
284 | * TODO The logic feels a bit kludge-y. make it better.. | 291 | * TODO The logic feels a bit kludge-y. make it better.. |
285 | */ | 292 | */ |
286 | static int btt_log_get_old(struct log_entry *ent) | 293 | static int btt_log_get_old(struct arena_info *a, struct log_group *log) |
287 | { | 294 | { |
295 | int idx0 = a->log_index[0]; | ||
296 | int idx1 = a->log_index[1]; | ||
288 | int old; | 297 | int old; |
289 | 298 | ||
290 | /* | 299 | /* |
@@ -292,23 +301,23 @@ static int btt_log_get_old(struct log_entry *ent) | |||
292 | * the next time, the following logic works out to put this | 301 | * the next time, the following logic works out to put this |
293 | * (next) entry into [1] | 302 | * (next) entry into [1] |
294 | */ | 303 | */ |
295 | if (ent[0].seq == 0) { | 304 | if (log_seq(log, idx0) == 0) { |
296 | ent[0].seq = cpu_to_le32(1); | 305 | log->ent[idx0].seq = cpu_to_le32(1); |
297 | return 0; | 306 | return 0; |
298 | } | 307 | } |
299 | 308 | ||
300 | if (ent[0].seq == ent[1].seq) | 309 | if (log_seq(log, idx0) == log_seq(log, idx1)) |
301 | return -EINVAL; | 310 | return -EINVAL; |
302 | if (le32_to_cpu(ent[0].seq) + le32_to_cpu(ent[1].seq) > 5) | 311 | if (log_seq(log, idx0) + log_seq(log, idx1) > 5) |
303 | return -EINVAL; | 312 | return -EINVAL; |
304 | 313 | ||
305 | if (le32_to_cpu(ent[0].seq) < le32_to_cpu(ent[1].seq)) { | 314 | if (log_seq(log, idx0) < log_seq(log, idx1)) { |
306 | if (le32_to_cpu(ent[1].seq) - le32_to_cpu(ent[0].seq) == 1) | 315 | if ((log_seq(log, idx1) - log_seq(log, idx0)) == 1) |
307 | old = 0; | 316 | old = 0; |
308 | else | 317 | else |
309 | old = 1; | 318 | old = 1; |
310 | } else { | 319 | } else { |
311 | if (le32_to_cpu(ent[0].seq) - le32_to_cpu(ent[1].seq) == 1) | 320 | if ((log_seq(log, idx0) - log_seq(log, idx1)) == 1) |
312 | old = 1; | 321 | old = 1; |
313 | else | 322 | else |
314 | old = 0; | 323 | old = 0; |
@@ -328,17 +337,18 @@ static int btt_log_read(struct arena_info *arena, u32 lane, | |||
328 | { | 337 | { |
329 | int ret; | 338 | int ret; |
330 | int old_ent, ret_ent; | 339 | int old_ent, ret_ent; |
331 | struct log_entry log[2]; | 340 | struct log_group log; |
332 | 341 | ||
333 | ret = btt_log_read_pair(arena, lane, log); | 342 | ret = btt_log_group_read(arena, lane, &log); |
334 | if (ret) | 343 | if (ret) |
335 | return -EIO; | 344 | return -EIO; |
336 | 345 | ||
337 | old_ent = btt_log_get_old(log); | 346 | old_ent = btt_log_get_old(arena, &log); |
338 | if (old_ent < 0 || old_ent > 1) { | 347 | if (old_ent < 0 || old_ent > 1) { |
339 | dev_err(to_dev(arena), | 348 | dev_err(to_dev(arena), |
340 | "log corruption (%d): lane %d seq [%d, %d]\n", | 349 | "log corruption (%d): lane %d seq [%d, %d]\n", |
341 | old_ent, lane, log[0].seq, log[1].seq); | 350 | old_ent, lane, log.ent[arena->log_index[0]].seq, |
351 | log.ent[arena->log_index[1]].seq); | ||
342 | /* TODO set error state? */ | 352 | /* TODO set error state? */ |
343 | return -EIO; | 353 | return -EIO; |
344 | } | 354 | } |
@@ -346,7 +356,7 @@ static int btt_log_read(struct arena_info *arena, u32 lane, | |||
346 | ret_ent = (old_flag ? old_ent : (1 - old_ent)); | 356 | ret_ent = (old_flag ? old_ent : (1 - old_ent)); |
347 | 357 | ||
348 | if (ent != NULL) | 358 | if (ent != NULL) |
349 | memcpy(ent, &log[ret_ent], LOG_ENT_SIZE); | 359 | memcpy(ent, &log.ent[arena->log_index[ret_ent]], LOG_ENT_SIZE); |
350 | 360 | ||
351 | return ret_ent; | 361 | return ret_ent; |
352 | } | 362 | } |
@@ -360,17 +370,13 @@ static int __btt_log_write(struct arena_info *arena, u32 lane, | |||
360 | u32 sub, struct log_entry *ent, unsigned long flags) | 370 | u32 sub, struct log_entry *ent, unsigned long flags) |
361 | { | 371 | { |
362 | int ret; | 372 | int ret; |
363 | /* | 373 | u32 group_slot = arena->log_index[sub]; |
364 | * Ignore the padding in log_entry for calculating log_half. | 374 | unsigned int log_half = LOG_ENT_SIZE / 2; |
365 | * The entry is 'committed' when we write the sequence number, | ||
366 | * and we want to ensure that that is the last thing written. | ||
367 | * We don't bother writing the padding as that would be extra | ||
368 | * media wear and write amplification | ||
369 | */ | ||
370 | unsigned int log_half = (LOG_ENT_SIZE - 2 * sizeof(u64)) / 2; | ||
371 | u64 ns_off = arena->logoff + (((2 * lane) + sub) * LOG_ENT_SIZE); | ||
372 | void *src = ent; | 375 | void *src = ent; |
376 | u64 ns_off; | ||
373 | 377 | ||
378 | ns_off = arena->logoff + (lane * LOG_GRP_SIZE) + | ||
379 | (group_slot * LOG_ENT_SIZE); | ||
374 | /* split the 16B write into atomic, durable halves */ | 380 | /* split the 16B write into atomic, durable halves */ |
375 | ret = arena_write_bytes(arena, ns_off, src, log_half, flags); | 381 | ret = arena_write_bytes(arena, ns_off, src, log_half, flags); |
376 | if (ret) | 382 | if (ret) |
@@ -453,7 +459,7 @@ static int btt_log_init(struct arena_info *arena) | |||
453 | { | 459 | { |
454 | size_t logsize = arena->info2off - arena->logoff; | 460 | size_t logsize = arena->info2off - arena->logoff; |
455 | size_t chunk_size = SZ_4K, offset = 0; | 461 | size_t chunk_size = SZ_4K, offset = 0; |
456 | struct log_entry log; | 462 | struct log_entry ent; |
457 | void *zerobuf; | 463 | void *zerobuf; |
458 | int ret; | 464 | int ret; |
459 | u32 i; | 465 | u32 i; |
@@ -485,11 +491,11 @@ static int btt_log_init(struct arena_info *arena) | |||
485 | } | 491 | } |
486 | 492 | ||
487 | for (i = 0; i < arena->nfree; i++) { | 493 | for (i = 0; i < arena->nfree; i++) { |
488 | log.lba = cpu_to_le32(i); | 494 | ent.lba = cpu_to_le32(i); |
489 | log.old_map = cpu_to_le32(arena->external_nlba + i); | 495 | ent.old_map = cpu_to_le32(arena->external_nlba + i); |
490 | log.new_map = cpu_to_le32(arena->external_nlba + i); | 496 | ent.new_map = cpu_to_le32(arena->external_nlba + i); |
491 | log.seq = cpu_to_le32(LOG_SEQ_INIT); | 497 | ent.seq = cpu_to_le32(LOG_SEQ_INIT); |
492 | ret = __btt_log_write(arena, i, 0, &log, 0); | 498 | ret = __btt_log_write(arena, i, 0, &ent, 0); |
493 | if (ret) | 499 | if (ret) |
494 | goto free; | 500 | goto free; |
495 | } | 501 | } |
@@ -594,6 +600,123 @@ static int btt_freelist_init(struct arena_info *arena) | |||
594 | return 0; | 600 | return 0; |
595 | } | 601 | } |
596 | 602 | ||
603 | static bool ent_is_padding(struct log_entry *ent) | ||
604 | { | ||
605 | return (ent->lba == 0) && (ent->old_map == 0) && (ent->new_map == 0) | ||
606 | && (ent->seq == 0); | ||
607 | } | ||
608 | |||
609 | /* | ||
610 | * Detecting valid log indices: We read a log group (see the comments in btt.h | ||
611 | * for a description of a 'log_group' and its 'slots'), and iterate over its | ||
612 | * four slots. We expect that a padding slot will be all-zeroes, and use this | ||
613 | * to detect a padding slot vs. an actual entry. | ||
614 | * | ||
615 | * If a log_group is in the initial state, i.e. hasn't been used since the | ||
616 | * creation of this BTT layout, it will have three of the four slots with | ||
617 | * zeroes. We skip over these log_groups for the detection of log_index. If | ||
618 | * all log_groups are in the initial state (i.e. the BTT has never been | ||
619 | * written to), it is safe to assume the 'new format' of log entries in slots | ||
620 | * (0, 1). | ||
621 | */ | ||
622 | static int log_set_indices(struct arena_info *arena) | ||
623 | { | ||
624 | bool idx_set = false, initial_state = true; | ||
625 | int ret, log_index[2] = {-1, -1}; | ||
626 | u32 i, j, next_idx = 0; | ||
627 | struct log_group log; | ||
628 | u32 pad_count = 0; | ||
629 | |||
630 | for (i = 0; i < arena->nfree; i++) { | ||
631 | ret = btt_log_group_read(arena, i, &log); | ||
632 | if (ret < 0) | ||
633 | return ret; | ||
634 | |||
635 | for (j = 0; j < 4; j++) { | ||
636 | if (!idx_set) { | ||
637 | if (ent_is_padding(&log.ent[j])) { | ||
638 | pad_count++; | ||
639 | continue; | ||
640 | } else { | ||
641 | /* Skip if index has been recorded */ | ||
642 | if ((next_idx == 1) && | ||
643 | (j == log_index[0])) | ||
644 | continue; | ||
645 | /* valid entry, record index */ | ||
646 | log_index[next_idx] = j; | ||
647 | next_idx++; | ||
648 | } | ||
649 | if (next_idx == 2) { | ||
650 | /* two valid entries found */ | ||
651 | idx_set = true; | ||
652 | } else if (next_idx > 2) { | ||
653 | /* too many valid indices */ | ||
654 | return -ENXIO; | ||
655 | } | ||
656 | } else { | ||
657 | /* | ||
658 | * once the indices have been set, just verify | ||
659 | * that all subsequent log groups are either in | ||
660 | * their initial state or follow the same | ||
661 | * indices. | ||
662 | */ | ||
663 | if (j == log_index[0]) { | ||
664 | /* entry must be 'valid' */ | ||
665 | if (ent_is_padding(&log.ent[j])) | ||
666 | return -ENXIO; | ||
667 | } else if (j == log_index[1]) { | ||
668 | ; | ||
669 | /* | ||
670 | * log_index[1] can be padding if the | ||
671 | * lane never got used and it is still | ||
672 | * in the initial state (three 'padding' | ||
673 | * entries) | ||
674 | */ | ||
675 | } else { | ||
676 | /* entry must be invalid (padding) */ | ||
677 | if (!ent_is_padding(&log.ent[j])) | ||
678 | return -ENXIO; | ||
679 | } | ||
680 | } | ||
681 | } | ||
682 | /* | ||
683 | * If any of the log_groups have more than one valid, | ||
684 | * non-padding entry, then the we are no longer in the | ||
685 | * initial_state | ||
686 | */ | ||
687 | if (pad_count < 3) | ||
688 | initial_state = false; | ||
689 | pad_count = 0; | ||
690 | } | ||
691 | |||
692 | if (!initial_state && !idx_set) | ||
693 | return -ENXIO; | ||
694 | |||
695 | /* | ||
696 | * If all the entries in the log were in the initial state, | ||
697 | * assume new padding scheme | ||
698 | */ | ||
699 | if (initial_state) | ||
700 | log_index[1] = 1; | ||
701 | |||
702 | /* | ||
703 | * Only allow the known permutations of log/padding indices, | ||
704 | * i.e. (0, 1), and (0, 2) | ||
705 | */ | ||
706 | if ((log_index[0] == 0) && ((log_index[1] == 1) || (log_index[1] == 2))) | ||
707 | ; /* known index possibilities */ | ||
708 | else { | ||
709 | dev_err(to_dev(arena), "Found an unknown padding scheme\n"); | ||
710 | return -ENXIO; | ||
711 | } | ||
712 | |||
713 | arena->log_index[0] = log_index[0]; | ||
714 | arena->log_index[1] = log_index[1]; | ||
715 | dev_dbg(to_dev(arena), "log_index_0 = %d\n", log_index[0]); | ||
716 | dev_dbg(to_dev(arena), "log_index_1 = %d\n", log_index[1]); | ||
717 | return 0; | ||
718 | } | ||
719 | |||
597 | static int btt_rtt_init(struct arena_info *arena) | 720 | static int btt_rtt_init(struct arena_info *arena) |
598 | { | 721 | { |
599 | arena->rtt = kcalloc(arena->nfree, sizeof(u32), GFP_KERNEL); | 722 | arena->rtt = kcalloc(arena->nfree, sizeof(u32), GFP_KERNEL); |
@@ -650,8 +773,7 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, | |||
650 | available -= 2 * BTT_PG_SIZE; | 773 | available -= 2 * BTT_PG_SIZE; |
651 | 774 | ||
652 | /* The log takes a fixed amount of space based on nfree */ | 775 | /* The log takes a fixed amount of space based on nfree */ |
653 | logsize = roundup(2 * arena->nfree * sizeof(struct log_entry), | 776 | logsize = roundup(arena->nfree * LOG_GRP_SIZE, BTT_PG_SIZE); |
654 | BTT_PG_SIZE); | ||
655 | available -= logsize; | 777 | available -= logsize; |
656 | 778 | ||
657 | /* Calculate optimal split between map and data area */ | 779 | /* Calculate optimal split between map and data area */ |
@@ -668,6 +790,10 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, | |||
668 | arena->mapoff = arena->dataoff + datasize; | 790 | arena->mapoff = arena->dataoff + datasize; |
669 | arena->logoff = arena->mapoff + mapsize; | 791 | arena->logoff = arena->mapoff + mapsize; |
670 | arena->info2off = arena->logoff + logsize; | 792 | arena->info2off = arena->logoff + logsize; |
793 | |||
794 | /* Default log indices are (0,1) */ | ||
795 | arena->log_index[0] = 0; | ||
796 | arena->log_index[1] = 1; | ||
671 | return arena; | 797 | return arena; |
672 | } | 798 | } |
673 | 799 | ||
@@ -758,6 +884,13 @@ static int discover_arenas(struct btt *btt) | |||
758 | arena->external_lba_start = cur_nlba; | 884 | arena->external_lba_start = cur_nlba; |
759 | parse_arena_meta(arena, super, cur_off); | 885 | parse_arena_meta(arena, super, cur_off); |
760 | 886 | ||
887 | ret = log_set_indices(arena); | ||
888 | if (ret) { | ||
889 | dev_err(to_dev(arena), | ||
890 | "Unable to deduce log/padding indices\n"); | ||
891 | goto out; | ||
892 | } | ||
893 | |||
761 | mutex_init(&arena->err_lock); | 894 | mutex_init(&arena->err_lock); |
762 | ret = btt_freelist_init(arena); | 895 | ret = btt_freelist_init(arena); |
763 | if (ret) | 896 | if (ret) |
diff --git a/drivers/nvdimm/btt.h b/drivers/nvdimm/btt.h index 578c2057524d..db3cb6d4d0d4 100644 --- a/drivers/nvdimm/btt.h +++ b/drivers/nvdimm/btt.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define MAP_ERR_MASK (1 << MAP_ERR_SHIFT) | 27 | #define MAP_ERR_MASK (1 << MAP_ERR_SHIFT) |
28 | #define MAP_LBA_MASK (~((1 << MAP_TRIM_SHIFT) | (1 << MAP_ERR_SHIFT))) | 28 | #define MAP_LBA_MASK (~((1 << MAP_TRIM_SHIFT) | (1 << MAP_ERR_SHIFT))) |
29 | #define MAP_ENT_NORMAL 0xC0000000 | 29 | #define MAP_ENT_NORMAL 0xC0000000 |
30 | #define LOG_GRP_SIZE sizeof(struct log_group) | ||
30 | #define LOG_ENT_SIZE sizeof(struct log_entry) | 31 | #define LOG_ENT_SIZE sizeof(struct log_entry) |
31 | #define ARENA_MIN_SIZE (1UL << 24) /* 16 MB */ | 32 | #define ARENA_MIN_SIZE (1UL << 24) /* 16 MB */ |
32 | #define ARENA_MAX_SIZE (1ULL << 39) /* 512 GB */ | 33 | #define ARENA_MAX_SIZE (1ULL << 39) /* 512 GB */ |
@@ -50,12 +51,52 @@ enum btt_init_state { | |||
50 | INIT_READY | 51 | INIT_READY |
51 | }; | 52 | }; |
52 | 53 | ||
54 | /* | ||
55 | * A log group represents one log 'lane', and consists of four log entries. | ||
56 | * Two of the four entries are valid entries, and the remaining two are | ||
57 | * padding. Due to an old bug in the padding location, we need to perform a | ||
58 | * test to determine the padding scheme being used, and use that scheme | ||
59 | * thereafter. | ||
60 | * | ||
61 | * In kernels prior to 4.15, 'log group' would have actual log entries at | ||
62 | * indices (0, 2) and padding at indices (1, 3), where as the correct/updated | ||
63 | * format has log entries at indices (0, 1) and padding at indices (2, 3). | ||
64 | * | ||
65 | * Old (pre 4.15) format: | ||
66 | * +-----------------+-----------------+ | ||
67 | * | ent[0] | ent[1] | | ||
68 | * | 16B | 16B | | ||
69 | * | lba/old/new/seq | pad | | ||
70 | * +-----------------------------------+ | ||
71 | * | ent[2] | ent[3] | | ||
72 | * | 16B | 16B | | ||
73 | * | lba/old/new/seq | pad | | ||
74 | * +-----------------+-----------------+ | ||
75 | * | ||
76 | * New format: | ||
77 | * +-----------------+-----------------+ | ||
78 | * | ent[0] | ent[1] | | ||
79 | * | 16B | 16B | | ||
80 | * | lba/old/new/seq | lba/old/new/seq | | ||
81 | * +-----------------------------------+ | ||
82 | * | ent[2] | ent[3] | | ||
83 | * | 16B | 16B | | ||
84 | * | pad | pad | | ||
85 | * +-----------------+-----------------+ | ||
86 | * | ||
87 | * We detect during start-up which format is in use, and set | ||
88 | * arena->log_index[(0, 1)] with the detected format. | ||
89 | */ | ||
90 | |||
53 | struct log_entry { | 91 | struct log_entry { |
54 | __le32 lba; | 92 | __le32 lba; |
55 | __le32 old_map; | 93 | __le32 old_map; |
56 | __le32 new_map; | 94 | __le32 new_map; |
57 | __le32 seq; | 95 | __le32 seq; |
58 | __le64 padding[2]; | 96 | }; |
97 | |||
98 | struct log_group { | ||
99 | struct log_entry ent[4]; | ||
59 | }; | 100 | }; |
60 | 101 | ||
61 | struct btt_sb { | 102 | struct btt_sb { |
@@ -125,6 +166,8 @@ struct aligned_lock { | |||
125 | * @list: List head for list of arenas | 166 | * @list: List head for list of arenas |
126 | * @debugfs_dir: Debugfs dentry | 167 | * @debugfs_dir: Debugfs dentry |
127 | * @flags: Arena flags - may signify error states. | 168 | * @flags: Arena flags - may signify error states. |
169 | * @err_lock: Mutex for synchronizing error clearing. | ||
170 | * @log_index: Indices of the valid log entries in a log_group | ||
128 | * | 171 | * |
129 | * arena_info is a per-arena handle. Once an arena is narrowed down for an | 172 | * arena_info is a per-arena handle. Once an arena is narrowed down for an |
130 | * IO, this struct is passed around for the duration of the IO. | 173 | * IO, this struct is passed around for the duration of the IO. |
@@ -157,6 +200,7 @@ struct arena_info { | |||
157 | /* Arena flags */ | 200 | /* Arena flags */ |
158 | u32 flags; | 201 | u32 flags; |
159 | struct mutex err_lock; | 202 | struct mutex err_lock; |
203 | int log_index[2]; | ||
160 | }; | 204 | }; |
161 | 205 | ||
162 | /** | 206 | /** |
@@ -176,6 +220,7 @@ struct arena_info { | |||
176 | * @init_lock: Mutex used for the BTT initialization | 220 | * @init_lock: Mutex used for the BTT initialization |
177 | * @init_state: Flag describing the initialization state for the BTT | 221 | * @init_state: Flag describing the initialization state for the BTT |
178 | * @num_arenas: Number of arenas in the BTT instance | 222 | * @num_arenas: Number of arenas in the BTT instance |
223 | * @phys_bb: Pointer to the namespace's badblocks structure | ||
179 | */ | 224 | */ |
180 | struct btt { | 225 | struct btt { |
181 | struct gendisk *btt_disk; | 226 | struct gendisk *btt_disk; |
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 65cc171c721d..2adada1a5855 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c | |||
@@ -364,9 +364,9 @@ struct device *nd_pfn_create(struct nd_region *nd_region) | |||
364 | int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) | 364 | int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) |
365 | { | 365 | { |
366 | u64 checksum, offset; | 366 | u64 checksum, offset; |
367 | unsigned long align; | ||
368 | enum nd_pfn_mode mode; | 367 | enum nd_pfn_mode mode; |
369 | struct nd_namespace_io *nsio; | 368 | struct nd_namespace_io *nsio; |
369 | unsigned long align, start_pad; | ||
370 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; | 370 | struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; |
371 | struct nd_namespace_common *ndns = nd_pfn->ndns; | 371 | struct nd_namespace_common *ndns = nd_pfn->ndns; |
372 | const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev); | 372 | const u8 *parent_uuid = nd_dev_to_uuid(&ndns->dev); |
@@ -410,6 +410,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) | |||
410 | 410 | ||
411 | align = le32_to_cpu(pfn_sb->align); | 411 | align = le32_to_cpu(pfn_sb->align); |
412 | offset = le64_to_cpu(pfn_sb->dataoff); | 412 | offset = le64_to_cpu(pfn_sb->dataoff); |
413 | start_pad = le32_to_cpu(pfn_sb->start_pad); | ||
413 | if (align == 0) | 414 | if (align == 0) |
414 | align = 1UL << ilog2(offset); | 415 | align = 1UL << ilog2(offset); |
415 | mode = le32_to_cpu(pfn_sb->mode); | 416 | mode = le32_to_cpu(pfn_sb->mode); |
@@ -468,7 +469,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) | |||
468 | return -EBUSY; | 469 | return -EBUSY; |
469 | } | 470 | } |
470 | 471 | ||
471 | if ((align && !IS_ALIGNED(offset, align)) | 472 | if ((align && !IS_ALIGNED(nsio->res.start + offset + start_pad, align)) |
472 | || !IS_ALIGNED(offset, PAGE_SIZE)) { | 473 | || !IS_ALIGNED(offset, PAGE_SIZE)) { |
473 | dev_err(&nd_pfn->dev, | 474 | dev_err(&nd_pfn->dev, |
474 | "bad offset: %#llx dax disabled align: %#lx\n", | 475 | "bad offset: %#llx dax disabled align: %#lx\n", |
@@ -582,6 +583,12 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn, | |||
582 | return altmap; | 583 | return altmap; |
583 | } | 584 | } |
584 | 585 | ||
586 | static u64 phys_pmem_align_down(struct nd_pfn *nd_pfn, u64 phys) | ||
587 | { | ||
588 | return min_t(u64, PHYS_SECTION_ALIGN_DOWN(phys), | ||
589 | ALIGN_DOWN(phys, nd_pfn->align)); | ||
590 | } | ||
591 | |||
585 | static int nd_pfn_init(struct nd_pfn *nd_pfn) | 592 | static int nd_pfn_init(struct nd_pfn *nd_pfn) |
586 | { | 593 | { |
587 | u32 dax_label_reserve = is_nd_dax(&nd_pfn->dev) ? SZ_128K : 0; | 594 | u32 dax_label_reserve = is_nd_dax(&nd_pfn->dev) ? SZ_128K : 0; |
@@ -637,13 +644,16 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) | |||
637 | start = nsio->res.start; | 644 | start = nsio->res.start; |
638 | size = PHYS_SECTION_ALIGN_UP(start + size) - start; | 645 | size = PHYS_SECTION_ALIGN_UP(start + size) - start; |
639 | if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, | 646 | if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, |
640 | IORES_DESC_NONE) == REGION_MIXED) { | 647 | IORES_DESC_NONE) == REGION_MIXED |
648 | || !IS_ALIGNED(start + resource_size(&nsio->res), | ||
649 | nd_pfn->align)) { | ||
641 | size = resource_size(&nsio->res); | 650 | size = resource_size(&nsio->res); |
642 | end_trunc = start + size - PHYS_SECTION_ALIGN_DOWN(start + size); | 651 | end_trunc = start + size - phys_pmem_align_down(nd_pfn, |
652 | start + size); | ||
643 | } | 653 | } |
644 | 654 | ||
645 | if (start_pad + end_trunc) | 655 | if (start_pad + end_trunc) |
646 | dev_info(&nd_pfn->dev, "%s section collision, truncate %d bytes\n", | 656 | dev_info(&nd_pfn->dev, "%s alignment collision, truncate %d bytes\n", |
647 | dev_name(&ndns->dev), start_pad + end_trunc); | 657 | dev_name(&ndns->dev), start_pad + end_trunc); |
648 | 658 | ||
649 | /* | 659 | /* |
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index bdedb6325c72..4471fd94e1fe 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c | |||
@@ -1620,6 +1620,22 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) | |||
1620 | clear_bit(i, chip->irq.valid_mask); | 1620 | clear_bit(i, chip->irq.valid_mask); |
1621 | } | 1621 | } |
1622 | 1622 | ||
1623 | /* | ||
1624 | * The same set of machines in chv_no_valid_mask[] have incorrectly | ||
1625 | * configured GPIOs that generate spurious interrupts so we use | ||
1626 | * this same list to apply another quirk for them. | ||
1627 | * | ||
1628 | * See also https://bugzilla.kernel.org/show_bug.cgi?id=197953. | ||
1629 | */ | ||
1630 | if (!need_valid_mask) { | ||
1631 | /* | ||
1632 | * Mask all interrupts the community is able to generate | ||
1633 | * but leave the ones that can only generate GPEs unmasked. | ||
1634 | */ | ||
1635 | chv_writel(GENMASK(31, pctrl->community->nirqs), | ||
1636 | pctrl->regs + CHV_INTMASK); | ||
1637 | } | ||
1638 | |||
1623 | /* Clear all interrupts */ | 1639 | /* Clear all interrupts */ |
1624 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); | 1640 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); |
1625 | 1641 | ||
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index f77e499afddd..065f0b607373 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
@@ -257,10 +257,25 @@ static void release_memory_resource(struct resource *resource) | |||
257 | kfree(resource); | 257 | kfree(resource); |
258 | } | 258 | } |
259 | 259 | ||
260 | /* | ||
261 | * Host memory not allocated to dom0. We can use this range for hotplug-based | ||
262 | * ballooning. | ||
263 | * | ||
264 | * It's a type-less resource. Setting IORESOURCE_MEM will make resource | ||
265 | * management algorithms (arch_remove_reservations()) look into guest e820, | ||
266 | * which we don't want. | ||
267 | */ | ||
268 | static struct resource hostmem_resource = { | ||
269 | .name = "Host RAM", | ||
270 | }; | ||
271 | |||
272 | void __attribute__((weak)) __init arch_xen_balloon_init(struct resource *res) | ||
273 | {} | ||
274 | |||
260 | static struct resource *additional_memory_resource(phys_addr_t size) | 275 | static struct resource *additional_memory_resource(phys_addr_t size) |
261 | { | 276 | { |
262 | struct resource *res; | 277 | struct resource *res, *res_hostmem; |
263 | int ret; | 278 | int ret = -ENOMEM; |
264 | 279 | ||
265 | res = kzalloc(sizeof(*res), GFP_KERNEL); | 280 | res = kzalloc(sizeof(*res), GFP_KERNEL); |
266 | if (!res) | 281 | if (!res) |
@@ -269,13 +284,42 @@ static struct resource *additional_memory_resource(phys_addr_t size) | |||
269 | res->name = "System RAM"; | 284 | res->name = "System RAM"; |
270 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; | 285 | res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; |
271 | 286 | ||
272 | ret = allocate_resource(&iomem_resource, res, | 287 | res_hostmem = kzalloc(sizeof(*res), GFP_KERNEL); |
273 | size, 0, -1, | 288 | if (res_hostmem) { |
274 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | 289 | /* Try to grab a range from hostmem */ |
275 | if (ret < 0) { | 290 | res_hostmem->name = "Host memory"; |
276 | pr_err("Cannot allocate new System RAM resource\n"); | 291 | ret = allocate_resource(&hostmem_resource, res_hostmem, |
277 | kfree(res); | 292 | size, 0, -1, |
278 | return NULL; | 293 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); |
294 | } | ||
295 | |||
296 | if (!ret) { | ||
297 | /* | ||
298 | * Insert this resource into iomem. Because hostmem_resource | ||
299 | * tracks portion of guest e820 marked as UNUSABLE noone else | ||
300 | * should try to use it. | ||
301 | */ | ||
302 | res->start = res_hostmem->start; | ||
303 | res->end = res_hostmem->end; | ||
304 | ret = insert_resource(&iomem_resource, res); | ||
305 | if (ret < 0) { | ||
306 | pr_err("Can't insert iomem_resource [%llx - %llx]\n", | ||
307 | res->start, res->end); | ||
308 | release_memory_resource(res_hostmem); | ||
309 | res_hostmem = NULL; | ||
310 | res->start = res->end = 0; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | if (ret) { | ||
315 | ret = allocate_resource(&iomem_resource, res, | ||
316 | size, 0, -1, | ||
317 | PAGES_PER_SECTION * PAGE_SIZE, NULL, NULL); | ||
318 | if (ret < 0) { | ||
319 | pr_err("Cannot allocate new System RAM resource\n"); | ||
320 | kfree(res); | ||
321 | return NULL; | ||
322 | } | ||
279 | } | 323 | } |
280 | 324 | ||
281 | #ifdef CONFIG_SPARSEMEM | 325 | #ifdef CONFIG_SPARSEMEM |
@@ -287,6 +331,7 @@ static struct resource *additional_memory_resource(phys_addr_t size) | |||
287 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", | 331 | pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", |
288 | pfn, limit); | 332 | pfn, limit); |
289 | release_memory_resource(res); | 333 | release_memory_resource(res); |
334 | release_memory_resource(res_hostmem); | ||
290 | return NULL; | 335 | return NULL; |
291 | } | 336 | } |
292 | } | 337 | } |
@@ -765,6 +810,8 @@ static int __init balloon_init(void) | |||
765 | set_online_page_callback(&xen_online_page); | 810 | set_online_page_callback(&xen_online_page); |
766 | register_memory_notifier(&xen_memory_nb); | 811 | register_memory_notifier(&xen_memory_nb); |
767 | register_sysctl_table(xen_root); | 812 | register_sysctl_table(xen_root); |
813 | |||
814 | arch_xen_balloon_init(&hostmem_resource); | ||
768 | #endif | 815 | #endif |
769 | 816 | ||
770 | #ifdef CONFIG_XEN_PV | 817 | #ifdef CONFIG_XEN_PV |
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 0da80019a917..83ed7715f856 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c | |||
@@ -702,7 +702,7 @@ xfs_alloc_ag_vextent( | |||
702 | ASSERT(args->agbno % args->alignment == 0); | 702 | ASSERT(args->agbno % args->alignment == 0); |
703 | 703 | ||
704 | /* if not file data, insert new block into the reverse map btree */ | 704 | /* if not file data, insert new block into the reverse map btree */ |
705 | if (args->oinfo.oi_owner != XFS_RMAP_OWN_UNKNOWN) { | 705 | if (!xfs_rmap_should_skip_owner_update(&args->oinfo)) { |
706 | error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, | 706 | error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, |
707 | args->agbno, args->len, &args->oinfo); | 707 | args->agbno, args->len, &args->oinfo); |
708 | if (error) | 708 | if (error) |
@@ -1682,7 +1682,7 @@ xfs_free_ag_extent( | |||
1682 | bno_cur = cnt_cur = NULL; | 1682 | bno_cur = cnt_cur = NULL; |
1683 | mp = tp->t_mountp; | 1683 | mp = tp->t_mountp; |
1684 | 1684 | ||
1685 | if (oinfo->oi_owner != XFS_RMAP_OWN_UNKNOWN) { | 1685 | if (!xfs_rmap_should_skip_owner_update(oinfo)) { |
1686 | error = xfs_rmap_free(tp, agbp, agno, bno, len, oinfo); | 1686 | error = xfs_rmap_free(tp, agbp, agno, bno, len, oinfo); |
1687 | if (error) | 1687 | if (error) |
1688 | goto error0; | 1688 | goto error0; |
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 6249c92671de..a76914db72ef 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c | |||
@@ -212,6 +212,7 @@ xfs_attr_set( | |||
212 | int flags) | 212 | int flags) |
213 | { | 213 | { |
214 | struct xfs_mount *mp = dp->i_mount; | 214 | struct xfs_mount *mp = dp->i_mount; |
215 | struct xfs_buf *leaf_bp = NULL; | ||
215 | struct xfs_da_args args; | 216 | struct xfs_da_args args; |
216 | struct xfs_defer_ops dfops; | 217 | struct xfs_defer_ops dfops; |
217 | struct xfs_trans_res tres; | 218 | struct xfs_trans_res tres; |
@@ -327,9 +328,16 @@ xfs_attr_set( | |||
327 | * GROT: another possible req'mt for a double-split btree op. | 328 | * GROT: another possible req'mt for a double-split btree op. |
328 | */ | 329 | */ |
329 | xfs_defer_init(args.dfops, args.firstblock); | 330 | xfs_defer_init(args.dfops, args.firstblock); |
330 | error = xfs_attr_shortform_to_leaf(&args); | 331 | error = xfs_attr_shortform_to_leaf(&args, &leaf_bp); |
331 | if (error) | 332 | if (error) |
332 | goto out_defer_cancel; | 333 | goto out_defer_cancel; |
334 | /* | ||
335 | * Prevent the leaf buffer from being unlocked so that a | ||
336 | * concurrent AIL push cannot grab the half-baked leaf | ||
337 | * buffer and run into problems with the write verifier. | ||
338 | */ | ||
339 | xfs_trans_bhold(args.trans, leaf_bp); | ||
340 | xfs_defer_bjoin(args.dfops, leaf_bp); | ||
333 | xfs_defer_ijoin(args.dfops, dp); | 341 | xfs_defer_ijoin(args.dfops, dp); |
334 | error = xfs_defer_finish(&args.trans, args.dfops); | 342 | error = xfs_defer_finish(&args.trans, args.dfops); |
335 | if (error) | 343 | if (error) |
@@ -337,13 +345,14 @@ xfs_attr_set( | |||
337 | 345 | ||
338 | /* | 346 | /* |
339 | * Commit the leaf transformation. We'll need another (linked) | 347 | * Commit the leaf transformation. We'll need another (linked) |
340 | * transaction to add the new attribute to the leaf. | 348 | * transaction to add the new attribute to the leaf, which |
349 | * means that we have to hold & join the leaf buffer here too. | ||
341 | */ | 350 | */ |
342 | |||
343 | error = xfs_trans_roll_inode(&args.trans, dp); | 351 | error = xfs_trans_roll_inode(&args.trans, dp); |
344 | if (error) | 352 | if (error) |
345 | goto out; | 353 | goto out; |
346 | 354 | xfs_trans_bjoin(args.trans, leaf_bp); | |
355 | leaf_bp = NULL; | ||
347 | } | 356 | } |
348 | 357 | ||
349 | if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) | 358 | if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) |
@@ -374,8 +383,9 @@ xfs_attr_set( | |||
374 | 383 | ||
375 | out_defer_cancel: | 384 | out_defer_cancel: |
376 | xfs_defer_cancel(&dfops); | 385 | xfs_defer_cancel(&dfops); |
377 | args.trans = NULL; | ||
378 | out: | 386 | out: |
387 | if (leaf_bp) | ||
388 | xfs_trans_brelse(args.trans, leaf_bp); | ||
379 | if (args.trans) | 389 | if (args.trans) |
380 | xfs_trans_cancel(args.trans); | 390 | xfs_trans_cancel(args.trans); |
381 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 391 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 53cc8b986eac..601eaa36f1ad 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c | |||
@@ -735,10 +735,13 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args) | |||
735 | } | 735 | } |
736 | 736 | ||
737 | /* | 737 | /* |
738 | * Convert from using the shortform to the leaf. | 738 | * Convert from using the shortform to the leaf. On success, return the |
739 | * buffer so that we can keep it locked until we're totally done with it. | ||
739 | */ | 740 | */ |
740 | int | 741 | int |
741 | xfs_attr_shortform_to_leaf(xfs_da_args_t *args) | 742 | xfs_attr_shortform_to_leaf( |
743 | struct xfs_da_args *args, | ||
744 | struct xfs_buf **leaf_bp) | ||
742 | { | 745 | { |
743 | xfs_inode_t *dp; | 746 | xfs_inode_t *dp; |
744 | xfs_attr_shortform_t *sf; | 747 | xfs_attr_shortform_t *sf; |
@@ -818,7 +821,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) | |||
818 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); | 821 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); |
819 | } | 822 | } |
820 | error = 0; | 823 | error = 0; |
821 | 824 | *leaf_bp = bp; | |
822 | out: | 825 | out: |
823 | kmem_free(tmpbuffer); | 826 | kmem_free(tmpbuffer); |
824 | return error; | 827 | return error; |
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index f7dda0c237b0..894124efb421 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h | |||
@@ -48,7 +48,8 @@ void xfs_attr_shortform_create(struct xfs_da_args *args); | |||
48 | void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff); | 48 | void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff); |
49 | int xfs_attr_shortform_lookup(struct xfs_da_args *args); | 49 | int xfs_attr_shortform_lookup(struct xfs_da_args *args); |
50 | int xfs_attr_shortform_getvalue(struct xfs_da_args *args); | 50 | int xfs_attr_shortform_getvalue(struct xfs_da_args *args); |
51 | int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); | 51 | int xfs_attr_shortform_to_leaf(struct xfs_da_args *args, |
52 | struct xfs_buf **leaf_bp); | ||
52 | int xfs_attr_shortform_remove(struct xfs_da_args *args); | 53 | int xfs_attr_shortform_remove(struct xfs_da_args *args); |
53 | int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); | 54 | int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); |
54 | int xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes); | 55 | int xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes); |
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 1210f684d3c2..1bddbba6b80c 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
@@ -5136,7 +5136,7 @@ __xfs_bunmapi( | |||
5136 | * blowing out the transaction with a mix of EFIs and reflink | 5136 | * blowing out the transaction with a mix of EFIs and reflink |
5137 | * adjustments. | 5137 | * adjustments. |
5138 | */ | 5138 | */ |
5139 | if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) | 5139 | if (tp && xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) |
5140 | max_len = min(len, xfs_refcount_max_unmap(tp->t_log_res)); | 5140 | max_len = min(len, xfs_refcount_max_unmap(tp->t_log_res)); |
5141 | else | 5141 | else |
5142 | max_len = len; | 5142 | max_len = len; |
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 072ebfe1d6ae..087fea02c389 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c | |||
@@ -249,6 +249,10 @@ xfs_defer_trans_roll( | |||
249 | for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) | 249 | for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) |
250 | xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); | 250 | xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); |
251 | 251 | ||
252 | /* Hold the (previously bjoin'd) buffer locked across the roll. */ | ||
253 | for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) | ||
254 | xfs_trans_dirty_buf(*tp, dop->dop_bufs[i]); | ||
255 | |||
252 | trace_xfs_defer_trans_roll((*tp)->t_mountp, dop); | 256 | trace_xfs_defer_trans_roll((*tp)->t_mountp, dop); |
253 | 257 | ||
254 | /* Roll the transaction. */ | 258 | /* Roll the transaction. */ |
@@ -264,6 +268,12 @@ xfs_defer_trans_roll( | |||
264 | for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) | 268 | for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) |
265 | xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); | 269 | xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); |
266 | 270 | ||
271 | /* Rejoin the buffers and dirty them so the log moves forward. */ | ||
272 | for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) { | ||
273 | xfs_trans_bjoin(*tp, dop->dop_bufs[i]); | ||
274 | xfs_trans_bhold(*tp, dop->dop_bufs[i]); | ||
275 | } | ||
276 | |||
267 | return error; | 277 | return error; |
268 | } | 278 | } |
269 | 279 | ||
@@ -295,6 +305,31 @@ xfs_defer_ijoin( | |||
295 | } | 305 | } |
296 | } | 306 | } |
297 | 307 | ||
308 | ASSERT(0); | ||
309 | return -EFSCORRUPTED; | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Add this buffer to the deferred op. Each joined buffer is relogged | ||
314 | * each time we roll the transaction. | ||
315 | */ | ||
316 | int | ||
317 | xfs_defer_bjoin( | ||
318 | struct xfs_defer_ops *dop, | ||
319 | struct xfs_buf *bp) | ||
320 | { | ||
321 | int i; | ||
322 | |||
323 | for (i = 0; i < XFS_DEFER_OPS_NR_BUFS; i++) { | ||
324 | if (dop->dop_bufs[i] == bp) | ||
325 | return 0; | ||
326 | else if (dop->dop_bufs[i] == NULL) { | ||
327 | dop->dop_bufs[i] = bp; | ||
328 | return 0; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | ASSERT(0); | ||
298 | return -EFSCORRUPTED; | 333 | return -EFSCORRUPTED; |
299 | } | 334 | } |
300 | 335 | ||
@@ -493,9 +528,7 @@ xfs_defer_init( | |||
493 | struct xfs_defer_ops *dop, | 528 | struct xfs_defer_ops *dop, |
494 | xfs_fsblock_t *fbp) | 529 | xfs_fsblock_t *fbp) |
495 | { | 530 | { |
496 | dop->dop_committed = false; | 531 | memset(dop, 0, sizeof(struct xfs_defer_ops)); |
497 | dop->dop_low = false; | ||
498 | memset(&dop->dop_inodes, 0, sizeof(dop->dop_inodes)); | ||
499 | *fbp = NULLFSBLOCK; | 532 | *fbp = NULLFSBLOCK; |
500 | INIT_LIST_HEAD(&dop->dop_intake); | 533 | INIT_LIST_HEAD(&dop->dop_intake); |
501 | INIT_LIST_HEAD(&dop->dop_pending); | 534 | INIT_LIST_HEAD(&dop->dop_pending); |
diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index d4f046dd44bd..045beacdd37d 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h | |||
@@ -59,6 +59,7 @@ enum xfs_defer_ops_type { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | #define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ | 61 | #define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ |
62 | #define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ | ||
62 | 63 | ||
63 | struct xfs_defer_ops { | 64 | struct xfs_defer_ops { |
64 | bool dop_committed; /* did any trans commit? */ | 65 | bool dop_committed; /* did any trans commit? */ |
@@ -66,8 +67,9 @@ struct xfs_defer_ops { | |||
66 | struct list_head dop_intake; /* unlogged pending work */ | 67 | struct list_head dop_intake; /* unlogged pending work */ |
67 | struct list_head dop_pending; /* logged pending work */ | 68 | struct list_head dop_pending; /* logged pending work */ |
68 | 69 | ||
69 | /* relog these inodes with each roll */ | 70 | /* relog these with each roll */ |
70 | struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; | 71 | struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; |
72 | struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, | 75 | void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, |
@@ -77,6 +79,7 @@ void xfs_defer_cancel(struct xfs_defer_ops *dop); | |||
77 | void xfs_defer_init(struct xfs_defer_ops *dop, xfs_fsblock_t *fbp); | 79 | void xfs_defer_init(struct xfs_defer_ops *dop, xfs_fsblock_t *fbp); |
78 | bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); | 80 | bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); |
79 | int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); | 81 | int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); |
82 | int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp); | ||
80 | 83 | ||
81 | /* Description of a deferred type. */ | 84 | /* Description of a deferred type. */ |
82 | struct xfs_defer_op_type { | 85 | struct xfs_defer_op_type { |
diff --git a/fs/xfs/libxfs/xfs_iext_tree.c b/fs/xfs/libxfs/xfs_iext_tree.c index 89bf16b4d937..b0f31791c7e6 100644 --- a/fs/xfs/libxfs/xfs_iext_tree.c +++ b/fs/xfs/libxfs/xfs_iext_tree.c | |||
@@ -632,8 +632,6 @@ xfs_iext_insert( | |||
632 | struct xfs_iext_leaf *new = NULL; | 632 | struct xfs_iext_leaf *new = NULL; |
633 | int nr_entries, i; | 633 | int nr_entries, i; |
634 | 634 | ||
635 | trace_xfs_iext_insert(ip, cur, state, _RET_IP_); | ||
636 | |||
637 | if (ifp->if_height == 0) | 635 | if (ifp->if_height == 0) |
638 | xfs_iext_alloc_root(ifp, cur); | 636 | xfs_iext_alloc_root(ifp, cur); |
639 | else if (ifp->if_height == 1) | 637 | else if (ifp->if_height == 1) |
@@ -661,6 +659,8 @@ xfs_iext_insert( | |||
661 | xfs_iext_set(cur_rec(cur), irec); | 659 | xfs_iext_set(cur_rec(cur), irec); |
662 | ifp->if_bytes += sizeof(struct xfs_iext_rec); | 660 | ifp->if_bytes += sizeof(struct xfs_iext_rec); |
663 | 661 | ||
662 | trace_xfs_iext_insert(ip, cur, state, _RET_IP_); | ||
663 | |||
664 | if (new) | 664 | if (new) |
665 | xfs_iext_insert_node(ifp, xfs_iext_leaf_key(new, 0), new, 2); | 665 | xfs_iext_insert_node(ifp, xfs_iext_leaf_key(new, 0), new, 2); |
666 | } | 666 | } |
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 585b35d34142..c40d26763075 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c | |||
@@ -1488,27 +1488,12 @@ __xfs_refcount_cow_alloc( | |||
1488 | xfs_extlen_t aglen, | 1488 | xfs_extlen_t aglen, |
1489 | struct xfs_defer_ops *dfops) | 1489 | struct xfs_defer_ops *dfops) |
1490 | { | 1490 | { |
1491 | int error; | ||
1492 | |||
1493 | trace_xfs_refcount_cow_increase(rcur->bc_mp, rcur->bc_private.a.agno, | 1491 | trace_xfs_refcount_cow_increase(rcur->bc_mp, rcur->bc_private.a.agno, |
1494 | agbno, aglen); | 1492 | agbno, aglen); |
1495 | 1493 | ||
1496 | /* Add refcount btree reservation */ | 1494 | /* Add refcount btree reservation */ |
1497 | error = xfs_refcount_adjust_cow(rcur, agbno, aglen, | 1495 | return xfs_refcount_adjust_cow(rcur, agbno, aglen, |
1498 | XFS_REFCOUNT_ADJUST_COW_ALLOC, dfops); | 1496 | XFS_REFCOUNT_ADJUST_COW_ALLOC, dfops); |
1499 | if (error) | ||
1500 | return error; | ||
1501 | |||
1502 | /* Add rmap entry */ | ||
1503 | if (xfs_sb_version_hasrmapbt(&rcur->bc_mp->m_sb)) { | ||
1504 | error = xfs_rmap_alloc_extent(rcur->bc_mp, dfops, | ||
1505 | rcur->bc_private.a.agno, | ||
1506 | agbno, aglen, XFS_RMAP_OWN_COW); | ||
1507 | if (error) | ||
1508 | return error; | ||
1509 | } | ||
1510 | |||
1511 | return error; | ||
1512 | } | 1497 | } |
1513 | 1498 | ||
1514 | /* | 1499 | /* |
@@ -1521,27 +1506,12 @@ __xfs_refcount_cow_free( | |||
1521 | xfs_extlen_t aglen, | 1506 | xfs_extlen_t aglen, |
1522 | struct xfs_defer_ops *dfops) | 1507 | struct xfs_defer_ops *dfops) |
1523 | { | 1508 | { |
1524 | int error; | ||
1525 | |||
1526 | trace_xfs_refcount_cow_decrease(rcur->bc_mp, rcur->bc_private.a.agno, | 1509 | trace_xfs_refcount_cow_decrease(rcur->bc_mp, rcur->bc_private.a.agno, |
1527 | agbno, aglen); | 1510 | agbno, aglen); |
1528 | 1511 | ||
1529 | /* Remove refcount btree reservation */ | 1512 | /* Remove refcount btree reservation */ |
1530 | error = xfs_refcount_adjust_cow(rcur, agbno, aglen, | 1513 | return xfs_refcount_adjust_cow(rcur, agbno, aglen, |
1531 | XFS_REFCOUNT_ADJUST_COW_FREE, dfops); | 1514 | XFS_REFCOUNT_ADJUST_COW_FREE, dfops); |
1532 | if (error) | ||
1533 | return error; | ||
1534 | |||
1535 | /* Remove rmap entry */ | ||
1536 | if (xfs_sb_version_hasrmapbt(&rcur->bc_mp->m_sb)) { | ||
1537 | error = xfs_rmap_free_extent(rcur->bc_mp, dfops, | ||
1538 | rcur->bc_private.a.agno, | ||
1539 | agbno, aglen, XFS_RMAP_OWN_COW); | ||
1540 | if (error) | ||
1541 | return error; | ||
1542 | } | ||
1543 | |||
1544 | return error; | ||
1545 | } | 1515 | } |
1546 | 1516 | ||
1547 | /* Record a CoW staging extent in the refcount btree. */ | 1517 | /* Record a CoW staging extent in the refcount btree. */ |
@@ -1552,11 +1522,19 @@ xfs_refcount_alloc_cow_extent( | |||
1552 | xfs_fsblock_t fsb, | 1522 | xfs_fsblock_t fsb, |
1553 | xfs_extlen_t len) | 1523 | xfs_extlen_t len) |
1554 | { | 1524 | { |
1525 | int error; | ||
1526 | |||
1555 | if (!xfs_sb_version_hasreflink(&mp->m_sb)) | 1527 | if (!xfs_sb_version_hasreflink(&mp->m_sb)) |
1556 | return 0; | 1528 | return 0; |
1557 | 1529 | ||
1558 | return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_ALLOC_COW, | 1530 | error = __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_ALLOC_COW, |
1559 | fsb, len); | 1531 | fsb, len); |
1532 | if (error) | ||
1533 | return error; | ||
1534 | |||
1535 | /* Add rmap entry */ | ||
1536 | return xfs_rmap_alloc_extent(mp, dfops, XFS_FSB_TO_AGNO(mp, fsb), | ||
1537 | XFS_FSB_TO_AGBNO(mp, fsb), len, XFS_RMAP_OWN_COW); | ||
1560 | } | 1538 | } |
1561 | 1539 | ||
1562 | /* Forget a CoW staging event in the refcount btree. */ | 1540 | /* Forget a CoW staging event in the refcount btree. */ |
@@ -1567,9 +1545,17 @@ xfs_refcount_free_cow_extent( | |||
1567 | xfs_fsblock_t fsb, | 1545 | xfs_fsblock_t fsb, |
1568 | xfs_extlen_t len) | 1546 | xfs_extlen_t len) |
1569 | { | 1547 | { |
1548 | int error; | ||
1549 | |||
1570 | if (!xfs_sb_version_hasreflink(&mp->m_sb)) | 1550 | if (!xfs_sb_version_hasreflink(&mp->m_sb)) |
1571 | return 0; | 1551 | return 0; |
1572 | 1552 | ||
1553 | /* Remove rmap entry */ | ||
1554 | error = xfs_rmap_free_extent(mp, dfops, XFS_FSB_TO_AGNO(mp, fsb), | ||
1555 | XFS_FSB_TO_AGBNO(mp, fsb), len, XFS_RMAP_OWN_COW); | ||
1556 | if (error) | ||
1557 | return error; | ||
1558 | |||
1573 | return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_FREE_COW, | 1559 | return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_FREE_COW, |
1574 | fsb, len); | 1560 | fsb, len); |
1575 | } | 1561 | } |
diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index dd019cee1b3b..50db920ceeeb 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c | |||
@@ -368,6 +368,51 @@ xfs_rmap_lookup_le_range( | |||
368 | } | 368 | } |
369 | 369 | ||
370 | /* | 370 | /* |
371 | * Perform all the relevant owner checks for a removal op. If we're doing an | ||
372 | * unknown-owner removal then we have no owner information to check. | ||
373 | */ | ||
374 | static int | ||
375 | xfs_rmap_free_check_owner( | ||
376 | struct xfs_mount *mp, | ||
377 | uint64_t ltoff, | ||
378 | struct xfs_rmap_irec *rec, | ||
379 | xfs_fsblock_t bno, | ||
380 | xfs_filblks_t len, | ||
381 | uint64_t owner, | ||
382 | uint64_t offset, | ||
383 | unsigned int flags) | ||
384 | { | ||
385 | int error = 0; | ||
386 | |||
387 | if (owner == XFS_RMAP_OWN_UNKNOWN) | ||
388 | return 0; | ||
389 | |||
390 | /* Make sure the unwritten flag matches. */ | ||
391 | XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) == | ||
392 | (rec->rm_flags & XFS_RMAP_UNWRITTEN), out); | ||
393 | |||
394 | /* Make sure the owner matches what we expect to find in the tree. */ | ||
395 | XFS_WANT_CORRUPTED_GOTO(mp, owner == rec->rm_owner, out); | ||
396 | |||
397 | /* Check the offset, if necessary. */ | ||
398 | if (XFS_RMAP_NON_INODE_OWNER(owner)) | ||
399 | goto out; | ||
400 | |||
401 | if (flags & XFS_RMAP_BMBT_BLOCK) { | ||
402 | XFS_WANT_CORRUPTED_GOTO(mp, rec->rm_flags & XFS_RMAP_BMBT_BLOCK, | ||
403 | out); | ||
404 | } else { | ||
405 | XFS_WANT_CORRUPTED_GOTO(mp, rec->rm_offset <= offset, out); | ||
406 | XFS_WANT_CORRUPTED_GOTO(mp, | ||
407 | ltoff + rec->rm_blockcount >= offset + len, | ||
408 | out); | ||
409 | } | ||
410 | |||
411 | out: | ||
412 | return error; | ||
413 | } | ||
414 | |||
415 | /* | ||
371 | * Find the extent in the rmap btree and remove it. | 416 | * Find the extent in the rmap btree and remove it. |
372 | * | 417 | * |
373 | * The record we find should always be an exact match for the extent that we're | 418 | * The record we find should always be an exact match for the extent that we're |
@@ -444,33 +489,40 @@ xfs_rmap_unmap( | |||
444 | goto out_done; | 489 | goto out_done; |
445 | } | 490 | } |
446 | 491 | ||
447 | /* Make sure the unwritten flag matches. */ | 492 | /* |
448 | XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) == | 493 | * If we're doing an unknown-owner removal for EFI recovery, we expect |
449 | (ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error); | 494 | * to find the full range in the rmapbt or nothing at all. If we |
495 | * don't find any rmaps overlapping either end of the range, we're | ||
496 | * done. Hopefully this means that the EFI creator already queued | ||
497 | * (and finished) a RUI to remove the rmap. | ||
498 | */ | ||
499 | if (owner == XFS_RMAP_OWN_UNKNOWN && | ||
500 | ltrec.rm_startblock + ltrec.rm_blockcount <= bno) { | ||
501 | struct xfs_rmap_irec rtrec; | ||
502 | |||
503 | error = xfs_btree_increment(cur, 0, &i); | ||
504 | if (error) | ||
505 | goto out_error; | ||
506 | if (i == 0) | ||
507 | goto out_done; | ||
508 | error = xfs_rmap_get_rec(cur, &rtrec, &i); | ||
509 | if (error) | ||
510 | goto out_error; | ||
511 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); | ||
512 | if (rtrec.rm_startblock >= bno + len) | ||
513 | goto out_done; | ||
514 | } | ||
450 | 515 | ||
451 | /* Make sure the extent we found covers the entire freeing range. */ | 516 | /* Make sure the extent we found covers the entire freeing range. */ |
452 | XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno && | 517 | XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno && |
453 | ltrec.rm_startblock + ltrec.rm_blockcount >= | 518 | ltrec.rm_startblock + ltrec.rm_blockcount >= |
454 | bno + len, out_error); | 519 | bno + len, out_error); |
455 | 520 | ||
456 | /* Make sure the owner matches what we expect to find in the tree. */ | 521 | /* Check owner information. */ |
457 | XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner || | 522 | error = xfs_rmap_free_check_owner(mp, ltoff, <rec, bno, len, owner, |
458 | XFS_RMAP_NON_INODE_OWNER(owner), out_error); | 523 | offset, flags); |
459 | 524 | if (error) | |
460 | /* Check the offset, if necessary. */ | 525 | goto out_error; |
461 | if (!XFS_RMAP_NON_INODE_OWNER(owner)) { | ||
462 | if (flags & XFS_RMAP_BMBT_BLOCK) { | ||
463 | XFS_WANT_CORRUPTED_GOTO(mp, | ||
464 | ltrec.rm_flags & XFS_RMAP_BMBT_BLOCK, | ||
465 | out_error); | ||
466 | } else { | ||
467 | XFS_WANT_CORRUPTED_GOTO(mp, | ||
468 | ltrec.rm_offset <= offset, out_error); | ||
469 | XFS_WANT_CORRUPTED_GOTO(mp, | ||
470 | ltoff + ltrec.rm_blockcount >= offset + len, | ||
471 | out_error); | ||
472 | } | ||
473 | } | ||
474 | 526 | ||
475 | if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { | 527 | if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { |
476 | /* exact match, simply remove the record from rmap tree */ | 528 | /* exact match, simply remove the record from rmap tree */ |
@@ -664,6 +716,7 @@ xfs_rmap_map( | |||
664 | flags |= XFS_RMAP_UNWRITTEN; | 716 | flags |= XFS_RMAP_UNWRITTEN; |
665 | trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len, | 717 | trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len, |
666 | unwritten, oinfo); | 718 | unwritten, oinfo); |
719 | ASSERT(!xfs_rmap_should_skip_owner_update(oinfo)); | ||
667 | 720 | ||
668 | /* | 721 | /* |
669 | * For the initial lookup, look for an exact match or the left-adjacent | 722 | * For the initial lookup, look for an exact match or the left-adjacent |
diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h index 466ede637080..0fcd5b1ba729 100644 --- a/fs/xfs/libxfs/xfs_rmap.h +++ b/fs/xfs/libxfs/xfs_rmap.h | |||
@@ -61,7 +61,21 @@ static inline void | |||
61 | xfs_rmap_skip_owner_update( | 61 | xfs_rmap_skip_owner_update( |
62 | struct xfs_owner_info *oi) | 62 | struct xfs_owner_info *oi) |
63 | { | 63 | { |
64 | oi->oi_owner = XFS_RMAP_OWN_UNKNOWN; | 64 | xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_NULL); |
65 | } | ||
66 | |||
67 | static inline bool | ||
68 | xfs_rmap_should_skip_owner_update( | ||
69 | struct xfs_owner_info *oi) | ||
70 | { | ||
71 | return oi->oi_owner == XFS_RMAP_OWN_NULL; | ||
72 | } | ||
73 | |||
74 | static inline void | ||
75 | xfs_rmap_any_owner_update( | ||
76 | struct xfs_owner_info *oi) | ||
77 | { | ||
78 | xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_UNKNOWN); | ||
65 | } | 79 | } |
66 | 80 | ||
67 | /* Reverse mapping functions. */ | 81 | /* Reverse mapping functions. */ |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 44f8c5451210..64da90655e95 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
@@ -538,7 +538,7 @@ xfs_efi_recover( | |||
538 | return error; | 538 | return error; |
539 | efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); | 539 | efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); |
540 | 540 | ||
541 | xfs_rmap_skip_owner_update(&oinfo); | 541 | xfs_rmap_any_owner_update(&oinfo); |
542 | for (i = 0; i < efip->efi_format.efi_nextents; i++) { | 542 | for (i = 0; i < efip->efi_format.efi_nextents; i++) { |
543 | extp = &efip->efi_format.efi_extents[i]; | 543 | extp = &efip->efi_format.efi_extents[i]; |
544 | error = xfs_trans_free_extent(tp, efdp, extp->ext_start, | 544 | error = xfs_trans_free_extent(tp, efdp, extp->ext_start, |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 8f22fc579dbb..60a2e128cb6a 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -571,6 +571,11 @@ xfs_growfs_data_private( | |||
571 | * this doesn't actually exist in the rmap btree. | 571 | * this doesn't actually exist in the rmap btree. |
572 | */ | 572 | */ |
573 | xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_NULL); | 573 | xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_NULL); |
574 | error = xfs_rmap_free(tp, bp, agno, | ||
575 | be32_to_cpu(agf->agf_length) - new, | ||
576 | new, &oinfo); | ||
577 | if (error) | ||
578 | goto error0; | ||
574 | error = xfs_free_extent(tp, | 579 | error = xfs_free_extent(tp, |
575 | XFS_AGB_TO_FSB(mp, agno, | 580 | XFS_AGB_TO_FSB(mp, agno, |
576 | be32_to_cpu(agf->agf_length) - new), | 581 | be32_to_cpu(agf->agf_length) - new), |
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 43005fbe8b1e..3861d61fb265 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -870,7 +870,7 @@ xfs_eofblocks_worker( | |||
870 | * based on the 'speculative_cow_prealloc_lifetime' tunable (5m by default). | 870 | * based on the 'speculative_cow_prealloc_lifetime' tunable (5m by default). |
871 | * (We'll just piggyback on the post-EOF prealloc space workqueue.) | 871 | * (We'll just piggyback on the post-EOF prealloc space workqueue.) |
872 | */ | 872 | */ |
873 | STATIC void | 873 | void |
874 | xfs_queue_cowblocks( | 874 | xfs_queue_cowblocks( |
875 | struct xfs_mount *mp) | 875 | struct xfs_mount *mp) |
876 | { | 876 | { |
@@ -1536,8 +1536,23 @@ xfs_inode_free_quota_eofblocks( | |||
1536 | return __xfs_inode_free_quota_eofblocks(ip, xfs_icache_free_eofblocks); | 1536 | return __xfs_inode_free_quota_eofblocks(ip, xfs_icache_free_eofblocks); |
1537 | } | 1537 | } |
1538 | 1538 | ||
1539 | static inline unsigned long | ||
1540 | xfs_iflag_for_tag( | ||
1541 | int tag) | ||
1542 | { | ||
1543 | switch (tag) { | ||
1544 | case XFS_ICI_EOFBLOCKS_TAG: | ||
1545 | return XFS_IEOFBLOCKS; | ||
1546 | case XFS_ICI_COWBLOCKS_TAG: | ||
1547 | return XFS_ICOWBLOCKS; | ||
1548 | default: | ||
1549 | ASSERT(0); | ||
1550 | return 0; | ||
1551 | } | ||
1552 | } | ||
1553 | |||
1539 | static void | 1554 | static void |
1540 | __xfs_inode_set_eofblocks_tag( | 1555 | __xfs_inode_set_blocks_tag( |
1541 | xfs_inode_t *ip, | 1556 | xfs_inode_t *ip, |
1542 | void (*execute)(struct xfs_mount *mp), | 1557 | void (*execute)(struct xfs_mount *mp), |
1543 | void (*set_tp)(struct xfs_mount *mp, xfs_agnumber_t agno, | 1558 | void (*set_tp)(struct xfs_mount *mp, xfs_agnumber_t agno, |
@@ -1552,10 +1567,10 @@ __xfs_inode_set_eofblocks_tag( | |||
1552 | * Don't bother locking the AG and looking up in the radix trees | 1567 | * Don't bother locking the AG and looking up in the radix trees |
1553 | * if we already know that we have the tag set. | 1568 | * if we already know that we have the tag set. |
1554 | */ | 1569 | */ |
1555 | if (ip->i_flags & XFS_IEOFBLOCKS) | 1570 | if (ip->i_flags & xfs_iflag_for_tag(tag)) |
1556 | return; | 1571 | return; |
1557 | spin_lock(&ip->i_flags_lock); | 1572 | spin_lock(&ip->i_flags_lock); |
1558 | ip->i_flags |= XFS_IEOFBLOCKS; | 1573 | ip->i_flags |= xfs_iflag_for_tag(tag); |
1559 | spin_unlock(&ip->i_flags_lock); | 1574 | spin_unlock(&ip->i_flags_lock); |
1560 | 1575 | ||
1561 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); | 1576 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); |
@@ -1587,13 +1602,13 @@ xfs_inode_set_eofblocks_tag( | |||
1587 | xfs_inode_t *ip) | 1602 | xfs_inode_t *ip) |
1588 | { | 1603 | { |
1589 | trace_xfs_inode_set_eofblocks_tag(ip); | 1604 | trace_xfs_inode_set_eofblocks_tag(ip); |
1590 | return __xfs_inode_set_eofblocks_tag(ip, xfs_queue_eofblocks, | 1605 | return __xfs_inode_set_blocks_tag(ip, xfs_queue_eofblocks, |
1591 | trace_xfs_perag_set_eofblocks, | 1606 | trace_xfs_perag_set_eofblocks, |
1592 | XFS_ICI_EOFBLOCKS_TAG); | 1607 | XFS_ICI_EOFBLOCKS_TAG); |
1593 | } | 1608 | } |
1594 | 1609 | ||
1595 | static void | 1610 | static void |
1596 | __xfs_inode_clear_eofblocks_tag( | 1611 | __xfs_inode_clear_blocks_tag( |
1597 | xfs_inode_t *ip, | 1612 | xfs_inode_t *ip, |
1598 | void (*clear_tp)(struct xfs_mount *mp, xfs_agnumber_t agno, | 1613 | void (*clear_tp)(struct xfs_mount *mp, xfs_agnumber_t agno, |
1599 | int error, unsigned long caller_ip), | 1614 | int error, unsigned long caller_ip), |
@@ -1603,7 +1618,7 @@ __xfs_inode_clear_eofblocks_tag( | |||
1603 | struct xfs_perag *pag; | 1618 | struct xfs_perag *pag; |
1604 | 1619 | ||
1605 | spin_lock(&ip->i_flags_lock); | 1620 | spin_lock(&ip->i_flags_lock); |
1606 | ip->i_flags &= ~XFS_IEOFBLOCKS; | 1621 | ip->i_flags &= ~xfs_iflag_for_tag(tag); |
1607 | spin_unlock(&ip->i_flags_lock); | 1622 | spin_unlock(&ip->i_flags_lock); |
1608 | 1623 | ||
1609 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); | 1624 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); |
@@ -1630,7 +1645,7 @@ xfs_inode_clear_eofblocks_tag( | |||
1630 | xfs_inode_t *ip) | 1645 | xfs_inode_t *ip) |
1631 | { | 1646 | { |
1632 | trace_xfs_inode_clear_eofblocks_tag(ip); | 1647 | trace_xfs_inode_clear_eofblocks_tag(ip); |
1633 | return __xfs_inode_clear_eofblocks_tag(ip, | 1648 | return __xfs_inode_clear_blocks_tag(ip, |
1634 | trace_xfs_perag_clear_eofblocks, XFS_ICI_EOFBLOCKS_TAG); | 1649 | trace_xfs_perag_clear_eofblocks, XFS_ICI_EOFBLOCKS_TAG); |
1635 | } | 1650 | } |
1636 | 1651 | ||
@@ -1724,7 +1739,7 @@ xfs_inode_set_cowblocks_tag( | |||
1724 | xfs_inode_t *ip) | 1739 | xfs_inode_t *ip) |
1725 | { | 1740 | { |
1726 | trace_xfs_inode_set_cowblocks_tag(ip); | 1741 | trace_xfs_inode_set_cowblocks_tag(ip); |
1727 | return __xfs_inode_set_eofblocks_tag(ip, xfs_queue_cowblocks, | 1742 | return __xfs_inode_set_blocks_tag(ip, xfs_queue_cowblocks, |
1728 | trace_xfs_perag_set_cowblocks, | 1743 | trace_xfs_perag_set_cowblocks, |
1729 | XFS_ICI_COWBLOCKS_TAG); | 1744 | XFS_ICI_COWBLOCKS_TAG); |
1730 | } | 1745 | } |
@@ -1734,6 +1749,6 @@ xfs_inode_clear_cowblocks_tag( | |||
1734 | xfs_inode_t *ip) | 1749 | xfs_inode_t *ip) |
1735 | { | 1750 | { |
1736 | trace_xfs_inode_clear_cowblocks_tag(ip); | 1751 | trace_xfs_inode_clear_cowblocks_tag(ip); |
1737 | return __xfs_inode_clear_eofblocks_tag(ip, | 1752 | return __xfs_inode_clear_blocks_tag(ip, |
1738 | trace_xfs_perag_clear_cowblocks, XFS_ICI_COWBLOCKS_TAG); | 1753 | trace_xfs_perag_clear_cowblocks, XFS_ICI_COWBLOCKS_TAG); |
1739 | } | 1754 | } |
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index bff4d85e5498..d4a77588eca1 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h | |||
@@ -81,6 +81,7 @@ void xfs_inode_clear_cowblocks_tag(struct xfs_inode *ip); | |||
81 | int xfs_icache_free_cowblocks(struct xfs_mount *, struct xfs_eofblocks *); | 81 | int xfs_icache_free_cowblocks(struct xfs_mount *, struct xfs_eofblocks *); |
82 | int xfs_inode_free_quota_cowblocks(struct xfs_inode *ip); | 82 | int xfs_inode_free_quota_cowblocks(struct xfs_inode *ip); |
83 | void xfs_cowblocks_worker(struct work_struct *); | 83 | void xfs_cowblocks_worker(struct work_struct *); |
84 | void xfs_queue_cowblocks(struct xfs_mount *); | ||
84 | 85 | ||
85 | int xfs_inode_ag_iterator(struct xfs_mount *mp, | 86 | int xfs_inode_ag_iterator(struct xfs_mount *mp, |
86 | int (*execute)(struct xfs_inode *ip, int flags, void *args), | 87 | int (*execute)(struct xfs_inode *ip, int flags, void *args), |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index b41952a4ddd8..6f95bdb408ce 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1487,6 +1487,24 @@ xfs_link( | |||
1487 | return error; | 1487 | return error; |
1488 | } | 1488 | } |
1489 | 1489 | ||
1490 | /* Clear the reflink flag and the cowblocks tag if possible. */ | ||
1491 | static void | ||
1492 | xfs_itruncate_clear_reflink_flags( | ||
1493 | struct xfs_inode *ip) | ||
1494 | { | ||
1495 | struct xfs_ifork *dfork; | ||
1496 | struct xfs_ifork *cfork; | ||
1497 | |||
1498 | if (!xfs_is_reflink_inode(ip)) | ||
1499 | return; | ||
1500 | dfork = XFS_IFORK_PTR(ip, XFS_DATA_FORK); | ||
1501 | cfork = XFS_IFORK_PTR(ip, XFS_COW_FORK); | ||
1502 | if (dfork->if_bytes == 0 && cfork->if_bytes == 0) | ||
1503 | ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; | ||
1504 | if (cfork->if_bytes == 0) | ||
1505 | xfs_inode_clear_cowblocks_tag(ip); | ||
1506 | } | ||
1507 | |||
1490 | /* | 1508 | /* |
1491 | * Free up the underlying blocks past new_size. The new size must be smaller | 1509 | * Free up the underlying blocks past new_size. The new size must be smaller |
1492 | * than the current size. This routine can be used both for the attribute and | 1510 | * than the current size. This routine can be used both for the attribute and |
@@ -1583,15 +1601,7 @@ xfs_itruncate_extents( | |||
1583 | if (error) | 1601 | if (error) |
1584 | goto out; | 1602 | goto out; |
1585 | 1603 | ||
1586 | /* | 1604 | xfs_itruncate_clear_reflink_flags(ip); |
1587 | * Clear the reflink flag if there are no data fork blocks and | ||
1588 | * there are no extents staged in the cow fork. | ||
1589 | */ | ||
1590 | if (xfs_is_reflink_inode(ip) && ip->i_cnextents == 0) { | ||
1591 | if (ip->i_d.di_nblocks == 0) | ||
1592 | ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; | ||
1593 | xfs_inode_clear_cowblocks_tag(ip); | ||
1594 | } | ||
1595 | 1605 | ||
1596 | /* | 1606 | /* |
1597 | * Always re-log the inode so that our permanent transaction can keep | 1607 | * Always re-log the inode so that our permanent transaction can keep |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index b2136af9289f..d383e392ec9d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -232,6 +232,7 @@ static inline bool xfs_is_reflink_inode(struct xfs_inode *ip) | |||
232 | * log recovery to replay a bmap operation on the inode. | 232 | * log recovery to replay a bmap operation on the inode. |
233 | */ | 233 | */ |
234 | #define XFS_IRECOVERY (1 << 11) | 234 | #define XFS_IRECOVERY (1 << 11) |
235 | #define XFS_ICOWBLOCKS (1 << 12)/* has the cowblocks tag set */ | ||
235 | 236 | ||
236 | /* | 237 | /* |
237 | * Per-lifetime flags need to be reset when re-using a reclaimable inode during | 238 | * Per-lifetime flags need to be reset when re-using a reclaimable inode during |
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index cf7c8f81bebb..47aea2e82c26 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c | |||
@@ -454,6 +454,8 @@ retry: | |||
454 | if (error) | 454 | if (error) |
455 | goto out_bmap_cancel; | 455 | goto out_bmap_cancel; |
456 | 456 | ||
457 | xfs_inode_set_cowblocks_tag(ip); | ||
458 | |||
457 | /* Finish up. */ | 459 | /* Finish up. */ |
458 | error = xfs_defer_finish(&tp, &dfops); | 460 | error = xfs_defer_finish(&tp, &dfops); |
459 | if (error) | 461 | if (error) |
@@ -490,8 +492,9 @@ xfs_reflink_find_cow_mapping( | |||
490 | struct xfs_iext_cursor icur; | 492 | struct xfs_iext_cursor icur; |
491 | 493 | ||
492 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); | 494 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); |
493 | ASSERT(xfs_is_reflink_inode(ip)); | ||
494 | 495 | ||
496 | if (!xfs_is_reflink_inode(ip)) | ||
497 | return false; | ||
495 | offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); | 498 | offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); |
496 | if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) | 499 | if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) |
497 | return false; | 500 | return false; |
@@ -610,6 +613,9 @@ xfs_reflink_cancel_cow_blocks( | |||
610 | 613 | ||
611 | /* Remove the mapping from the CoW fork. */ | 614 | /* Remove the mapping from the CoW fork. */ |
612 | xfs_bmap_del_extent_cow(ip, &icur, &got, &del); | 615 | xfs_bmap_del_extent_cow(ip, &icur, &got, &del); |
616 | } else { | ||
617 | /* Didn't do anything, push cursor back. */ | ||
618 | xfs_iext_prev(ifp, &icur); | ||
613 | } | 619 | } |
614 | next_extent: | 620 | next_extent: |
615 | if (!xfs_iext_get_extent(ifp, &icur, &got)) | 621 | if (!xfs_iext_get_extent(ifp, &icur, &got)) |
@@ -725,7 +731,7 @@ xfs_reflink_end_cow( | |||
725 | (unsigned int)(end_fsb - offset_fsb), | 731 | (unsigned int)(end_fsb - offset_fsb), |
726 | XFS_DATA_FORK); | 732 | XFS_DATA_FORK); |
727 | error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write, | 733 | error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write, |
728 | resblks, 0, 0, &tp); | 734 | resblks, 0, XFS_TRANS_RESERVE, &tp); |
729 | if (error) | 735 | if (error) |
730 | goto out; | 736 | goto out; |
731 | 737 | ||
@@ -1291,6 +1297,17 @@ xfs_reflink_remap_range( | |||
1291 | 1297 | ||
1292 | trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); | 1298 | trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); |
1293 | 1299 | ||
1300 | /* | ||
1301 | * Clear out post-eof preallocations because we don't have page cache | ||
1302 | * backing the delayed allocations and they'll never get freed on | ||
1303 | * their own. | ||
1304 | */ | ||
1305 | if (xfs_can_free_eofblocks(dest, true)) { | ||
1306 | ret = xfs_free_eofblocks(dest); | ||
1307 | if (ret) | ||
1308 | goto out_unlock; | ||
1309 | } | ||
1310 | |||
1294 | /* Set flags and remap blocks. */ | 1311 | /* Set flags and remap blocks. */ |
1295 | ret = xfs_reflink_set_inode_flag(src, dest); | 1312 | ret = xfs_reflink_set_inode_flag(src, dest); |
1296 | if (ret) | 1313 | if (ret) |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 5122d3021117..1dacccc367f8 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -1360,6 +1360,7 @@ xfs_fs_remount( | |||
1360 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | 1360 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
1361 | return error; | 1361 | return error; |
1362 | } | 1362 | } |
1363 | xfs_queue_cowblocks(mp); | ||
1363 | 1364 | ||
1364 | /* Create the per-AG metadata reservation pool .*/ | 1365 | /* Create the per-AG metadata reservation pool .*/ |
1365 | error = xfs_fs_reserve_ag_blocks(mp); | 1366 | error = xfs_fs_reserve_ag_blocks(mp); |
@@ -1369,6 +1370,14 @@ xfs_fs_remount( | |||
1369 | 1370 | ||
1370 | /* rw -> ro */ | 1371 | /* rw -> ro */ |
1371 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) { | 1372 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) { |
1373 | /* Get rid of any leftover CoW reservations... */ | ||
1374 | cancel_delayed_work_sync(&mp->m_cowblocks_work); | ||
1375 | error = xfs_icache_free_cowblocks(mp, NULL); | ||
1376 | if (error) { | ||
1377 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | ||
1378 | return error; | ||
1379 | } | ||
1380 | |||
1372 | /* Free the per-AG metadata reservation pool. */ | 1381 | /* Free the per-AG metadata reservation pool. */ |
1373 | error = xfs_fs_unreserve_ag_blocks(mp); | 1382 | error = xfs_fs_unreserve_ag_blocks(mp); |
1374 | if (error) { | 1383 | if (error) { |
diff --git a/include/asm-generic/mm_hooks.h b/include/asm-generic/mm_hooks.h index ea189d88a3cc..8ac4e68a12f0 100644 --- a/include/asm-generic/mm_hooks.h +++ b/include/asm-generic/mm_hooks.h | |||
@@ -7,9 +7,10 @@ | |||
7 | #ifndef _ASM_GENERIC_MM_HOOKS_H | 7 | #ifndef _ASM_GENERIC_MM_HOOKS_H |
8 | #define _ASM_GENERIC_MM_HOOKS_H | 8 | #define _ASM_GENERIC_MM_HOOKS_H |
9 | 9 | ||
10 | static inline void arch_dup_mmap(struct mm_struct *oldmm, | 10 | static inline int arch_dup_mmap(struct mm_struct *oldmm, |
11 | struct mm_struct *mm) | 11 | struct mm_struct *mm) |
12 | { | 12 | { |
13 | return 0; | ||
13 | } | 14 | } |
14 | 15 | ||
15 | static inline void arch_exit_mmap(struct mm_struct *mm) | 16 | static inline void arch_exit_mmap(struct mm_struct *mm) |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index b234d54f2cb6..868e68561f91 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
@@ -1025,6 +1025,11 @@ static inline int pmd_clear_huge(pmd_t *pmd) | |||
1025 | struct file; | 1025 | struct file; |
1026 | int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | 1026 | int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, |
1027 | unsigned long size, pgprot_t *vma_prot); | 1027 | unsigned long size, pgprot_t *vma_prot); |
1028 | |||
1029 | #ifndef CONFIG_X86_ESPFIX64 | ||
1030 | static inline void init_espfix_bsp(void) { } | ||
1031 | #endif | ||
1032 | |||
1028 | #endif /* !__ASSEMBLY__ */ | 1033 | #endif /* !__ASSEMBLY__ */ |
1029 | 1034 | ||
1030 | #ifndef io_remap_pfn_range | 1035 | #ifndef io_remap_pfn_range |
diff --git a/include/crypto/mcryptd.h b/include/crypto/mcryptd.h index cceafa01f907..b67404fc4b34 100644 --- a/include/crypto/mcryptd.h +++ b/include/crypto/mcryptd.h | |||
@@ -27,6 +27,7 @@ static inline struct mcryptd_ahash *__mcryptd_ahash_cast( | |||
27 | 27 | ||
28 | struct mcryptd_cpu_queue { | 28 | struct mcryptd_cpu_queue { |
29 | struct crypto_queue queue; | 29 | struct crypto_queue queue; |
30 | spinlock_t q_lock; | ||
30 | struct work_struct work; | 31 | struct work_struct work; |
31 | }; | 32 | }; |
32 | 33 | ||
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 57b109c6e422..1f509d072026 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h | |||
@@ -1165,6 +1165,10 @@ int mlx5_cmd_create_vport_lag(struct mlx5_core_dev *dev); | |||
1165 | int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev); | 1165 | int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev); |
1166 | bool mlx5_lag_is_active(struct mlx5_core_dev *dev); | 1166 | bool mlx5_lag_is_active(struct mlx5_core_dev *dev); |
1167 | struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev); | 1167 | struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev); |
1168 | int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, | ||
1169 | u64 *values, | ||
1170 | int num_counters, | ||
1171 | size_t *offsets); | ||
1168 | struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev); | 1172 | struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev); |
1169 | void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up); | 1173 | void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up); |
1170 | 1174 | ||
diff --git a/include/net/sock.h b/include/net/sock.h index 6c1db823f8b9..66fd3951e6f3 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -1515,6 +1515,11 @@ static inline bool sock_owned_by_user(const struct sock *sk) | |||
1515 | return sk->sk_lock.owned; | 1515 | return sk->sk_lock.owned; |
1516 | } | 1516 | } |
1517 | 1517 | ||
1518 | static inline bool sock_owned_by_user_nocheck(const struct sock *sk) | ||
1519 | { | ||
1520 | return sk->sk_lock.owned; | ||
1521 | } | ||
1522 | |||
1518 | /* no reclassification while locks are held */ | 1523 | /* no reclassification while locks are held */ |
1519 | static inline bool sock_allow_reclassification(const struct sock *csk) | 1524 | static inline bool sock_allow_reclassification(const struct sock *csk) |
1520 | { | 1525 | { |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 079ea9455bcd..2e6d4fe6b0ba 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -1601,6 +1601,9 @@ int xfrm_init_state(struct xfrm_state *x); | |||
1601 | int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb); | 1601 | int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb); |
1602 | int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type); | 1602 | int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type); |
1603 | int xfrm_input_resume(struct sk_buff *skb, int nexthdr); | 1603 | int xfrm_input_resume(struct sk_buff *skb, int nexthdr); |
1604 | int xfrm_trans_queue(struct sk_buff *skb, | ||
1605 | int (*finish)(struct net *, struct sock *, | ||
1606 | struct sk_buff *)); | ||
1604 | int xfrm_output_resume(struct sk_buff *skb, int err); | 1607 | int xfrm_output_resume(struct sk_buff *skb, int err); |
1605 | int xfrm_output(struct sock *sk, struct sk_buff *skb); | 1608 | int xfrm_output(struct sock *sk, struct sk_buff *skb); |
1606 | int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb); | 1609 | int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb); |
diff --git a/include/trace/events/clk.h b/include/trace/events/clk.h index 758607226bfd..2cd449328aee 100644 --- a/include/trace/events/clk.h +++ b/include/trace/events/clk.h | |||
@@ -134,12 +134,12 @@ DECLARE_EVENT_CLASS(clk_parent, | |||
134 | 134 | ||
135 | TP_STRUCT__entry( | 135 | TP_STRUCT__entry( |
136 | __string( name, core->name ) | 136 | __string( name, core->name ) |
137 | __string( pname, parent->name ) | 137 | __string( pname, parent ? parent->name : "none" ) |
138 | ), | 138 | ), |
139 | 139 | ||
140 | TP_fast_assign( | 140 | TP_fast_assign( |
141 | __assign_str(name, core->name); | 141 | __assign_str(name, core->name); |
142 | __assign_str(pname, parent->name); | 142 | __assign_str(pname, parent ? parent->name : "none"); |
143 | ), | 143 | ), |
144 | 144 | ||
145 | TP_printk("%s %s", __get_str(name), __get_str(pname)) | 145 | TP_printk("%s %s", __get_str(name), __get_str(pname)) |
diff --git a/include/trace/events/tcp.h b/include/trace/events/tcp.h index 8e88a1671538..bb00459d2d4d 100644 --- a/include/trace/events/tcp.h +++ b/include/trace/events/tcp.h | |||
@@ -9,6 +9,35 @@ | |||
9 | #include <linux/tracepoint.h> | 9 | #include <linux/tracepoint.h> |
10 | #include <net/ipv6.h> | 10 | #include <net/ipv6.h> |
11 | 11 | ||
12 | #define TP_STORE_V4MAPPED(__entry, saddr, daddr) \ | ||
13 | do { \ | ||
14 | struct in6_addr *pin6; \ | ||
15 | \ | ||
16 | pin6 = (struct in6_addr *)__entry->saddr_v6; \ | ||
17 | ipv6_addr_set_v4mapped(saddr, pin6); \ | ||
18 | pin6 = (struct in6_addr *)__entry->daddr_v6; \ | ||
19 | ipv6_addr_set_v4mapped(daddr, pin6); \ | ||
20 | } while (0) | ||
21 | |||
22 | #if IS_ENABLED(CONFIG_IPV6) | ||
23 | #define TP_STORE_ADDRS(__entry, saddr, daddr, saddr6, daddr6) \ | ||
24 | do { \ | ||
25 | if (sk->sk_family == AF_INET6) { \ | ||
26 | struct in6_addr *pin6; \ | ||
27 | \ | ||
28 | pin6 = (struct in6_addr *)__entry->saddr_v6; \ | ||
29 | *pin6 = saddr6; \ | ||
30 | pin6 = (struct in6_addr *)__entry->daddr_v6; \ | ||
31 | *pin6 = daddr6; \ | ||
32 | } else { \ | ||
33 | TP_STORE_V4MAPPED(__entry, saddr, daddr); \ | ||
34 | } \ | ||
35 | } while (0) | ||
36 | #else | ||
37 | #define TP_STORE_ADDRS(__entry, saddr, daddr, saddr6, daddr6) \ | ||
38 | TP_STORE_V4MAPPED(__entry, saddr, daddr) | ||
39 | #endif | ||
40 | |||
12 | /* | 41 | /* |
13 | * tcp event with arguments sk and skb | 42 | * tcp event with arguments sk and skb |
14 | * | 43 | * |
@@ -34,7 +63,6 @@ DECLARE_EVENT_CLASS(tcp_event_sk_skb, | |||
34 | 63 | ||
35 | TP_fast_assign( | 64 | TP_fast_assign( |
36 | struct inet_sock *inet = inet_sk(sk); | 65 | struct inet_sock *inet = inet_sk(sk); |
37 | struct in6_addr *pin6; | ||
38 | __be32 *p32; | 66 | __be32 *p32; |
39 | 67 | ||
40 | __entry->skbaddr = skb; | 68 | __entry->skbaddr = skb; |
@@ -49,20 +77,8 @@ DECLARE_EVENT_CLASS(tcp_event_sk_skb, | |||
49 | p32 = (__be32 *) __entry->daddr; | 77 | p32 = (__be32 *) __entry->daddr; |
50 | *p32 = inet->inet_daddr; | 78 | *p32 = inet->inet_daddr; |
51 | 79 | ||
52 | #if IS_ENABLED(CONFIG_IPV6) | 80 | TP_STORE_ADDRS(__entry, inet->inet_saddr, inet->inet_daddr, |
53 | if (sk->sk_family == AF_INET6) { | 81 | sk->sk_v6_rcv_saddr, sk->sk_v6_daddr); |
54 | pin6 = (struct in6_addr *)__entry->saddr_v6; | ||
55 | *pin6 = sk->sk_v6_rcv_saddr; | ||
56 | pin6 = (struct in6_addr *)__entry->daddr_v6; | ||
57 | *pin6 = sk->sk_v6_daddr; | ||
58 | } else | ||
59 | #endif | ||
60 | { | ||
61 | pin6 = (struct in6_addr *)__entry->saddr_v6; | ||
62 | ipv6_addr_set_v4mapped(inet->inet_saddr, pin6); | ||
63 | pin6 = (struct in6_addr *)__entry->daddr_v6; | ||
64 | ipv6_addr_set_v4mapped(inet->inet_daddr, pin6); | ||
65 | } | ||
66 | ), | 82 | ), |
67 | 83 | ||
68 | TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c", | 84 | TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c", |
@@ -111,7 +127,6 @@ DECLARE_EVENT_CLASS(tcp_event_sk, | |||
111 | 127 | ||
112 | TP_fast_assign( | 128 | TP_fast_assign( |
113 | struct inet_sock *inet = inet_sk(sk); | 129 | struct inet_sock *inet = inet_sk(sk); |
114 | struct in6_addr *pin6; | ||
115 | __be32 *p32; | 130 | __be32 *p32; |
116 | 131 | ||
117 | __entry->skaddr = sk; | 132 | __entry->skaddr = sk; |
@@ -125,20 +140,8 @@ DECLARE_EVENT_CLASS(tcp_event_sk, | |||
125 | p32 = (__be32 *) __entry->daddr; | 140 | p32 = (__be32 *) __entry->daddr; |
126 | *p32 = inet->inet_daddr; | 141 | *p32 = inet->inet_daddr; |
127 | 142 | ||
128 | #if IS_ENABLED(CONFIG_IPV6) | 143 | TP_STORE_ADDRS(__entry, inet->inet_saddr, inet->inet_daddr, |
129 | if (sk->sk_family == AF_INET6) { | 144 | sk->sk_v6_rcv_saddr, sk->sk_v6_daddr); |
130 | pin6 = (struct in6_addr *)__entry->saddr_v6; | ||
131 | *pin6 = sk->sk_v6_rcv_saddr; | ||
132 | pin6 = (struct in6_addr *)__entry->daddr_v6; | ||
133 | *pin6 = sk->sk_v6_daddr; | ||
134 | } else | ||
135 | #endif | ||
136 | { | ||
137 | pin6 = (struct in6_addr *)__entry->saddr_v6; | ||
138 | ipv6_addr_set_v4mapped(inet->inet_saddr, pin6); | ||
139 | pin6 = (struct in6_addr *)__entry->daddr_v6; | ||
140 | ipv6_addr_set_v4mapped(inet->inet_daddr, pin6); | ||
141 | } | ||
142 | ), | 145 | ), |
143 | 146 | ||
144 | TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c", | 147 | TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c", |
@@ -181,7 +184,6 @@ TRACE_EVENT(tcp_set_state, | |||
181 | 184 | ||
182 | TP_fast_assign( | 185 | TP_fast_assign( |
183 | struct inet_sock *inet = inet_sk(sk); | 186 | struct inet_sock *inet = inet_sk(sk); |
184 | struct in6_addr *pin6; | ||
185 | __be32 *p32; | 187 | __be32 *p32; |
186 | 188 | ||
187 | __entry->skaddr = sk; | 189 | __entry->skaddr = sk; |
@@ -197,20 +199,8 @@ TRACE_EVENT(tcp_set_state, | |||
197 | p32 = (__be32 *) __entry->daddr; | 199 | p32 = (__be32 *) __entry->daddr; |
198 | *p32 = inet->inet_daddr; | 200 | *p32 = inet->inet_daddr; |
199 | 201 | ||
200 | #if IS_ENABLED(CONFIG_IPV6) | 202 | TP_STORE_ADDRS(__entry, inet->inet_saddr, inet->inet_daddr, |
201 | if (sk->sk_family == AF_INET6) { | 203 | sk->sk_v6_rcv_saddr, sk->sk_v6_daddr); |
202 | pin6 = (struct in6_addr *)__entry->saddr_v6; | ||
203 | *pin6 = sk->sk_v6_rcv_saddr; | ||
204 | pin6 = (struct in6_addr *)__entry->daddr_v6; | ||
205 | *pin6 = sk->sk_v6_daddr; | ||
206 | } else | ||
207 | #endif | ||
208 | { | ||
209 | pin6 = (struct in6_addr *)__entry->saddr_v6; | ||
210 | ipv6_addr_set_v4mapped(inet->inet_saddr, pin6); | ||
211 | pin6 = (struct in6_addr *)__entry->daddr_v6; | ||
212 | ipv6_addr_set_v4mapped(inet->inet_daddr, pin6); | ||
213 | } | ||
214 | ), | 204 | ), |
215 | 205 | ||
216 | TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c oldstate=%s newstate=%s", | 206 | TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c oldstate=%s newstate=%s", |
@@ -240,7 +230,6 @@ TRACE_EVENT(tcp_retransmit_synack, | |||
240 | 230 | ||
241 | TP_fast_assign( | 231 | TP_fast_assign( |
242 | struct inet_request_sock *ireq = inet_rsk(req); | 232 | struct inet_request_sock *ireq = inet_rsk(req); |
243 | struct in6_addr *pin6; | ||
244 | __be32 *p32; | 233 | __be32 *p32; |
245 | 234 | ||
246 | __entry->skaddr = sk; | 235 | __entry->skaddr = sk; |
@@ -255,20 +244,8 @@ TRACE_EVENT(tcp_retransmit_synack, | |||
255 | p32 = (__be32 *) __entry->daddr; | 244 | p32 = (__be32 *) __entry->daddr; |
256 | *p32 = ireq->ir_rmt_addr; | 245 | *p32 = ireq->ir_rmt_addr; |
257 | 246 | ||
258 | #if IS_ENABLED(CONFIG_IPV6) | 247 | TP_STORE_ADDRS(__entry, ireq->ir_loc_addr, ireq->ir_rmt_addr, |
259 | if (sk->sk_family == AF_INET6) { | 248 | ireq->ir_v6_loc_addr, ireq->ir_v6_rmt_addr); |
260 | pin6 = (struct in6_addr *)__entry->saddr_v6; | ||
261 | *pin6 = ireq->ir_v6_loc_addr; | ||
262 | pin6 = (struct in6_addr *)__entry->daddr_v6; | ||
263 | *pin6 = ireq->ir_v6_rmt_addr; | ||
264 | } else | ||
265 | #endif | ||
266 | { | ||
267 | pin6 = (struct in6_addr *)__entry->saddr_v6; | ||
268 | ipv6_addr_set_v4mapped(ireq->ir_loc_addr, pin6); | ||
269 | pin6 = (struct in6_addr *)__entry->daddr_v6; | ||
270 | ipv6_addr_set_v4mapped(ireq->ir_rmt_addr, pin6); | ||
271 | } | ||
272 | ), | 249 | ), |
273 | 250 | ||
274 | TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c", | 251 | TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c", |
diff --git a/include/xen/balloon.h b/include/xen/balloon.h index 4914b93a23f2..61f410fd74e4 100644 --- a/include/xen/balloon.h +++ b/include/xen/balloon.h | |||
@@ -44,3 +44,8 @@ static inline void xen_balloon_init(void) | |||
44 | { | 44 | { |
45 | } | 45 | } |
46 | #endif | 46 | #endif |
47 | |||
48 | #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG | ||
49 | struct resource; | ||
50 | void arch_xen_balloon_init(struct resource *hostmem_resource); | ||
51 | #endif | ||
diff --git a/init/main.c b/init/main.c index e96e3a14533c..7b606fc48482 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -504,6 +504,8 @@ static void __init mm_init(void) | |||
504 | pgtable_init(); | 504 | pgtable_init(); |
505 | vmalloc_init(); | 505 | vmalloc_init(); |
506 | ioremap_huge_init(); | 506 | ioremap_huge_init(); |
507 | /* Should be run before the first non-init thread is created */ | ||
508 | init_espfix_bsp(); | ||
507 | } | 509 | } |
508 | 510 | ||
509 | asmlinkage __visible void __init start_kernel(void) | 511 | asmlinkage __visible void __init start_kernel(void) |
@@ -679,10 +681,6 @@ asmlinkage __visible void __init start_kernel(void) | |||
679 | if (efi_enabled(EFI_RUNTIME_SERVICES)) | 681 | if (efi_enabled(EFI_RUNTIME_SERVICES)) |
680 | efi_enter_virtual_mode(); | 682 | efi_enter_virtual_mode(); |
681 | #endif | 683 | #endif |
682 | #ifdef CONFIG_X86_ESPFIX64 | ||
683 | /* Should be run before the first non-init thread is created */ | ||
684 | init_espfix_bsp(); | ||
685 | #endif | ||
686 | thread_stack_cache_init(); | 684 | thread_stack_cache_init(); |
687 | cred_init(); | 685 | cred_init(); |
688 | fork_init(); | 686 | fork_init(); |
diff --git a/kernel/fork.c b/kernel/fork.c index 432eadf6b58c..2295fc69717f 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -721,8 +721,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, | |||
721 | goto out; | 721 | goto out; |
722 | } | 722 | } |
723 | /* a new mm has just been created */ | 723 | /* a new mm has just been created */ |
724 | arch_dup_mmap(oldmm, mm); | 724 | retval = arch_dup_mmap(oldmm, mm); |
725 | retval = 0; | ||
726 | out: | 725 | out: |
727 | up_write(&mm->mmap_sem); | 726 | up_write(&mm->mmap_sem); |
728 | flush_tlb_mm(oldmm); | 727 | flush_tlb_mm(oldmm); |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index c87766c1c204..9ab18995ff1e 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -280,6 +280,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data); | |||
280 | /* Missed count stored at end */ | 280 | /* Missed count stored at end */ |
281 | #define RB_MISSED_STORED (1 << 30) | 281 | #define RB_MISSED_STORED (1 << 30) |
282 | 282 | ||
283 | #define RB_MISSED_FLAGS (RB_MISSED_EVENTS|RB_MISSED_STORED) | ||
284 | |||
283 | struct buffer_data_page { | 285 | struct buffer_data_page { |
284 | u64 time_stamp; /* page time stamp */ | 286 | u64 time_stamp; /* page time stamp */ |
285 | local_t commit; /* write committed index */ | 287 | local_t commit; /* write committed index */ |
@@ -331,7 +333,9 @@ static void rb_init_page(struct buffer_data_page *bpage) | |||
331 | */ | 333 | */ |
332 | size_t ring_buffer_page_len(void *page) | 334 | size_t ring_buffer_page_len(void *page) |
333 | { | 335 | { |
334 | return local_read(&((struct buffer_data_page *)page)->commit) | 336 | struct buffer_data_page *bpage = page; |
337 | |||
338 | return (local_read(&bpage->commit) & ~RB_MISSED_FLAGS) | ||
335 | + BUF_PAGE_HDR_SIZE; | 339 | + BUF_PAGE_HDR_SIZE; |
336 | } | 340 | } |
337 | 341 | ||
@@ -4400,8 +4404,13 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data) | |||
4400 | { | 4404 | { |
4401 | struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; | 4405 | struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; |
4402 | struct buffer_data_page *bpage = data; | 4406 | struct buffer_data_page *bpage = data; |
4407 | struct page *page = virt_to_page(bpage); | ||
4403 | unsigned long flags; | 4408 | unsigned long flags; |
4404 | 4409 | ||
4410 | /* If the page is still in use someplace else, we can't reuse it */ | ||
4411 | if (page_ref_count(page) > 1) | ||
4412 | goto out; | ||
4413 | |||
4405 | local_irq_save(flags); | 4414 | local_irq_save(flags); |
4406 | arch_spin_lock(&cpu_buffer->lock); | 4415 | arch_spin_lock(&cpu_buffer->lock); |
4407 | 4416 | ||
@@ -4413,6 +4422,7 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data) | |||
4413 | arch_spin_unlock(&cpu_buffer->lock); | 4422 | arch_spin_unlock(&cpu_buffer->lock); |
4414 | local_irq_restore(flags); | 4423 | local_irq_restore(flags); |
4415 | 4424 | ||
4425 | out: | ||
4416 | free_page((unsigned long)bpage); | 4426 | free_page((unsigned long)bpage); |
4417 | } | 4427 | } |
4418 | EXPORT_SYMBOL_GPL(ring_buffer_free_read_page); | 4428 | EXPORT_SYMBOL_GPL(ring_buffer_free_read_page); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 59518b8126d0..2a8d8a294345 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -6769,7 +6769,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
6769 | .spd_release = buffer_spd_release, | 6769 | .spd_release = buffer_spd_release, |
6770 | }; | 6770 | }; |
6771 | struct buffer_ref *ref; | 6771 | struct buffer_ref *ref; |
6772 | int entries, size, i; | 6772 | int entries, i; |
6773 | ssize_t ret = 0; | 6773 | ssize_t ret = 0; |
6774 | 6774 | ||
6775 | #ifdef CONFIG_TRACER_MAX_TRACE | 6775 | #ifdef CONFIG_TRACER_MAX_TRACE |
@@ -6823,14 +6823,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
6823 | break; | 6823 | break; |
6824 | } | 6824 | } |
6825 | 6825 | ||
6826 | /* | ||
6827 | * zero out any left over data, this is going to | ||
6828 | * user land. | ||
6829 | */ | ||
6830 | size = ring_buffer_page_len(ref->page); | ||
6831 | if (size < PAGE_SIZE) | ||
6832 | memset(ref->page + size, 0, PAGE_SIZE - size); | ||
6833 | |||
6834 | page = virt_to_page(ref->page); | 6826 | page = virt_to_page(ref->page); |
6835 | 6827 | ||
6836 | spd.pages[i] = page; | 6828 | spd.pages[i] = page; |
@@ -7588,6 +7580,7 @@ allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size | |||
7588 | buf->data = alloc_percpu(struct trace_array_cpu); | 7580 | buf->data = alloc_percpu(struct trace_array_cpu); |
7589 | if (!buf->data) { | 7581 | if (!buf->data) { |
7590 | ring_buffer_free(buf->buffer); | 7582 | ring_buffer_free(buf->buffer); |
7583 | buf->buffer = NULL; | ||
7591 | return -ENOMEM; | 7584 | return -ENOMEM; |
7592 | } | 7585 | } |
7593 | 7586 | ||
@@ -7611,7 +7604,9 @@ static int allocate_trace_buffers(struct trace_array *tr, int size) | |||
7611 | allocate_snapshot ? size : 1); | 7604 | allocate_snapshot ? size : 1); |
7612 | if (WARN_ON(ret)) { | 7605 | if (WARN_ON(ret)) { |
7613 | ring_buffer_free(tr->trace_buffer.buffer); | 7606 | ring_buffer_free(tr->trace_buffer.buffer); |
7607 | tr->trace_buffer.buffer = NULL; | ||
7614 | free_percpu(tr->trace_buffer.data); | 7608 | free_percpu(tr->trace_buffer.data); |
7609 | tr->trace_buffer.data = NULL; | ||
7615 | return -ENOMEM; | 7610 | return -ENOMEM; |
7616 | } | 7611 | } |
7617 | tr->allocated_snapshot = allocate_snapshot; | 7612 | tr->allocated_snapshot = allocate_snapshot; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 00b0757830e2..01e8285aea73 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1177,12 +1177,12 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) | |||
1177 | int i, new_frags; | 1177 | int i, new_frags; |
1178 | u32 d_off; | 1178 | u32 d_off; |
1179 | 1179 | ||
1180 | if (!num_frags) | ||
1181 | goto release; | ||
1182 | |||
1183 | if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) | 1180 | if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) |
1184 | return -EINVAL; | 1181 | return -EINVAL; |
1185 | 1182 | ||
1183 | if (!num_frags) | ||
1184 | goto release; | ||
1185 | |||
1186 | new_frags = (__skb_pagelen(skb) + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1186 | new_frags = (__skb_pagelen(skb) + PAGE_SIZE - 1) >> PAGE_SHIFT; |
1187 | for (i = 0; i < new_frags; i++) { | 1187 | for (i = 0; i < new_frags; i++) { |
1188 | page = alloc_page(gfp_mask); | 1188 | page = alloc_page(gfp_mask); |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index e50b7fea57ee..bcfc00e88756 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -23,6 +23,12 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb) | |||
23 | return xfrm4_extract_header(skb); | 23 | return xfrm4_extract_header(skb); |
24 | } | 24 | } |
25 | 25 | ||
26 | static int xfrm4_rcv_encap_finish2(struct net *net, struct sock *sk, | ||
27 | struct sk_buff *skb) | ||
28 | { | ||
29 | return dst_input(skb); | ||
30 | } | ||
31 | |||
26 | static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, | 32 | static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, |
27 | struct sk_buff *skb) | 33 | struct sk_buff *skb) |
28 | { | 34 | { |
@@ -33,7 +39,11 @@ static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, | |||
33 | iph->tos, skb->dev)) | 39 | iph->tos, skb->dev)) |
34 | goto drop; | 40 | goto drop; |
35 | } | 41 | } |
36 | return dst_input(skb); | 42 | |
43 | if (xfrm_trans_queue(skb, xfrm4_rcv_encap_finish2)) | ||
44 | goto drop; | ||
45 | |||
46 | return 0; | ||
37 | drop: | 47 | drop: |
38 | kfree_skb(skb); | 48 | kfree_skb(skb); |
39 | return NET_RX_DROP; | 49 | return NET_RX_DROP; |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index b345b7e484c5..db99446e0276 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -1333,6 +1333,36 @@ static void ip6gre_tunnel_setup(struct net_device *dev) | |||
1333 | eth_random_addr(dev->perm_addr); | 1333 | eth_random_addr(dev->perm_addr); |
1334 | } | 1334 | } |
1335 | 1335 | ||
1336 | #define GRE6_FEATURES (NETIF_F_SG | \ | ||
1337 | NETIF_F_FRAGLIST | \ | ||
1338 | NETIF_F_HIGHDMA | \ | ||
1339 | NETIF_F_HW_CSUM) | ||
1340 | |||
1341 | static void ip6gre_tnl_init_features(struct net_device *dev) | ||
1342 | { | ||
1343 | struct ip6_tnl *nt = netdev_priv(dev); | ||
1344 | |||
1345 | dev->features |= GRE6_FEATURES; | ||
1346 | dev->hw_features |= GRE6_FEATURES; | ||
1347 | |||
1348 | if (!(nt->parms.o_flags & TUNNEL_SEQ)) { | ||
1349 | /* TCP offload with GRE SEQ is not supported, nor | ||
1350 | * can we support 2 levels of outer headers requiring | ||
1351 | * an update. | ||
1352 | */ | ||
1353 | if (!(nt->parms.o_flags & TUNNEL_CSUM) || | ||
1354 | nt->encap.type == TUNNEL_ENCAP_NONE) { | ||
1355 | dev->features |= NETIF_F_GSO_SOFTWARE; | ||
1356 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | ||
1357 | } | ||
1358 | |||
1359 | /* Can use a lockless transmit, unless we generate | ||
1360 | * output sequences | ||
1361 | */ | ||
1362 | dev->features |= NETIF_F_LLTX; | ||
1363 | } | ||
1364 | } | ||
1365 | |||
1336 | static int ip6gre_tunnel_init_common(struct net_device *dev) | 1366 | static int ip6gre_tunnel_init_common(struct net_device *dev) |
1337 | { | 1367 | { |
1338 | struct ip6_tnl *tunnel; | 1368 | struct ip6_tnl *tunnel; |
@@ -1371,6 +1401,7 @@ static int ip6gre_tunnel_init_common(struct net_device *dev) | |||
1371 | dev->features |= NETIF_F_NETNS_LOCAL; | 1401 | dev->features |= NETIF_F_NETNS_LOCAL; |
1372 | netif_keep_dst(dev); | 1402 | netif_keep_dst(dev); |
1373 | } | 1403 | } |
1404 | ip6gre_tnl_init_features(dev); | ||
1374 | 1405 | ||
1375 | return 0; | 1406 | return 0; |
1376 | } | 1407 | } |
@@ -1705,11 +1736,6 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = { | |||
1705 | .ndo_get_iflink = ip6_tnl_get_iflink, | 1736 | .ndo_get_iflink = ip6_tnl_get_iflink, |
1706 | }; | 1737 | }; |
1707 | 1738 | ||
1708 | #define GRE6_FEATURES (NETIF_F_SG | \ | ||
1709 | NETIF_F_FRAGLIST | \ | ||
1710 | NETIF_F_HIGHDMA | \ | ||
1711 | NETIF_F_HW_CSUM) | ||
1712 | |||
1713 | static int ip6erspan_tap_init(struct net_device *dev) | 1739 | static int ip6erspan_tap_init(struct net_device *dev) |
1714 | { | 1740 | { |
1715 | struct ip6_tnl *tunnel; | 1741 | struct ip6_tnl *tunnel; |
@@ -1848,26 +1874,6 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev, | |||
1848 | nt->net = dev_net(dev); | 1874 | nt->net = dev_net(dev); |
1849 | ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]); | 1875 | ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]); |
1850 | 1876 | ||
1851 | dev->features |= GRE6_FEATURES; | ||
1852 | dev->hw_features |= GRE6_FEATURES; | ||
1853 | |||
1854 | if (!(nt->parms.o_flags & TUNNEL_SEQ)) { | ||
1855 | /* TCP offload with GRE SEQ is not supported, nor | ||
1856 | * can we support 2 levels of outer headers requiring | ||
1857 | * an update. | ||
1858 | */ | ||
1859 | if (!(nt->parms.o_flags & TUNNEL_CSUM) || | ||
1860 | (nt->encap.type == TUNNEL_ENCAP_NONE)) { | ||
1861 | dev->features |= NETIF_F_GSO_SOFTWARE; | ||
1862 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | ||
1863 | } | ||
1864 | |||
1865 | /* Can use a lockless transmit, unless we generate | ||
1866 | * output sequences | ||
1867 | */ | ||
1868 | dev->features |= NETIF_F_LLTX; | ||
1869 | } | ||
1870 | |||
1871 | err = register_netdevice(dev); | 1877 | err = register_netdevice(dev); |
1872 | if (err) | 1878 | if (err) |
1873 | goto out; | 1879 | goto out; |
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index fe04e23af986..841f4a07438e 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -32,6 +32,14 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, | |||
32 | } | 32 | } |
33 | EXPORT_SYMBOL(xfrm6_rcv_spi); | 33 | EXPORT_SYMBOL(xfrm6_rcv_spi); |
34 | 34 | ||
35 | static int xfrm6_transport_finish2(struct net *net, struct sock *sk, | ||
36 | struct sk_buff *skb) | ||
37 | { | ||
38 | if (xfrm_trans_queue(skb, ip6_rcv_finish)) | ||
39 | __kfree_skb(skb); | ||
40 | return -1; | ||
41 | } | ||
42 | |||
35 | int xfrm6_transport_finish(struct sk_buff *skb, int async) | 43 | int xfrm6_transport_finish(struct sk_buff *skb, int async) |
36 | { | 44 | { |
37 | struct xfrm_offload *xo = xfrm_offload(skb); | 45 | struct xfrm_offload *xo = xfrm_offload(skb); |
@@ -56,7 +64,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) | |||
56 | 64 | ||
57 | NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, | 65 | NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, |
58 | dev_net(skb->dev), NULL, skb, skb->dev, NULL, | 66 | dev_net(skb->dev), NULL, skb, skb->dev, NULL, |
59 | ip6_rcv_finish); | 67 | xfrm6_transport_finish2); |
60 | return -1; | 68 | return -1; |
61 | } | 69 | } |
62 | 70 | ||
diff --git a/net/rds/send.c b/net/rds/send.c index b52cdc8ae428..f72466c63f0c 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -1009,6 +1009,9 @@ static int rds_rdma_bytes(struct msghdr *msg, size_t *rdma_bytes) | |||
1009 | continue; | 1009 | continue; |
1010 | 1010 | ||
1011 | if (cmsg->cmsg_type == RDS_CMSG_RDMA_ARGS) { | 1011 | if (cmsg->cmsg_type == RDS_CMSG_RDMA_ARGS) { |
1012 | if (cmsg->cmsg_len < | ||
1013 | CMSG_LEN(sizeof(struct rds_rdma_args))) | ||
1014 | return -EINVAL; | ||
1012 | args = CMSG_DATA(cmsg); | 1015 | args = CMSG_DATA(cmsg); |
1013 | *rdma_bytes += args->remote_vec.bytes; | 1016 | *rdma_bytes += args->remote_vec.bytes; |
1014 | } | 1017 | } |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 4591b87eaab5..6708b6953bfa 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -373,6 +373,8 @@ void tcf_block_put(struct tcf_block *block) | |||
373 | { | 373 | { |
374 | struct tcf_block_ext_info ei = {0, }; | 374 | struct tcf_block_ext_info ei = {0, }; |
375 | 375 | ||
376 | if (!block) | ||
377 | return; | ||
376 | tcf_block_put_ext(block, block->q, &ei); | 378 | tcf_block_put_ext(block, block->q, &ei); |
377 | } | 379 | } |
378 | 380 | ||
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 28b2a7964133..cc069b2acf0e 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -1261,6 +1261,8 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, | |||
1261 | 1261 | ||
1262 | if (!tp_head) { | 1262 | if (!tp_head) { |
1263 | RCU_INIT_POINTER(*miniqp->p_miniq, NULL); | 1263 | RCU_INIT_POINTER(*miniqp->p_miniq, NULL); |
1264 | /* Wait for flying RCU callback before it is freed. */ | ||
1265 | rcu_barrier_bh(); | ||
1264 | return; | 1266 | return; |
1265 | } | 1267 | } |
1266 | 1268 | ||
@@ -1276,7 +1278,7 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, | |||
1276 | rcu_assign_pointer(*miniqp->p_miniq, miniq); | 1278 | rcu_assign_pointer(*miniqp->p_miniq, miniq); |
1277 | 1279 | ||
1278 | if (miniq_old) | 1280 | if (miniq_old) |
1279 | /* This is counterpart of the rcu barrier above. We need to | 1281 | /* This is counterpart of the rcu barriers above. We need to |
1280 | * block potential new user of miniq_old until all readers | 1282 | * block potential new user of miniq_old until all readers |
1281 | * are not seeing it. | 1283 | * are not seeing it. |
1282 | */ | 1284 | */ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index aadcd4244d9b..a5e2150ab013 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4569,7 +4569,7 @@ static int sctp_init_sock(struct sock *sk) | |||
4569 | SCTP_DBG_OBJCNT_INC(sock); | 4569 | SCTP_DBG_OBJCNT_INC(sock); |
4570 | 4570 | ||
4571 | local_bh_disable(); | 4571 | local_bh_disable(); |
4572 | percpu_counter_inc(&sctp_sockets_allocated); | 4572 | sk_sockets_allocated_inc(sk); |
4573 | sock_prot_inuse_add(net, sk->sk_prot, 1); | 4573 | sock_prot_inuse_add(net, sk->sk_prot, 1); |
4574 | 4574 | ||
4575 | /* Nothing can fail after this block, otherwise | 4575 | /* Nothing can fail after this block, otherwise |
@@ -4613,7 +4613,7 @@ static void sctp_destroy_sock(struct sock *sk) | |||
4613 | } | 4613 | } |
4614 | sctp_endpoint_free(sp->ep); | 4614 | sctp_endpoint_free(sp->ep); |
4615 | local_bh_disable(); | 4615 | local_bh_disable(); |
4616 | percpu_counter_dec(&sctp_sockets_allocated); | 4616 | sk_sockets_allocated_dec(sk); |
4617 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | 4617 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); |
4618 | local_bh_enable(); | 4618 | local_bh_enable(); |
4619 | } | 4619 | } |
diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index c5fda15ba319..1fdab5c4eda8 100644 --- a/net/strparser/strparser.c +++ b/net/strparser/strparser.c | |||
@@ -401,7 +401,7 @@ void strp_data_ready(struct strparser *strp) | |||
401 | * allows a thread in BH context to safely check if the process | 401 | * allows a thread in BH context to safely check if the process |
402 | * lock is held. In this case, if the lock is held, queue work. | 402 | * lock is held. In this case, if the lock is held, queue work. |
403 | */ | 403 | */ |
404 | if (sock_owned_by_user(strp->sk)) { | 404 | if (sock_owned_by_user_nocheck(strp->sk)) { |
405 | queue_work(strp_wq, &strp->work); | 405 | queue_work(strp_wq, &strp->work); |
406 | return; | 406 | return; |
407 | } | 407 | } |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 47ec121574ce..c8001471da6c 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -324,6 +324,7 @@ restart: | |||
324 | if (res) { | 324 | if (res) { |
325 | pr_warn("Bearer <%s> rejected, enable failure (%d)\n", | 325 | pr_warn("Bearer <%s> rejected, enable failure (%d)\n", |
326 | name, -res); | 326 | name, -res); |
327 | kfree(b); | ||
327 | return -EINVAL; | 328 | return -EINVAL; |
328 | } | 329 | } |
329 | 330 | ||
@@ -347,8 +348,10 @@ restart: | |||
347 | if (skb) | 348 | if (skb) |
348 | tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); | 349 | tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); |
349 | 350 | ||
350 | if (tipc_mon_create(net, bearer_id)) | 351 | if (tipc_mon_create(net, bearer_id)) { |
352 | bearer_disable(net, b); | ||
351 | return -ENOMEM; | 353 | return -ENOMEM; |
354 | } | ||
352 | 355 | ||
353 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", | 356 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", |
354 | name, | 357 | name, |
diff --git a/net/tipc/group.c b/net/tipc/group.c index 7ebbdeb2a90e..8e12ab55346b 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c | |||
@@ -368,18 +368,20 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack) | |||
368 | u16 prev = grp->bc_snd_nxt - 1; | 368 | u16 prev = grp->bc_snd_nxt - 1; |
369 | struct tipc_member *m; | 369 | struct tipc_member *m; |
370 | struct rb_node *n; | 370 | struct rb_node *n; |
371 | u16 ackers = 0; | ||
371 | 372 | ||
372 | for (n = rb_first(&grp->members); n; n = rb_next(n)) { | 373 | for (n = rb_first(&grp->members); n; n = rb_next(n)) { |
373 | m = container_of(n, struct tipc_member, tree_node); | 374 | m = container_of(n, struct tipc_member, tree_node); |
374 | if (tipc_group_is_enabled(m)) { | 375 | if (tipc_group_is_enabled(m)) { |
375 | tipc_group_update_member(m, len); | 376 | tipc_group_update_member(m, len); |
376 | m->bc_acked = prev; | 377 | m->bc_acked = prev; |
378 | ackers++; | ||
377 | } | 379 | } |
378 | } | 380 | } |
379 | 381 | ||
380 | /* Mark number of acknowledges to expect, if any */ | 382 | /* Mark number of acknowledges to expect, if any */ |
381 | if (ack) | 383 | if (ack) |
382 | grp->bc_ackers = grp->member_cnt; | 384 | grp->bc_ackers = ackers; |
383 | grp->bc_snd_nxt++; | 385 | grp->bc_snd_nxt++; |
384 | } | 386 | } |
385 | 387 | ||
@@ -848,17 +850,26 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
848 | *usr_wakeup = true; | 850 | *usr_wakeup = true; |
849 | m->usr_pending = false; | 851 | m->usr_pending = false; |
850 | node_up = tipc_node_is_up(net, node); | 852 | node_up = tipc_node_is_up(net, node); |
851 | 853 | m->event_msg = NULL; | |
852 | /* Hold back event if more messages might be expected */ | 854 | |
853 | if (m->state != MBR_LEAVING && node_up) { | 855 | if (node_up) { |
854 | m->event_msg = skb; | 856 | /* Hold back event if a LEAVE msg should be expected */ |
855 | tipc_group_decr_active(grp, m); | 857 | if (m->state != MBR_LEAVING) { |
856 | m->state = MBR_LEAVING; | 858 | m->event_msg = skb; |
857 | } else { | 859 | tipc_group_decr_active(grp, m); |
858 | if (node_up) | 860 | m->state = MBR_LEAVING; |
861 | } else { | ||
859 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | 862 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); |
860 | else | 863 | __skb_queue_tail(inputq, skb); |
864 | } | ||
865 | } else { | ||
866 | if (m->state != MBR_LEAVING) { | ||
867 | tipc_group_decr_active(grp, m); | ||
868 | m->state = MBR_LEAVING; | ||
861 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); | 869 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); |
870 | } else { | ||
871 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | ||
872 | } | ||
862 | __skb_queue_tail(inputq, skb); | 873 | __skb_queue_tail(inputq, skb); |
863 | } | 874 | } |
864 | list_del_init(&m->list); | 875 | list_del_init(&m->list); |
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 8e884ed06d4b..32dc33a94bc7 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c | |||
@@ -642,9 +642,13 @@ void tipc_mon_delete(struct net *net, int bearer_id) | |||
642 | { | 642 | { |
643 | struct tipc_net *tn = tipc_net(net); | 643 | struct tipc_net *tn = tipc_net(net); |
644 | struct tipc_monitor *mon = tipc_monitor(net, bearer_id); | 644 | struct tipc_monitor *mon = tipc_monitor(net, bearer_id); |
645 | struct tipc_peer *self = get_self(net, bearer_id); | 645 | struct tipc_peer *self; |
646 | struct tipc_peer *peer, *tmp; | 646 | struct tipc_peer *peer, *tmp; |
647 | 647 | ||
648 | if (!mon) | ||
649 | return; | ||
650 | |||
651 | self = get_self(net, bearer_id); | ||
648 | write_lock_bh(&mon->lock); | 652 | write_lock_bh(&mon->lock); |
649 | tn->monitors[bearer_id] = NULL; | 653 | tn->monitors[bearer_id] = NULL; |
650 | list_for_each_entry_safe(peer, tmp, &self->list, list) { | 654 | list_for_each_entry_safe(peer, tmp, &self->list, list) { |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 0cdf5c2ad881..b51d5cba5094 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -727,11 +727,11 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
727 | 727 | ||
728 | switch (sk->sk_state) { | 728 | switch (sk->sk_state) { |
729 | case TIPC_ESTABLISHED: | 729 | case TIPC_ESTABLISHED: |
730 | case TIPC_CONNECTING: | ||
730 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) | 731 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) |
731 | revents |= POLLOUT; | 732 | revents |= POLLOUT; |
732 | /* fall thru' */ | 733 | /* fall thru' */ |
733 | case TIPC_LISTEN: | 734 | case TIPC_LISTEN: |
734 | case TIPC_CONNECTING: | ||
735 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 735 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
736 | revents |= POLLIN | POLLRDNORM; | 736 | revents |= POLLIN | POLLRDNORM; |
737 | break; | 737 | break; |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index ac277b97e0d7..26b10eb7a206 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -8,15 +8,29 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/bottom_half.h> | ||
12 | #include <linux/interrupt.h> | ||
11 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
12 | #include <linux/module.h> | 14 | #include <linux/module.h> |
13 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
16 | #include <linux/percpu.h> | ||
14 | #include <net/dst.h> | 17 | #include <net/dst.h> |
15 | #include <net/ip.h> | 18 | #include <net/ip.h> |
16 | #include <net/xfrm.h> | 19 | #include <net/xfrm.h> |
17 | #include <net/ip_tunnels.h> | 20 | #include <net/ip_tunnels.h> |
18 | #include <net/ip6_tunnel.h> | 21 | #include <net/ip6_tunnel.h> |
19 | 22 | ||
23 | struct xfrm_trans_tasklet { | ||
24 | struct tasklet_struct tasklet; | ||
25 | struct sk_buff_head queue; | ||
26 | }; | ||
27 | |||
28 | struct xfrm_trans_cb { | ||
29 | int (*finish)(struct net *net, struct sock *sk, struct sk_buff *skb); | ||
30 | }; | ||
31 | |||
32 | #define XFRM_TRANS_SKB_CB(__skb) ((struct xfrm_trans_cb *)&((__skb)->cb[0])) | ||
33 | |||
20 | static struct kmem_cache *secpath_cachep __read_mostly; | 34 | static struct kmem_cache *secpath_cachep __read_mostly; |
21 | 35 | ||
22 | static DEFINE_SPINLOCK(xfrm_input_afinfo_lock); | 36 | static DEFINE_SPINLOCK(xfrm_input_afinfo_lock); |
@@ -25,6 +39,8 @@ static struct xfrm_input_afinfo const __rcu *xfrm_input_afinfo[AF_INET6 + 1]; | |||
25 | static struct gro_cells gro_cells; | 39 | static struct gro_cells gro_cells; |
26 | static struct net_device xfrm_napi_dev; | 40 | static struct net_device xfrm_napi_dev; |
27 | 41 | ||
42 | static DEFINE_PER_CPU(struct xfrm_trans_tasklet, xfrm_trans_tasklet); | ||
43 | |||
28 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo) | 44 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo) |
29 | { | 45 | { |
30 | int err = 0; | 46 | int err = 0; |
@@ -207,7 +223,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
207 | xfrm_address_t *daddr; | 223 | xfrm_address_t *daddr; |
208 | struct xfrm_mode *inner_mode; | 224 | struct xfrm_mode *inner_mode; |
209 | u32 mark = skb->mark; | 225 | u32 mark = skb->mark; |
210 | unsigned int family; | 226 | unsigned int family = AF_UNSPEC; |
211 | int decaps = 0; | 227 | int decaps = 0; |
212 | int async = 0; | 228 | int async = 0; |
213 | bool xfrm_gro = false; | 229 | bool xfrm_gro = false; |
@@ -216,6 +232,16 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
216 | 232 | ||
217 | if (encap_type < 0) { | 233 | if (encap_type < 0) { |
218 | x = xfrm_input_state(skb); | 234 | x = xfrm_input_state(skb); |
235 | |||
236 | if (unlikely(x->km.state != XFRM_STATE_VALID)) { | ||
237 | if (x->km.state == XFRM_STATE_ACQ) | ||
238 | XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR); | ||
239 | else | ||
240 | XFRM_INC_STATS(net, | ||
241 | LINUX_MIB_XFRMINSTATEINVALID); | ||
242 | goto drop; | ||
243 | } | ||
244 | |||
219 | family = x->outer_mode->afinfo->family; | 245 | family = x->outer_mode->afinfo->family; |
220 | 246 | ||
221 | /* An encap_type of -1 indicates async resumption. */ | 247 | /* An encap_type of -1 indicates async resumption. */ |
@@ -466,9 +492,41 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr) | |||
466 | } | 492 | } |
467 | EXPORT_SYMBOL(xfrm_input_resume); | 493 | EXPORT_SYMBOL(xfrm_input_resume); |
468 | 494 | ||
495 | static void xfrm_trans_reinject(unsigned long data) | ||
496 | { | ||
497 | struct xfrm_trans_tasklet *trans = (void *)data; | ||
498 | struct sk_buff_head queue; | ||
499 | struct sk_buff *skb; | ||
500 | |||
501 | __skb_queue_head_init(&queue); | ||
502 | skb_queue_splice_init(&trans->queue, &queue); | ||
503 | |||
504 | while ((skb = __skb_dequeue(&queue))) | ||
505 | XFRM_TRANS_SKB_CB(skb)->finish(dev_net(skb->dev), NULL, skb); | ||
506 | } | ||
507 | |||
508 | int xfrm_trans_queue(struct sk_buff *skb, | ||
509 | int (*finish)(struct net *, struct sock *, | ||
510 | struct sk_buff *)) | ||
511 | { | ||
512 | struct xfrm_trans_tasklet *trans; | ||
513 | |||
514 | trans = this_cpu_ptr(&xfrm_trans_tasklet); | ||
515 | |||
516 | if (skb_queue_len(&trans->queue) >= netdev_max_backlog) | ||
517 | return -ENOBUFS; | ||
518 | |||
519 | XFRM_TRANS_SKB_CB(skb)->finish = finish; | ||
520 | skb_queue_tail(&trans->queue, skb); | ||
521 | tasklet_schedule(&trans->tasklet); | ||
522 | return 0; | ||
523 | } | ||
524 | EXPORT_SYMBOL(xfrm_trans_queue); | ||
525 | |||
469 | void __init xfrm_input_init(void) | 526 | void __init xfrm_input_init(void) |
470 | { | 527 | { |
471 | int err; | 528 | int err; |
529 | int i; | ||
472 | 530 | ||
473 | init_dummy_netdev(&xfrm_napi_dev); | 531 | init_dummy_netdev(&xfrm_napi_dev); |
474 | err = gro_cells_init(&gro_cells, &xfrm_napi_dev); | 532 | err = gro_cells_init(&gro_cells, &xfrm_napi_dev); |
@@ -479,4 +537,13 @@ void __init xfrm_input_init(void) | |||
479 | sizeof(struct sec_path), | 537 | sizeof(struct sec_path), |
480 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, | 538 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, |
481 | NULL); | 539 | NULL); |
540 | |||
541 | for_each_possible_cpu(i) { | ||
542 | struct xfrm_trans_tasklet *trans; | ||
543 | |||
544 | trans = &per_cpu(xfrm_trans_tasklet, i); | ||
545 | __skb_queue_head_init(&trans->queue); | ||
546 | tasklet_init(&trans->tasklet, xfrm_trans_reinject, | ||
547 | (unsigned long)trans); | ||
548 | } | ||
482 | } | 549 | } |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index e3a5aca9cdda..d8a8129b9232 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1168,9 +1168,15 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, | |||
1168 | again: | 1168 | again: |
1169 | pol = rcu_dereference(sk->sk_policy[dir]); | 1169 | pol = rcu_dereference(sk->sk_policy[dir]); |
1170 | if (pol != NULL) { | 1170 | if (pol != NULL) { |
1171 | bool match = xfrm_selector_match(&pol->selector, fl, family); | 1171 | bool match; |
1172 | int err = 0; | 1172 | int err = 0; |
1173 | 1173 | ||
1174 | if (pol->family != family) { | ||
1175 | pol = NULL; | ||
1176 | goto out; | ||
1177 | } | ||
1178 | |||
1179 | match = xfrm_selector_match(&pol->selector, fl, family); | ||
1174 | if (match) { | 1180 | if (match) { |
1175 | if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { | 1181 | if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { |
1176 | pol = NULL; | 1182 | pol = NULL; |
@@ -1835,6 +1841,7 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, | |||
1835 | sizeof(struct xfrm_policy *) * num_pols) == 0 && | 1841 | sizeof(struct xfrm_policy *) * num_pols) == 0 && |
1836 | xfrm_xdst_can_reuse(xdst, xfrm, err)) { | 1842 | xfrm_xdst_can_reuse(xdst, xfrm, err)) { |
1837 | dst_hold(&xdst->u.dst); | 1843 | dst_hold(&xdst->u.dst); |
1844 | xfrm_pols_put(pols, num_pols); | ||
1838 | while (err > 0) | 1845 | while (err > 0) |
1839 | xfrm_state_put(xfrm[--err]); | 1846 | xfrm_state_put(xfrm[--err]); |
1840 | return xdst; | 1847 | return xdst; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 1b7856be3eeb..cc4c519cad76 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -1343,6 +1343,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, | |||
1343 | 1343 | ||
1344 | if (orig->aead) { | 1344 | if (orig->aead) { |
1345 | x->aead = xfrm_algo_aead_clone(orig->aead); | 1345 | x->aead = xfrm_algo_aead_clone(orig->aead); |
1346 | x->geniv = orig->geniv; | ||
1346 | if (!x->aead) | 1347 | if (!x->aead) |
1347 | goto error; | 1348 | goto error; |
1348 | } | 1349 | } |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 983b0233767b..bdb48e5dba04 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1419,11 +1419,14 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | |||
1419 | 1419 | ||
1420 | static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | 1420 | static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) |
1421 | { | 1421 | { |
1422 | u16 prev_family; | ||
1422 | int i; | 1423 | int i; |
1423 | 1424 | ||
1424 | if (nr > XFRM_MAX_DEPTH) | 1425 | if (nr > XFRM_MAX_DEPTH) |
1425 | return -EINVAL; | 1426 | return -EINVAL; |
1426 | 1427 | ||
1428 | prev_family = family; | ||
1429 | |||
1427 | for (i = 0; i < nr; i++) { | 1430 | for (i = 0; i < nr; i++) { |
1428 | /* We never validated the ut->family value, so many | 1431 | /* We never validated the ut->family value, so many |
1429 | * applications simply leave it at zero. The check was | 1432 | * applications simply leave it at zero. The check was |
@@ -1435,6 +1438,12 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | |||
1435 | if (!ut[i].family) | 1438 | if (!ut[i].family) |
1436 | ut[i].family = family; | 1439 | ut[i].family = family; |
1437 | 1440 | ||
1441 | if ((ut[i].mode == XFRM_MODE_TRANSPORT) && | ||
1442 | (ut[i].family != prev_family)) | ||
1443 | return -EINVAL; | ||
1444 | |||
1445 | prev_family = ut[i].family; | ||
1446 | |||
1438 | switch (ut[i].family) { | 1447 | switch (ut[i].family) { |
1439 | case AF_INET: | 1448 | case AF_INET: |
1440 | break; | 1449 | break; |
@@ -1445,6 +1454,21 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | |||
1445 | default: | 1454 | default: |
1446 | return -EINVAL; | 1455 | return -EINVAL; |
1447 | } | 1456 | } |
1457 | |||
1458 | switch (ut[i].id.proto) { | ||
1459 | case IPPROTO_AH: | ||
1460 | case IPPROTO_ESP: | ||
1461 | case IPPROTO_COMP: | ||
1462 | #if IS_ENABLED(CONFIG_IPV6) | ||
1463 | case IPPROTO_ROUTING: | ||
1464 | case IPPROTO_DSTOPTS: | ||
1465 | #endif | ||
1466 | case IPSEC_PROTO_ANY: | ||
1467 | break; | ||
1468 | default: | ||
1469 | return -EINVAL; | ||
1470 | } | ||
1471 | |||
1448 | } | 1472 | } |
1449 | 1473 | ||
1450 | return 0; | 1474 | return 0; |
@@ -2470,7 +2494,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { | |||
2470 | [XFRMA_PROTO] = { .type = NLA_U8 }, | 2494 | [XFRMA_PROTO] = { .type = NLA_U8 }, |
2471 | [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) }, | 2495 | [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) }, |
2472 | [XFRMA_OFFLOAD_DEV] = { .len = sizeof(struct xfrm_user_offload) }, | 2496 | [XFRMA_OFFLOAD_DEV] = { .len = sizeof(struct xfrm_user_offload) }, |
2473 | [XFRMA_OUTPUT_MARK] = { .len = NLA_U32 }, | 2497 | [XFRMA_OUTPUT_MARK] = { .type = NLA_U32 }, |
2474 | }; | 2498 | }; |
2475 | 2499 | ||
2476 | static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { | 2500 | static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { |
diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 038a180d3f81..cbe818eda336 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c | |||
@@ -325,7 +325,7 @@ static int hdac_component_master_match(struct device *dev, void *data) | |||
325 | */ | 325 | */ |
326 | int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *aops) | 326 | int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *aops) |
327 | { | 327 | { |
328 | if (WARN_ON(!hdac_acomp)) | 328 | if (!hdac_acomp) |
329 | return -ENODEV; | 329 | return -ENODEV; |
330 | 330 | ||
331 | hdac_acomp->audio_ops = aops; | 331 | hdac_acomp->audio_ops = aops; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a81aacf684b2..37e1cf8218ff 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -271,6 +271,8 @@ enum { | |||
271 | CXT_FIXUP_HP_SPECTRE, | 271 | CXT_FIXUP_HP_SPECTRE, |
272 | CXT_FIXUP_HP_GATE_MIC, | 272 | CXT_FIXUP_HP_GATE_MIC, |
273 | CXT_FIXUP_MUTE_LED_GPIO, | 273 | CXT_FIXUP_MUTE_LED_GPIO, |
274 | CXT_FIXUP_HEADSET_MIC, | ||
275 | CXT_FIXUP_HP_MIC_NO_PRESENCE, | ||
274 | }; | 276 | }; |
275 | 277 | ||
276 | /* for hda_fixup_thinkpad_acpi() */ | 278 | /* for hda_fixup_thinkpad_acpi() */ |
@@ -350,6 +352,18 @@ static void cxt_fixup_headphone_mic(struct hda_codec *codec, | |||
350 | } | 352 | } |
351 | } | 353 | } |
352 | 354 | ||
355 | static void cxt_fixup_headset_mic(struct hda_codec *codec, | ||
356 | const struct hda_fixup *fix, int action) | ||
357 | { | ||
358 | struct conexant_spec *spec = codec->spec; | ||
359 | |||
360 | switch (action) { | ||
361 | case HDA_FIXUP_ACT_PRE_PROBE: | ||
362 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | ||
363 | break; | ||
364 | } | ||
365 | } | ||
366 | |||
353 | /* OPLC XO 1.5 fixup */ | 367 | /* OPLC XO 1.5 fixup */ |
354 | 368 | ||
355 | /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors) | 369 | /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors) |
@@ -880,6 +894,19 @@ static const struct hda_fixup cxt_fixups[] = { | |||
880 | .type = HDA_FIXUP_FUNC, | 894 | .type = HDA_FIXUP_FUNC, |
881 | .v.func = cxt_fixup_mute_led_gpio, | 895 | .v.func = cxt_fixup_mute_led_gpio, |
882 | }, | 896 | }, |
897 | [CXT_FIXUP_HEADSET_MIC] = { | ||
898 | .type = HDA_FIXUP_FUNC, | ||
899 | .v.func = cxt_fixup_headset_mic, | ||
900 | }, | ||
901 | [CXT_FIXUP_HP_MIC_NO_PRESENCE] = { | ||
902 | .type = HDA_FIXUP_PINS, | ||
903 | .v.pins = (const struct hda_pintbl[]) { | ||
904 | { 0x1a, 0x02a1113c }, | ||
905 | { } | ||
906 | }, | ||
907 | .chained = true, | ||
908 | .chain_id = CXT_FIXUP_HEADSET_MIC, | ||
909 | }, | ||
883 | }; | 910 | }; |
884 | 911 | ||
885 | static const struct snd_pci_quirk cxt5045_fixups[] = { | 912 | static const struct snd_pci_quirk cxt5045_fixups[] = { |
@@ -934,6 +961,8 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { | |||
934 | SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), | 961 | SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), |
935 | SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), | 962 | SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), |
936 | SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), | 963 | SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), |
964 | SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), | ||
965 | SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), | ||
937 | SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), | 966 | SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), |
938 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), | 967 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), |
939 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), | 968 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6a4db00511ab..8fd2d9c62c96 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -324,8 +324,12 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) | |||
324 | case 0x10ec0292: | 324 | case 0x10ec0292: |
325 | alc_update_coef_idx(codec, 0x4, 1<<15, 0); | 325 | alc_update_coef_idx(codec, 0x4, 1<<15, 0); |
326 | break; | 326 | break; |
327 | case 0x10ec0215: | ||
328 | case 0x10ec0225: | 327 | case 0x10ec0225: |
328 | case 0x10ec0295: | ||
329 | case 0x10ec0299: | ||
330 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); | ||
331 | /* fallthrough */ | ||
332 | case 0x10ec0215: | ||
329 | case 0x10ec0233: | 333 | case 0x10ec0233: |
330 | case 0x10ec0236: | 334 | case 0x10ec0236: |
331 | case 0x10ec0255: | 335 | case 0x10ec0255: |
@@ -336,10 +340,8 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) | |||
336 | case 0x10ec0286: | 340 | case 0x10ec0286: |
337 | case 0x10ec0288: | 341 | case 0x10ec0288: |
338 | case 0x10ec0285: | 342 | case 0x10ec0285: |
339 | case 0x10ec0295: | ||
340 | case 0x10ec0298: | 343 | case 0x10ec0298: |
341 | case 0x10ec0289: | 344 | case 0x10ec0289: |
342 | case 0x10ec0299: | ||
343 | alc_update_coef_idx(codec, 0x10, 1<<9, 0); | 345 | alc_update_coef_idx(codec, 0x10, 1<<9, 0); |
344 | break; | 346 | break; |
345 | case 0x10ec0275: | 347 | case 0x10ec0275: |
@@ -6328,6 +6330,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6328 | SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | 6330 | SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), |
6329 | SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | 6331 | SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), |
6330 | SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), | 6332 | SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), |
6333 | SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), | ||
6331 | SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), | 6334 | SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), |
6332 | SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), | 6335 | SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), |
6333 | SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), | 6336 | SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), |
@@ -6586,6 +6589,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | |||
6586 | {0x1b, 0x01011020}, | 6589 | {0x1b, 0x01011020}, |
6587 | {0x21, 0x02211010}), | 6590 | {0x21, 0x02211010}), |
6588 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | 6591 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, |
6592 | {0x12, 0x90a60130}, | ||
6593 | {0x14, 0x90170110}, | ||
6594 | {0x1b, 0x01011020}, | ||
6595 | {0x21, 0x0221101f}), | ||
6596 | SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
6589 | {0x12, 0x90a60160}, | 6597 | {0x12, 0x90a60160}, |
6590 | {0x14, 0x90170120}, | 6598 | {0x14, 0x90170120}, |
6591 | {0x21, 0x02211030}), | 6599 | {0x21, 0x02211030}), |
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 9f521a55d610..b5e41df6bb3a 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c | |||
@@ -1051,6 +1051,11 @@ static int acp_audio_probe(struct platform_device *pdev) | |||
1051 | struct resource *res; | 1051 | struct resource *res; |
1052 | const u32 *pdata = pdev->dev.platform_data; | 1052 | const u32 *pdata = pdev->dev.platform_data; |
1053 | 1053 | ||
1054 | if (!pdata) { | ||
1055 | dev_err(&pdev->dev, "Missing platform data\n"); | ||
1056 | return -ENODEV; | ||
1057 | } | ||
1058 | |||
1054 | audio_drv_data = devm_kzalloc(&pdev->dev, sizeof(struct audio_drv_data), | 1059 | audio_drv_data = devm_kzalloc(&pdev->dev, sizeof(struct audio_drv_data), |
1055 | GFP_KERNEL); | 1060 | GFP_KERNEL); |
1056 | if (audio_drv_data == NULL) | 1061 | if (audio_drv_data == NULL) |
@@ -1058,6 +1063,8 @@ static int acp_audio_probe(struct platform_device *pdev) | |||
1058 | 1063 | ||
1059 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1064 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1060 | audio_drv_data->acp_mmio = devm_ioremap_resource(&pdev->dev, res); | 1065 | audio_drv_data->acp_mmio = devm_ioremap_resource(&pdev->dev, res); |
1066 | if (IS_ERR(audio_drv_data->acp_mmio)) | ||
1067 | return PTR_ERR(audio_drv_data->acp_mmio); | ||
1061 | 1068 | ||
1062 | /* The following members gets populated in device 'open' | 1069 | /* The following members gets populated in device 'open' |
1063 | * function. Till then interrupts are disabled in 'acp_init' | 1070 | * function. Till then interrupts are disabled in 'acp_init' |
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index 4a56f3dfba51..dcee145dd179 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
@@ -64,7 +64,7 @@ config SND_AT91_SOC_SAM9X5_WM8731 | |||
64 | config SND_ATMEL_SOC_CLASSD | 64 | config SND_ATMEL_SOC_CLASSD |
65 | tristate "Atmel ASoC driver for boards using CLASSD" | 65 | tristate "Atmel ASoC driver for boards using CLASSD" |
66 | depends on ARCH_AT91 || COMPILE_TEST | 66 | depends on ARCH_AT91 || COMPILE_TEST |
67 | select SND_ATMEL_SOC_DMA | 67 | select SND_SOC_GENERIC_DMAENGINE_PCM |
68 | select REGMAP_MMIO | 68 | select REGMAP_MMIO |
69 | help | 69 | help |
70 | Say Y if you want to add support for Atmel ASoC driver for boards using | 70 | Say Y if you want to add support for Atmel ASoC driver for boards using |
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index b2d42ec1dcd9..56564ce90cb6 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c | |||
@@ -2520,7 +2520,7 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec) | |||
2520 | } | 2520 | } |
2521 | 2521 | ||
2522 | if (da7218->dev_id == DA7218_DEV_ID) { | 2522 | if (da7218->dev_id == DA7218_DEV_ID) { |
2523 | hpldet_np = of_find_node_by_name(np, "da7218_hpldet"); | 2523 | hpldet_np = of_get_child_by_name(np, "da7218_hpldet"); |
2524 | if (!hpldet_np) | 2524 | if (!hpldet_np) |
2525 | return pdata; | 2525 | return pdata; |
2526 | 2526 | ||
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index 5f3c42c4f74a..066ea2f4ce7b 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c | |||
@@ -267,7 +267,7 @@ | |||
267 | #define MSM8916_WCD_ANALOG_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ | 267 | #define MSM8916_WCD_ANALOG_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ |
268 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) | 268 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) |
269 | #define MSM8916_WCD_ANALOG_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ | 269 | #define MSM8916_WCD_ANALOG_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ |
270 | SNDRV_PCM_FMTBIT_S24_LE) | 270 | SNDRV_PCM_FMTBIT_S32_LE) |
271 | 271 | ||
272 | static int btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | | 272 | static int btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | |
273 | SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4; | 273 | SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4; |
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index a10a724eb448..13354d6304a8 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c | |||
@@ -194,7 +194,7 @@ | |||
194 | SNDRV_PCM_RATE_32000 | \ | 194 | SNDRV_PCM_RATE_32000 | \ |
195 | SNDRV_PCM_RATE_48000) | 195 | SNDRV_PCM_RATE_48000) |
196 | #define MSM8916_WCD_DIGITAL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ | 196 | #define MSM8916_WCD_DIGITAL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ |
197 | SNDRV_PCM_FMTBIT_S24_LE) | 197 | SNDRV_PCM_FMTBIT_S32_LE) |
198 | 198 | ||
199 | struct msm8916_wcd_digital_priv { | 199 | struct msm8916_wcd_digital_priv { |
200 | struct clk *ahbclk, *mclk; | 200 | struct clk *ahbclk, *mclk; |
@@ -645,7 +645,7 @@ static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream, | |||
645 | RX_I2S_CTL_RX_I2S_MODE_MASK, | 645 | RX_I2S_CTL_RX_I2S_MODE_MASK, |
646 | RX_I2S_CTL_RX_I2S_MODE_16); | 646 | RX_I2S_CTL_RX_I2S_MODE_16); |
647 | break; | 647 | break; |
648 | case SNDRV_PCM_FORMAT_S24_LE: | 648 | case SNDRV_PCM_FORMAT_S32_LE: |
649 | snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_TX_I2S_CTL, | 649 | snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_TX_I2S_CTL, |
650 | TX_I2S_CTL_TX_I2S_MODE_MASK, | 650 | TX_I2S_CTL_TX_I2S_MODE_MASK, |
651 | TX_I2S_CTL_TX_I2S_MODE_32); | 651 | TX_I2S_CTL_TX_I2S_MODE_32); |
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 714ce17da717..e853a6dfd33b 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c | |||
@@ -905,6 +905,7 @@ static int nau8825_adc_event(struct snd_soc_dapm_widget *w, | |||
905 | 905 | ||
906 | switch (event) { | 906 | switch (event) { |
907 | case SND_SOC_DAPM_POST_PMU: | 907 | case SND_SOC_DAPM_POST_PMU: |
908 | msleep(125); | ||
908 | regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL, | 909 | regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL, |
909 | NAU8825_ENABLE_ADC, NAU8825_ENABLE_ADC); | 910 | NAU8825_ENABLE_ADC, NAU8825_ENABLE_ADC); |
910 | break; | 911 | break; |
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index 2df91db765ac..64bf26cec20d 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c | |||
@@ -289,6 +289,8 @@ static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform) | |||
289 | dev_err(&rt5514_spi->dev, | 289 | dev_err(&rt5514_spi->dev, |
290 | "%s Failed to reguest IRQ: %d\n", __func__, | 290 | "%s Failed to reguest IRQ: %d\n", __func__, |
291 | ret); | 291 | ret); |
292 | else | ||
293 | device_init_wakeup(rt5514_dsp->dev, true); | ||
292 | } | 294 | } |
293 | 295 | ||
294 | return 0; | 296 | return 0; |
@@ -456,8 +458,6 @@ static int rt5514_spi_probe(struct spi_device *spi) | |||
456 | return ret; | 458 | return ret; |
457 | } | 459 | } |
458 | 460 | ||
459 | device_init_wakeup(&spi->dev, true); | ||
460 | |||
461 | return 0; | 461 | return 0; |
462 | } | 462 | } |
463 | 463 | ||
@@ -482,10 +482,13 @@ static int __maybe_unused rt5514_resume(struct device *dev) | |||
482 | if (device_may_wakeup(dev)) | 482 | if (device_may_wakeup(dev)) |
483 | disable_irq_wake(irq); | 483 | disable_irq_wake(irq); |
484 | 484 | ||
485 | if (rt5514_dsp->substream) { | 485 | if (rt5514_dsp) { |
486 | rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf)); | 486 | if (rt5514_dsp->substream) { |
487 | if (buf[0] & RT5514_IRQ_STATUS_BIT) | 487 | rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, |
488 | rt5514_schedule_copy(rt5514_dsp); | 488 | sizeof(buf)); |
489 | if (buf[0] & RT5514_IRQ_STATUS_BIT) | ||
490 | rt5514_schedule_copy(rt5514_dsp); | ||
491 | } | ||
489 | } | 492 | } |
490 | 493 | ||
491 | return 0; | 494 | return 0; |
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 2a5b5d74e697..2dd6e9f990a4 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c | |||
@@ -496,7 +496,7 @@ static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { | |||
496 | SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0), | 496 | SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0), |
497 | SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0), | 497 | SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0), |
498 | 498 | ||
499 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, | 499 | SND_SOC_DAPM_SUPPLY_S("DMIC CLK", 1, SND_SOC_NOPM, 0, 0, |
500 | rt5514_set_dmic_clk, SND_SOC_DAPM_PRE_PMU), | 500 | rt5514_set_dmic_clk, SND_SOC_DAPM_PRE_PMU), |
501 | 501 | ||
502 | SND_SOC_DAPM_SUPPLY("ADC CLK", RT5514_CLK_CTRL1, | 502 | SND_SOC_DAPM_SUPPLY("ADC CLK", RT5514_CLK_CTRL1, |
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index f020d2d1eef4..edc152c8a1fe 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -3823,6 +3823,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
3823 | regmap_read(regmap, RT5645_VENDOR_ID, &val); | 3823 | regmap_read(regmap, RT5645_VENDOR_ID, &val); |
3824 | rt5645->v_id = val & 0xff; | 3824 | rt5645->v_id = val & 0xff; |
3825 | 3825 | ||
3826 | regmap_write(rt5645->regmap, RT5645_AD_DA_MIXER, 0x8080); | ||
3827 | |||
3826 | ret = regmap_register_patch(rt5645->regmap, init_list, | 3828 | ret = regmap_register_patch(rt5645->regmap, init_list, |
3827 | ARRAY_SIZE(init_list)); | 3829 | ARRAY_SIZE(init_list)); |
3828 | if (ret != 0) | 3830 | if (ret != 0) |
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index b036c9dc0c8c..d329bf719d80 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c | |||
@@ -1560,6 +1560,10 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) | |||
1560 | RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN); | 1560 | RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN); |
1561 | snd_soc_update_bits(codec, RT5663_IRQ_1, | 1561 | snd_soc_update_bits(codec, RT5663_IRQ_1, |
1562 | RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN); | 1562 | RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN); |
1563 | snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1, | ||
1564 | RT5663_EM_JD_MASK, RT5663_EM_JD_RST); | ||
1565 | snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1, | ||
1566 | RT5663_EM_JD_MASK, RT5663_EM_JD_NOR); | ||
1563 | 1567 | ||
1564 | while (true) { | 1568 | while (true) { |
1565 | regmap_read(rt5663->regmap, RT5663_INT_ST_2, &val); | 1569 | regmap_read(rt5663->regmap, RT5663_INT_ST_2, &val); |
diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h index c5a9b69579ad..03adc8004ba9 100644 --- a/sound/soc/codecs/rt5663.h +++ b/sound/soc/codecs/rt5663.h | |||
@@ -1029,6 +1029,10 @@ | |||
1029 | #define RT5663_POL_EXT_JD_SHIFT 10 | 1029 | #define RT5663_POL_EXT_JD_SHIFT 10 |
1030 | #define RT5663_POL_EXT_JD_EN (0x1 << 10) | 1030 | #define RT5663_POL_EXT_JD_EN (0x1 << 10) |
1031 | #define RT5663_POL_EXT_JD_DIS (0x0 << 10) | 1031 | #define RT5663_POL_EXT_JD_DIS (0x0 << 10) |
1032 | #define RT5663_EM_JD_MASK (0x1 << 7) | ||
1033 | #define RT5663_EM_JD_SHIFT 7 | ||
1034 | #define RT5663_EM_JD_NOR (0x1 << 7) | ||
1035 | #define RT5663_EM_JD_RST (0x0 << 7) | ||
1032 | 1036 | ||
1033 | /* DACREF LDO Control (0x0112)*/ | 1037 | /* DACREF LDO Control (0x0112)*/ |
1034 | #define RT5663_PWR_LDO_DACREFL_MASK (0x1 << 9) | 1038 | #define RT5663_PWR_LDO_DACREFL_MASK (0x1 << 9) |
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h index 730fb2058869..1ff3edb7bbb6 100644 --- a/sound/soc/codecs/tlv320aic31xx.h +++ b/sound/soc/codecs/tlv320aic31xx.h | |||
@@ -116,7 +116,7 @@ struct aic31xx_pdata { | |||
116 | /* INT2 interrupt control */ | 116 | /* INT2 interrupt control */ |
117 | #define AIC31XX_INT2CTRL AIC31XX_REG(0, 49) | 117 | #define AIC31XX_INT2CTRL AIC31XX_REG(0, 49) |
118 | /* GPIO1 control */ | 118 | /* GPIO1 control */ |
119 | #define AIC31XX_GPIO1 AIC31XX_REG(0, 50) | 119 | #define AIC31XX_GPIO1 AIC31XX_REG(0, 51) |
120 | 120 | ||
121 | #define AIC31XX_DACPRB AIC31XX_REG(0, 60) | 121 | #define AIC31XX_DACPRB AIC31XX_REG(0, 60) |
122 | /* ADC Instruction Set Register */ | 122 | /* ADC Instruction Set Register */ |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index c482b2e7a7d2..cfe72b9d4356 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -232,7 +232,7 @@ static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec) | |||
232 | struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); | 232 | struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); |
233 | struct device_node *twl4030_codec_node = NULL; | 233 | struct device_node *twl4030_codec_node = NULL; |
234 | 234 | ||
235 | twl4030_codec_node = of_find_node_by_name(codec->dev->parent->of_node, | 235 | twl4030_codec_node = of_get_child_by_name(codec->dev->parent->of_node, |
236 | "codec"); | 236 | "codec"); |
237 | 237 | ||
238 | if (!pdata && twl4030_codec_node) { | 238 | if (!pdata && twl4030_codec_node) { |
@@ -241,9 +241,11 @@ static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec) | |||
241 | GFP_KERNEL); | 241 | GFP_KERNEL); |
242 | if (!pdata) { | 242 | if (!pdata) { |
243 | dev_err(codec->dev, "Can not allocate memory\n"); | 243 | dev_err(codec->dev, "Can not allocate memory\n"); |
244 | of_node_put(twl4030_codec_node); | ||
244 | return NULL; | 245 | return NULL; |
245 | } | 246 | } |
246 | twl4030_setup_pdata_of(pdata, twl4030_codec_node); | 247 | twl4030_setup_pdata_of(pdata, twl4030_codec_node); |
248 | of_node_put(twl4030_codec_node); | ||
247 | } | 249 | } |
248 | 250 | ||
249 | return pdata; | 251 | return pdata; |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 65c059b5ffd7..66e32f5d2917 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -1733,7 +1733,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
1733 | le64_to_cpu(footer->timestamp)); | 1733 | le64_to_cpu(footer->timestamp)); |
1734 | 1734 | ||
1735 | while (pos < firmware->size && | 1735 | while (pos < firmware->size && |
1736 | pos - firmware->size > sizeof(*region)) { | 1736 | sizeof(*region) < firmware->size - pos) { |
1737 | region = (void *)&(firmware->data[pos]); | 1737 | region = (void *)&(firmware->data[pos]); |
1738 | region_name = "Unknown"; | 1738 | region_name = "Unknown"; |
1739 | reg = 0; | 1739 | reg = 0; |
@@ -1782,8 +1782,8 @@ static int wm_adsp_load(struct wm_adsp *dsp) | |||
1782 | regions, le32_to_cpu(region->len), offset, | 1782 | regions, le32_to_cpu(region->len), offset, |
1783 | region_name); | 1783 | region_name); |
1784 | 1784 | ||
1785 | if ((pos + le32_to_cpu(region->len) + sizeof(*region)) > | 1785 | if (le32_to_cpu(region->len) > |
1786 | firmware->size) { | 1786 | firmware->size - pos - sizeof(*region)) { |
1787 | adsp_err(dsp, | 1787 | adsp_err(dsp, |
1788 | "%s.%d: %s region len %d bytes exceeds file length %zu\n", | 1788 | "%s.%d: %s region len %d bytes exceeds file length %zu\n", |
1789 | file, regions, region_name, | 1789 | file, regions, region_name, |
@@ -2253,7 +2253,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) | |||
2253 | 2253 | ||
2254 | blocks = 0; | 2254 | blocks = 0; |
2255 | while (pos < firmware->size && | 2255 | while (pos < firmware->size && |
2256 | pos - firmware->size > sizeof(*blk)) { | 2256 | sizeof(*blk) < firmware->size - pos) { |
2257 | blk = (void *)(&firmware->data[pos]); | 2257 | blk = (void *)(&firmware->data[pos]); |
2258 | 2258 | ||
2259 | type = le16_to_cpu(blk->type); | 2259 | type = le16_to_cpu(blk->type); |
@@ -2327,8 +2327,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) | |||
2327 | } | 2327 | } |
2328 | 2328 | ||
2329 | if (reg) { | 2329 | if (reg) { |
2330 | if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) > | 2330 | if (le32_to_cpu(blk->len) > |
2331 | firmware->size) { | 2331 | firmware->size - pos - sizeof(*blk)) { |
2332 | adsp_err(dsp, | 2332 | adsp_err(dsp, |
2333 | "%s.%d: %s region len %d bytes exceeds file length %zu\n", | 2333 | "%s.%d: %s region len %d bytes exceeds file length %zu\n", |
2334 | file, blocks, region_name, | 2334 | file, blocks, region_name, |
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 0f163abe4ba3..52c27a358933 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h | |||
@@ -260,8 +260,8 @@ | |||
260 | #define ASRFSTi_OUTPUT_FIFO_SHIFT 12 | 260 | #define ASRFSTi_OUTPUT_FIFO_SHIFT 12 |
261 | #define ASRFSTi_OUTPUT_FIFO_MASK (((1 << ASRFSTi_OUTPUT_FIFO_WIDTH) - 1) << ASRFSTi_OUTPUT_FIFO_SHIFT) | 261 | #define ASRFSTi_OUTPUT_FIFO_MASK (((1 << ASRFSTi_OUTPUT_FIFO_WIDTH) - 1) << ASRFSTi_OUTPUT_FIFO_SHIFT) |
262 | #define ASRFSTi_IAEi_SHIFT 11 | 262 | #define ASRFSTi_IAEi_SHIFT 11 |
263 | #define ASRFSTi_IAEi_MASK (1 << ASRFSTi_OAFi_SHIFT) | 263 | #define ASRFSTi_IAEi_MASK (1 << ASRFSTi_IAEi_SHIFT) |
264 | #define ASRFSTi_IAEi (1 << ASRFSTi_OAFi_SHIFT) | 264 | #define ASRFSTi_IAEi (1 << ASRFSTi_IAEi_SHIFT) |
265 | #define ASRFSTi_INPUT_FIFO_WIDTH 7 | 265 | #define ASRFSTi_INPUT_FIFO_WIDTH 7 |
266 | #define ASRFSTi_INPUT_FIFO_SHIFT 0 | 266 | #define ASRFSTi_INPUT_FIFO_SHIFT 0 |
267 | #define ASRFSTi_INPUT_FIFO_MASK ((1 << ASRFSTi_INPUT_FIFO_WIDTH) - 1) | 267 | #define ASRFSTi_INPUT_FIFO_MASK ((1 << ASRFSTi_INPUT_FIFO_WIDTH) - 1) |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index f2f51e06e22c..424bafaf51ef 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/ctype.h> | 38 | #include <linux/ctype.h> |
39 | #include <linux/device.h> | 39 | #include <linux/device.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/mutex.h> | ||
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
42 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
43 | #include <linux/of.h> | 44 | #include <linux/of.h> |
@@ -265,6 +266,8 @@ struct fsl_ssi_private { | |||
265 | 266 | ||
266 | u32 fifo_watermark; | 267 | u32 fifo_watermark; |
267 | u32 dma_maxburst; | 268 | u32 dma_maxburst; |
269 | |||
270 | struct mutex ac97_reg_lock; | ||
268 | }; | 271 | }; |
269 | 272 | ||
270 | /* | 273 | /* |
@@ -1260,11 +1263,13 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
1260 | if (reg > 0x7f) | 1263 | if (reg > 0x7f) |
1261 | return; | 1264 | return; |
1262 | 1265 | ||
1266 | mutex_lock(&fsl_ac97_data->ac97_reg_lock); | ||
1267 | |||
1263 | ret = clk_prepare_enable(fsl_ac97_data->clk); | 1268 | ret = clk_prepare_enable(fsl_ac97_data->clk); |
1264 | if (ret) { | 1269 | if (ret) { |
1265 | pr_err("ac97 write clk_prepare_enable failed: %d\n", | 1270 | pr_err("ac97 write clk_prepare_enable failed: %d\n", |
1266 | ret); | 1271 | ret); |
1267 | return; | 1272 | goto ret_unlock; |
1268 | } | 1273 | } |
1269 | 1274 | ||
1270 | lreg = reg << 12; | 1275 | lreg = reg << 12; |
@@ -1278,6 +1283,9 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
1278 | udelay(100); | 1283 | udelay(100); |
1279 | 1284 | ||
1280 | clk_disable_unprepare(fsl_ac97_data->clk); | 1285 | clk_disable_unprepare(fsl_ac97_data->clk); |
1286 | |||
1287 | ret_unlock: | ||
1288 | mutex_unlock(&fsl_ac97_data->ac97_reg_lock); | ||
1281 | } | 1289 | } |
1282 | 1290 | ||
1283 | static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, | 1291 | static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, |
@@ -1285,16 +1293,18 @@ static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, | |||
1285 | { | 1293 | { |
1286 | struct regmap *regs = fsl_ac97_data->regs; | 1294 | struct regmap *regs = fsl_ac97_data->regs; |
1287 | 1295 | ||
1288 | unsigned short val = -1; | 1296 | unsigned short val = 0; |
1289 | u32 reg_val; | 1297 | u32 reg_val; |
1290 | unsigned int lreg; | 1298 | unsigned int lreg; |
1291 | int ret; | 1299 | int ret; |
1292 | 1300 | ||
1301 | mutex_lock(&fsl_ac97_data->ac97_reg_lock); | ||
1302 | |||
1293 | ret = clk_prepare_enable(fsl_ac97_data->clk); | 1303 | ret = clk_prepare_enable(fsl_ac97_data->clk); |
1294 | if (ret) { | 1304 | if (ret) { |
1295 | pr_err("ac97 read clk_prepare_enable failed: %d\n", | 1305 | pr_err("ac97 read clk_prepare_enable failed: %d\n", |
1296 | ret); | 1306 | ret); |
1297 | return -1; | 1307 | goto ret_unlock; |
1298 | } | 1308 | } |
1299 | 1309 | ||
1300 | lreg = (reg & 0x7f) << 12; | 1310 | lreg = (reg & 0x7f) << 12; |
@@ -1309,6 +1319,8 @@ static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, | |||
1309 | 1319 | ||
1310 | clk_disable_unprepare(fsl_ac97_data->clk); | 1320 | clk_disable_unprepare(fsl_ac97_data->clk); |
1311 | 1321 | ||
1322 | ret_unlock: | ||
1323 | mutex_unlock(&fsl_ac97_data->ac97_reg_lock); | ||
1312 | return val; | 1324 | return val; |
1313 | } | 1325 | } |
1314 | 1326 | ||
@@ -1458,12 +1470,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1458 | sizeof(fsl_ssi_ac97_dai)); | 1470 | sizeof(fsl_ssi_ac97_dai)); |
1459 | 1471 | ||
1460 | fsl_ac97_data = ssi_private; | 1472 | fsl_ac97_data = ssi_private; |
1461 | |||
1462 | ret = snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev); | ||
1463 | if (ret) { | ||
1464 | dev_err(&pdev->dev, "could not set AC'97 ops\n"); | ||
1465 | return ret; | ||
1466 | } | ||
1467 | } else { | 1473 | } else { |
1468 | /* Initialize this copy of the CPU DAI driver structure */ | 1474 | /* Initialize this copy of the CPU DAI driver structure */ |
1469 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, | 1475 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, |
@@ -1574,6 +1580,15 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1574 | return ret; | 1580 | return ret; |
1575 | } | 1581 | } |
1576 | 1582 | ||
1583 | if (fsl_ssi_is_ac97(ssi_private)) { | ||
1584 | mutex_init(&ssi_private->ac97_reg_lock); | ||
1585 | ret = snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev); | ||
1586 | if (ret) { | ||
1587 | dev_err(&pdev->dev, "could not set AC'97 ops\n"); | ||
1588 | goto error_ac97_ops; | ||
1589 | } | ||
1590 | } | ||
1591 | |||
1577 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_ssi_component, | 1592 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_ssi_component, |
1578 | &ssi_private->cpu_dai_drv, 1); | 1593 | &ssi_private->cpu_dai_drv, 1); |
1579 | if (ret) { | 1594 | if (ret) { |
@@ -1657,6 +1672,13 @@ error_sound_card: | |||
1657 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); | 1672 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); |
1658 | 1673 | ||
1659 | error_asoc_register: | 1674 | error_asoc_register: |
1675 | if (fsl_ssi_is_ac97(ssi_private)) | ||
1676 | snd_soc_set_ac97_ops(NULL); | ||
1677 | |||
1678 | error_ac97_ops: | ||
1679 | if (fsl_ssi_is_ac97(ssi_private)) | ||
1680 | mutex_destroy(&ssi_private->ac97_reg_lock); | ||
1681 | |||
1660 | if (ssi_private->soc->imx) | 1682 | if (ssi_private->soc->imx) |
1661 | fsl_ssi_imx_clean(pdev, ssi_private); | 1683 | fsl_ssi_imx_clean(pdev, ssi_private); |
1662 | 1684 | ||
@@ -1675,8 +1697,10 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
1675 | if (ssi_private->soc->imx) | 1697 | if (ssi_private->soc->imx) |
1676 | fsl_ssi_imx_clean(pdev, ssi_private); | 1698 | fsl_ssi_imx_clean(pdev, ssi_private); |
1677 | 1699 | ||
1678 | if (fsl_ssi_is_ac97(ssi_private)) | 1700 | if (fsl_ssi_is_ac97(ssi_private)) { |
1679 | snd_soc_set_ac97_ops(NULL); | 1701 | snd_soc_set_ac97_ops(NULL); |
1702 | mutex_destroy(&ssi_private->ac97_reg_lock); | ||
1703 | } | ||
1680 | 1704 | ||
1681 | return 0; | 1705 | return 0; |
1682 | } | 1706 | } |
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index 6f9a8bcf20f3..6dcad0a8a0d0 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c | |||
@@ -101,7 +101,7 @@ static const struct snd_soc_dapm_route kabylake_map[] = { | |||
101 | { "ssp0 Tx", NULL, "spk_out" }, | 101 | { "ssp0 Tx", NULL, "spk_out" }, |
102 | 102 | ||
103 | { "AIF Playback", NULL, "ssp1 Tx" }, | 103 | { "AIF Playback", NULL, "ssp1 Tx" }, |
104 | { "ssp1 Tx", NULL, "hs_out" }, | 104 | { "ssp1 Tx", NULL, "codec1_out" }, |
105 | 105 | ||
106 | { "hs_in", NULL, "ssp1 Rx" }, | 106 | { "hs_in", NULL, "ssp1 Rx" }, |
107 | { "ssp1 Rx", NULL, "AIF Capture" }, | 107 | { "ssp1 Rx", NULL, "AIF Capture" }, |
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 6072164f2d43..271ae3c2c535 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c | |||
@@ -109,7 +109,7 @@ static const struct snd_soc_dapm_route kabylake_map[] = { | |||
109 | { "ssp0 Tx", NULL, "spk_out" }, | 109 | { "ssp0 Tx", NULL, "spk_out" }, |
110 | 110 | ||
111 | { "AIF Playback", NULL, "ssp1 Tx" }, | 111 | { "AIF Playback", NULL, "ssp1 Tx" }, |
112 | { "ssp1 Tx", NULL, "hs_out" }, | 112 | { "ssp1 Tx", NULL, "codec1_out" }, |
113 | 113 | ||
114 | { "hs_in", NULL, "ssp1 Rx" }, | 114 | { "hs_in", NULL, "ssp1 Rx" }, |
115 | { "ssp1 Rx", NULL, "AIF Capture" }, | 115 | { "ssp1 Rx", NULL, "AIF Capture" }, |
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c index d14c50a60289..3eaac41090ca 100644 --- a/sound/soc/intel/skylake/skl-nhlt.c +++ b/sound/soc/intel/skylake/skl-nhlt.c | |||
@@ -119,11 +119,16 @@ static bool skl_check_ep_match(struct device *dev, struct nhlt_endpoint *epnt, | |||
119 | 119 | ||
120 | if ((epnt->virtual_bus_id == instance_id) && | 120 | if ((epnt->virtual_bus_id == instance_id) && |
121 | (epnt->linktype == link_type) && | 121 | (epnt->linktype == link_type) && |
122 | (epnt->direction == dirn) && | 122 | (epnt->direction == dirn)) { |
123 | (epnt->device_type == dev_type)) | 123 | /* do not check dev_type for DMIC link type */ |
124 | return true; | 124 | if (epnt->linktype == NHLT_LINK_DMIC) |
125 | else | 125 | return true; |
126 | return false; | 126 | |
127 | if (epnt->device_type == dev_type) | ||
128 | return true; | ||
129 | } | ||
130 | |||
131 | return false; | ||
127 | } | 132 | } |
128 | 133 | ||
129 | struct nhlt_specific_cfg | 134 | struct nhlt_specific_cfg |
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index a072bcf209d2..81923da18ac2 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c | |||
@@ -2908,7 +2908,7 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt, | |||
2908 | break; | 2908 | break; |
2909 | 2909 | ||
2910 | default: | 2910 | default: |
2911 | dev_warn(bus->dev, "Control load not supported %d:%d:%d\n", | 2911 | dev_dbg(bus->dev, "Control load not supported %d:%d:%d\n", |
2912 | hdr->ops.get, hdr->ops.put, hdr->ops.info); | 2912 | hdr->ops.get, hdr->ops.put, hdr->ops.info); |
2913 | break; | 2913 | break; |
2914 | } | 2914 | } |
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index ee5055d47d13..a89fe9b6463b 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c | |||
@@ -322,26 +322,30 @@ static int rk_spdif_probe(struct platform_device *pdev) | |||
322 | spdif->mclk = devm_clk_get(&pdev->dev, "mclk"); | 322 | spdif->mclk = devm_clk_get(&pdev->dev, "mclk"); |
323 | if (IS_ERR(spdif->mclk)) { | 323 | if (IS_ERR(spdif->mclk)) { |
324 | dev_err(&pdev->dev, "Can't retrieve rk_spdif master clock\n"); | 324 | dev_err(&pdev->dev, "Can't retrieve rk_spdif master clock\n"); |
325 | return PTR_ERR(spdif->mclk); | 325 | ret = PTR_ERR(spdif->mclk); |
326 | goto err_disable_hclk; | ||
326 | } | 327 | } |
327 | 328 | ||
328 | ret = clk_prepare_enable(spdif->mclk); | 329 | ret = clk_prepare_enable(spdif->mclk); |
329 | if (ret) { | 330 | if (ret) { |
330 | dev_err(spdif->dev, "clock enable failed %d\n", ret); | 331 | dev_err(spdif->dev, "clock enable failed %d\n", ret); |
331 | return ret; | 332 | goto err_disable_clocks; |
332 | } | 333 | } |
333 | 334 | ||
334 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 335 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
335 | regs = devm_ioremap_resource(&pdev->dev, res); | 336 | regs = devm_ioremap_resource(&pdev->dev, res); |
336 | if (IS_ERR(regs)) | 337 | if (IS_ERR(regs)) { |
337 | return PTR_ERR(regs); | 338 | ret = PTR_ERR(regs); |
339 | goto err_disable_clocks; | ||
340 | } | ||
338 | 341 | ||
339 | spdif->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "hclk", regs, | 342 | spdif->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "hclk", regs, |
340 | &rk_spdif_regmap_config); | 343 | &rk_spdif_regmap_config); |
341 | if (IS_ERR(spdif->regmap)) { | 344 | if (IS_ERR(spdif->regmap)) { |
342 | dev_err(&pdev->dev, | 345 | dev_err(&pdev->dev, |
343 | "Failed to initialise managed register map\n"); | 346 | "Failed to initialise managed register map\n"); |
344 | return PTR_ERR(spdif->regmap); | 347 | ret = PTR_ERR(spdif->regmap); |
348 | goto err_disable_clocks; | ||
345 | } | 349 | } |
346 | 350 | ||
347 | spdif->playback_dma_data.addr = res->start + SPDIF_SMPDR; | 351 | spdif->playback_dma_data.addr = res->start + SPDIF_SMPDR; |
@@ -373,6 +377,10 @@ static int rk_spdif_probe(struct platform_device *pdev) | |||
373 | 377 | ||
374 | err_pm_runtime: | 378 | err_pm_runtime: |
375 | pm_runtime_disable(&pdev->dev); | 379 | pm_runtime_disable(&pdev->dev); |
380 | err_disable_clocks: | ||
381 | clk_disable_unprepare(spdif->mclk); | ||
382 | err_disable_hclk: | ||
383 | clk_disable_unprepare(spdif->hclk); | ||
376 | 384 | ||
377 | return ret; | 385 | return ret; |
378 | } | 386 | } |
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 8ddb08714faa..4672688cac32 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c | |||
@@ -222,7 +222,7 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod, | |||
222 | NULL, &val, NULL); | 222 | NULL, &val, NULL); |
223 | 223 | ||
224 | val = val << shift; | 224 | val = val << shift; |
225 | mask = 0xffff << shift; | 225 | mask = 0x0f1f << shift; |
226 | 226 | ||
227 | rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val); | 227 | rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val); |
228 | 228 | ||
@@ -250,7 +250,7 @@ int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod, | |||
250 | 250 | ||
251 | in = in << shift; | 251 | in = in << shift; |
252 | out = out << shift; | 252 | out = out << shift; |
253 | mask = 0xffff << shift; | 253 | mask = 0x0f1f << shift; |
254 | 254 | ||
255 | switch (id / 2) { | 255 | switch (id / 2) { |
256 | case 0: | 256 | case 0: |
@@ -380,7 +380,7 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate) | |||
380 | ckr = 0x80000000; | 380 | ckr = 0x80000000; |
381 | } | 381 | } |
382 | 382 | ||
383 | rsnd_mod_bset(adg_mod, BRGCKR, 0x80FF0000, adg->ckr | ckr); | 383 | rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr); |
384 | rsnd_mod_write(adg_mod, BRRA, adg->rbga); | 384 | rsnd_mod_write(adg_mod, BRRA, adg->rbga); |
385 | rsnd_mod_write(adg_mod, BRRB, adg->rbgb); | 385 | rsnd_mod_write(adg_mod, BRRB, adg->rbgb); |
386 | 386 | ||
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index c70eb2097816..f12a88a21dfa 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -1332,8 +1332,8 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
1332 | 1332 | ||
1333 | return snd_pcm_lib_preallocate_pages_for_all( | 1333 | return snd_pcm_lib_preallocate_pages_for_all( |
1334 | rtd->pcm, | 1334 | rtd->pcm, |
1335 | SNDRV_DMA_TYPE_CONTINUOUS, | 1335 | SNDRV_DMA_TYPE_DEV, |
1336 | snd_dma_continuous_data(GFP_KERNEL), | 1336 | rtd->card->snd_card->dev, |
1337 | PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); | 1337 | PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); |
1338 | } | 1338 | } |
1339 | 1339 | ||
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index fd557abfe390..4d750bdf8e24 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c | |||
@@ -26,10 +26,7 @@ | |||
26 | struct rsnd_dmaen { | 26 | struct rsnd_dmaen { |
27 | struct dma_chan *chan; | 27 | struct dma_chan *chan; |
28 | dma_cookie_t cookie; | 28 | dma_cookie_t cookie; |
29 | dma_addr_t dma_buf; | ||
30 | unsigned int dma_len; | 29 | unsigned int dma_len; |
31 | unsigned int dma_period; | ||
32 | unsigned int dma_cnt; | ||
33 | }; | 30 | }; |
34 | 31 | ||
35 | struct rsnd_dmapp { | 32 | struct rsnd_dmapp { |
@@ -71,38 +68,10 @@ static struct rsnd_mod mem = { | |||
71 | /* | 68 | /* |
72 | * Audio DMAC | 69 | * Audio DMAC |
73 | */ | 70 | */ |
74 | #define rsnd_dmaen_sync(dmaen, io, i) __rsnd_dmaen_sync(dmaen, io, i, 1) | ||
75 | #define rsnd_dmaen_unsync(dmaen, io, i) __rsnd_dmaen_sync(dmaen, io, i, 0) | ||
76 | static void __rsnd_dmaen_sync(struct rsnd_dmaen *dmaen, struct rsnd_dai_stream *io, | ||
77 | int i, int sync) | ||
78 | { | ||
79 | struct device *dev = dmaen->chan->device->dev; | ||
80 | enum dma_data_direction dir; | ||
81 | int is_play = rsnd_io_is_play(io); | ||
82 | dma_addr_t buf; | ||
83 | int len, max; | ||
84 | size_t period; | ||
85 | |||
86 | len = dmaen->dma_len; | ||
87 | period = dmaen->dma_period; | ||
88 | max = len / period; | ||
89 | i = i % max; | ||
90 | buf = dmaen->dma_buf + (period * i); | ||
91 | |||
92 | dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | ||
93 | |||
94 | if (sync) | ||
95 | dma_sync_single_for_device(dev, buf, period, dir); | ||
96 | else | ||
97 | dma_sync_single_for_cpu(dev, buf, period, dir); | ||
98 | } | ||
99 | |||
100 | static void __rsnd_dmaen_complete(struct rsnd_mod *mod, | 71 | static void __rsnd_dmaen_complete(struct rsnd_mod *mod, |
101 | struct rsnd_dai_stream *io) | 72 | struct rsnd_dai_stream *io) |
102 | { | 73 | { |
103 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 74 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
104 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | ||
105 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | ||
106 | bool elapsed = false; | 75 | bool elapsed = false; |
107 | unsigned long flags; | 76 | unsigned long flags; |
108 | 77 | ||
@@ -115,22 +84,9 @@ static void __rsnd_dmaen_complete(struct rsnd_mod *mod, | |||
115 | */ | 84 | */ |
116 | spin_lock_irqsave(&priv->lock, flags); | 85 | spin_lock_irqsave(&priv->lock, flags); |
117 | 86 | ||
118 | if (rsnd_io_is_working(io)) { | 87 | if (rsnd_io_is_working(io)) |
119 | rsnd_dmaen_unsync(dmaen, io, dmaen->dma_cnt); | ||
120 | |||
121 | /* | ||
122 | * Next period is already started. | ||
123 | * Let's sync Next Next period | ||
124 | * see | ||
125 | * rsnd_dmaen_start() | ||
126 | */ | ||
127 | rsnd_dmaen_sync(dmaen, io, dmaen->dma_cnt + 2); | ||
128 | |||
129 | elapsed = true; | 88 | elapsed = true; |
130 | 89 | ||
131 | dmaen->dma_cnt++; | ||
132 | } | ||
133 | |||
134 | spin_unlock_irqrestore(&priv->lock, flags); | 90 | spin_unlock_irqrestore(&priv->lock, flags); |
135 | 91 | ||
136 | if (elapsed) | 92 | if (elapsed) |
@@ -165,14 +121,8 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod, | |||
165 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 121 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
166 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); | 122 | struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); |
167 | 123 | ||
168 | if (dmaen->chan) { | 124 | if (dmaen->chan) |
169 | int is_play = rsnd_io_is_play(io); | ||
170 | |||
171 | dmaengine_terminate_all(dmaen->chan); | 125 | dmaengine_terminate_all(dmaen->chan); |
172 | dma_unmap_single(dmaen->chan->device->dev, | ||
173 | dmaen->dma_buf, dmaen->dma_len, | ||
174 | is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
175 | } | ||
176 | 126 | ||
177 | return 0; | 127 | return 0; |
178 | } | 128 | } |
@@ -237,11 +187,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod, | |||
237 | struct device *dev = rsnd_priv_to_dev(priv); | 187 | struct device *dev = rsnd_priv_to_dev(priv); |
238 | struct dma_async_tx_descriptor *desc; | 188 | struct dma_async_tx_descriptor *desc; |
239 | struct dma_slave_config cfg = {}; | 189 | struct dma_slave_config cfg = {}; |
240 | dma_addr_t buf; | ||
241 | size_t len; | ||
242 | size_t period; | ||
243 | int is_play = rsnd_io_is_play(io); | 190 | int is_play = rsnd_io_is_play(io); |
244 | int i; | ||
245 | int ret; | 191 | int ret; |
246 | 192 | ||
247 | cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; | 193 | cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; |
@@ -258,19 +204,10 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod, | |||
258 | if (ret < 0) | 204 | if (ret < 0) |
259 | return ret; | 205 | return ret; |
260 | 206 | ||
261 | len = snd_pcm_lib_buffer_bytes(substream); | ||
262 | period = snd_pcm_lib_period_bytes(substream); | ||
263 | buf = dma_map_single(dmaen->chan->device->dev, | ||
264 | substream->runtime->dma_area, | ||
265 | len, | ||
266 | is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
267 | if (dma_mapping_error(dmaen->chan->device->dev, buf)) { | ||
268 | dev_err(dev, "dma map failed\n"); | ||
269 | return -EIO; | ||
270 | } | ||
271 | |||
272 | desc = dmaengine_prep_dma_cyclic(dmaen->chan, | 207 | desc = dmaengine_prep_dma_cyclic(dmaen->chan, |
273 | buf, len, period, | 208 | substream->runtime->dma_addr, |
209 | snd_pcm_lib_buffer_bytes(substream), | ||
210 | snd_pcm_lib_period_bytes(substream), | ||
274 | is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, | 211 | is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, |
275 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 212 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
276 | 213 | ||
@@ -282,18 +219,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod, | |||
282 | desc->callback = rsnd_dmaen_complete; | 219 | desc->callback = rsnd_dmaen_complete; |
283 | desc->callback_param = rsnd_mod_get(dma); | 220 | desc->callback_param = rsnd_mod_get(dma); |
284 | 221 | ||
285 | dmaen->dma_buf = buf; | 222 | dmaen->dma_len = snd_pcm_lib_buffer_bytes(substream); |
286 | dmaen->dma_len = len; | ||
287 | dmaen->dma_period = period; | ||
288 | dmaen->dma_cnt = 0; | ||
289 | |||
290 | /* | ||
291 | * synchronize this and next period | ||
292 | * see | ||
293 | * __rsnd_dmaen_complete() | ||
294 | */ | ||
295 | for (i = 0; i < 2; i++) | ||
296 | rsnd_dmaen_sync(dmaen, io, i); | ||
297 | 223 | ||
298 | dmaen->cookie = dmaengine_submit(desc); | 224 | dmaen->cookie = dmaengine_submit(desc); |
299 | if (dmaen->cookie < 0) { | 225 | if (dmaen->cookie < 0) { |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index fece1e5f582f..cbf3bf312d23 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -446,25 +446,29 @@ static bool rsnd_ssi_pointer_update(struct rsnd_mod *mod, | |||
446 | int byte) | 446 | int byte) |
447 | { | 447 | { |
448 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 448 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
449 | bool ret = false; | ||
450 | int byte_pos; | ||
449 | 451 | ||
450 | ssi->byte_pos += byte; | 452 | byte_pos = ssi->byte_pos + byte; |
451 | 453 | ||
452 | if (ssi->byte_pos >= ssi->next_period_byte) { | 454 | if (byte_pos >= ssi->next_period_byte) { |
453 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 455 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
454 | 456 | ||
455 | ssi->period_pos++; | 457 | ssi->period_pos++; |
456 | ssi->next_period_byte += ssi->byte_per_period; | 458 | ssi->next_period_byte += ssi->byte_per_period; |
457 | 459 | ||
458 | if (ssi->period_pos >= runtime->periods) { | 460 | if (ssi->period_pos >= runtime->periods) { |
459 | ssi->byte_pos = 0; | 461 | byte_pos = 0; |
460 | ssi->period_pos = 0; | 462 | ssi->period_pos = 0; |
461 | ssi->next_period_byte = ssi->byte_per_period; | 463 | ssi->next_period_byte = ssi->byte_per_period; |
462 | } | 464 | } |
463 | 465 | ||
464 | return true; | 466 | ret = true; |
465 | } | 467 | } |
466 | 468 | ||
467 | return false; | 469 | WRITE_ONCE(ssi->byte_pos, byte_pos); |
470 | |||
471 | return ret; | ||
468 | } | 472 | } |
469 | 473 | ||
470 | /* | 474 | /* |
@@ -838,7 +842,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod, | |||
838 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 842 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
839 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 843 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
840 | 844 | ||
841 | *pointer = bytes_to_frames(runtime, ssi->byte_pos); | 845 | *pointer = bytes_to_frames(runtime, READ_ONCE(ssi->byte_pos)); |
842 | 846 | ||
843 | return 0; | 847 | return 0; |
844 | } | 848 | } |
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 4d948757d300..6ff8a36c2c82 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c | |||
@@ -125,6 +125,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, | |||
125 | { | 125 | { |
126 | int hdmi = rsnd_ssi_hdmi_port(io); | 126 | int hdmi = rsnd_ssi_hdmi_port(io); |
127 | int ret; | 127 | int ret; |
128 | u32 mode = 0; | ||
128 | 129 | ||
129 | ret = rsnd_ssiu_init(mod, io, priv); | 130 | ret = rsnd_ssiu_init(mod, io, priv); |
130 | if (ret < 0) | 131 | if (ret < 0) |
@@ -136,9 +137,11 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, | |||
136 | * see | 137 | * see |
137 | * rsnd_ssi_config_init() | 138 | * rsnd_ssi_config_init() |
138 | */ | 139 | */ |
139 | rsnd_mod_write(mod, SSI_MODE, 0x1); | 140 | mode = 0x1; |
140 | } | 141 | } |
141 | 142 | ||
143 | rsnd_mod_write(mod, SSI_MODE, mode); | ||
144 | |||
142 | if (rsnd_ssi_use_busif(io)) { | 145 | if (rsnd_ssi_use_busif(io)) { |
143 | rsnd_mod_write(mod, SSI_BUSIF_ADINR, | 146 | rsnd_mod_write(mod, SSI_BUSIF_ADINR, |
144 | rsnd_get_adinr_bit(mod, io) | | 147 | rsnd_get_adinr_bit(mod, io) | |
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index e2450c8e88e6..a8c3a33dd185 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c | |||
@@ -523,21 +523,23 @@ static int do_show(int argc, char **argv) | |||
523 | break; | 523 | break; |
524 | p_err("can't get next map: %s%s", strerror(errno), | 524 | p_err("can't get next map: %s%s", strerror(errno), |
525 | errno == EINVAL ? " -- kernel too old?" : ""); | 525 | errno == EINVAL ? " -- kernel too old?" : ""); |
526 | return -1; | 526 | break; |
527 | } | 527 | } |
528 | 528 | ||
529 | fd = bpf_map_get_fd_by_id(id); | 529 | fd = bpf_map_get_fd_by_id(id); |
530 | if (fd < 0) { | 530 | if (fd < 0) { |
531 | if (errno == ENOENT) | ||
532 | continue; | ||
531 | p_err("can't get map by id (%u): %s", | 533 | p_err("can't get map by id (%u): %s", |
532 | id, strerror(errno)); | 534 | id, strerror(errno)); |
533 | return -1; | 535 | break; |
534 | } | 536 | } |
535 | 537 | ||
536 | err = bpf_obj_get_info_by_fd(fd, &info, &len); | 538 | err = bpf_obj_get_info_by_fd(fd, &info, &len); |
537 | if (err) { | 539 | if (err) { |
538 | p_err("can't get map info: %s", strerror(errno)); | 540 | p_err("can't get map info: %s", strerror(errno)); |
539 | close(fd); | 541 | close(fd); |
540 | return -1; | 542 | break; |
541 | } | 543 | } |
542 | 544 | ||
543 | if (json_output) | 545 | if (json_output) |
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 42ee8892549c..fd0873178503 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -383,6 +383,8 @@ static int do_show(int argc, char **argv) | |||
383 | 383 | ||
384 | fd = bpf_prog_get_fd_by_id(id); | 384 | fd = bpf_prog_get_fd_by_id(id); |
385 | if (fd < 0) { | 385 | if (fd < 0) { |
386 | if (errno == ENOENT) | ||
387 | continue; | ||
386 | p_err("can't get prog by id (%u): %s", | 388 | p_err("can't get prog by id (%u): %s", |
387 | id, strerror(errno)); | 389 | id, strerror(errno)); |
388 | err = -1; | 390 | err = -1; |
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index f1fdb36269f2..1304753d29ea 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile | |||
@@ -41,7 +41,7 @@ $(BPFOBJ): force | |||
41 | CLANG ?= clang | 41 | CLANG ?= clang |
42 | LLC ?= llc | 42 | LLC ?= llc |
43 | 43 | ||
44 | PROBE := $(shell llc -march=bpf -mcpu=probe -filetype=null /dev/null 2>&1) | 44 | PROBE := $(shell $(LLC) -march=bpf -mcpu=probe -filetype=null /dev/null 2>&1) |
45 | 45 | ||
46 | # Let newer LLVM versions transparently probe the kernel for availability | 46 | # Let newer LLVM versions transparently probe the kernel for availability |
47 | # of full BPF instruction set. | 47 | # of full BPF instruction set. |
diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c index 66e5ce5b91f0..0304ffb714f2 100644 --- a/tools/testing/selftests/x86/ldt_gdt.c +++ b/tools/testing/selftests/x86/ldt_gdt.c | |||
@@ -627,13 +627,10 @@ static void do_multicpu_tests(void) | |||
627 | static int finish_exec_test(void) | 627 | static int finish_exec_test(void) |
628 | { | 628 | { |
629 | /* | 629 | /* |
630 | * In a sensible world, this would be check_invalid_segment(0, 1); | 630 | * Older kernel versions did inherit the LDT on exec() which is |
631 | * For better or for worse, though, the LDT is inherited across exec. | 631 | * wrong because exec() starts from a clean state. |
632 | * We can probably change this safely, but for now we test it. | ||
633 | */ | 632 | */ |
634 | check_valid_segment(0, 1, | 633 | check_invalid_segment(0, 1); |
635 | AR_DPL3 | AR_TYPE_XRCODE | AR_S | AR_P | AR_DB, | ||
636 | 42, true); | ||
637 | 634 | ||
638 | return nerrs ? 1 : 0; | 635 | return nerrs ? 1 : 0; |
639 | } | 636 | } |