Contents of /trunk/kernel-magellan/patches-3.9/0107-3.9.8-all-fixes.patch
Parent Directory | Revision Log
Revision 2222 -
(show annotations)
(download)
Mon Jul 1 09:43:39 2013 UTC (11 years, 2 months ago) by niro
File size: 144858 byte(s)
Mon Jul 1 09:43:39 2013 UTC (11 years, 2 months ago) by niro
File size: 144858 byte(s)
-linux-3.9.8
1 | diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig |
2 | index 1cacda4..70cd012 100644 |
3 | --- a/arch/arm/Kconfig |
4 | +++ b/arch/arm/Kconfig |
5 | @@ -1306,6 +1306,16 @@ config PL310_ERRATA_588369 |
6 | is not correctly implemented in PL310 as clean lines are not |
7 | invalidated as a result of these operations. |
8 | |
9 | +config ARM_ERRATA_643719 |
10 | + bool "ARM errata: LoUIS bit field in CLIDR register is incorrect" |
11 | + depends on CPU_V7 && SMP |
12 | + help |
13 | + This option enables the workaround for the 643719 Cortex-A9 (prior to |
14 | + r1p0) erratum. On affected cores the LoUIS bit field of the CLIDR |
15 | + register returns zero when it should return one. The workaround |
16 | + corrects this value, ensuring cache maintenance operations which use |
17 | + it behave as intended and avoiding data corruption. |
18 | + |
19 | config ARM_ERRATA_720789 |
20 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" |
21 | depends on CPU_V7 |
22 | diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S |
23 | index 15451ee..515b000 100644 |
24 | --- a/arch/arm/mm/cache-v7.S |
25 | +++ b/arch/arm/mm/cache-v7.S |
26 | @@ -92,6 +92,14 @@ ENTRY(v7_flush_dcache_louis) |
27 | mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr |
28 | ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr |
29 | ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr |
30 | +#ifdef CONFIG_ARM_ERRATA_643719 |
31 | + ALT_SMP(mrceq p15, 0, r2, c0, c0, 0) @ read main ID register |
32 | + ALT_UP(moveq pc, lr) @ LoUU is zero, so nothing to do |
33 | + ldreq r1, =0x410fc090 @ ID of ARM Cortex A9 r0p? |
34 | + biceq r2, r2, #0x0000000f @ clear minor revision number |
35 | + teqeq r2, r1 @ test for errata affected core and if so... |
36 | + orreqs r3, #(1 << 21) @ fix LoUIS value (and set flags state to 'ne') |
37 | +#endif |
38 | ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2 |
39 | ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2 |
40 | moveq pc, lr @ return if level == 0 |
41 | diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S |
42 | index f584d3f..77470d7 100644 |
43 | --- a/arch/arm/mm/proc-v7.S |
44 | +++ b/arch/arm/mm/proc-v7.S |
45 | @@ -407,8 +407,8 @@ __v7_ca9mp_proc_info: |
46 | */ |
47 | .type __v7_pj4b_proc_info, #object |
48 | __v7_pj4b_proc_info: |
49 | - .long 0x562f5840 |
50 | - .long 0xfffffff0 |
51 | + .long 0x560f5800 |
52 | + .long 0xff0fff00 |
53 | __v7_proc __v7_pj4b_setup |
54 | .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info |
55 | #endif /* CONFIG_ARM_LPAE */ |
56 | diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c |
57 | index 1e49e5eb..9ba33c4 100644 |
58 | --- a/arch/arm64/kernel/perf_event.c |
59 | +++ b/arch/arm64/kernel/perf_event.c |
60 | @@ -1336,6 +1336,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry, |
61 | return; |
62 | } |
63 | |
64 | + perf_callchain_store(entry, regs->pc); |
65 | tail = (struct frame_tail __user *)regs->regs[29]; |
66 | |
67 | while (entry->nr < PERF_MAX_STACK_DEPTH && |
68 | diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig |
69 | index 0339181..827d4fe 100644 |
70 | --- a/arch/parisc/Kconfig |
71 | +++ b/arch/parisc/Kconfig |
72 | @@ -241,6 +241,14 @@ config SMP |
73 | |
74 | If you don't know what to do here, say N. |
75 | |
76 | +config IRQSTACKS |
77 | + bool "Use separate kernel stacks when processing interrupts" |
78 | + default y |
79 | + help |
80 | + If you say Y here the kernel will use separate kernel stacks |
81 | + for handling hard and soft interrupts. This can help avoid |
82 | + overflowing the process kernel stacks. |
83 | + |
84 | config HOTPLUG_CPU |
85 | bool |
86 | default y if SMP |
87 | diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug |
88 | index 7305ac8..eb0225f 100644 |
89 | --- a/arch/parisc/Kconfig.debug |
90 | +++ b/arch/parisc/Kconfig.debug |
91 | @@ -27,3 +27,14 @@ config DEBUG_STRICT_USER_COPY_CHECKS |
92 | If unsure, or if you run an older (pre 4.4) gcc, say N. |
93 | |
94 | endmenu |
95 | + |
96 | +config DEBUG_STACKOVERFLOW |
97 | + bool "Check for stack overflows" |
98 | + default y |
99 | + depends on DEBUG_KERNEL |
100 | + ---help--- |
101 | + Say Y here if you want to check the overflows of kernel, IRQ |
102 | + and exception stacks. This option will cause messages of the |
103 | + stacks in detail when free stack space drops below a certain |
104 | + limit. |
105 | + If in doubt, say "N". |
106 | diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile |
107 | index 1976900..96ec398 100644 |
108 | --- a/arch/parisc/Makefile |
109 | +++ b/arch/parisc/Makefile |
110 | @@ -66,7 +66,7 @@ KBUILD_CFLAGS_KERNEL += -mlong-calls |
111 | endif |
112 | |
113 | # select which processor to optimise for |
114 | -cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100 |
115 | +cflags-$(CONFIG_PA7000) += -march=1.1 -mschedule=7100 |
116 | cflags-$(CONFIG_PA7200) += -march=1.1 -mschedule=7200 |
117 | cflags-$(CONFIG_PA7100LC) += -march=1.1 -mschedule=7100LC |
118 | cflags-$(CONFIG_PA7300LC) += -march=1.1 -mschedule=7300 |
119 | diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h |
120 | index 89fb400..0da8482 100644 |
121 | --- a/arch/parisc/include/asm/assembly.h |
122 | +++ b/arch/parisc/include/asm/assembly.h |
123 | @@ -438,7 +438,6 @@ |
124 | SAVE_SP (%sr4, PT_SR4 (\regs)) |
125 | SAVE_SP (%sr5, PT_SR5 (\regs)) |
126 | SAVE_SP (%sr6, PT_SR6 (\regs)) |
127 | - SAVE_SP (%sr7, PT_SR7 (\regs)) |
128 | |
129 | SAVE_CR (%cr17, PT_IASQ0(\regs)) |
130 | mtctl %r0, %cr17 |
131 | diff --git a/arch/parisc/include/asm/hardirq.h b/arch/parisc/include/asm/hardirq.h |
132 | index 0d68184..241c345 100644 |
133 | --- a/arch/parisc/include/asm/hardirq.h |
134 | +++ b/arch/parisc/include/asm/hardirq.h |
135 | @@ -1,11 +1,47 @@ |
136 | /* hardirq.h: PA-RISC hard IRQ support. |
137 | * |
138 | * Copyright (C) 2001 Matthew Wilcox <matthew@wil.cx> |
139 | + * Copyright (C) 2013 Helge Deller <deller@gmx.de> |
140 | */ |
141 | |
142 | #ifndef _PARISC_HARDIRQ_H |
143 | #define _PARISC_HARDIRQ_H |
144 | |
145 | -#include <asm-generic/hardirq.h> |
146 | +#include <linux/cache.h> |
147 | +#include <linux/threads.h> |
148 | +#include <linux/irq.h> |
149 | + |
150 | +#ifdef CONFIG_IRQSTACKS |
151 | +#define __ARCH_HAS_DO_SOFTIRQ |
152 | +#endif |
153 | + |
154 | +typedef struct { |
155 | + unsigned int __softirq_pending; |
156 | + unsigned int kernel_stack_usage; |
157 | + unsigned int irq_stack_usage; |
158 | +#ifdef CONFIG_SMP |
159 | + unsigned int irq_resched_count; |
160 | + unsigned int irq_call_count; |
161 | +#endif |
162 | + unsigned int irq_unaligned_count; |
163 | + unsigned int irq_fpassist_count; |
164 | + unsigned int irq_tlb_count; |
165 | +} ____cacheline_aligned irq_cpustat_t; |
166 | + |
167 | +DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); |
168 | + |
169 | +#define __ARCH_IRQ_STAT |
170 | +#define __IRQ_STAT(cpu, member) (irq_stat[cpu].member) |
171 | +#define inc_irq_stat(member) this_cpu_inc(irq_stat.member) |
172 | +#define __inc_irq_stat(member) __this_cpu_inc(irq_stat.member) |
173 | +#define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending) |
174 | + |
175 | +#define __ARCH_SET_SOFTIRQ_PENDING |
176 | + |
177 | +#define set_softirq_pending(x) \ |
178 | + this_cpu_write(irq_stat.__softirq_pending, (x)) |
179 | +#define or_softirq_pending(x) this_cpu_or(irq_stat.__softirq_pending, (x)) |
180 | + |
181 | +#define ack_bad_irq(irq) WARN(1, "unexpected IRQ trap at vector %02x\n", irq) |
182 | |
183 | #endif /* _PARISC_HARDIRQ_H */ |
184 | diff --git a/arch/parisc/include/asm/mmzone.h b/arch/parisc/include/asm/mmzone.h |
185 | index 0e625ab..b6b34a0 100644 |
186 | --- a/arch/parisc/include/asm/mmzone.h |
187 | +++ b/arch/parisc/include/asm/mmzone.h |
188 | @@ -27,7 +27,7 @@ extern struct node_map_data node_data[]; |
189 | |
190 | #define PFNNID_SHIFT (30 - PAGE_SHIFT) |
191 | #define PFNNID_MAP_MAX 512 /* support 512GB */ |
192 | -extern unsigned char pfnnid_map[PFNNID_MAP_MAX]; |
193 | +extern signed char pfnnid_map[PFNNID_MAP_MAX]; |
194 | |
195 | #ifndef CONFIG_64BIT |
196 | #define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT)) |
197 | @@ -39,17 +39,14 @@ extern unsigned char pfnnid_map[PFNNID_MAP_MAX]; |
198 | static inline int pfn_to_nid(unsigned long pfn) |
199 | { |
200 | unsigned int i; |
201 | - unsigned char r; |
202 | |
203 | if (unlikely(pfn_is_io(pfn))) |
204 | return 0; |
205 | |
206 | i = pfn >> PFNNID_SHIFT; |
207 | BUG_ON(i >= ARRAY_SIZE(pfnnid_map)); |
208 | - r = pfnnid_map[i]; |
209 | - BUG_ON(r == 0xff); |
210 | |
211 | - return (int)r; |
212 | + return pfnnid_map[i]; |
213 | } |
214 | |
215 | static inline int pfn_valid(int pfn) |
216 | diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h |
217 | index 3234f49..4651540 100644 |
218 | --- a/arch/parisc/include/asm/pci.h |
219 | +++ b/arch/parisc/include/asm/pci.h |
220 | @@ -225,4 +225,9 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) |
221 | return channel ? 15 : 14; |
222 | } |
223 | |
224 | +#define HAVE_PCI_MMAP |
225 | + |
226 | +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
227 | + enum pci_mmap_state mmap_state, int write_combine); |
228 | + |
229 | #endif /* __ASM_PARISC_PCI_H */ |
230 | diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h |
231 | index 09b54a5..cc2290a 100644 |
232 | --- a/arch/parisc/include/asm/processor.h |
233 | +++ b/arch/parisc/include/asm/processor.h |
234 | @@ -17,11 +17,8 @@ |
235 | #include <asm/ptrace.h> |
236 | #include <asm/types.h> |
237 | #include <asm/percpu.h> |
238 | - |
239 | #endif /* __ASSEMBLY__ */ |
240 | |
241 | -#define KERNEL_STACK_SIZE (4*PAGE_SIZE) |
242 | - |
243 | /* |
244 | * Default implementation of macro that returns current |
245 | * instruction pointer ("program counter"). |
246 | @@ -97,7 +94,6 @@ struct cpuinfo_parisc { |
247 | unsigned long txn_addr; /* MMIO addr of EIR or id_eid */ |
248 | #ifdef CONFIG_SMP |
249 | unsigned long pending_ipi; /* bitmap of type ipi_message_type */ |
250 | - unsigned long ipi_count; /* number ipi Interrupts */ |
251 | #endif |
252 | unsigned long bh_count; /* number of times bh was invoked */ |
253 | unsigned long prof_counter; /* per CPU profiling support */ |
254 | diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h |
255 | index d1fb79a..3ebe6c4 100644 |
256 | --- a/arch/parisc/include/asm/thread_info.h |
257 | +++ b/arch/parisc/include/asm/thread_info.h |
258 | @@ -40,7 +40,7 @@ struct thread_info { |
259 | |
260 | /* thread information allocation */ |
261 | |
262 | -#define THREAD_SIZE_ORDER 2 |
263 | +#define THREAD_SIZE_ORDER 2 /* PA-RISC requires at least 16k stack */ |
264 | /* Be sure to hunt all references to this down when you change the size of |
265 | * the kernel stack */ |
266 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
267 | diff --git a/arch/parisc/include/asm/tlbflush.h b/arch/parisc/include/asm/tlbflush.h |
268 | index 8f1a810..5273da9 100644 |
269 | --- a/arch/parisc/include/asm/tlbflush.h |
270 | +++ b/arch/parisc/include/asm/tlbflush.h |
271 | @@ -22,6 +22,8 @@ extern spinlock_t pa_tlb_lock; |
272 | extern void flush_tlb_all(void); |
273 | extern void flush_tlb_all_local(void *); |
274 | |
275 | +#define smp_flush_tlb_all() flush_tlb_all() |
276 | + |
277 | /* |
278 | * flush_tlb_mm() |
279 | * |
280 | diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c |
281 | index 83ded26..65fb4cb 100644 |
282 | --- a/arch/parisc/kernel/cache.c |
283 | +++ b/arch/parisc/kernel/cache.c |
284 | @@ -606,7 +606,7 @@ void clear_user_highpage(struct page *page, unsigned long vaddr) |
285 | /* Clear using TMPALIAS region. The page doesn't need to |
286 | be flushed but the kernel mapping needs to be purged. */ |
287 | |
288 | - vto = kmap_atomic(page, KM_USER0); |
289 | + vto = kmap_atomic(page); |
290 | |
291 | /* The PA-RISC 2.0 Architecture book states on page F-6: |
292 | "Before a write-capable translation is enabled, *all* |
293 | @@ -641,8 +641,8 @@ void copy_user_highpage(struct page *to, struct page *from, |
294 | the `to' page must be flushed in copy_user_page_asm since |
295 | it can be used to bring in executable code. */ |
296 | |
297 | - vfrom = kmap_atomic(from, KM_USER0); |
298 | - vto = kmap_atomic(to, KM_USER1); |
299 | + vfrom = kmap_atomic(from); |
300 | + vto = kmap_atomic(to); |
301 | |
302 | purge_kernel_dcache_page_asm((unsigned long)vto); |
303 | purge_tlb_start(flags); |
304 | diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c |
305 | index 5709c5e..14285ca 100644 |
306 | --- a/arch/parisc/kernel/drivers.c |
307 | +++ b/arch/parisc/kernel/drivers.c |
308 | @@ -394,7 +394,7 @@ EXPORT_SYMBOL(print_pci_hwpath); |
309 | static void setup_bus_id(struct parisc_device *padev) |
310 | { |
311 | struct hardware_path path; |
312 | - char name[20]; |
313 | + char name[28]; |
314 | char *output = name; |
315 | int i; |
316 | |
317 | diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S |
318 | index 897bce4..950699c 100644 |
319 | --- a/arch/parisc/kernel/entry.S |
320 | +++ b/arch/parisc/kernel/entry.S |
321 | @@ -65,15 +65,11 @@ |
322 | rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */ |
323 | mtsp %r0, %sr4 |
324 | mtsp %r0, %sr5 |
325 | - mfsp %sr7, %r1 |
326 | - or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */ |
327 | - mtsp %r1, %sr3 |
328 | + mtsp %r0, %sr6 |
329 | tovirt_r1 %r29 |
330 | load32 KERNEL_PSW, %r1 |
331 | |
332 | rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */ |
333 | - mtsp %r0, %sr6 |
334 | - mtsp %r0, %sr7 |
335 | mtctl %r0, %cr17 /* Clear IIASQ tail */ |
336 | mtctl %r0, %cr17 /* Clear IIASQ head */ |
337 | mtctl %r1, %ipsw |
338 | @@ -119,17 +115,20 @@ |
339 | |
340 | /* we save the registers in the task struct */ |
341 | |
342 | + copy %r30, %r17 |
343 | mfctl %cr30, %r1 |
344 | + ldo THREAD_SZ_ALGN(%r1), %r30 |
345 | + mtsp %r0,%sr7 |
346 | + mtsp %r16,%sr3 |
347 | tophys %r1,%r9 |
348 | LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */ |
349 | tophys %r1,%r9 |
350 | ldo TASK_REGS(%r9),%r9 |
351 | - STREG %r30, PT_GR30(%r9) |
352 | + STREG %r17,PT_GR30(%r9) |
353 | STREG %r29,PT_GR29(%r9) |
354 | STREG %r26,PT_GR26(%r9) |
355 | + STREG %r16,PT_SR7(%r9) |
356 | copy %r9,%r29 |
357 | - mfctl %cr30, %r1 |
358 | - ldo THREAD_SZ_ALGN(%r1), %r30 |
359 | .endm |
360 | |
361 | .macro get_stack_use_r30 |
362 | @@ -137,10 +136,12 @@ |
363 | /* we put a struct pt_regs on the stack and save the registers there */ |
364 | |
365 | tophys %r30,%r9 |
366 | - STREG %r30,PT_GR30(%r9) |
367 | + copy %r30,%r1 |
368 | ldo PT_SZ_ALGN(%r30),%r30 |
369 | + STREG %r1,PT_GR30(%r9) |
370 | STREG %r29,PT_GR29(%r9) |
371 | STREG %r26,PT_GR26(%r9) |
372 | + STREG %r16,PT_SR7(%r9) |
373 | copy %r9,%r29 |
374 | .endm |
375 | |
376 | @@ -2013,6 +2014,47 @@ ftrace_stub: |
377 | ENDPROC(return_to_handler) |
378 | #endif /* CONFIG_FUNCTION_TRACER */ |
379 | |
380 | +#ifdef CONFIG_IRQSTACKS |
381 | +/* void call_on_stack(unsigned long param1, void *func, |
382 | + unsigned long new_stack) */ |
383 | +ENTRY(call_on_stack) |
384 | + copy %sp, %r1 |
385 | + |
386 | + /* Regarding the HPPA calling conventions for function pointers, |
387 | + we assume the PIC register is not changed across call. For |
388 | + CONFIG_64BIT, the argument pointer is left to point at the |
389 | + argument region allocated for the call to call_on_stack. */ |
390 | +# ifdef CONFIG_64BIT |
391 | + /* Switch to new stack. We allocate two 128 byte frames. */ |
392 | + ldo 256(%arg2), %sp |
393 | + /* Save previous stack pointer and return pointer in frame marker */ |
394 | + STREG %rp, -144(%sp) |
395 | + /* Calls always use function descriptor */ |
396 | + LDREG 16(%arg1), %arg1 |
397 | + bve,l (%arg1), %rp |
398 | + STREG %r1, -136(%sp) |
399 | + LDREG -144(%sp), %rp |
400 | + bve (%rp) |
401 | + LDREG -136(%sp), %sp |
402 | +# else |
403 | + /* Switch to new stack. We allocate two 64 byte frames. */ |
404 | + ldo 128(%arg2), %sp |
405 | + /* Save previous stack pointer and return pointer in frame marker */ |
406 | + STREG %r1, -68(%sp) |
407 | + STREG %rp, -84(%sp) |
408 | + /* Calls use function descriptor if PLABEL bit is set */ |
409 | + bb,>=,n %arg1, 30, 1f |
410 | + depwi 0,31,2, %arg1 |
411 | + LDREG 0(%arg1), %arg1 |
412 | +1: |
413 | + be,l 0(%sr4,%arg1), %sr0, %r31 |
414 | + copy %r31, %rp |
415 | + LDREG -84(%sp), %rp |
416 | + bv (%rp) |
417 | + LDREG -68(%sp), %sp |
418 | +# endif /* CONFIG_64BIT */ |
419 | +ENDPROC(call_on_stack) |
420 | +#endif /* CONFIG_IRQSTACKS */ |
421 | |
422 | get_register: |
423 | /* |
424 | diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c |
425 | index f7752f6..8722756 100644 |
426 | --- a/arch/parisc/kernel/hardware.c |
427 | +++ b/arch/parisc/kernel/hardware.c |
428 | @@ -222,6 +222,7 @@ static struct hp_hardware hp_hardware_list[] = { |
429 | {HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"}, |
430 | {HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"}, |
431 | {HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"}, |
432 | + {HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"}, |
433 | {HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"}, |
434 | {HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"}, |
435 | {HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"}, |
436 | @@ -1204,6 +1205,7 @@ static struct hp_hardware hp_hardware_list[] = { |
437 | {HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"}, |
438 | {HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"}, |
439 | {HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"}, |
440 | + {HPHW_FIO, 0x076, 0x000AD, 0x00, "Crestone Peak RS-232"}, |
441 | {HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, |
442 | {HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, |
443 | {HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, |
444 | diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c |
445 | index 8094d3e..2e6443b 100644 |
446 | --- a/arch/parisc/kernel/irq.c |
447 | +++ b/arch/parisc/kernel/irq.c |
448 | @@ -27,11 +27,11 @@ |
449 | #include <linux/interrupt.h> |
450 | #include <linux/kernel_stat.h> |
451 | #include <linux/seq_file.h> |
452 | -#include <linux/spinlock.h> |
453 | #include <linux/types.h> |
454 | #include <asm/io.h> |
455 | |
456 | #include <asm/smp.h> |
457 | +#include <asm/ldcw.h> |
458 | |
459 | #undef PARISC_IRQ_CR16_COUNTS |
460 | |
461 | @@ -152,6 +152,53 @@ static struct irq_chip cpu_interrupt_type = { |
462 | .irq_retrigger = NULL, |
463 | }; |
464 | |
465 | +DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); |
466 | +#define irq_stats(x) (&per_cpu(irq_stat, x)) |
467 | + |
468 | +/* |
469 | + * /proc/interrupts printing for arch specific interrupts |
470 | + */ |
471 | +int arch_show_interrupts(struct seq_file *p, int prec) |
472 | +{ |
473 | + int j; |
474 | + |
475 | +#ifdef CONFIG_DEBUG_STACKOVERFLOW |
476 | + seq_printf(p, "%*s: ", prec, "STK"); |
477 | + for_each_online_cpu(j) |
478 | + seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage); |
479 | + seq_puts(p, " Kernel stack usage\n"); |
480 | +# ifdef CONFIG_IRQSTACKS |
481 | + seq_printf(p, "%*s: ", prec, "IST"); |
482 | + for_each_online_cpu(j) |
483 | + seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage); |
484 | + seq_puts(p, " Interrupt stack usage\n"); |
485 | +# endif |
486 | +#endif |
487 | +#ifdef CONFIG_SMP |
488 | + seq_printf(p, "%*s: ", prec, "RES"); |
489 | + for_each_online_cpu(j) |
490 | + seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); |
491 | + seq_puts(p, " Rescheduling interrupts\n"); |
492 | + seq_printf(p, "%*s: ", prec, "CAL"); |
493 | + for_each_online_cpu(j) |
494 | + seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); |
495 | + seq_puts(p, " Function call interrupts\n"); |
496 | +#endif |
497 | + seq_printf(p, "%*s: ", prec, "UAH"); |
498 | + for_each_online_cpu(j) |
499 | + seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count); |
500 | + seq_puts(p, " Unaligned access handler traps\n"); |
501 | + seq_printf(p, "%*s: ", prec, "FPA"); |
502 | + for_each_online_cpu(j) |
503 | + seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count); |
504 | + seq_puts(p, " Floating point assist traps\n"); |
505 | + seq_printf(p, "%*s: ", prec, "TLB"); |
506 | + for_each_online_cpu(j) |
507 | + seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); |
508 | + seq_puts(p, " TLB shootdowns\n"); |
509 | + return 0; |
510 | +} |
511 | + |
512 | int show_interrupts(struct seq_file *p, void *v) |
513 | { |
514 | int i = *(loff_t *) v, j; |
515 | @@ -219,6 +266,9 @@ int show_interrupts(struct seq_file *p, void *v) |
516 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
517 | } |
518 | |
519 | + if (i == NR_IRQS) |
520 | + arch_show_interrupts(p, 3); |
521 | + |
522 | return 0; |
523 | } |
524 | |
525 | @@ -330,6 +380,144 @@ static inline int eirr_to_irq(unsigned long eirr) |
526 | return (BITS_PER_LONG - bit) + TIMER_IRQ; |
527 | } |
528 | |
529 | +#ifdef CONFIG_IRQSTACKS |
530 | +/* |
531 | + * IRQ STACK - used for irq handler |
532 | + */ |
533 | +#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ |
534 | + |
535 | +union irq_stack_union { |
536 | + unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; |
537 | + volatile unsigned int slock[4]; |
538 | + volatile unsigned int lock[1]; |
539 | +}; |
540 | + |
541 | +DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { |
542 | + .slock = { 1,1,1,1 }, |
543 | + }; |
544 | +#endif |
545 | + |
546 | + |
547 | +int sysctl_panic_on_stackoverflow = 1; |
548 | + |
549 | +static inline void stack_overflow_check(struct pt_regs *regs) |
550 | +{ |
551 | +#ifdef CONFIG_DEBUG_STACKOVERFLOW |
552 | + #define STACK_MARGIN (256*6) |
553 | + |
554 | + /* Our stack starts directly behind the thread_info struct. */ |
555 | + unsigned long stack_start = (unsigned long) current_thread_info(); |
556 | + unsigned long sp = regs->gr[30]; |
557 | + unsigned long stack_usage; |
558 | + unsigned int *last_usage; |
559 | + int cpu = smp_processor_id(); |
560 | + |
561 | + /* if sr7 != 0, we interrupted a userspace process which we do not want |
562 | + * to check for stack overflow. We will only check the kernel stack. */ |
563 | + if (regs->sr[7]) |
564 | + return; |
565 | + |
566 | + /* calculate kernel stack usage */ |
567 | + stack_usage = sp - stack_start; |
568 | +#ifdef CONFIG_IRQSTACKS |
569 | + if (likely(stack_usage <= THREAD_SIZE)) |
570 | + goto check_kernel_stack; /* found kernel stack */ |
571 | + |
572 | + /* check irq stack usage */ |
573 | + stack_start = (unsigned long) &per_cpu(irq_stack_union, cpu).stack; |
574 | + stack_usage = sp - stack_start; |
575 | + |
576 | + last_usage = &per_cpu(irq_stat.irq_stack_usage, cpu); |
577 | + if (unlikely(stack_usage > *last_usage)) |
578 | + *last_usage = stack_usage; |
579 | + |
580 | + if (likely(stack_usage < (IRQ_STACK_SIZE - STACK_MARGIN))) |
581 | + return; |
582 | + |
583 | + pr_emerg("stackcheck: %s will most likely overflow irq stack " |
584 | + "(sp:%lx, stk bottom-top:%lx-%lx)\n", |
585 | + current->comm, sp, stack_start, stack_start + IRQ_STACK_SIZE); |
586 | + goto panic_check; |
587 | + |
588 | +check_kernel_stack: |
589 | +#endif |
590 | + |
591 | + /* check kernel stack usage */ |
592 | + last_usage = &per_cpu(irq_stat.kernel_stack_usage, cpu); |
593 | + |
594 | + if (unlikely(stack_usage > *last_usage)) |
595 | + *last_usage = stack_usage; |
596 | + |
597 | + if (likely(stack_usage < (THREAD_SIZE - STACK_MARGIN))) |
598 | + return; |
599 | + |
600 | + pr_emerg("stackcheck: %s will most likely overflow kernel stack " |
601 | + "(sp:%lx, stk bottom-top:%lx-%lx)\n", |
602 | + current->comm, sp, stack_start, stack_start + THREAD_SIZE); |
603 | + |
604 | +#ifdef CONFIG_IRQSTACKS |
605 | +panic_check: |
606 | +#endif |
607 | + if (sysctl_panic_on_stackoverflow) |
608 | + panic("low stack detected by irq handler - check messages\n"); |
609 | +#endif |
610 | +} |
611 | + |
612 | +#ifdef CONFIG_IRQSTACKS |
613 | +/* in entry.S: */ |
614 | +void call_on_stack(unsigned long p1, void *func, unsigned long new_stack); |
615 | + |
616 | +static void execute_on_irq_stack(void *func, unsigned long param1) |
617 | +{ |
618 | + union irq_stack_union *union_ptr; |
619 | + unsigned long irq_stack; |
620 | + volatile unsigned int *irq_stack_in_use; |
621 | + |
622 | + union_ptr = &per_cpu(irq_stack_union, smp_processor_id()); |
623 | + irq_stack = (unsigned long) &union_ptr->stack; |
624 | + irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock), |
625 | + 64); /* align for stack frame usage */ |
626 | + |
627 | + /* We may be called recursive. If we are already using the irq stack, |
628 | + * just continue to use it. Use spinlocks to serialize |
629 | + * the irq stack usage. |
630 | + */ |
631 | + irq_stack_in_use = (volatile unsigned int *)__ldcw_align(union_ptr); |
632 | + if (!__ldcw(irq_stack_in_use)) { |
633 | + void (*direct_call)(unsigned long p1) = func; |
634 | + |
635 | + /* We are using the IRQ stack already. |
636 | + * Do direct call on current stack. */ |
637 | + direct_call(param1); |
638 | + return; |
639 | + } |
640 | + |
641 | + /* This is where we switch to the IRQ stack. */ |
642 | + call_on_stack(param1, func, irq_stack); |
643 | + |
644 | + /* free up irq stack usage. */ |
645 | + *irq_stack_in_use = 1; |
646 | +} |
647 | + |
648 | +asmlinkage void do_softirq(void) |
649 | +{ |
650 | + __u32 pending; |
651 | + unsigned long flags; |
652 | + |
653 | + if (in_interrupt()) |
654 | + return; |
655 | + |
656 | + local_irq_save(flags); |
657 | + |
658 | + pending = local_softirq_pending(); |
659 | + |
660 | + if (pending) |
661 | + execute_on_irq_stack(__do_softirq, 0); |
662 | + |
663 | + local_irq_restore(flags); |
664 | +} |
665 | +#endif /* CONFIG_IRQSTACKS */ |
666 | + |
667 | /* ONLY called from entry.S:intr_extint() */ |
668 | void do_cpu_irq_mask(struct pt_regs *regs) |
669 | { |
670 | @@ -364,7 +552,13 @@ void do_cpu_irq_mask(struct pt_regs *regs) |
671 | goto set_out; |
672 | } |
673 | #endif |
674 | + stack_overflow_check(regs); |
675 | + |
676 | +#ifdef CONFIG_IRQSTACKS |
677 | + execute_on_irq_stack(&generic_handle_irq, irq); |
678 | +#else |
679 | generic_handle_irq(irq); |
680 | +#endif /* CONFIG_IRQSTACKS */ |
681 | |
682 | out: |
683 | irq_exit(); |
684 | @@ -420,6 +614,4 @@ void __init init_IRQ(void) |
685 | cpu_eiem = EIEM_MASK(TIMER_IRQ); |
686 | #endif |
687 | set_eiem(cpu_eiem); /* EIEM : enable all external intr */ |
688 | - |
689 | } |
690 | - |
691 | diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c |
692 | index 6030905..64f2764 100644 |
693 | --- a/arch/parisc/kernel/pci.c |
694 | +++ b/arch/parisc/kernel/pci.c |
695 | @@ -220,6 +220,33 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, |
696 | } |
697 | |
698 | |
699 | +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
700 | + enum pci_mmap_state mmap_state, int write_combine) |
701 | +{ |
702 | + unsigned long prot; |
703 | + |
704 | + /* |
705 | + * I/O space can be accessed via normal processor loads and stores on |
706 | + * this platform but for now we elect not to do this and portable |
707 | + * drivers should not do this anyway. |
708 | + */ |
709 | + if (mmap_state == pci_mmap_io) |
710 | + return -EINVAL; |
711 | + |
712 | + if (write_combine) |
713 | + return -EINVAL; |
714 | + |
715 | + /* |
716 | + * Ignore write-combine; for now only return uncached mappings. |
717 | + */ |
718 | + prot = pgprot_val(vma->vm_page_prot); |
719 | + prot |= _PAGE_NO_CACHE; |
720 | + vma->vm_page_prot = __pgprot(prot); |
721 | + |
722 | + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
723 | + vma->vm_end - vma->vm_start, vma->vm_page_prot); |
724 | +} |
725 | + |
726 | /* |
727 | * A driver is enabling the device. We make sure that all the appropriate |
728 | * bits are set to allow the device to operate as the driver is expecting. |
729 | diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c |
730 | index a3328c2..3b812eb 100644 |
731 | --- a/arch/parisc/kernel/setup.c |
732 | +++ b/arch/parisc/kernel/setup.c |
733 | @@ -69,7 +69,8 @@ void __init setup_cmdline(char **cmdline_p) |
734 | /* called from hpux boot loader */ |
735 | boot_command_line[0] = '\0'; |
736 | } else { |
737 | - strcpy(boot_command_line, (char *)__va(boot_args[1])); |
738 | + strlcpy(boot_command_line, (char *)__va(boot_args[1]), |
739 | + COMMAND_LINE_SIZE); |
740 | |
741 | #ifdef CONFIG_BLK_DEV_INITRD |
742 | if (boot_args[2] != 0) /* did palo pass us a ramdisk? */ |
743 | diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c |
744 | index 6266730..677dedb 100644 |
745 | --- a/arch/parisc/kernel/smp.c |
746 | +++ b/arch/parisc/kernel/smp.c |
747 | @@ -127,7 +127,7 @@ ipi_interrupt(int irq, void *dev_id) |
748 | unsigned long flags; |
749 | |
750 | /* Count this now; we may make a call that never returns. */ |
751 | - p->ipi_count++; |
752 | + inc_irq_stat(irq_call_count); |
753 | |
754 | mb(); /* Order interrupt and bit testing. */ |
755 | |
756 | @@ -155,6 +155,7 @@ ipi_interrupt(int irq, void *dev_id) |
757 | |
758 | case IPI_RESCHEDULE: |
759 | smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu); |
760 | + inc_irq_stat(irq_resched_count); |
761 | scheduler_ipi(); |
762 | break; |
763 | |
764 | @@ -263,17 +264,6 @@ void arch_send_call_function_single_ipi(int cpu) |
765 | } |
766 | |
767 | /* |
768 | - * Flush all other CPU's tlb and then mine. Do this with on_each_cpu() |
769 | - * as we want to ensure all TLB's flushed before proceeding. |
770 | - */ |
771 | - |
772 | -void |
773 | -smp_flush_tlb_all(void) |
774 | -{ |
775 | - on_each_cpu(flush_tlb_all_local, NULL, 1); |
776 | -} |
777 | - |
778 | -/* |
779 | * Called by secondaries to update state and initialize CPU registers. |
780 | */ |
781 | static void __init |
782 | diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c |
783 | index aeb8f8f..c6ae9f5 100644 |
784 | --- a/arch/parisc/kernel/traps.c |
785 | +++ b/arch/parisc/kernel/traps.c |
786 | @@ -652,6 +652,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) |
787 | case 14: |
788 | /* Assist Exception Trap, i.e. floating point exception. */ |
789 | die_if_kernel("Floating point exception", regs, 0); /* quiet */ |
790 | + __inc_irq_stat(irq_fpassist_count); |
791 | handle_fpe(regs); |
792 | return; |
793 | |
794 | diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c |
795 | index 234e368..d7c0acb 100644 |
796 | --- a/arch/parisc/kernel/unaligned.c |
797 | +++ b/arch/parisc/kernel/unaligned.c |
798 | @@ -27,6 +27,7 @@ |
799 | #include <linux/signal.h> |
800 | #include <linux/ratelimit.h> |
801 | #include <asm/uaccess.h> |
802 | +#include <asm/hardirq.h> |
803 | |
804 | /* #define DEBUG_UNALIGNED 1 */ |
805 | |
806 | @@ -454,6 +455,8 @@ void handle_unaligned(struct pt_regs *regs) |
807 | struct siginfo si; |
808 | register int flop=0; /* true if this is a flop */ |
809 | |
810 | + __inc_irq_stat(irq_unaligned_count); |
811 | + |
812 | /* log a message with pacing */ |
813 | if (user_mode(regs)) { |
814 | if (current->thread.flags & PARISC_UAC_SIGBUS) { |
815 | diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S |
816 | index 64a9998..4bb095a 100644 |
817 | --- a/arch/parisc/kernel/vmlinux.lds.S |
818 | +++ b/arch/parisc/kernel/vmlinux.lds.S |
819 | @@ -95,7 +95,7 @@ SECTIONS |
820 | NOTES |
821 | |
822 | /* Data */ |
823 | - RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) |
824 | + RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, PAGE_SIZE) |
825 | |
826 | /* PA-RISC locks requires 16-byte alignment */ |
827 | . = ALIGN(16); |
828 | diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c |
829 | index 3ac462d..d7403b1 100644 |
830 | --- a/arch/parisc/mm/init.c |
831 | +++ b/arch/parisc/mm/init.c |
832 | @@ -47,7 +47,7 @@ pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pt |
833 | |
834 | #ifdef CONFIG_DISCONTIGMEM |
835 | struct node_map_data node_data[MAX_NUMNODES] __read_mostly; |
836 | -unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; |
837 | +signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; |
838 | #endif |
839 | |
840 | static struct resource data_resource = { |
841 | @@ -1077,6 +1077,7 @@ void flush_tlb_all(void) |
842 | { |
843 | int do_recycle; |
844 | |
845 | + __inc_irq_stat(irq_tlb_count); |
846 | do_recycle = 0; |
847 | spin_lock(&sid_lock); |
848 | if (dirty_space_ids > RECYCLE_THRESHOLD) { |
849 | @@ -1097,6 +1098,7 @@ void flush_tlb_all(void) |
850 | #else |
851 | void flush_tlb_all(void) |
852 | { |
853 | + __inc_irq_stat(irq_tlb_count); |
854 | spin_lock(&sid_lock); |
855 | flush_tlb_all_local(NULL); |
856 | recycle_sids(); |
857 | diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c |
858 | index 4385cb6..a93b02a 100644 |
859 | --- a/arch/tile/lib/exports.c |
860 | +++ b/arch/tile/lib/exports.c |
861 | @@ -84,4 +84,6 @@ uint64_t __ashrdi3(uint64_t, unsigned int); |
862 | EXPORT_SYMBOL(__ashrdi3); |
863 | uint64_t __ashldi3(uint64_t, unsigned int); |
864 | EXPORT_SYMBOL(__ashldi3); |
865 | +int __ffsdi2(uint64_t); |
866 | +EXPORT_SYMBOL(__ffsdi2); |
867 | #endif |
868 | diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
869 | index 6ef2a37..de80b33 100644 |
870 | --- a/arch/x86/Kconfig |
871 | +++ b/arch/x86/Kconfig |
872 | @@ -2268,6 +2268,7 @@ source "fs/Kconfig.binfmt" |
873 | config IA32_EMULATION |
874 | bool "IA32 Emulation" |
875 | depends on X86_64 |
876 | + select BINFMT_ELF |
877 | select COMPAT_BINFMT_ELF |
878 | select HAVE_UID16 |
879 | ---help--- |
880 | diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h |
881 | index 6825e2e..6bc3985 100644 |
882 | --- a/arch/x86/include/asm/microcode.h |
883 | +++ b/arch/x86/include/asm/microcode.h |
884 | @@ -60,11 +60,11 @@ static inline void __exit exit_amd_microcode(void) {} |
885 | #ifdef CONFIG_MICROCODE_EARLY |
886 | #define MAX_UCODE_COUNT 128 |
887 | extern void __init load_ucode_bsp(void); |
888 | -extern __init void load_ucode_ap(void); |
889 | +extern void __cpuinit load_ucode_ap(void); |
890 | extern int __init save_microcode_in_initrd(void); |
891 | #else |
892 | static inline void __init load_ucode_bsp(void) {} |
893 | -static inline __init void load_ucode_ap(void) {} |
894 | +static inline void __cpuinit load_ucode_ap(void) {} |
895 | static inline int __init save_microcode_in_initrd(void) |
896 | { |
897 | return 0; |
898 | diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c |
899 | index 35ffda5..5f90b85 100644 |
900 | --- a/arch/x86/kernel/cpu/mtrr/cleanup.c |
901 | +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c |
902 | @@ -714,15 +714,15 @@ int __init mtrr_cleanup(unsigned address_bits) |
903 | if (mtrr_tom2) |
904 | x_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - x_remove_base; |
905 | |
906 | - nr_range = x86_get_mtrr_mem_range(range, 0, x_remove_base, x_remove_size); |
907 | /* |
908 | * [0, 1M) should always be covered by var mtrr with WB |
909 | * and fixed mtrrs should take effect before var mtrr for it: |
910 | */ |
911 | - nr_range = add_range_with_merge(range, RANGE_NUM, nr_range, 0, |
912 | + nr_range = add_range_with_merge(range, RANGE_NUM, 0, 0, |
913 | 1ULL<<(20 - PAGE_SHIFT)); |
914 | - /* Sort the ranges: */ |
915 | - sort_range(range, nr_range); |
916 | + /* add from var mtrr at last */ |
917 | + nr_range = x86_get_mtrr_mem_range(range, nr_range, |
918 | + x_remove_base, x_remove_size); |
919 | |
920 | range_sums = sum_ranges(range, nr_range); |
921 | printk(KERN_INFO "total RAM covered: %ldM\n", |
922 | diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c |
923 | index 0732f00..1590a3a 100644 |
924 | --- a/arch/x86/kernel/kvmclock.c |
925 | +++ b/arch/x86/kernel/kvmclock.c |
926 | @@ -238,6 +238,7 @@ void __init kvmclock_init(void) |
927 | if (!mem) |
928 | return; |
929 | hv_clock = __va(mem); |
930 | + memset(hv_clock, 0, size); |
931 | |
932 | if (kvm_register_clock("boot clock")) { |
933 | hv_clock = NULL; |
934 | diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c |
935 | index e172132..8563b45 100644 |
936 | --- a/arch/x86/kvm/x86.c |
937 | +++ b/arch/x86/kvm/x86.c |
938 | @@ -558,8 +558,6 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) |
939 | if (index != XCR_XFEATURE_ENABLED_MASK) |
940 | return 1; |
941 | xcr0 = xcr; |
942 | - if (kvm_x86_ops->get_cpl(vcpu) != 0) |
943 | - return 1; |
944 | if (!(xcr0 & XSTATE_FP)) |
945 | return 1; |
946 | if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE)) |
947 | @@ -573,7 +571,8 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) |
948 | |
949 | int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) |
950 | { |
951 | - if (__kvm_set_xcr(vcpu, index, xcr)) { |
952 | + if (kvm_x86_ops->get_cpl(vcpu) != 0 || |
953 | + __kvm_set_xcr(vcpu, index, xcr)) { |
954 | kvm_inject_gp(vcpu, 0); |
955 | return 1; |
956 | } |
957 | diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c |
958 | index 90f3a52..714e825 100644 |
959 | --- a/arch/x86/platform/efi/efi.c |
960 | +++ b/arch/x86/platform/efi/efi.c |
961 | @@ -1059,7 +1059,10 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) |
962 | * that by attempting to use more space than is available. |
963 | */ |
964 | unsigned long dummy_size = remaining_size + 1024; |
965 | - void *dummy = kmalloc(dummy_size, GFP_ATOMIC); |
966 | + void *dummy = kzalloc(dummy_size, GFP_ATOMIC); |
967 | + |
968 | + if (!dummy) |
969 | + return EFI_OUT_OF_RESOURCES; |
970 | |
971 | status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, |
972 | EFI_VARIABLE_NON_VOLATILE | |
973 | @@ -1079,6 +1082,8 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) |
974 | 0, dummy); |
975 | } |
976 | |
977 | + kfree(dummy); |
978 | + |
979 | /* |
980 | * The runtime code may now have triggered a garbage collection |
981 | * run, so check the variable info again |
982 | diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c |
983 | index 4fdea38..ec117c6 100644 |
984 | --- a/drivers/acpi/dock.c |
985 | +++ b/drivers/acpi/dock.c |
986 | @@ -868,8 +868,10 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr, |
987 | if (!count) |
988 | return -EINVAL; |
989 | |
990 | + acpi_scan_lock_acquire(); |
991 | begin_undock(dock_station); |
992 | ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); |
993 | + acpi_scan_lock_release(); |
994 | return ret ? ret: count; |
995 | } |
996 | static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); |
997 | diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c |
998 | index 34f5ef1..4d0624f 100644 |
999 | --- a/drivers/acpi/power.c |
1000 | +++ b/drivers/acpi/power.c |
1001 | @@ -865,6 +865,7 @@ int acpi_add_power_resource(acpi_handle handle) |
1002 | ACPI_STA_DEFAULT); |
1003 | mutex_init(&resource->resource_lock); |
1004 | INIT_LIST_HEAD(&resource->dependent); |
1005 | + INIT_LIST_HEAD(&resource->list_node); |
1006 | resource->name = device->pnp.bus_id; |
1007 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); |
1008 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); |
1009 | diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c |
1010 | index a3868f6..3322b47 100644 |
1011 | --- a/drivers/acpi/resource.c |
1012 | +++ b/drivers/acpi/resource.c |
1013 | @@ -304,7 +304,8 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) |
1014 | } |
1015 | |
1016 | static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, |
1017 | - u8 triggering, u8 polarity, u8 shareable) |
1018 | + u8 triggering, u8 polarity, u8 shareable, |
1019 | + bool legacy) |
1020 | { |
1021 | int irq, p, t; |
1022 | |
1023 | @@ -317,14 +318,19 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, |
1024 | * In IO-APIC mode, use overrided attribute. Two reasons: |
1025 | * 1. BIOS bug in DSDT |
1026 | * 2. BIOS uses IO-APIC mode Interrupt Source Override |
1027 | + * |
1028 | + * We do this only if we are dealing with IRQ() or IRQNoFlags() |
1029 | + * resource (the legacy ISA resources). With modern ACPI 5 devices |
1030 | + * using extended IRQ descriptors we take the IRQ configuration |
1031 | + * from _CRS directly. |
1032 | */ |
1033 | - if (!acpi_get_override_irq(gsi, &t, &p)) { |
1034 | + if (legacy && !acpi_get_override_irq(gsi, &t, &p)) { |
1035 | u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; |
1036 | u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; |
1037 | |
1038 | if (triggering != trig || polarity != pol) { |
1039 | pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi, |
1040 | - t ? "edge" : "level", p ? "low" : "high"); |
1041 | + t ? "level" : "edge", p ? "low" : "high"); |
1042 | triggering = trig; |
1043 | polarity = pol; |
1044 | } |
1045 | @@ -373,7 +379,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, |
1046 | } |
1047 | acpi_dev_get_irqresource(res, irq->interrupts[index], |
1048 | irq->triggering, irq->polarity, |
1049 | - irq->sharable); |
1050 | + irq->sharable, true); |
1051 | break; |
1052 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
1053 | ext_irq = &ares->data.extended_irq; |
1054 | @@ -383,7 +389,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, |
1055 | } |
1056 | acpi_dev_get_irqresource(res, ext_irq->interrupts[index], |
1057 | ext_irq->triggering, ext_irq->polarity, |
1058 | - ext_irq->sharable); |
1059 | + ext_irq->sharable, false); |
1060 | break; |
1061 | default: |
1062 | return false; |
1063 | diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c |
1064 | index 4b1f926..01e2103 100644 |
1065 | --- a/drivers/base/firmware_class.c |
1066 | +++ b/drivers/base/firmware_class.c |
1067 | @@ -450,8 +450,18 @@ static void fw_load_abort(struct firmware_priv *fw_priv) |
1068 | { |
1069 | struct firmware_buf *buf = fw_priv->buf; |
1070 | |
1071 | + /* |
1072 | + * There is a small window in which user can write to 'loading' |
1073 | + * between loading done and disappearance of 'loading' |
1074 | + */ |
1075 | + if (test_bit(FW_STATUS_DONE, &buf->status)) |
1076 | + return; |
1077 | + |
1078 | set_bit(FW_STATUS_ABORT, &buf->status); |
1079 | complete_all(&buf->completion); |
1080 | + |
1081 | + /* avoid user action after loading abort */ |
1082 | + fw_priv->buf = NULL; |
1083 | } |
1084 | |
1085 | #define is_fw_load_aborted(buf) \ |
1086 | @@ -528,7 +538,12 @@ static ssize_t firmware_loading_show(struct device *dev, |
1087 | struct device_attribute *attr, char *buf) |
1088 | { |
1089 | struct firmware_priv *fw_priv = to_firmware_priv(dev); |
1090 | - int loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status); |
1091 | + int loading = 0; |
1092 | + |
1093 | + mutex_lock(&fw_lock); |
1094 | + if (fw_priv->buf) |
1095 | + loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status); |
1096 | + mutex_unlock(&fw_lock); |
1097 | |
1098 | return sprintf(buf, "%d\n", loading); |
1099 | } |
1100 | @@ -570,12 +585,12 @@ static ssize_t firmware_loading_store(struct device *dev, |
1101 | const char *buf, size_t count) |
1102 | { |
1103 | struct firmware_priv *fw_priv = to_firmware_priv(dev); |
1104 | - struct firmware_buf *fw_buf = fw_priv->buf; |
1105 | + struct firmware_buf *fw_buf; |
1106 | int loading = simple_strtol(buf, NULL, 10); |
1107 | int i; |
1108 | |
1109 | mutex_lock(&fw_lock); |
1110 | - |
1111 | + fw_buf = fw_priv->buf; |
1112 | if (!fw_buf) |
1113 | goto out; |
1114 | |
1115 | @@ -777,10 +792,6 @@ static void firmware_class_timeout_work(struct work_struct *work) |
1116 | struct firmware_priv, timeout_work.work); |
1117 | |
1118 | mutex_lock(&fw_lock); |
1119 | - if (test_bit(FW_STATUS_DONE, &(fw_priv->buf->status))) { |
1120 | - mutex_unlock(&fw_lock); |
1121 | - return; |
1122 | - } |
1123 | fw_load_abort(fw_priv); |
1124 | mutex_unlock(&fw_lock); |
1125 | } |
1126 | @@ -861,8 +872,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, |
1127 | |
1128 | cancel_delayed_work_sync(&fw_priv->timeout_work); |
1129 | |
1130 | - fw_priv->buf = NULL; |
1131 | - |
1132 | device_remove_file(f_dev, &dev_attr_loading); |
1133 | err_del_bin_attr: |
1134 | device_remove_bin_file(f_dev, &firmware_attr_data); |
1135 | diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c |
1136 | index fe333e4..c2b1427 100644 |
1137 | --- a/drivers/block/rbd.c |
1138 | +++ b/drivers/block/rbd.c |
1139 | @@ -833,12 +833,16 @@ static const char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset) |
1140 | char *name; |
1141 | u64 segment; |
1142 | int ret; |
1143 | + char *name_format; |
1144 | |
1145 | name = kmalloc(MAX_OBJ_NAME_SIZE + 1, GFP_NOIO); |
1146 | if (!name) |
1147 | return NULL; |
1148 | segment = offset >> rbd_dev->header.obj_order; |
1149 | - ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, "%s.%012llx", |
1150 | + name_format = "%s.%012llx"; |
1151 | + if (rbd_dev->image_format == 2) |
1152 | + name_format = "%s.%016llx"; |
1153 | + ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, name_format, |
1154 | rbd_dev->header.object_prefix, segment); |
1155 | if (ret < 0 || ret > MAX_OBJ_NAME_SIZE) { |
1156 | pr_err("error formatting segment name for #%llu (%d)\n", |
1157 | diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c |
1158 | index ed87b24..c2c23c0 100644 |
1159 | --- a/drivers/clk/clk.c |
1160 | +++ b/drivers/clk/clk.c |
1161 | @@ -1759,6 +1759,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) |
1162 | /* XXX the notifier code should handle this better */ |
1163 | if (!cn->notifier_head.head) { |
1164 | srcu_cleanup_notifier_head(&cn->notifier_head); |
1165 | + list_del(&cn->node); |
1166 | kfree(cn); |
1167 | } |
1168 | |
1169 | diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c |
1170 | index db767ca..bde91b4 100644 |
1171 | --- a/drivers/gpu/drm/drm_prime.c |
1172 | +++ b/drivers/gpu/drm/drm_prime.c |
1173 | @@ -190,8 +190,7 @@ struct dma_buf *drm_gem_prime_export(struct drm_device *dev, |
1174 | if (ret) |
1175 | return ERR_PTR(ret); |
1176 | } |
1177 | - return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, |
1178 | - 0600); |
1179 | + return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, flags); |
1180 | } |
1181 | EXPORT_SYMBOL(drm_gem_prime_export); |
1182 | |
1183 | diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c |
1184 | index 2c1341f..43ec4a4 100644 |
1185 | --- a/drivers/gpu/drm/radeon/radeon_gart.c |
1186 | +++ b/drivers/gpu/drm/radeon/radeon_gart.c |
1187 | @@ -1197,11 +1197,13 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, |
1188 | int radeon_vm_bo_rmv(struct radeon_device *rdev, |
1189 | struct radeon_bo_va *bo_va) |
1190 | { |
1191 | - int r; |
1192 | + int r = 0; |
1193 | |
1194 | mutex_lock(&rdev->vm_manager.lock); |
1195 | mutex_lock(&bo_va->vm->mutex); |
1196 | - r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL); |
1197 | + if (bo_va->soffset) { |
1198 | + r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL); |
1199 | + } |
1200 | mutex_unlock(&rdev->vm_manager.lock); |
1201 | list_del(&bo_va->vm_list); |
1202 | mutex_unlock(&bo_va->vm->mutex); |
1203 | diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c |
1204 | index 1ef5eaa..e2fd0f7 100644 |
1205 | --- a/drivers/gpu/drm/radeon/radeon_ring.c |
1206 | +++ b/drivers/gpu/drm/radeon/radeon_ring.c |
1207 | @@ -402,6 +402,13 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi |
1208 | return -ENOMEM; |
1209 | /* Align requested size with padding so unlock_commit can |
1210 | * pad safely */ |
1211 | + radeon_ring_free_size(rdev, ring); |
1212 | + if (ring->ring_free_dw == (ring->ring_size / 4)) { |
1213 | + /* This is an empty ring update lockup info to avoid |
1214 | + * false positive. |
1215 | + */ |
1216 | + radeon_ring_lockup_update(ring); |
1217 | + } |
1218 | ndw = (ndw + ring->align_mask) & ~ring->align_mask; |
1219 | while (ndw > (ring->ring_free_dw - 1)) { |
1220 | radeon_ring_free_size(rdev, ring); |
1221 | diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c |
1222 | index d6cbfe9..fa061d4 100644 |
1223 | --- a/drivers/input/joystick/xpad.c |
1224 | +++ b/drivers/input/joystick/xpad.c |
1225 | @@ -137,7 +137,7 @@ static const struct xpad_device { |
1226 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
1227 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, |
1228 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
1229 | - { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", XTYPE_XBOX360 }, |
1230 | + { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
1231 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
1232 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
1233 | { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 }, |
1234 | diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig |
1235 | index ac05006..c62ca1b 100644 |
1236 | --- a/drivers/input/keyboard/Kconfig |
1237 | +++ b/drivers/input/keyboard/Kconfig |
1238 | @@ -431,6 +431,7 @@ config KEYBOARD_TEGRA |
1239 | |
1240 | config KEYBOARD_OPENCORES |
1241 | tristate "OpenCores Keyboard Controller" |
1242 | + depends on HAS_IOMEM |
1243 | help |
1244 | Say Y here if you want to use the OpenCores Keyboard Controller |
1245 | http://www.opencores.org/project,keyboardcontroller |
1246 | diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig |
1247 | index 3ec5ef2..dbe1af5 100644 |
1248 | --- a/drivers/input/serio/Kconfig |
1249 | +++ b/drivers/input/serio/Kconfig |
1250 | @@ -205,6 +205,7 @@ config SERIO_XILINX_XPS_PS2 |
1251 | |
1252 | config SERIO_ALTERA_PS2 |
1253 | tristate "Altera UP PS/2 controller" |
1254 | + depends on HAS_IOMEM |
1255 | help |
1256 | Say Y here if you have Altera University Program PS/2 ports. |
1257 | |
1258 | diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c |
1259 | index 8e60437..97ba891 100644 |
1260 | --- a/drivers/input/touchscreen/cyttsp_core.c |
1261 | +++ b/drivers/input/touchscreen/cyttsp_core.c |
1262 | @@ -133,7 +133,7 @@ static int cyttsp_exit_bl_mode(struct cyttsp *ts) |
1263 | memcpy(bl_cmd, bl_command, sizeof(bl_command)); |
1264 | if (ts->pdata->bl_keys) |
1265 | memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], |
1266 | - ts->pdata->bl_keys, sizeof(bl_command)); |
1267 | + ts->pdata->bl_keys, CY_NUM_BL_KEYS); |
1268 | |
1269 | error = ttsp_write_block_data(ts, CY_REG_BASE, |
1270 | sizeof(bl_cmd), bl_cmd); |
1271 | diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c |
1272 | index 73195f6..ef5b595 100644 |
1273 | --- a/drivers/net/ethernet/freescale/fec.c |
1274 | +++ b/drivers/net/ethernet/freescale/fec.c |
1275 | @@ -407,6 +407,13 @@ fec_restart(struct net_device *ndev, int duplex) |
1276 | u32 rcntl = OPT_FRAME_SIZE | 0x04; |
1277 | u32 ecntl = 0x2; /* ETHEREN */ |
1278 | |
1279 | + if (netif_running(ndev)) { |
1280 | + netif_device_detach(ndev); |
1281 | + napi_disable(&fep->napi); |
1282 | + netif_stop_queue(ndev); |
1283 | + netif_tx_lock_bh(ndev); |
1284 | + } |
1285 | + |
1286 | /* Whack a reset. We should wait for this. */ |
1287 | writel(1, fep->hwp + FEC_ECNTRL); |
1288 | udelay(10); |
1289 | @@ -559,6 +566,13 @@ fec_restart(struct net_device *ndev, int duplex) |
1290 | |
1291 | /* Enable interrupts we wish to service */ |
1292 | writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); |
1293 | + |
1294 | + if (netif_running(ndev)) { |
1295 | + netif_device_attach(ndev); |
1296 | + napi_enable(&fep->napi); |
1297 | + netif_wake_queue(ndev); |
1298 | + netif_tx_unlock_bh(ndev); |
1299 | + } |
1300 | } |
1301 | |
1302 | static void |
1303 | @@ -598,8 +612,22 @@ fec_timeout(struct net_device *ndev) |
1304 | |
1305 | ndev->stats.tx_errors++; |
1306 | |
1307 | - fec_restart(ndev, fep->full_duplex); |
1308 | - netif_wake_queue(ndev); |
1309 | + fep->delay_work.timeout = true; |
1310 | + schedule_delayed_work(&(fep->delay_work.delay_work), 0); |
1311 | +} |
1312 | + |
1313 | +static void fec_enet_work(struct work_struct *work) |
1314 | +{ |
1315 | + struct fec_enet_private *fep = |
1316 | + container_of(work, |
1317 | + struct fec_enet_private, |
1318 | + delay_work.delay_work.work); |
1319 | + |
1320 | + if (fep->delay_work.timeout) { |
1321 | + fep->delay_work.timeout = false; |
1322 | + fec_restart(fep->netdev, fep->full_duplex); |
1323 | + netif_wake_queue(fep->netdev); |
1324 | + } |
1325 | } |
1326 | |
1327 | static void |
1328 | @@ -970,16 +998,12 @@ static void fec_enet_adjust_link(struct net_device *ndev) |
1329 | { |
1330 | struct fec_enet_private *fep = netdev_priv(ndev); |
1331 | struct phy_device *phy_dev = fep->phy_dev; |
1332 | - unsigned long flags; |
1333 | - |
1334 | int status_change = 0; |
1335 | |
1336 | - spin_lock_irqsave(&fep->hw_lock, flags); |
1337 | - |
1338 | /* Prevent a state halted on mii error */ |
1339 | if (fep->mii_timeout && phy_dev->state == PHY_HALTED) { |
1340 | phy_dev->state = PHY_RESUMING; |
1341 | - goto spin_unlock; |
1342 | + return; |
1343 | } |
1344 | |
1345 | if (phy_dev->link) { |
1346 | @@ -1007,9 +1031,6 @@ static void fec_enet_adjust_link(struct net_device *ndev) |
1347 | } |
1348 | } |
1349 | |
1350 | -spin_unlock: |
1351 | - spin_unlock_irqrestore(&fep->hw_lock, flags); |
1352 | - |
1353 | if (status_change) |
1354 | phy_print_status(phy_dev); |
1355 | } |
1356 | @@ -1656,7 +1677,6 @@ static int fec_enet_init(struct net_device *ndev) |
1357 | } |
1358 | |
1359 | memset(cbd_base, 0, PAGE_SIZE); |
1360 | - spin_lock_init(&fep->hw_lock); |
1361 | |
1362 | fep->netdev = ndev; |
1363 | |
1364 | @@ -1882,6 +1902,7 @@ fec_probe(struct platform_device *pdev) |
1365 | if (ret) |
1366 | goto failed_register; |
1367 | |
1368 | + INIT_DELAYED_WORK(&(fep->delay_work.delay_work), fec_enet_work); |
1369 | return 0; |
1370 | |
1371 | failed_register: |
1372 | @@ -1918,6 +1939,7 @@ fec_drv_remove(struct platform_device *pdev) |
1373 | struct resource *r; |
1374 | int i; |
1375 | |
1376 | + cancel_delayed_work_sync(&(fep->delay_work.delay_work)); |
1377 | unregister_netdev(ndev); |
1378 | fec_enet_mii_remove(fep); |
1379 | del_timer_sync(&fep->time_keep); |
1380 | diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h |
1381 | index eb43729..5045f33 100644 |
1382 | --- a/drivers/net/ethernet/freescale/fec.h |
1383 | +++ b/drivers/net/ethernet/freescale/fec.h |
1384 | @@ -191,6 +191,11 @@ struct bufdesc_ex { |
1385 | #define BD_ENET_RX_INT 0x00800000 |
1386 | #define BD_ENET_RX_PTP ((ushort)0x0400) |
1387 | |
1388 | +struct fec_enet_delayed_work { |
1389 | + struct delayed_work delay_work; |
1390 | + bool timeout; |
1391 | +}; |
1392 | + |
1393 | /* The FEC buffer descriptors track the ring buffers. The rx_bd_base and |
1394 | * tx_bd_base always point to the base of the buffer descriptors. The |
1395 | * cur_rx and cur_tx point to the currently available buffer. |
1396 | @@ -224,9 +229,6 @@ struct fec_enet_private { |
1397 | /* The ring entries to be free()ed */ |
1398 | struct bufdesc *dirty_tx; |
1399 | |
1400 | - /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ |
1401 | - spinlock_t hw_lock; |
1402 | - |
1403 | struct platform_device *pdev; |
1404 | |
1405 | int opened; |
1406 | @@ -260,7 +262,7 @@ struct fec_enet_private { |
1407 | int hwts_rx_en; |
1408 | int hwts_tx_en; |
1409 | struct timer_list time_keep; |
1410 | - |
1411 | + struct fec_enet_delayed_work delay_work; |
1412 | }; |
1413 | |
1414 | void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev); |
1415 | diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c |
1416 | index a3f8a25..2a2bc0b 100644 |
1417 | --- a/drivers/net/ethernet/freescale/gianfar_ptp.c |
1418 | +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c |
1419 | @@ -521,6 +521,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) |
1420 | return 0; |
1421 | |
1422 | no_clock: |
1423 | + iounmap(etsects->regs); |
1424 | no_ioremap: |
1425 | release_resource(etsects->rsrc); |
1426 | no_resource: |
1427 | diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c |
1428 | index b62a324..dd45d7d 100644 |
1429 | --- a/drivers/net/ethernet/realtek/8139cp.c |
1430 | +++ b/drivers/net/ethernet/realtek/8139cp.c |
1431 | @@ -1136,6 +1136,7 @@ static void cp_clean_rings (struct cp_private *cp) |
1432 | cp->dev->stats.tx_dropped++; |
1433 | } |
1434 | } |
1435 | + netdev_reset_queue(cp->dev); |
1436 | |
1437 | memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); |
1438 | memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); |
1439 | diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c |
1440 | index 15ba8c4..54fd2ef 100644 |
1441 | --- a/drivers/net/ethernet/realtek/r8169.c |
1442 | +++ b/drivers/net/ethernet/realtek/r8169.c |
1443 | @@ -5747,7 +5747,20 @@ err_out: |
1444 | return -EIO; |
1445 | } |
1446 | |
1447 | -static inline void rtl8169_tso_csum(struct rtl8169_private *tp, |
1448 | +static bool rtl_skb_pad(struct sk_buff *skb) |
1449 | +{ |
1450 | + if (skb_padto(skb, ETH_ZLEN)) |
1451 | + return false; |
1452 | + skb_put(skb, ETH_ZLEN - skb->len); |
1453 | + return true; |
1454 | +} |
1455 | + |
1456 | +static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) |
1457 | +{ |
1458 | + return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; |
1459 | +} |
1460 | + |
1461 | +static inline bool rtl8169_tso_csum(struct rtl8169_private *tp, |
1462 | struct sk_buff *skb, u32 *opts) |
1463 | { |
1464 | const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; |
1465 | @@ -5760,13 +5773,20 @@ static inline void rtl8169_tso_csum(struct rtl8169_private *tp, |
1466 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
1467 | const struct iphdr *ip = ip_hdr(skb); |
1468 | |
1469 | + if (unlikely(rtl_test_hw_pad_bug(tp, skb))) |
1470 | + return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb); |
1471 | + |
1472 | if (ip->protocol == IPPROTO_TCP) |
1473 | opts[offset] |= info->checksum.tcp; |
1474 | else if (ip->protocol == IPPROTO_UDP) |
1475 | opts[offset] |= info->checksum.udp; |
1476 | else |
1477 | WARN_ON_ONCE(1); |
1478 | + } else { |
1479 | + if (unlikely(rtl_test_hw_pad_bug(tp, skb))) |
1480 | + return rtl_skb_pad(skb); |
1481 | } |
1482 | + return true; |
1483 | } |
1484 | |
1485 | static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, |
1486 | @@ -5787,17 +5807,15 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, |
1487 | goto err_stop_0; |
1488 | } |
1489 | |
1490 | - /* 8168evl does not automatically pad to minimum length. */ |
1491 | - if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 && |
1492 | - skb->len < ETH_ZLEN)) { |
1493 | - if (skb_padto(skb, ETH_ZLEN)) |
1494 | - goto err_update_stats; |
1495 | - skb_put(skb, ETH_ZLEN - skb->len); |
1496 | - } |
1497 | - |
1498 | if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) |
1499 | goto err_stop_0; |
1500 | |
1501 | + opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); |
1502 | + opts[0] = DescOwn; |
1503 | + |
1504 | + if (!rtl8169_tso_csum(tp, skb, opts)) |
1505 | + goto err_update_stats; |
1506 | + |
1507 | len = skb_headlen(skb); |
1508 | mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); |
1509 | if (unlikely(dma_mapping_error(d, mapping))) { |
1510 | @@ -5809,11 +5827,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, |
1511 | tp->tx_skb[entry].len = len; |
1512 | txd->addr = cpu_to_le64(mapping); |
1513 | |
1514 | - opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); |
1515 | - opts[0] = DescOwn; |
1516 | - |
1517 | - rtl8169_tso_csum(tp, skb, opts); |
1518 | - |
1519 | frags = rtl8169_xmit_frags(tp, skb, opts); |
1520 | if (frags < 0) |
1521 | goto err_dma_1; |
1522 | diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c |
1523 | index 6ed333f..8791999 100644 |
1524 | --- a/drivers/net/ethernet/renesas/sh_eth.c |
1525 | +++ b/drivers/net/ethernet/renesas/sh_eth.c |
1526 | @@ -1100,16 +1100,23 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status) |
1527 | desc_status = edmac_to_cpu(mdp, rxdesc->status); |
1528 | pkt_len = rxdesc->frame_length; |
1529 | |
1530 | -#if defined(CONFIG_ARCH_R8A7740) |
1531 | - desc_status >>= 16; |
1532 | -#endif |
1533 | - |
1534 | if (--boguscnt < 0) |
1535 | break; |
1536 | |
1537 | if (!(desc_status & RDFEND)) |
1538 | ndev->stats.rx_length_errors++; |
1539 | |
1540 | +#if defined(CONFIG_ARCH_R8A7740) |
1541 | + /* |
1542 | + * In case of almost all GETHER/ETHERs, the Receive Frame State |
1543 | + * (RFS) bits in the Receive Descriptor 0 are from bit 9 to |
1544 | + * bit 0. However, in case of the R8A7740's GETHER, the RFS |
1545 | + * bits are from bit 25 to bit 16. So, the driver needs right |
1546 | + * shifting by 16. |
1547 | + */ |
1548 | + desc_status >>= 16; |
1549 | +#endif |
1550 | + |
1551 | if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 | |
1552 | RD_RFS5 | RD_RFS6 | RD_RFS10)) { |
1553 | ndev->stats.rx_errors++; |
1554 | diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c |
1555 | index a449439..acf6450 100644 |
1556 | --- a/drivers/net/macvtap.c |
1557 | +++ b/drivers/net/macvtap.c |
1558 | @@ -21,6 +21,7 @@ |
1559 | #include <net/rtnetlink.h> |
1560 | #include <net/sock.h> |
1561 | #include <linux/virtio_net.h> |
1562 | +#include <net/flow_keys.h> |
1563 | |
1564 | /* |
1565 | * A macvtap queue is the central object of this driver, it connects |
1566 | @@ -645,6 +646,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, |
1567 | int vnet_hdr_len = 0; |
1568 | int copylen = 0; |
1569 | bool zerocopy = false; |
1570 | + struct flow_keys keys; |
1571 | |
1572 | if (q->flags & IFF_VNET_HDR) { |
1573 | vnet_hdr_len = q->vnet_hdr_sz; |
1574 | @@ -725,6 +727,13 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, |
1575 | goto err_kfree; |
1576 | } |
1577 | |
1578 | + if (skb->ip_summed == CHECKSUM_PARTIAL) |
1579 | + skb_set_transport_header(skb, skb_checksum_start_offset(skb)); |
1580 | + else if (skb_flow_dissect(skb, &keys)) |
1581 | + skb_set_transport_header(skb, keys.thoff); |
1582 | + else |
1583 | + skb_set_transport_header(skb, ETH_HLEN); |
1584 | + |
1585 | rcu_read_lock_bh(); |
1586 | vlan = rcu_dereference_bh(q->vlan); |
1587 | /* copy skb_ubuf_info for callback when skb has no error */ |
1588 | diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c |
1589 | index ef9ea92..c17f636 100644 |
1590 | --- a/drivers/net/phy/phy.c |
1591 | +++ b/drivers/net/phy/phy.c |
1592 | @@ -1092,7 +1092,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) |
1593 | adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); |
1594 | lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); |
1595 | idx = phy_find_setting(phydev->speed, phydev->duplex); |
1596 | - if ((lp & adv & settings[idx].setting)) |
1597 | + if (!(lp & adv & settings[idx].setting)) |
1598 | goto eee_exit; |
1599 | |
1600 | if (clk_stop_enable) { |
1601 | diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c |
1602 | index bf34192..0017b67 100644 |
1603 | --- a/drivers/net/team/team.c |
1604 | +++ b/drivers/net/team/team.c |
1605 | @@ -1079,8 +1079,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev) |
1606 | } |
1607 | |
1608 | port->index = -1; |
1609 | - team_port_enable(team, port); |
1610 | list_add_tail_rcu(&port->list, &team->port_list); |
1611 | + team_port_enable(team, port); |
1612 | __team_compute_features(team); |
1613 | __team_port_change_port_added(port, !!netif_carrier_ok(port_dev)); |
1614 | __team_options_change_check(team); |
1615 | diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c |
1616 | index 105135a..041cc0a 100644 |
1617 | --- a/drivers/net/team/team_mode_roundrobin.c |
1618 | +++ b/drivers/net/team/team_mode_roundrobin.c |
1619 | @@ -52,6 +52,8 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb) |
1620 | |
1621 | port_index = rr_priv(team)->sent_packets++ % team->en_port_count; |
1622 | port = team_get_port_by_index_rcu(team, port_index); |
1623 | + if (unlikely(!port)) |
1624 | + goto drop; |
1625 | port = __get_first_port_up(team, port); |
1626 | if (unlikely(!port)) |
1627 | goto drop; |
1628 | diff --git a/drivers/net/tun.c b/drivers/net/tun.c |
1629 | index 755fa9e..8ad822e 100644 |
1630 | --- a/drivers/net/tun.c |
1631 | +++ b/drivers/net/tun.c |
1632 | @@ -70,6 +70,7 @@ |
1633 | #include <net/sock.h> |
1634 | |
1635 | #include <asm/uaccess.h> |
1636 | +#include <net/flow_keys.h> |
1637 | |
1638 | /* Uncomment to enable debugging */ |
1639 | /* #define TUN_DEBUG 1 */ |
1640 | @@ -1051,6 +1052,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, |
1641 | bool zerocopy = false; |
1642 | int err; |
1643 | u32 rxhash; |
1644 | + struct flow_keys keys; |
1645 | |
1646 | if (!(tun->flags & TUN_NO_PI)) { |
1647 | if ((len -= sizeof(pi)) > total_len) |
1648 | @@ -1205,6 +1207,14 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, |
1649 | } |
1650 | |
1651 | skb_reset_network_header(skb); |
1652 | + |
1653 | + if (skb->ip_summed == CHECKSUM_PARTIAL) |
1654 | + skb_set_transport_header(skb, skb_checksum_start_offset(skb)); |
1655 | + else if (skb_flow_dissect(skb, &keys)) |
1656 | + skb_set_transport_header(skb, keys.thoff); |
1657 | + else |
1658 | + skb_reset_transport_header(skb); |
1659 | + |
1660 | rxhash = skb_get_rxhash(skb); |
1661 | netif_rx_ni(skb); |
1662 | |
1663 | @@ -1585,6 +1595,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) |
1664 | else |
1665 | return -EINVAL; |
1666 | |
1667 | + if (!!(ifr->ifr_flags & IFF_MULTI_QUEUE) != |
1668 | + !!(tun->flags & TUN_TAP_MQ)) |
1669 | + return -EINVAL; |
1670 | + |
1671 | if (tun_not_capable(tun)) |
1672 | return -EPERM; |
1673 | err = security_tun_dev_open(tun->security); |
1674 | @@ -1596,8 +1610,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) |
1675 | return err; |
1676 | |
1677 | if (tun->flags & TUN_TAP_MQ && |
1678 | - (tun->numqueues + tun->numdisabled > 1)) |
1679 | - return -EBUSY; |
1680 | + (tun->numqueues + tun->numdisabled > 1)) { |
1681 | + /* One or more queue has already been attached, no need |
1682 | + * to initialize the device again. |
1683 | + */ |
1684 | + return 0; |
1685 | + } |
1686 | } |
1687 | else { |
1688 | char *name; |
1689 | @@ -2150,6 +2168,8 @@ static int tun_chr_open(struct inode *inode, struct file * file) |
1690 | set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags); |
1691 | INIT_LIST_HEAD(&tfile->next); |
1692 | |
1693 | + sock_set_flag(&tfile->sk, SOCK_ZEROCOPY); |
1694 | + |
1695 | return 0; |
1696 | } |
1697 | |
1698 | diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c |
1699 | index 7cee7a3..a4fe5f1 100644 |
1700 | --- a/drivers/net/vxlan.c |
1701 | +++ b/drivers/net/vxlan.c |
1702 | @@ -285,7 +285,7 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan, |
1703 | } |
1704 | |
1705 | /* Look up Ethernet address in forwarding table */ |
1706 | -static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, |
1707 | +static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, |
1708 | const u8 *mac) |
1709 | |
1710 | { |
1711 | @@ -300,6 +300,18 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, |
1712 | return NULL; |
1713 | } |
1714 | |
1715 | +static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, |
1716 | + const u8 *mac) |
1717 | +{ |
1718 | + struct vxlan_fdb *f; |
1719 | + |
1720 | + f = __vxlan_find_mac(vxlan, mac); |
1721 | + if (f) |
1722 | + f->used = jiffies; |
1723 | + |
1724 | + return f; |
1725 | +} |
1726 | + |
1727 | /* Add new entry to forwarding table -- assumes lock held */ |
1728 | static int vxlan_fdb_create(struct vxlan_dev *vxlan, |
1729 | const u8 *mac, __be32 ip, |
1730 | @@ -308,7 +320,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, |
1731 | struct vxlan_fdb *f; |
1732 | int notify = 0; |
1733 | |
1734 | - f = vxlan_find_mac(vxlan, mac); |
1735 | + f = __vxlan_find_mac(vxlan, mac); |
1736 | if (f) { |
1737 | if (flags & NLM_F_EXCL) { |
1738 | netdev_dbg(vxlan->dev, |
1739 | @@ -453,7 +465,6 @@ static void vxlan_snoop(struct net_device *dev, |
1740 | |
1741 | f = vxlan_find_mac(vxlan, src_mac); |
1742 | if (likely(f)) { |
1743 | - f->used = jiffies; |
1744 | if (likely(f->remote_ip == src_ip)) |
1745 | return; |
1746 | |
1747 | diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c |
1748 | index 9c0b150..c61cafa 100644 |
1749 | --- a/drivers/net/wireless/ath/carl9170/tx.c |
1750 | +++ b/drivers/net/wireless/ath/carl9170/tx.c |
1751 | @@ -387,8 +387,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, |
1752 | u8 tid; |
1753 | |
1754 | if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || |
1755 | - txinfo->flags & IEEE80211_TX_CTL_INJECTED || |
1756 | - (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) |
1757 | + txinfo->flags & IEEE80211_TX_CTL_INJECTED) |
1758 | return; |
1759 | |
1760 | rcu_read_lock(); |
1761 | @@ -981,30 +980,6 @@ static int carl9170_tx_prepare(struct ar9170 *ar, |
1762 | |
1763 | SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, |
1764 | txc->s.ampdu_settings, factor); |
1765 | - |
1766 | - for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { |
1767 | - txrate = &info->control.rates[i]; |
1768 | - if (txrate->idx >= 0) { |
1769 | - txc->s.ri[i] = |
1770 | - CARL9170_TX_SUPER_RI_AMPDU; |
1771 | - |
1772 | - if (WARN_ON(!(txrate->flags & |
1773 | - IEEE80211_TX_RC_MCS))) { |
1774 | - /* |
1775 | - * Not sure if it's even possible |
1776 | - * to aggregate non-ht rates with |
1777 | - * this HW. |
1778 | - */ |
1779 | - goto err_out; |
1780 | - } |
1781 | - continue; |
1782 | - } |
1783 | - |
1784 | - txrate->idx = 0; |
1785 | - txrate->count = ar->hw->max_rate_tries; |
1786 | - } |
1787 | - |
1788 | - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); |
1789 | } |
1790 | |
1791 | /* |
1792 | @@ -1012,11 +987,31 @@ static int carl9170_tx_prepare(struct ar9170 *ar, |
1793 | * taken from mac_control. For all fallback rate, the firmware |
1794 | * updates the mac_control flags from the rate info field. |
1795 | */ |
1796 | - for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { |
1797 | + for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { |
1798 | + __le32 phy_set; |
1799 | txrate = &info->control.rates[i]; |
1800 | if (txrate->idx < 0) |
1801 | break; |
1802 | |
1803 | + phy_set = carl9170_tx_physet(ar, info, txrate); |
1804 | + if (i == 0) { |
1805 | + /* first rate - part of the hw's frame header */ |
1806 | + txc->f.phy_control = phy_set; |
1807 | + |
1808 | + if (ampdu && txrate->flags & IEEE80211_TX_RC_MCS) |
1809 | + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); |
1810 | + if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) |
1811 | + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); |
1812 | + else if (carl9170_tx_cts_check(ar, txrate)) |
1813 | + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); |
1814 | + |
1815 | + } else { |
1816 | + /* fallback rates are stored in the firmware's |
1817 | + * retry rate set array. |
1818 | + */ |
1819 | + txc->s.rr[i - 1] = phy_set; |
1820 | + } |
1821 | + |
1822 | SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i], |
1823 | txrate->count); |
1824 | |
1825 | @@ -1027,21 +1022,13 @@ static int carl9170_tx_prepare(struct ar9170 *ar, |
1826 | txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS << |
1827 | CARL9170_TX_SUPER_RI_ERP_PROT_S); |
1828 | |
1829 | - txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate); |
1830 | + if (ampdu && (txrate->flags & IEEE80211_TX_RC_MCS)) |
1831 | + txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU; |
1832 | } |
1833 | |
1834 | - txrate = &info->control.rates[0]; |
1835 | - SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count); |
1836 | - |
1837 | - if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) |
1838 | - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); |
1839 | - else if (carl9170_tx_cts_check(ar, txrate)) |
1840 | - mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); |
1841 | - |
1842 | txc->s.len = cpu_to_le16(skb->len); |
1843 | txc->f.length = cpu_to_le16(len + FCS_LEN); |
1844 | txc->f.mac_control = mac_tmp; |
1845 | - txc->f.phy_control = carl9170_tx_physet(ar, info, txrate); |
1846 | |
1847 | arinfo = (void *)info->rate_driver_data; |
1848 | arinfo->timeout = jiffies; |
1849 | @@ -1381,9 +1368,9 @@ static void carl9170_tx(struct ar9170 *ar) |
1850 | } |
1851 | |
1852 | static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, |
1853 | - struct ieee80211_sta *sta, struct sk_buff *skb) |
1854 | + struct ieee80211_sta *sta, struct sk_buff *skb, |
1855 | + struct ieee80211_tx_info *txinfo) |
1856 | { |
1857 | - struct _carl9170_tx_superframe *super = (void *) skb->data; |
1858 | struct carl9170_sta_info *sta_info; |
1859 | struct carl9170_sta_tid *agg; |
1860 | struct sk_buff *iter; |
1861 | @@ -1450,7 +1437,7 @@ err_unlock: |
1862 | |
1863 | err_unlock_rcu: |
1864 | rcu_read_unlock(); |
1865 | - super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR); |
1866 | + txinfo->flags &= ~IEEE80211_TX_CTL_AMPDU; |
1867 | carl9170_tx_status(ar, skb, false); |
1868 | ar->tx_dropped++; |
1869 | return false; |
1870 | @@ -1492,7 +1479,7 @@ void carl9170_op_tx(struct ieee80211_hw *hw, |
1871 | * sta == NULL checks are redundant in this |
1872 | * special case. |
1873 | */ |
1874 | - run = carl9170_tx_ampdu_queue(ar, sta, skb); |
1875 | + run = carl9170_tx_ampdu_queue(ar, sta, skb, info); |
1876 | if (run) |
1877 | carl9170_tx_ampdu(ar); |
1878 | |
1879 | diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c |
1880 | index 4544342..9480e19 100644 |
1881 | --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c |
1882 | +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c |
1883 | @@ -26,7 +26,6 @@ |
1884 | #include "fwil.h" |
1885 | |
1886 | #define PKTFILTER_BUF_SIZE 128 |
1887 | -#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ |
1888 | #define BRCMF_DEFAULT_BCN_TIMEOUT 3 |
1889 | #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 |
1890 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 |
1891 | @@ -337,23 +336,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) |
1892 | goto done; |
1893 | } |
1894 | |
1895 | - /* Try to set and enable ARP offload feature, this may fail */ |
1896 | - err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE); |
1897 | - if (err) { |
1898 | - brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", |
1899 | - BRCMF_ARPOL_MODE, err); |
1900 | - err = 0; |
1901 | - } else { |
1902 | - err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1); |
1903 | - if (err) { |
1904 | - brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n", |
1905 | - err); |
1906 | - err = 0; |
1907 | - } else |
1908 | - brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n", |
1909 | - BRCMF_ARPOL_MODE); |
1910 | - } |
1911 | - |
1912 | /* Setup packet filter */ |
1913 | brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER); |
1914 | brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, |
1915 | diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h |
1916 | index 0f2c83b..665ef69 100644 |
1917 | --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h |
1918 | +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h |
1919 | @@ -23,6 +23,12 @@ |
1920 | |
1921 | #define BRCMF_FIL_ACTION_FRAME_SIZE 1800 |
1922 | |
1923 | +/* ARP Offload feature flags for arp_ol iovar */ |
1924 | +#define BRCMF_ARP_OL_AGENT 0x00000001 |
1925 | +#define BRCMF_ARP_OL_SNOOP 0x00000002 |
1926 | +#define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004 |
1927 | +#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008 |
1928 | + |
1929 | |
1930 | enum brcmf_fil_p2p_if_types { |
1931 | BRCMF_FIL_P2P_IF_CLIENT, |
1932 | diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c |
1933 | index 78da3ef..d5c4e24 100644 |
1934 | --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c |
1935 | +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c |
1936 | @@ -505,6 +505,38 @@ send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key) |
1937 | return err; |
1938 | } |
1939 | |
1940 | +static s32 |
1941 | +brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable) |
1942 | +{ |
1943 | + s32 err; |
1944 | + u32 mode; |
1945 | + |
1946 | + if (enable) |
1947 | + mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; |
1948 | + else |
1949 | + mode = 0; |
1950 | + |
1951 | + /* Try to set and enable ARP offload feature, this may fail, then it */ |
1952 | + /* is simply not supported and err 0 will be returned */ |
1953 | + err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); |
1954 | + if (err) { |
1955 | + brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", |
1956 | + mode, err); |
1957 | + err = 0; |
1958 | + } else { |
1959 | + err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); |
1960 | + if (err) { |
1961 | + brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", |
1962 | + enable, err); |
1963 | + err = 0; |
1964 | + } else |
1965 | + brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", |
1966 | + enable, mode); |
1967 | + } |
1968 | + |
1969 | + return err; |
1970 | +} |
1971 | + |
1972 | static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, |
1973 | const char *name, |
1974 | enum nl80211_iftype type, |
1975 | @@ -3709,6 +3741,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, |
1976 | } |
1977 | |
1978 | brcmf_set_mpc(ndev, 0); |
1979 | + brcmf_configure_arp_offload(ifp, false); |
1980 | |
1981 | /* find the RSN_IE */ |
1982 | rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, |
1983 | @@ -3815,8 +3848,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, |
1984 | set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); |
1985 | |
1986 | exit: |
1987 | - if (err) |
1988 | + if (err) { |
1989 | brcmf_set_mpc(ndev, 1); |
1990 | + brcmf_configure_arp_offload(ifp, true); |
1991 | + } |
1992 | return err; |
1993 | } |
1994 | |
1995 | @@ -3857,6 +3892,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) |
1996 | brcmf_err("bss_enable config failed %d\n", err); |
1997 | } |
1998 | brcmf_set_mpc(ndev, 1); |
1999 | + brcmf_configure_arp_offload(ifp, true); |
2000 | set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); |
2001 | clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); |
2002 | |
2003 | @@ -4995,6 +5031,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) |
2004 | if (err) |
2005 | goto default_conf_out; |
2006 | |
2007 | + brcmf_configure_arp_offload(ifp, true); |
2008 | + |
2009 | cfg->dongle_up = true; |
2010 | default_conf_out: |
2011 | |
2012 | diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c |
2013 | index c08d0f4..908c46d 100644 |
2014 | --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c |
2015 | +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c |
2016 | @@ -1973,26 +1973,35 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) |
2017 | } |
2018 | } |
2019 | |
2020 | -void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
2021 | - struct ieee80211_sta *sta, |
2022 | - u8 rssi_level) |
2023 | +static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
2024 | + struct ieee80211_sta *sta) |
2025 | { |
2026 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
2027 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
2028 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
2029 | - u32 ratr_value = (u32) mac->basic_rates; |
2030 | - u8 *mcsrate = mac->mcs; |
2031 | + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
2032 | + u32 ratr_value; |
2033 | u8 ratr_index = 0; |
2034 | u8 nmode = mac->ht_enable; |
2035 | - u8 mimo_ps = 1; |
2036 | - u16 shortgi_rate = 0; |
2037 | - u32 tmp_ratr_value = 0; |
2038 | + u8 mimo_ps = IEEE80211_SMPS_OFF; |
2039 | + u16 shortgi_rate; |
2040 | + u32 tmp_ratr_value; |
2041 | u8 curtxbw_40mhz = mac->bw_40; |
2042 | - u8 curshortgi_40mhz = mac->sgi_40; |
2043 | - u8 curshortgi_20mhz = mac->sgi_20; |
2044 | + u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? |
2045 | + 1 : 0; |
2046 | + u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? |
2047 | + 1 : 0; |
2048 | enum wireless_mode wirelessmode = mac->mode; |
2049 | |
2050 | - ratr_value |= ((*(u16 *) (mcsrate))) << 12; |
2051 | + if (rtlhal->current_bandtype == BAND_ON_5G) |
2052 | + ratr_value = sta->supp_rates[1] << 4; |
2053 | + else |
2054 | + ratr_value = sta->supp_rates[0]; |
2055 | + if (mac->opmode == NL80211_IFTYPE_ADHOC) |
2056 | + ratr_value = 0xfff; |
2057 | + |
2058 | + ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | |
2059 | + sta->ht_cap.mcs.rx_mask[0] << 12); |
2060 | switch (wirelessmode) { |
2061 | case WIRELESS_MODE_B: |
2062 | if (ratr_value & 0x0000000c) |
2063 | @@ -2006,7 +2015,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
2064 | case WIRELESS_MODE_N_24G: |
2065 | case WIRELESS_MODE_N_5G: |
2066 | nmode = 1; |
2067 | - if (mimo_ps == 0) { |
2068 | + if (mimo_ps == IEEE80211_SMPS_STATIC) { |
2069 | ratr_value &= 0x0007F005; |
2070 | } else { |
2071 | u32 ratr_mask; |
2072 | @@ -2016,8 +2025,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
2073 | ratr_mask = 0x000ff005; |
2074 | else |
2075 | ratr_mask = 0x0f0ff005; |
2076 | - if (curtxbw_40mhz) |
2077 | - ratr_mask |= 0x00000010; |
2078 | + |
2079 | ratr_value &= ratr_mask; |
2080 | } |
2081 | break; |
2082 | @@ -2026,41 +2034,74 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
2083 | ratr_value &= 0x000ff0ff; |
2084 | else |
2085 | ratr_value &= 0x0f0ff0ff; |
2086 | + |
2087 | break; |
2088 | } |
2089 | + |
2090 | ratr_value &= 0x0FFFFFFF; |
2091 | - if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || |
2092 | - (!curtxbw_40mhz && curshortgi_20mhz))) { |
2093 | + |
2094 | + if (nmode && ((curtxbw_40mhz && |
2095 | + curshortgi_40mhz) || (!curtxbw_40mhz && |
2096 | + curshortgi_20mhz))) { |
2097 | + |
2098 | ratr_value |= 0x10000000; |
2099 | tmp_ratr_value = (ratr_value >> 12); |
2100 | + |
2101 | for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { |
2102 | if ((1 << shortgi_rate) & tmp_ratr_value) |
2103 | break; |
2104 | } |
2105 | + |
2106 | shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | |
2107 | - (shortgi_rate << 4) | (shortgi_rate); |
2108 | + (shortgi_rate << 4) | (shortgi_rate); |
2109 | } |
2110 | + |
2111 | rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); |
2112 | + |
2113 | + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", |
2114 | + rtl_read_dword(rtlpriv, REG_ARFR0)); |
2115 | } |
2116 | |
2117 | -void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) |
2118 | +static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, |
2119 | + struct ieee80211_sta *sta, |
2120 | + u8 rssi_level) |
2121 | { |
2122 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
2123 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
2124 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
2125 | - u32 ratr_bitmap = (u32) mac->basic_rates; |
2126 | - u8 *p_mcsrate = mac->mcs; |
2127 | - u8 ratr_index = 0; |
2128 | - u8 curtxbw_40mhz = mac->bw_40; |
2129 | - u8 curshortgi_40mhz = mac->sgi_40; |
2130 | - u8 curshortgi_20mhz = mac->sgi_20; |
2131 | - enum wireless_mode wirelessmode = mac->mode; |
2132 | + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
2133 | + struct rtl_sta_info *sta_entry = NULL; |
2134 | + u32 ratr_bitmap; |
2135 | + u8 ratr_index; |
2136 | + u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; |
2137 | + u8 curshortgi_40mhz = curtxbw_40mhz && |
2138 | + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? |
2139 | + 1 : 0; |
2140 | + u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? |
2141 | + 1 : 0; |
2142 | + enum wireless_mode wirelessmode = 0; |
2143 | bool shortgi = false; |
2144 | u8 rate_mask[5]; |
2145 | u8 macid = 0; |
2146 | - u8 mimops = 1; |
2147 | - |
2148 | - ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); |
2149 | + u8 mimo_ps = IEEE80211_SMPS_OFF; |
2150 | + |
2151 | + sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
2152 | + wirelessmode = sta_entry->wireless_mode; |
2153 | + if (mac->opmode == NL80211_IFTYPE_STATION || |
2154 | + mac->opmode == NL80211_IFTYPE_MESH_POINT) |
2155 | + curtxbw_40mhz = mac->bw_40; |
2156 | + else if (mac->opmode == NL80211_IFTYPE_AP || |
2157 | + mac->opmode == NL80211_IFTYPE_ADHOC) |
2158 | + macid = sta->aid + 1; |
2159 | + |
2160 | + if (rtlhal->current_bandtype == BAND_ON_5G) |
2161 | + ratr_bitmap = sta->supp_rates[1] << 4; |
2162 | + else |
2163 | + ratr_bitmap = sta->supp_rates[0]; |
2164 | + if (mac->opmode == NL80211_IFTYPE_ADHOC) |
2165 | + ratr_bitmap = 0xfff; |
2166 | + ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | |
2167 | + sta->ht_cap.mcs.rx_mask[0] << 12); |
2168 | switch (wirelessmode) { |
2169 | case WIRELESS_MODE_B: |
2170 | ratr_index = RATR_INX_WIRELESS_B; |
2171 | @@ -2071,6 +2112,7 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) |
2172 | break; |
2173 | case WIRELESS_MODE_G: |
2174 | ratr_index = RATR_INX_WIRELESS_GB; |
2175 | + |
2176 | if (rssi_level == 1) |
2177 | ratr_bitmap &= 0x00000f00; |
2178 | else if (rssi_level == 2) |
2179 | @@ -2085,7 +2127,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) |
2180 | case WIRELESS_MODE_N_24G: |
2181 | case WIRELESS_MODE_N_5G: |
2182 | ratr_index = RATR_INX_WIRELESS_NGB; |
2183 | - if (mimops == 0) { |
2184 | + |
2185 | + if (mimo_ps == IEEE80211_SMPS_STATIC) { |
2186 | if (rssi_level == 1) |
2187 | ratr_bitmap &= 0x00070000; |
2188 | else if (rssi_level == 2) |
2189 | @@ -2128,8 +2171,10 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) |
2190 | } |
2191 | } |
2192 | } |
2193 | + |
2194 | if ((curtxbw_40mhz && curshortgi_40mhz) || |
2195 | (!curtxbw_40mhz && curshortgi_20mhz)) { |
2196 | + |
2197 | if (macid == 0) |
2198 | shortgi = true; |
2199 | else if (macid == 1) |
2200 | @@ -2138,21 +2183,42 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) |
2201 | break; |
2202 | default: |
2203 | ratr_index = RATR_INX_WIRELESS_NGB; |
2204 | + |
2205 | if (rtlphy->rf_type == RF_1T2R) |
2206 | ratr_bitmap &= 0x000ff0ff; |
2207 | else |
2208 | ratr_bitmap &= 0x0f0ff0ff; |
2209 | break; |
2210 | } |
2211 | - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n", |
2212 | - ratr_bitmap); |
2213 | - *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) | |
2214 | - ratr_index << 28); |
2215 | + sta_entry->ratr_index = ratr_index; |
2216 | + |
2217 | + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
2218 | + "ratr_bitmap :%x\n", ratr_bitmap); |
2219 | + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | |
2220 | + (ratr_index << 28); |
2221 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; |
2222 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
2223 | "Rate_index:%x, ratr_val:%x, %5phC\n", |
2224 | ratr_index, ratr_bitmap, rate_mask); |
2225 | - rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); |
2226 | + memcpy(rtlpriv->rate_mask, rate_mask, 5); |
2227 | + /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a |
2228 | + * "scheduled while atomic" if called directly */ |
2229 | + schedule_work(&rtlpriv->works.fill_h2c_cmd); |
2230 | + |
2231 | + if (macid != 0) |
2232 | + sta_entry->ratr_index = ratr_index; |
2233 | +} |
2234 | + |
2235 | +void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, |
2236 | + struct ieee80211_sta *sta, |
2237 | + u8 rssi_level) |
2238 | +{ |
2239 | + struct rtl_priv *rtlpriv = rtl_priv(hw); |
2240 | + |
2241 | + if (rtlpriv->dm.useramask) |
2242 | + rtl92cu_update_hal_rate_mask(hw, sta, rssi_level); |
2243 | + else |
2244 | + rtl92cu_update_hal_rate_table(hw, sta); |
2245 | } |
2246 | |
2247 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) |
2248 | diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h |
2249 | index f41a3aa..8e3ec1e 100644 |
2250 | --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h |
2251 | +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h |
2252 | @@ -98,10 +98,6 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, |
2253 | u32 add_msr, u32 rm_msr); |
2254 | void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); |
2255 | void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); |
2256 | -void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
2257 | - struct ieee80211_sta *sta, |
2258 | - u8 rssi_level); |
2259 | -void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); |
2260 | |
2261 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); |
2262 | bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); |
2263 | diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c |
2264 | index 85b6bdb..da4f587 100644 |
2265 | --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c |
2266 | +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c |
2267 | @@ -289,14 +289,30 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, |
2268 | macaddr = cam_const_broad; |
2269 | entry_id = key_index; |
2270 | } else { |
2271 | + if (mac->opmode == NL80211_IFTYPE_AP || |
2272 | + mac->opmode == NL80211_IFTYPE_MESH_POINT) { |
2273 | + entry_id = rtl_cam_get_free_entry(hw, |
2274 | + p_macaddr); |
2275 | + if (entry_id >= TOTAL_CAM_ENTRY) { |
2276 | + RT_TRACE(rtlpriv, COMP_SEC, |
2277 | + DBG_EMERG, |
2278 | + "Can not find free hw security cam entry\n"); |
2279 | + return; |
2280 | + } |
2281 | + } else { |
2282 | + entry_id = CAM_PAIRWISE_KEY_POSITION; |
2283 | + } |
2284 | + |
2285 | key_index = PAIRWISE_KEYIDX; |
2286 | - entry_id = CAM_PAIRWISE_KEY_POSITION; |
2287 | is_pairwise = true; |
2288 | } |
2289 | } |
2290 | if (rtlpriv->sec.key_len[key_index] == 0) { |
2291 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, |
2292 | "delete one entry\n"); |
2293 | + if (mac->opmode == NL80211_IFTYPE_AP || |
2294 | + mac->opmode == NL80211_IFTYPE_MESH_POINT) |
2295 | + rtl_cam_del_entry(hw, p_macaddr); |
2296 | rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); |
2297 | } else { |
2298 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
2299 | diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c |
2300 | index a73a17b..a71614f 100644 |
2301 | --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c |
2302 | +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c |
2303 | @@ -106,8 +106,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { |
2304 | .update_interrupt_mask = rtl92cu_update_interrupt_mask, |
2305 | .get_hw_reg = rtl92cu_get_hw_reg, |
2306 | .set_hw_reg = rtl92cu_set_hw_reg, |
2307 | - .update_rate_tbl = rtl92cu_update_hal_rate_table, |
2308 | - .update_rate_mask = rtl92cu_update_hal_rate_mask, |
2309 | + .update_rate_tbl = rtl92cu_update_hal_rate_tbl, |
2310 | .fill_tx_desc = rtl92cu_tx_fill_desc, |
2311 | .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, |
2312 | .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, |
2313 | @@ -137,6 +136,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { |
2314 | .phy_lc_calibrate = _rtl92cu_phy_lc_calibrate, |
2315 | .phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback, |
2316 | .dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower, |
2317 | + .fill_h2c_cmd = rtl92c_fill_h2c_cmd, |
2318 | }; |
2319 | |
2320 | static struct rtl_mod_params rtl92cu_mod_params = { |
2321 | diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h |
2322 | index a1310ab..262e1e4 100644 |
2323 | --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h |
2324 | +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h |
2325 | @@ -49,5 +49,8 @@ bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, |
2326 | u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, |
2327 | enum radio_path rfpath, u32 regaddr, u32 bitmask); |
2328 | void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); |
2329 | +void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, |
2330 | + struct ieee80211_sta *sta, |
2331 | + u8 rssi_level); |
2332 | |
2333 | #endif |
2334 | diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c |
2335 | index 5847d6d..dbada54 100644 |
2336 | --- a/drivers/net/wireless/rtlwifi/usb.c |
2337 | +++ b/drivers/net/wireless/rtlwifi/usb.c |
2338 | @@ -740,6 +740,7 @@ static void rtl_usb_stop(struct ieee80211_hw *hw) |
2339 | |
2340 | /* should after adapter start and interrupt enable. */ |
2341 | set_hal_stop(rtlhal); |
2342 | + cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); |
2343 | /* Enable software */ |
2344 | SET_USB_STOP(rtlusb); |
2345 | rtl_usb_deinit(hw); |
2346 | @@ -942,6 +943,16 @@ static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw, |
2347 | return false; |
2348 | } |
2349 | |
2350 | +static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work) |
2351 | +{ |
2352 | + struct rtl_works *rtlworks = |
2353 | + container_of(work, struct rtl_works, fill_h2c_cmd); |
2354 | + struct ieee80211_hw *hw = rtlworks->hw; |
2355 | + struct rtl_priv *rtlpriv = rtl_priv(hw); |
2356 | + |
2357 | + rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask); |
2358 | +} |
2359 | + |
2360 | static struct rtl_intf_ops rtl_usb_ops = { |
2361 | .adapter_start = rtl_usb_start, |
2362 | .adapter_stop = rtl_usb_stop, |
2363 | @@ -973,6 +984,8 @@ int rtl_usb_probe(struct usb_interface *intf, |
2364 | |
2365 | /* this spin lock must be initialized early */ |
2366 | spin_lock_init(&rtlpriv->locks.usb_lock); |
2367 | + INIT_WORK(&rtlpriv->works.fill_h2c_cmd, |
2368 | + rtl_fill_h2c_cmd_work_callback); |
2369 | |
2370 | rtlpriv->usb_data_index = 0; |
2371 | init_completion(&rtlpriv->firmware_loading_complete); |
2372 | diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h |
2373 | index f13258a..a33779b 100644 |
2374 | --- a/drivers/net/wireless/rtlwifi/wifi.h |
2375 | +++ b/drivers/net/wireless/rtlwifi/wifi.h |
2376 | @@ -1572,6 +1572,8 @@ struct rtl_hal_ops { |
2377 | void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, |
2378 | bool mstate); |
2379 | void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); |
2380 | + void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id, |
2381 | + u32 cmd_len, u8 *p_cmdbuffer); |
2382 | }; |
2383 | |
2384 | struct rtl_intf_ops { |
2385 | @@ -1698,6 +1700,7 @@ struct rtl_works { |
2386 | struct delayed_work ps_rfon_wq; |
2387 | |
2388 | struct work_struct lps_leave_work; |
2389 | + struct work_struct fill_h2c_cmd; |
2390 | }; |
2391 | |
2392 | struct rtl_debug { |
2393 | @@ -1866,6 +1869,7 @@ struct rtl_priv { |
2394 | bool bt_operation_on; |
2395 | }; |
2396 | }; |
2397 | + u8 rate_mask[5]; |
2398 | |
2399 | /*This must be the last item so |
2400 | that it points to the data allocated |
2401 | diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c |
2402 | index 8099e9d..401e414 100644 |
2403 | --- a/drivers/net/xen-netback/netback.c |
2404 | +++ b/drivers/net/xen-netback/netback.c |
2405 | @@ -39,6 +39,7 @@ |
2406 | #include <linux/udp.h> |
2407 | |
2408 | #include <net/tcp.h> |
2409 | +#include <net/flow_keys.h> |
2410 | |
2411 | #include <xen/xen.h> |
2412 | #include <xen/events.h> |
2413 | @@ -1352,6 +1353,7 @@ static int checksum_setup(struct xenvif *vif, struct sk_buff *skb) |
2414 | if (th >= skb_tail_pointer(skb)) |
2415 | goto out; |
2416 | |
2417 | + skb_set_transport_header(skb, 4 * iph->ihl); |
2418 | skb->csum_start = th - skb->head; |
2419 | switch (iph->protocol) { |
2420 | case IPPROTO_TCP: |
2421 | @@ -1665,6 +1667,7 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk) |
2422 | |
2423 | skb->dev = vif->dev; |
2424 | skb->protocol = eth_type_trans(skb, skb->dev); |
2425 | + skb_reset_network_header(skb); |
2426 | |
2427 | if (checksum_setup(vif, skb)) { |
2428 | netdev_dbg(vif->dev, |
2429 | @@ -1673,6 +1676,15 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk) |
2430 | continue; |
2431 | } |
2432 | |
2433 | + if (!skb_transport_header_was_set(skb)) { |
2434 | + struct flow_keys keys; |
2435 | + |
2436 | + if (skb_flow_dissect(skb, &keys)) |
2437 | + skb_set_transport_header(skb, keys.thoff); |
2438 | + else |
2439 | + skb_reset_transport_header(skb); |
2440 | + } |
2441 | + |
2442 | vif->dev->stats.rx_bytes += skb->len; |
2443 | vif->dev->stats.rx_packets++; |
2444 | |
2445 | diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c |
2446 | index 9544cdc..e79e006 100644 |
2447 | --- a/drivers/parisc/iosapic.c |
2448 | +++ b/drivers/parisc/iosapic.c |
2449 | @@ -811,6 +811,70 @@ int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev) |
2450 | return pcidev->irq; |
2451 | } |
2452 | |
2453 | +static struct iosapic_info *first_isi = NULL; |
2454 | + |
2455 | +#ifdef CONFIG_64BIT |
2456 | +int iosapic_serial_irq(int num) |
2457 | +{ |
2458 | + struct iosapic_info *isi = first_isi; |
2459 | + struct irt_entry *irte = NULL; /* only used if PAT PDC */ |
2460 | + struct vector_info *vi; |
2461 | + int isi_line; /* line used by device */ |
2462 | + |
2463 | + /* lookup IRT entry for isi/slot/pin set */ |
2464 | + irte = &irt_cell[num]; |
2465 | + |
2466 | + DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n", |
2467 | + irte, |
2468 | + irte->entry_type, |
2469 | + irte->entry_length, |
2470 | + irte->polarity_trigger, |
2471 | + irte->src_bus_irq_devno, |
2472 | + irte->src_bus_id, |
2473 | + irte->src_seg_id, |
2474 | + irte->dest_iosapic_intin, |
2475 | + (u32) irte->dest_iosapic_addr); |
2476 | + isi_line = irte->dest_iosapic_intin; |
2477 | + |
2478 | + /* get vector info for this input line */ |
2479 | + vi = isi->isi_vector + isi_line; |
2480 | + DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", isi_line, vi); |
2481 | + |
2482 | + /* If this IRQ line has already been setup, skip it */ |
2483 | + if (vi->irte) |
2484 | + goto out; |
2485 | + |
2486 | + vi->irte = irte; |
2487 | + |
2488 | + /* |
2489 | + * Allocate processor IRQ |
2490 | + * |
2491 | + * XXX/FIXME The txn_alloc_irq() code and related code should be |
2492 | + * moved to enable_irq(). That way we only allocate processor IRQ |
2493 | + * bits for devices that actually have drivers claiming them. |
2494 | + * Right now we assign an IRQ to every PCI device present, |
2495 | + * regardless of whether it's used or not. |
2496 | + */ |
2497 | + vi->txn_irq = txn_alloc_irq(8); |
2498 | + |
2499 | + if (vi->txn_irq < 0) |
2500 | + panic("I/O sapic: couldn't get TXN IRQ\n"); |
2501 | + |
2502 | + /* enable_irq() will use txn_* to program IRdT */ |
2503 | + vi->txn_addr = txn_alloc_addr(vi->txn_irq); |
2504 | + vi->txn_data = txn_alloc_data(vi->txn_irq); |
2505 | + |
2506 | + vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI; |
2507 | + vi->eoi_data = cpu_to_le32(vi->txn_data); |
2508 | + |
2509 | + cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi); |
2510 | + |
2511 | + out: |
2512 | + |
2513 | + return vi->txn_irq; |
2514 | +} |
2515 | +#endif |
2516 | + |
2517 | |
2518 | /* |
2519 | ** squirrel away the I/O Sapic Version |
2520 | @@ -877,6 +941,8 @@ void *iosapic_register(unsigned long hpa) |
2521 | vip->irqline = (unsigned char) cnt; |
2522 | vip->iosapic = isi; |
2523 | } |
2524 | + if (!first_isi) |
2525 | + first_isi = isi; |
2526 | return isi; |
2527 | } |
2528 | |
2529 | diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c |
2530 | index 050773c..b2ff8ef 100644 |
2531 | --- a/drivers/parport/parport_gsc.c |
2532 | +++ b/drivers/parport/parport_gsc.c |
2533 | @@ -234,7 +234,7 @@ static int parport_PS2_supported(struct parport *pb) |
2534 | |
2535 | struct parport *parport_gsc_probe_port(unsigned long base, |
2536 | unsigned long base_hi, int irq, |
2537 | - int dma, struct pci_dev *dev) |
2538 | + int dma, struct parisc_device *padev) |
2539 | { |
2540 | struct parport_gsc_private *priv; |
2541 | struct parport_operations *ops; |
2542 | @@ -258,7 +258,6 @@ struct parport *parport_gsc_probe_port(unsigned long base, |
2543 | priv->ctr_writable = 0xff; |
2544 | priv->dma_buf = 0; |
2545 | priv->dma_handle = 0; |
2546 | - priv->dev = dev; |
2547 | p->base = base; |
2548 | p->base_hi = base_hi; |
2549 | p->irq = irq; |
2550 | @@ -282,6 +281,7 @@ struct parport *parport_gsc_probe_port(unsigned long base, |
2551 | return NULL; |
2552 | } |
2553 | |
2554 | + p->dev = &padev->dev; |
2555 | p->base_hi = base_hi; |
2556 | p->modes = tmp.modes; |
2557 | p->size = (p->modes & PARPORT_MODE_EPP)?8:3; |
2558 | @@ -373,7 +373,7 @@ static int parport_init_chip(struct parisc_device *dev) |
2559 | } |
2560 | |
2561 | p = parport_gsc_probe_port(port, 0, dev->irq, |
2562 | - /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL); |
2563 | + /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, dev); |
2564 | if (p) |
2565 | parport_count++; |
2566 | dev_set_drvdata(&dev->dev, p); |
2567 | diff --git a/drivers/parport/parport_gsc.h b/drivers/parport/parport_gsc.h |
2568 | index fc9c37c..8122147 100644 |
2569 | --- a/drivers/parport/parport_gsc.h |
2570 | +++ b/drivers/parport/parport_gsc.h |
2571 | @@ -217,6 +217,6 @@ extern void parport_gsc_dec_use_count(void); |
2572 | extern struct parport *parport_gsc_probe_port(unsigned long base, |
2573 | unsigned long base_hi, |
2574 | int irq, int dma, |
2575 | - struct pci_dev *dev); |
2576 | + struct parisc_device *padev); |
2577 | |
2578 | #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */ |
2579 | diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
2580 | index d182c96..0c58bd1 100644 |
2581 | --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
2582 | +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
2583 | @@ -688,8 +688,12 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) |
2584 | * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen |
2585 | * for qla_tgt_xmit_response LLD code |
2586 | */ |
2587 | + if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { |
2588 | + se_cmd->se_cmd_flags &= ~SCF_OVERFLOW_BIT; |
2589 | + se_cmd->residual_count = 0; |
2590 | + } |
2591 | se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; |
2592 | - se_cmd->residual_count = se_cmd->data_length; |
2593 | + se_cmd->residual_count += se_cmd->data_length; |
2594 | |
2595 | cmd->bufflen = 0; |
2596 | } |
2597 | diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c |
2598 | index c735c5a..6427600 100644 |
2599 | --- a/drivers/spi/spi-pxa2xx-dma.c |
2600 | +++ b/drivers/spi/spi-pxa2xx-dma.c |
2601 | @@ -59,7 +59,7 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data, |
2602 | int ret; |
2603 | |
2604 | sg_free_table(sgt); |
2605 | - ret = sg_alloc_table(sgt, nents, GFP_KERNEL); |
2606 | + ret = sg_alloc_table(sgt, nents, GFP_ATOMIC); |
2607 | if (ret) |
2608 | return ret; |
2609 | } |
2610 | diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c |
2611 | index 8104138..0a6dac4 100644 |
2612 | --- a/drivers/spi/spi-pxa2xx.c |
2613 | +++ b/drivers/spi/spi-pxa2xx.c |
2614 | @@ -1069,7 +1069,7 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) |
2615 | acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev)) |
2616 | return NULL; |
2617 | |
2618 | - pdata = devm_kzalloc(&pdev->dev, sizeof(*ssp), GFP_KERNEL); |
2619 | + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
2620 | if (!pdata) { |
2621 | dev_err(&pdev->dev, |
2622 | "failed to allocate memory for platform data\n"); |
2623 | diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c |
2624 | index 8e6298c..dcb199d 100644 |
2625 | --- a/drivers/target/iscsi/iscsi_target_erl0.c |
2626 | +++ b/drivers/target/iscsi/iscsi_target_erl0.c |
2627 | @@ -842,11 +842,11 @@ int iscsit_stop_time2retain_timer(struct iscsi_session *sess) |
2628 | return 0; |
2629 | |
2630 | sess->time2retain_timer_flags |= ISCSI_TF_STOP; |
2631 | - spin_unlock_bh(&se_tpg->session_lock); |
2632 | + spin_unlock(&se_tpg->session_lock); |
2633 | |
2634 | del_timer_sync(&sess->time2retain_timer); |
2635 | |
2636 | - spin_lock_bh(&se_tpg->session_lock); |
2637 | + spin_lock(&se_tpg->session_lock); |
2638 | sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING; |
2639 | pr_debug("Stopped Time2Retain Timer for SID: %u\n", |
2640 | sess->sid); |
2641 | diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c |
2642 | index 125e0fd..74a5e8b 100644 |
2643 | --- a/drivers/tty/pty.c |
2644 | +++ b/drivers/tty/pty.c |
2645 | @@ -244,14 +244,9 @@ static void pty_flush_buffer(struct tty_struct *tty) |
2646 | |
2647 | static int pty_open(struct tty_struct *tty, struct file *filp) |
2648 | { |
2649 | - int retval = -ENODEV; |
2650 | - |
2651 | if (!tty || !tty->link) |
2652 | - goto out; |
2653 | - |
2654 | - set_bit(TTY_IO_ERROR, &tty->flags); |
2655 | + return -ENODEV; |
2656 | |
2657 | - retval = -EIO; |
2658 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) |
2659 | goto out; |
2660 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) |
2661 | @@ -262,9 +257,11 @@ static int pty_open(struct tty_struct *tty, struct file *filp) |
2662 | clear_bit(TTY_IO_ERROR, &tty->flags); |
2663 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
2664 | set_bit(TTY_THROTTLED, &tty->flags); |
2665 | - retval = 0; |
2666 | + return 0; |
2667 | + |
2668 | out: |
2669 | - return retval; |
2670 | + set_bit(TTY_IO_ERROR, &tty->flags); |
2671 | + return -EIO; |
2672 | } |
2673 | |
2674 | static void pty_set_termios(struct tty_struct *tty, |
2675 | diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c |
2676 | index 097dff9..bb91b47 100644 |
2677 | --- a/drivers/tty/serial/8250/8250_gsc.c |
2678 | +++ b/drivers/tty/serial/8250/8250_gsc.c |
2679 | @@ -30,6 +30,12 @@ static int __init serial_init_chip(struct parisc_device *dev) |
2680 | unsigned long address; |
2681 | int err; |
2682 | |
2683 | +#ifdef CONFIG_64BIT |
2684 | + extern int iosapic_serial_irq(int cellnum); |
2685 | + if (!dev->irq && (dev->id.sversion == 0xad)) |
2686 | + dev->irq = iosapic_serial_irq(dev->mod_index-1); |
2687 | +#endif |
2688 | + |
2689 | if (!dev->irq) { |
2690 | /* We find some unattached serial ports by walking native |
2691 | * busses. These should be silently ignored. Otherwise, |
2692 | @@ -51,7 +57,8 @@ static int __init serial_init_chip(struct parisc_device *dev) |
2693 | memset(&uart, 0, sizeof(uart)); |
2694 | uart.port.iotype = UPIO_MEM; |
2695 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ |
2696 | - uart.port.uartclk = 7272727; |
2697 | + uart.port.uartclk = (dev->id.sversion != 0xad) ? |
2698 | + 7272727 : 1843200; |
2699 | uart.port.mapbase = address; |
2700 | uart.port.membase = ioremap_nocache(address, 16); |
2701 | uart.port.irq = dev->irq; |
2702 | @@ -73,6 +80,7 @@ static struct parisc_device_id serial_tbl[] = { |
2703 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, |
2704 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, |
2705 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, |
2706 | + { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x000ad }, |
2707 | { 0 } |
2708 | }; |
2709 | |
2710 | diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c |
2711 | index c8b9262..b645c47 100644 |
2712 | --- a/drivers/uio/uio.c |
2713 | +++ b/drivers/uio/uio.c |
2714 | @@ -374,6 +374,7 @@ static int uio_get_minor(struct uio_device *idev) |
2715 | retval = idr_alloc(&uio_idr, idev, 0, UIO_MAX_DEVICES, GFP_KERNEL); |
2716 | if (retval >= 0) { |
2717 | idev->minor = retval; |
2718 | + retval = 0; |
2719 | } else if (retval == -ENOSPC) { |
2720 | dev_err(idev->dev, "too many uio devices\n"); |
2721 | retval = -EINVAL; |
2722 | diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c |
2723 | index 73deb02..1d75833 100644 |
2724 | --- a/drivers/usb/serial/ti_usb_3410_5052.c |
2725 | +++ b/drivers/usb/serial/ti_usb_3410_5052.c |
2726 | @@ -178,7 +178,8 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { |
2727 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, |
2728 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, |
2729 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, |
2730 | - { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, |
2731 | + { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) }, |
2732 | + { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, |
2733 | { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, |
2734 | }; |
2735 | |
2736 | diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h |
2737 | index b353e7e..4a2423e 100644 |
2738 | --- a/drivers/usb/serial/ti_usb_3410_5052.h |
2739 | +++ b/drivers/usb/serial/ti_usb_3410_5052.h |
2740 | @@ -52,7 +52,9 @@ |
2741 | |
2742 | /* Abbott Diabetics vendor and product ids */ |
2743 | #define ABBOTT_VENDOR_ID 0x1a61 |
2744 | -#define ABBOTT_PRODUCT_ID 0x3410 |
2745 | +#define ABBOTT_STEREO_PLUG_ID 0x3410 |
2746 | +#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID |
2747 | +#define ABBOTT_STRIP_PORT_ID 0x3420 |
2748 | |
2749 | /* Commands */ |
2750 | #define TI_GET_VERSION 0x01 |
2751 | diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c |
2752 | index ec6fb3f..dfff647 100644 |
2753 | --- a/drivers/vhost/net.c |
2754 | +++ b/drivers/vhost/net.c |
2755 | @@ -353,7 +353,8 @@ static void handle_tx(struct vhost_net *net) |
2756 | kref_get(&ubufs->kref); |
2757 | } |
2758 | vq->upend_idx = (vq->upend_idx + 1) % UIO_MAXIOV; |
2759 | - } |
2760 | + } else |
2761 | + msg.msg_control = NULL; |
2762 | /* TODO: Check specific error and bomb out unless ENOBUFS? */ |
2763 | err = sock->ops->sendmsg(NULL, sock, &msg, len); |
2764 | if (unlikely(err < 0)) { |
2765 | diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h |
2766 | index 1d795df..2f522a3 100644 |
2767 | --- a/include/linux/perf_event.h |
2768 | +++ b/include/linux/perf_event.h |
2769 | @@ -404,8 +404,7 @@ struct perf_event { |
2770 | /* mmap bits */ |
2771 | struct mutex mmap_mutex; |
2772 | atomic_t mmap_count; |
2773 | - int mmap_locked; |
2774 | - struct user_struct *mmap_user; |
2775 | + |
2776 | struct ring_buffer *rb; |
2777 | struct list_head rb_entry; |
2778 | |
2779 | diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h |
2780 | index 2ae1371..1c33dd7 100644 |
2781 | --- a/include/linux/rculist_nulls.h |
2782 | +++ b/include/linux/rculist_nulls.h |
2783 | @@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n, |
2784 | * @head: the head for your list. |
2785 | * @member: the name of the hlist_nulls_node within the struct. |
2786 | * |
2787 | + * The barrier() is needed to make sure compiler doesn't cache first element [1], |
2788 | + * as this loop can be restarted [2] |
2789 | + * [1] Documentation/atomic_ops.txt around line 114 |
2790 | + * [2] Documentation/RCU/rculist_nulls.txt around line 146 |
2791 | */ |
2792 | #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \ |
2793 | - for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ |
2794 | + for (({barrier();}), \ |
2795 | + pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ |
2796 | (!is_a_nulls(pos)) && \ |
2797 | ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \ |
2798 | pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos))) |
2799 | diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h |
2800 | index b8292d8..1f2803c 100644 |
2801 | --- a/include/linux/skbuff.h |
2802 | +++ b/include/linux/skbuff.h |
2803 | @@ -2761,6 +2761,21 @@ static inline int skb_tnl_header_len(const struct sk_buff *inner_skb) |
2804 | SKB_GSO_CB(inner_skb)->mac_offset; |
2805 | } |
2806 | |
2807 | +static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra) |
2808 | +{ |
2809 | + int new_headroom, headroom; |
2810 | + int ret; |
2811 | + |
2812 | + headroom = skb_headroom(skb); |
2813 | + ret = pskb_expand_head(skb, extra, 0, GFP_ATOMIC); |
2814 | + if (ret) |
2815 | + return ret; |
2816 | + |
2817 | + new_headroom = skb_headroom(skb); |
2818 | + SKB_GSO_CB(skb)->mac_offset += (new_headroom - headroom); |
2819 | + return 0; |
2820 | +} |
2821 | + |
2822 | static inline bool skb_is_gso(const struct sk_buff *skb) |
2823 | { |
2824 | return skb_shinfo(skb)->gso_size; |
2825 | diff --git a/include/linux/socket.h b/include/linux/socket.h |
2826 | index 2b9f74b..e897bdc 100644 |
2827 | --- a/include/linux/socket.h |
2828 | +++ b/include/linux/socket.h |
2829 | @@ -321,6 +321,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); |
2830 | |
2831 | struct timespec; |
2832 | |
2833 | +/* The __sys_...msg variants allow MSG_CMSG_COMPAT */ |
2834 | +extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); |
2835 | +extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); |
2836 | extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
2837 | unsigned int flags, struct timespec *timeout); |
2838 | extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, |
2839 | diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h |
2840 | index f10818f..e7f4e21 100644 |
2841 | --- a/include/net/sch_generic.h |
2842 | +++ b/include/net/sch_generic.h |
2843 | @@ -679,22 +679,26 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask, |
2844 | #endif |
2845 | |
2846 | struct psched_ratecfg { |
2847 | - u64 rate_bps; |
2848 | - u32 mult; |
2849 | - u32 shift; |
2850 | + u64 rate_bps; |
2851 | + u32 mult; |
2852 | + u16 overhead; |
2853 | + u8 shift; |
2854 | }; |
2855 | |
2856 | static inline u64 psched_l2t_ns(const struct psched_ratecfg *r, |
2857 | unsigned int len) |
2858 | { |
2859 | - return ((u64)len * r->mult) >> r->shift; |
2860 | + return ((u64)(len + r->overhead) * r->mult) >> r->shift; |
2861 | } |
2862 | |
2863 | -extern void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate); |
2864 | +extern void psched_ratecfg_precompute(struct psched_ratecfg *r, const struct tc_ratespec *conf); |
2865 | |
2866 | -static inline u32 psched_ratecfg_getrate(const struct psched_ratecfg *r) |
2867 | +static inline void psched_ratecfg_getrate(struct tc_ratespec *res, |
2868 | + const struct psched_ratecfg *r) |
2869 | { |
2870 | - return r->rate_bps >> 3; |
2871 | + memset(res, 0, sizeof(*res)); |
2872 | + res->rate = r->rate_bps >> 3; |
2873 | + res->overhead = r->overhead; |
2874 | } |
2875 | |
2876 | #endif |
2877 | diff --git a/kernel/events/core.c b/kernel/events/core.c |
2878 | index 9fcb094..f8ddcfb 100644 |
2879 | --- a/kernel/events/core.c |
2880 | +++ b/kernel/events/core.c |
2881 | @@ -194,9 +194,6 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, |
2882 | static void update_context_time(struct perf_event_context *ctx); |
2883 | static u64 perf_event_time(struct perf_event *event); |
2884 | |
2885 | -static void ring_buffer_attach(struct perf_event *event, |
2886 | - struct ring_buffer *rb); |
2887 | - |
2888 | void __weak perf_event_print_debug(void) { } |
2889 | |
2890 | extern __weak const char *perf_pmu_name(void) |
2891 | @@ -2867,6 +2864,7 @@ static void free_event_rcu(struct rcu_head *head) |
2892 | } |
2893 | |
2894 | static void ring_buffer_put(struct ring_buffer *rb); |
2895 | +static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb); |
2896 | |
2897 | static void free_event(struct perf_event *event) |
2898 | { |
2899 | @@ -2891,15 +2889,30 @@ static void free_event(struct perf_event *event) |
2900 | if (has_branch_stack(event)) { |
2901 | static_key_slow_dec_deferred(&perf_sched_events); |
2902 | /* is system-wide event */ |
2903 | - if (!(event->attach_state & PERF_ATTACH_TASK)) |
2904 | + if (!(event->attach_state & PERF_ATTACH_TASK)) { |
2905 | atomic_dec(&per_cpu(perf_branch_stack_events, |
2906 | event->cpu)); |
2907 | + } |
2908 | } |
2909 | } |
2910 | |
2911 | if (event->rb) { |
2912 | - ring_buffer_put(event->rb); |
2913 | - event->rb = NULL; |
2914 | + struct ring_buffer *rb; |
2915 | + |
2916 | + /* |
2917 | + * Can happen when we close an event with re-directed output. |
2918 | + * |
2919 | + * Since we have a 0 refcount, perf_mmap_close() will skip |
2920 | + * over us; possibly making our ring_buffer_put() the last. |
2921 | + */ |
2922 | + mutex_lock(&event->mmap_mutex); |
2923 | + rb = event->rb; |
2924 | + if (rb) { |
2925 | + rcu_assign_pointer(event->rb, NULL); |
2926 | + ring_buffer_detach(event, rb); |
2927 | + ring_buffer_put(rb); /* could be last */ |
2928 | + } |
2929 | + mutex_unlock(&event->mmap_mutex); |
2930 | } |
2931 | |
2932 | if (is_cgroup_event(event)) |
2933 | @@ -3137,30 +3150,13 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) |
2934 | unsigned int events = POLL_HUP; |
2935 | |
2936 | /* |
2937 | - * Race between perf_event_set_output() and perf_poll(): perf_poll() |
2938 | - * grabs the rb reference but perf_event_set_output() overrides it. |
2939 | - * Here is the timeline for two threads T1, T2: |
2940 | - * t0: T1, rb = rcu_dereference(event->rb) |
2941 | - * t1: T2, old_rb = event->rb |
2942 | - * t2: T2, event->rb = new rb |
2943 | - * t3: T2, ring_buffer_detach(old_rb) |
2944 | - * t4: T1, ring_buffer_attach(rb1) |
2945 | - * t5: T1, poll_wait(event->waitq) |
2946 | - * |
2947 | - * To avoid this problem, we grab mmap_mutex in perf_poll() |
2948 | - * thereby ensuring that the assignment of the new ring buffer |
2949 | - * and the detachment of the old buffer appear atomic to perf_poll() |
2950 | + * Pin the event->rb by taking event->mmap_mutex; otherwise |
2951 | + * perf_event_set_output() can swizzle our rb and make us miss wakeups. |
2952 | */ |
2953 | mutex_lock(&event->mmap_mutex); |
2954 | - |
2955 | - rcu_read_lock(); |
2956 | - rb = rcu_dereference(event->rb); |
2957 | - if (rb) { |
2958 | - ring_buffer_attach(event, rb); |
2959 | + rb = event->rb; |
2960 | + if (rb) |
2961 | events = atomic_xchg(&rb->poll, 0); |
2962 | - } |
2963 | - rcu_read_unlock(); |
2964 | - |
2965 | mutex_unlock(&event->mmap_mutex); |
2966 | |
2967 | poll_wait(file, &event->waitq, wait); |
2968 | @@ -3470,16 +3466,12 @@ static void ring_buffer_attach(struct perf_event *event, |
2969 | return; |
2970 | |
2971 | spin_lock_irqsave(&rb->event_lock, flags); |
2972 | - if (!list_empty(&event->rb_entry)) |
2973 | - goto unlock; |
2974 | - |
2975 | - list_add(&event->rb_entry, &rb->event_list); |
2976 | -unlock: |
2977 | + if (list_empty(&event->rb_entry)) |
2978 | + list_add(&event->rb_entry, &rb->event_list); |
2979 | spin_unlock_irqrestore(&rb->event_lock, flags); |
2980 | } |
2981 | |
2982 | -static void ring_buffer_detach(struct perf_event *event, |
2983 | - struct ring_buffer *rb) |
2984 | +static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb) |
2985 | { |
2986 | unsigned long flags; |
2987 | |
2988 | @@ -3498,13 +3490,10 @@ static void ring_buffer_wakeup(struct perf_event *event) |
2989 | |
2990 | rcu_read_lock(); |
2991 | rb = rcu_dereference(event->rb); |
2992 | - if (!rb) |
2993 | - goto unlock; |
2994 | - |
2995 | - list_for_each_entry_rcu(event, &rb->event_list, rb_entry) |
2996 | - wake_up_all(&event->waitq); |
2997 | - |
2998 | -unlock: |
2999 | + if (rb) { |
3000 | + list_for_each_entry_rcu(event, &rb->event_list, rb_entry) |
3001 | + wake_up_all(&event->waitq); |
3002 | + } |
3003 | rcu_read_unlock(); |
3004 | } |
3005 | |
3006 | @@ -3533,18 +3522,10 @@ static struct ring_buffer *ring_buffer_get(struct perf_event *event) |
3007 | |
3008 | static void ring_buffer_put(struct ring_buffer *rb) |
3009 | { |
3010 | - struct perf_event *event, *n; |
3011 | - unsigned long flags; |
3012 | - |
3013 | if (!atomic_dec_and_test(&rb->refcount)) |
3014 | return; |
3015 | |
3016 | - spin_lock_irqsave(&rb->event_lock, flags); |
3017 | - list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) { |
3018 | - list_del_init(&event->rb_entry); |
3019 | - wake_up_all(&event->waitq); |
3020 | - } |
3021 | - spin_unlock_irqrestore(&rb->event_lock, flags); |
3022 | + WARN_ON_ONCE(!list_empty(&rb->event_list)); |
3023 | |
3024 | call_rcu(&rb->rcu_head, rb_free_rcu); |
3025 | } |
3026 | @@ -3554,26 +3535,100 @@ static void perf_mmap_open(struct vm_area_struct *vma) |
3027 | struct perf_event *event = vma->vm_file->private_data; |
3028 | |
3029 | atomic_inc(&event->mmap_count); |
3030 | + atomic_inc(&event->rb->mmap_count); |
3031 | } |
3032 | |
3033 | +/* |
3034 | + * A buffer can be mmap()ed multiple times; either directly through the same |
3035 | + * event, or through other events by use of perf_event_set_output(). |
3036 | + * |
3037 | + * In order to undo the VM accounting done by perf_mmap() we need to destroy |
3038 | + * the buffer here, where we still have a VM context. This means we need |
3039 | + * to detach all events redirecting to us. |
3040 | + */ |
3041 | static void perf_mmap_close(struct vm_area_struct *vma) |
3042 | { |
3043 | struct perf_event *event = vma->vm_file->private_data; |
3044 | |
3045 | - if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) { |
3046 | - unsigned long size = perf_data_size(event->rb); |
3047 | - struct user_struct *user = event->mmap_user; |
3048 | - struct ring_buffer *rb = event->rb; |
3049 | + struct ring_buffer *rb = event->rb; |
3050 | + struct user_struct *mmap_user = rb->mmap_user; |
3051 | + int mmap_locked = rb->mmap_locked; |
3052 | + unsigned long size = perf_data_size(rb); |
3053 | + |
3054 | + atomic_dec(&rb->mmap_count); |
3055 | + |
3056 | + if (!atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) |
3057 | + return; |
3058 | |
3059 | - atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm); |
3060 | - vma->vm_mm->pinned_vm -= event->mmap_locked; |
3061 | - rcu_assign_pointer(event->rb, NULL); |
3062 | - ring_buffer_detach(event, rb); |
3063 | + /* Detach current event from the buffer. */ |
3064 | + rcu_assign_pointer(event->rb, NULL); |
3065 | + ring_buffer_detach(event, rb); |
3066 | + mutex_unlock(&event->mmap_mutex); |
3067 | + |
3068 | + /* If there's still other mmap()s of this buffer, we're done. */ |
3069 | + if (atomic_read(&rb->mmap_count)) { |
3070 | + ring_buffer_put(rb); /* can't be last */ |
3071 | + return; |
3072 | + } |
3073 | + |
3074 | + /* |
3075 | + * No other mmap()s, detach from all other events that might redirect |
3076 | + * into the now unreachable buffer. Somewhat complicated by the |
3077 | + * fact that rb::event_lock otherwise nests inside mmap_mutex. |
3078 | + */ |
3079 | +again: |
3080 | + rcu_read_lock(); |
3081 | + list_for_each_entry_rcu(event, &rb->event_list, rb_entry) { |
3082 | + if (!atomic_long_inc_not_zero(&event->refcount)) { |
3083 | + /* |
3084 | + * This event is en-route to free_event() which will |
3085 | + * detach it and remove it from the list. |
3086 | + */ |
3087 | + continue; |
3088 | + } |
3089 | + rcu_read_unlock(); |
3090 | + |
3091 | + mutex_lock(&event->mmap_mutex); |
3092 | + /* |
3093 | + * Check we didn't race with perf_event_set_output() which can |
3094 | + * swizzle the rb from under us while we were waiting to |
3095 | + * acquire mmap_mutex. |
3096 | + * |
3097 | + * If we find a different rb; ignore this event, a next |
3098 | + * iteration will no longer find it on the list. We have to |
3099 | + * still restart the iteration to make sure we're not now |
3100 | + * iterating the wrong list. |
3101 | + */ |
3102 | + if (event->rb == rb) { |
3103 | + rcu_assign_pointer(event->rb, NULL); |
3104 | + ring_buffer_detach(event, rb); |
3105 | + ring_buffer_put(rb); /* can't be last, we still have one */ |
3106 | + } |
3107 | mutex_unlock(&event->mmap_mutex); |
3108 | + put_event(event); |
3109 | |
3110 | - ring_buffer_put(rb); |
3111 | - free_uid(user); |
3112 | + /* |
3113 | + * Restart the iteration; either we're on the wrong list or |
3114 | + * destroyed its integrity by doing a deletion. |
3115 | + */ |
3116 | + goto again; |
3117 | } |
3118 | + rcu_read_unlock(); |
3119 | + |
3120 | + /* |
3121 | + * It could be there's still a few 0-ref events on the list; they'll |
3122 | + * get cleaned up by free_event() -- they'll also still have their |
3123 | + * ref on the rb and will free it whenever they are done with it. |
3124 | + * |
3125 | + * Aside from that, this buffer is 'fully' detached and unmapped, |
3126 | + * undo the VM accounting. |
3127 | + */ |
3128 | + |
3129 | + atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm); |
3130 | + vma->vm_mm->pinned_vm -= mmap_locked; |
3131 | + free_uid(mmap_user); |
3132 | + |
3133 | + ring_buffer_put(rb); /* could be last */ |
3134 | } |
3135 | |
3136 | static const struct vm_operations_struct perf_mmap_vmops = { |
3137 | @@ -3623,12 +3678,24 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) |
3138 | return -EINVAL; |
3139 | |
3140 | WARN_ON_ONCE(event->ctx->parent_ctx); |
3141 | +again: |
3142 | mutex_lock(&event->mmap_mutex); |
3143 | if (event->rb) { |
3144 | - if (event->rb->nr_pages == nr_pages) |
3145 | - atomic_inc(&event->rb->refcount); |
3146 | - else |
3147 | + if (event->rb->nr_pages != nr_pages) { |
3148 | ret = -EINVAL; |
3149 | + goto unlock; |
3150 | + } |
3151 | + |
3152 | + if (!atomic_inc_not_zero(&event->rb->mmap_count)) { |
3153 | + /* |
3154 | + * Raced against perf_mmap_close() through |
3155 | + * perf_event_set_output(). Try again, hope for better |
3156 | + * luck. |
3157 | + */ |
3158 | + mutex_unlock(&event->mmap_mutex); |
3159 | + goto again; |
3160 | + } |
3161 | + |
3162 | goto unlock; |
3163 | } |
3164 | |
3165 | @@ -3669,12 +3736,16 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) |
3166 | ret = -ENOMEM; |
3167 | goto unlock; |
3168 | } |
3169 | - rcu_assign_pointer(event->rb, rb); |
3170 | + |
3171 | + atomic_set(&rb->mmap_count, 1); |
3172 | + rb->mmap_locked = extra; |
3173 | + rb->mmap_user = get_current_user(); |
3174 | |
3175 | atomic_long_add(user_extra, &user->locked_vm); |
3176 | - event->mmap_locked = extra; |
3177 | - event->mmap_user = get_current_user(); |
3178 | - vma->vm_mm->pinned_vm += event->mmap_locked; |
3179 | + vma->vm_mm->pinned_vm += extra; |
3180 | + |
3181 | + ring_buffer_attach(event, rb); |
3182 | + rcu_assign_pointer(event->rb, rb); |
3183 | |
3184 | perf_event_update_userpage(event); |
3185 | |
3186 | @@ -3683,7 +3754,11 @@ unlock: |
3187 | atomic_inc(&event->mmap_count); |
3188 | mutex_unlock(&event->mmap_mutex); |
3189 | |
3190 | - vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; |
3191 | + /* |
3192 | + * Since pinned accounting is per vm we cannot allow fork() to copy our |
3193 | + * vma. |
3194 | + */ |
3195 | + vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP; |
3196 | vma->vm_ops = &perf_mmap_vmops; |
3197 | |
3198 | return ret; |
3199 | @@ -6414,6 +6489,8 @@ set: |
3200 | if (atomic_read(&event->mmap_count)) |
3201 | goto unlock; |
3202 | |
3203 | + old_rb = event->rb; |
3204 | + |
3205 | if (output_event) { |
3206 | /* get the rb we want to redirect to */ |
3207 | rb = ring_buffer_get(output_event); |
3208 | @@ -6421,16 +6498,28 @@ set: |
3209 | goto unlock; |
3210 | } |
3211 | |
3212 | - old_rb = event->rb; |
3213 | - rcu_assign_pointer(event->rb, rb); |
3214 | if (old_rb) |
3215 | ring_buffer_detach(event, old_rb); |
3216 | + |
3217 | + if (rb) |
3218 | + ring_buffer_attach(event, rb); |
3219 | + |
3220 | + rcu_assign_pointer(event->rb, rb); |
3221 | + |
3222 | + if (old_rb) { |
3223 | + ring_buffer_put(old_rb); |
3224 | + /* |
3225 | + * Since we detached before setting the new rb, so that we |
3226 | + * could attach the new rb, we could have missed a wakeup. |
3227 | + * Provide it now. |
3228 | + */ |
3229 | + wake_up_all(&event->waitq); |
3230 | + } |
3231 | + |
3232 | ret = 0; |
3233 | unlock: |
3234 | mutex_unlock(&event->mmap_mutex); |
3235 | |
3236 | - if (old_rb) |
3237 | - ring_buffer_put(old_rb); |
3238 | out: |
3239 | return ret; |
3240 | } |
3241 | diff --git a/kernel/events/internal.h b/kernel/events/internal.h |
3242 | index eb675c4..ca65997 100644 |
3243 | --- a/kernel/events/internal.h |
3244 | +++ b/kernel/events/internal.h |
3245 | @@ -31,6 +31,10 @@ struct ring_buffer { |
3246 | spinlock_t event_lock; |
3247 | struct list_head event_list; |
3248 | |
3249 | + atomic_t mmap_count; |
3250 | + unsigned long mmap_locked; |
3251 | + struct user_struct *mmap_user; |
3252 | + |
3253 | struct perf_event_mmap_page *user_page; |
3254 | void *data_pages[0]; |
3255 | }; |
3256 | diff --git a/kernel/range.c b/kernel/range.c |
3257 | index 98883ed..2185716 100644 |
3258 | --- a/kernel/range.c |
3259 | +++ b/kernel/range.c |
3260 | @@ -4,7 +4,7 @@ |
3261 | #include <linux/kernel.h> |
3262 | #include <linux/init.h> |
3263 | #include <linux/sort.h> |
3264 | - |
3265 | +#include <linux/string.h> |
3266 | #include <linux/range.h> |
3267 | |
3268 | int add_range(struct range *range, int az, int nr_range, u64 start, u64 end) |
3269 | @@ -32,9 +32,8 @@ int add_range_with_merge(struct range *range, int az, int nr_range, |
3270 | if (start >= end) |
3271 | return nr_range; |
3272 | |
3273 | - /* Try to merge it with old one: */ |
3274 | + /* get new start/end: */ |
3275 | for (i = 0; i < nr_range; i++) { |
3276 | - u64 final_start, final_end; |
3277 | u64 common_start, common_end; |
3278 | |
3279 | if (!range[i].end) |
3280 | @@ -45,14 +44,16 @@ int add_range_with_merge(struct range *range, int az, int nr_range, |
3281 | if (common_start > common_end) |
3282 | continue; |
3283 | |
3284 | - final_start = min(range[i].start, start); |
3285 | - final_end = max(range[i].end, end); |
3286 | + /* new start/end, will add it back at last */ |
3287 | + start = min(range[i].start, start); |
3288 | + end = max(range[i].end, end); |
3289 | |
3290 | - /* clear it and add it back for further merge */ |
3291 | - range[i].start = 0; |
3292 | - range[i].end = 0; |
3293 | - return add_range_with_merge(range, az, nr_range, |
3294 | - final_start, final_end); |
3295 | + memmove(&range[i], &range[i + 1], |
3296 | + (nr_range - (i + 1)) * sizeof(range[i])); |
3297 | + range[nr_range - 1].start = 0; |
3298 | + range[nr_range - 1].end = 0; |
3299 | + nr_range--; |
3300 | + i--; |
3301 | } |
3302 | |
3303 | /* Need to add it: */ |
3304 | diff --git a/net/802/mrp.c b/net/802/mrp.c |
3305 | index e085bcc..1eb05d8 100644 |
3306 | --- a/net/802/mrp.c |
3307 | +++ b/net/802/mrp.c |
3308 | @@ -871,10 +871,10 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl) |
3309 | */ |
3310 | del_timer_sync(&app->join_timer); |
3311 | |
3312 | - spin_lock(&app->lock); |
3313 | + spin_lock_bh(&app->lock); |
3314 | mrp_mad_event(app, MRP_EVENT_TX); |
3315 | mrp_pdu_queue(app); |
3316 | - spin_unlock(&app->lock); |
3317 | + spin_unlock_bh(&app->lock); |
3318 | |
3319 | mrp_queue_xmit(app); |
3320 | |
3321 | diff --git a/net/compat.c b/net/compat.c |
3322 | index 79ae884..f0a1ba6 100644 |
3323 | --- a/net/compat.c |
3324 | +++ b/net/compat.c |
3325 | @@ -734,19 +734,25 @@ static unsigned char nas[21] = { |
3326 | |
3327 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) |
3328 | { |
3329 | - return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
3330 | + if (flags & MSG_CMSG_COMPAT) |
3331 | + return -EINVAL; |
3332 | + return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
3333 | } |
3334 | |
3335 | asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, |
3336 | unsigned int vlen, unsigned int flags) |
3337 | { |
3338 | + if (flags & MSG_CMSG_COMPAT) |
3339 | + return -EINVAL; |
3340 | return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, |
3341 | flags | MSG_CMSG_COMPAT); |
3342 | } |
3343 | |
3344 | asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) |
3345 | { |
3346 | - return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
3347 | + if (flags & MSG_CMSG_COMPAT) |
3348 | + return -EINVAL; |
3349 | + return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
3350 | } |
3351 | |
3352 | asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags) |
3353 | @@ -768,6 +774,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, |
3354 | int datagrams; |
3355 | struct timespec ktspec; |
3356 | |
3357 | + if (flags & MSG_CMSG_COMPAT) |
3358 | + return -EINVAL; |
3359 | + |
3360 | if (COMPAT_USE_64BIT_TIME) |
3361 | return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, |
3362 | flags | MSG_CMSG_COMPAT, |
3363 | diff --git a/net/core/dev.c b/net/core/dev.c |
3364 | index 9a278e9..c9eb9e6 100644 |
3365 | --- a/net/core/dev.c |
3366 | +++ b/net/core/dev.c |
3367 | @@ -2592,6 +2592,7 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) |
3368 | */ |
3369 | if (shinfo->gso_size) { |
3370 | unsigned int hdr_len; |
3371 | + u16 gso_segs = shinfo->gso_segs; |
3372 | |
3373 | /* mac layer + network layer */ |
3374 | hdr_len = skb_transport_header(skb) - skb_mac_header(skb); |
3375 | @@ -2601,7 +2602,12 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) |
3376 | hdr_len += tcp_hdrlen(skb); |
3377 | else |
3378 | hdr_len += sizeof(struct udphdr); |
3379 | - qdisc_skb_cb(skb)->pkt_len += (shinfo->gso_segs - 1) * hdr_len; |
3380 | + |
3381 | + if (shinfo->gso_type & SKB_GSO_DODGY) |
3382 | + gso_segs = DIV_ROUND_UP(skb->len - hdr_len, |
3383 | + shinfo->gso_size); |
3384 | + |
3385 | + qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len; |
3386 | } |
3387 | } |
3388 | |
3389 | diff --git a/net/core/sock.c b/net/core/sock.c |
3390 | index 1432266..684c37d 100644 |
3391 | --- a/net/core/sock.c |
3392 | +++ b/net/core/sock.c |
3393 | @@ -210,7 +210,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { |
3394 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
3395 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
3396 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , |
3397 | - "sk_lock-AF_NFC" , "sk_lock-AF_MAX" |
3398 | + "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_MAX" |
3399 | }; |
3400 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
3401 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , |
3402 | @@ -226,7 +226,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
3403 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
3404 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
3405 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , |
3406 | - "slock-AF_NFC" , "slock-AF_MAX" |
3407 | + "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_MAX" |
3408 | }; |
3409 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
3410 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , |
3411 | @@ -242,7 +242,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
3412 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
3413 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
3414 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , |
3415 | - "clock-AF_NFC" , "clock-AF_MAX" |
3416 | + "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_MAX" |
3417 | }; |
3418 | |
3419 | /* |
3420 | diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c |
3421 | index 91d66db..c7e8c04 100644 |
3422 | --- a/net/ipv4/ip_gre.c |
3423 | +++ b/net/ipv4/ip_gre.c |
3424 | @@ -804,6 +804,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev |
3425 | tiph = &tunnel->parms.iph; |
3426 | } |
3427 | |
3428 | + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
3429 | if ((dst = tiph->daddr) == 0) { |
3430 | /* NBMA tunnel */ |
3431 | |
3432 | @@ -952,7 +953,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev |
3433 | skb_push(skb, gre_hlen); |
3434 | skb_reset_network_header(skb); |
3435 | skb_set_transport_header(skb, sizeof(*iph)); |
3436 | - memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
3437 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
3438 | IPSKB_REROUTED); |
3439 | skb_dst_drop(skb); |
3440 | diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c |
3441 | index 8f024d4..7533846 100644 |
3442 | --- a/net/ipv4/ipip.c |
3443 | +++ b/net/ipv4/ipip.c |
3444 | @@ -491,6 +491,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
3445 | if (tos & 1) |
3446 | tos = old_iph->tos; |
3447 | |
3448 | + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
3449 | if (!dst) { |
3450 | /* NBMA tunnel */ |
3451 | if ((rt = skb_rtable(skb)) == NULL) { |
3452 | @@ -573,7 +574,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
3453 | skb->transport_header = skb->network_header; |
3454 | skb_push(skb, sizeof(struct iphdr)); |
3455 | skb_reset_network_header(skb); |
3456 | - memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
3457 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
3458 | IPSKB_REROUTED); |
3459 | skb_dst_drop(skb); |
3460 | diff --git a/net/ipv4/route.c b/net/ipv4/route.c |
3461 | index 6e28514..cfede9a 100644 |
3462 | --- a/net/ipv4/route.c |
3463 | +++ b/net/ipv4/route.c |
3464 | @@ -737,10 +737,15 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf |
3465 | { |
3466 | struct rtable *rt; |
3467 | struct flowi4 fl4; |
3468 | + const struct iphdr *iph = (const struct iphdr *) skb->data; |
3469 | + int oif = skb->dev->ifindex; |
3470 | + u8 tos = RT_TOS(iph->tos); |
3471 | + u8 prot = iph->protocol; |
3472 | + u32 mark = skb->mark; |
3473 | |
3474 | rt = (struct rtable *) dst; |
3475 | |
3476 | - ip_rt_build_flow_key(&fl4, sk, skb); |
3477 | + __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0); |
3478 | __ip_do_redirect(rt, skb, &fl4, true); |
3479 | } |
3480 | |
3481 | diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c |
3482 | index e220207..cdeb839 100644 |
3483 | --- a/net/ipv4/tcp.c |
3484 | +++ b/net/ipv4/tcp.c |
3485 | @@ -3383,8 +3383,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, |
3486 | |
3487 | for (i = 0; i < shi->nr_frags; ++i) { |
3488 | const struct skb_frag_struct *f = &shi->frags[i]; |
3489 | - struct page *page = skb_frag_page(f); |
3490 | - sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); |
3491 | + unsigned int offset = f->page_offset; |
3492 | + struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT); |
3493 | + |
3494 | + sg_set_page(&sg, page, skb_frag_size(f), |
3495 | + offset_in_page(offset)); |
3496 | if (crypto_hash_update(desc, &sg, skb_frag_size(f))) |
3497 | return 1; |
3498 | } |
3499 | diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
3500 | index 13b9c08..59163c8 100644 |
3501 | --- a/net/ipv4/tcp_input.c |
3502 | +++ b/net/ipv4/tcp_input.c |
3503 | @@ -2885,8 +2885,8 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack) |
3504 | * tcp_xmit_retransmit_queue(). |
3505 | */ |
3506 | static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, |
3507 | - int prior_sacked, bool is_dupack, |
3508 | - int flag) |
3509 | + int prior_sacked, int prior_packets, |
3510 | + bool is_dupack, int flag) |
3511 | { |
3512 | struct inet_connection_sock *icsk = inet_csk(sk); |
3513 | struct tcp_sock *tp = tcp_sk(sk); |
3514 | @@ -2952,7 +2952,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, |
3515 | tcp_add_reno_sack(sk); |
3516 | } else |
3517 | do_lost = tcp_try_undo_partial(sk, pkts_acked); |
3518 | - newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; |
3519 | + newly_acked_sacked = prior_packets - tp->packets_out + |
3520 | + tp->sacked_out - prior_sacked; |
3521 | break; |
3522 | case TCP_CA_Loss: |
3523 | if (flag & FLAG_DATA_ACKED) |
3524 | @@ -2974,7 +2975,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, |
3525 | if (is_dupack) |
3526 | tcp_add_reno_sack(sk); |
3527 | } |
3528 | - newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; |
3529 | + newly_acked_sacked = prior_packets - tp->packets_out + |
3530 | + tp->sacked_out - prior_sacked; |
3531 | |
3532 | if (icsk->icsk_ca_state <= TCP_CA_Disorder) |
3533 | tcp_try_undo_dsack(sk); |
3534 | @@ -3597,9 +3599,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) |
3535 | bool is_dupack = false; |
3536 | u32 prior_in_flight; |
3537 | u32 prior_fackets; |
3538 | - int prior_packets; |
3539 | + int prior_packets = tp->packets_out; |
3540 | int prior_sacked = tp->sacked_out; |
3541 | int pkts_acked = 0; |
3542 | + int previous_packets_out = 0; |
3543 | bool frto_cwnd = false; |
3544 | |
3545 | /* If the ack is older than previous acks |
3546 | @@ -3670,14 +3673,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) |
3547 | sk->sk_err_soft = 0; |
3548 | icsk->icsk_probes_out = 0; |
3549 | tp->rcv_tstamp = tcp_time_stamp; |
3550 | - prior_packets = tp->packets_out; |
3551 | if (!prior_packets) |
3552 | goto no_queue; |
3553 | |
3554 | /* See if we can take anything off of the retransmit queue. */ |
3555 | + previous_packets_out = tp->packets_out; |
3556 | flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); |
3557 | |
3558 | - pkts_acked = prior_packets - tp->packets_out; |
3559 | + pkts_acked = previous_packets_out - tp->packets_out; |
3560 | |
3561 | if (tp->frto_counter) |
3562 | frto_cwnd = tcp_process_frto(sk, flag); |
3563 | @@ -3692,7 +3695,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) |
3564 | tcp_cong_avoid(sk, ack, prior_in_flight); |
3565 | is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); |
3566 | tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, |
3567 | - is_dupack, flag); |
3568 | + prior_packets, is_dupack, flag); |
3569 | } else { |
3570 | if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) |
3571 | tcp_cong_avoid(sk, ack, prior_in_flight); |
3572 | @@ -3709,7 +3712,7 @@ no_queue: |
3573 | /* If data was DSACKed, see if we can undo a cwnd reduction. */ |
3574 | if (flag & FLAG_DSACKING_ACK) |
3575 | tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, |
3576 | - is_dupack, flag); |
3577 | + prior_packets, is_dupack, flag); |
3578 | /* If this ack opens up a zero window, clear backoff. It was |
3579 | * being used to time the probes, and is probably far higher than |
3580 | * it needs to be for normal retransmission. |
3581 | @@ -3729,7 +3732,7 @@ old_ack: |
3582 | if (TCP_SKB_CB(skb)->sacked) { |
3583 | flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); |
3584 | tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, |
3585 | - is_dupack, flag); |
3586 | + prior_packets, is_dupack, flag); |
3587 | } |
3588 | |
3589 | SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt); |
3590 | diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c |
3591 | index 509912a..84559e9 100644 |
3592 | --- a/net/ipv4/tcp_output.c |
3593 | +++ b/net/ipv4/tcp_output.c |
3594 | @@ -1032,11 +1032,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, |
3595 | &md5); |
3596 | tcp_header_size = tcp_options_size + sizeof(struct tcphdr); |
3597 | |
3598 | - if (tcp_packets_in_flight(tp) == 0) { |
3599 | + if (tcp_packets_in_flight(tp) == 0) |
3600 | tcp_ca_event(sk, CA_EVENT_TX_START); |
3601 | - skb->ooo_okay = 1; |
3602 | - } else |
3603 | - skb->ooo_okay = 0; |
3604 | + |
3605 | + /* if no packet is in qdisc/device queue, then allow XPS to select |
3606 | + * another queue. |
3607 | + */ |
3608 | + skb->ooo_okay = sk_wmem_alloc_get(sk) == 0; |
3609 | |
3610 | skb_push(skb, tcp_header_size); |
3611 | skb_reset_transport_header(skb); |
3612 | diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c |
3613 | index dae802c..50a4c7c 100644 |
3614 | --- a/net/ipv6/addrconf.c |
3615 | +++ b/net/ipv6/addrconf.c |
3616 | @@ -2560,8 +2560,10 @@ static void init_loopback(struct net_device *dev) |
3617 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); |
3618 | |
3619 | /* Failure cases are ignored */ |
3620 | - if (!IS_ERR(sp_rt)) |
3621 | + if (!IS_ERR(sp_rt)) { |
3622 | + sp_ifa->rt = sp_rt; |
3623 | ip6_ins_rt(sp_rt); |
3624 | + } |
3625 | } |
3626 | read_unlock_bh(&idev->lock); |
3627 | } |
3628 | diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
3629 | index 155eccf..851fdae 100644 |
3630 | --- a/net/ipv6/ip6_output.c |
3631 | +++ b/net/ipv6/ip6_output.c |
3632 | @@ -1147,7 +1147,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, |
3633 | if (WARN_ON(np->cork.opt)) |
3634 | return -EINVAL; |
3635 | |
3636 | - np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); |
3637 | + np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); |
3638 | if (unlikely(np->cork.opt == NULL)) |
3639 | return -ENOBUFS; |
3640 | |
3641 | diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c |
3642 | index cf05cf0..0da1bd2 100644 |
3643 | --- a/net/ipv6/udp_offload.c |
3644 | +++ b/net/ipv6/udp_offload.c |
3645 | @@ -42,11 +42,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, |
3646 | unsigned int mss; |
3647 | unsigned int unfrag_ip6hlen, unfrag_len; |
3648 | struct frag_hdr *fptr; |
3649 | - u8 *mac_start, *prevhdr; |
3650 | + u8 *packet_start, *prevhdr; |
3651 | u8 nexthdr; |
3652 | u8 frag_hdr_sz = sizeof(struct frag_hdr); |
3653 | int offset; |
3654 | __wsum csum; |
3655 | + int tnl_hlen; |
3656 | |
3657 | mss = skb_shinfo(skb)->gso_size; |
3658 | if (unlikely(skb->len <= mss)) |
3659 | @@ -77,9 +78,11 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, |
3660 | skb->ip_summed = CHECKSUM_NONE; |
3661 | |
3662 | /* Check if there is enough headroom to insert fragment header. */ |
3663 | - if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) && |
3664 | - pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC)) |
3665 | - goto out; |
3666 | + tnl_hlen = skb_tnl_header_len(skb); |
3667 | + if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) { |
3668 | + if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz)) |
3669 | + goto out; |
3670 | + } |
3671 | |
3672 | /* Find the unfragmentable header and shift it left by frag_hdr_sz |
3673 | * bytes to insert fragment header. |
3674 | @@ -87,11 +90,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, |
3675 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); |
3676 | nexthdr = *prevhdr; |
3677 | *prevhdr = NEXTHDR_FRAGMENT; |
3678 | - unfrag_len = skb_network_header(skb) - skb_mac_header(skb) + |
3679 | - unfrag_ip6hlen; |
3680 | - mac_start = skb_mac_header(skb); |
3681 | - memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len); |
3682 | + unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + |
3683 | + unfrag_ip6hlen + tnl_hlen; |
3684 | + packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset; |
3685 | + memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len); |
3686 | |
3687 | + SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz; |
3688 | skb->mac_header -= frag_hdr_sz; |
3689 | skb->network_header -= frag_hdr_sz; |
3690 | |
3691 | diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c |
3692 | index 637a341..8dec687 100644 |
3693 | --- a/net/l2tp/l2tp_ppp.c |
3694 | +++ b/net/l2tp/l2tp_ppp.c |
3695 | @@ -346,19 +346,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh |
3696 | skb_put(skb, 2); |
3697 | |
3698 | /* Copy user data into skb */ |
3699 | - error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); |
3700 | + error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, |
3701 | + total_len); |
3702 | if (error < 0) { |
3703 | kfree_skb(skb); |
3704 | goto error_put_sess_tun; |
3705 | } |
3706 | - skb_put(skb, total_len); |
3707 | |
3708 | l2tp_xmit_skb(session, skb, session->hdr_len); |
3709 | |
3710 | sock_put(ps->tunnel_sock); |
3711 | sock_put(sk); |
3712 | |
3713 | - return error; |
3714 | + return total_len; |
3715 | |
3716 | error_put_sess_tun: |
3717 | sock_put(ps->tunnel_sock); |
3718 | diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c |
3719 | index d8d4243..6bb1d42 100644 |
3720 | --- a/net/netlabel/netlabel_domainhash.c |
3721 | +++ b/net/netlabel/netlabel_domainhash.c |
3722 | @@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry, |
3723 | } |
3724 | } |
3725 | |
3726 | +/** |
3727 | + * netlbl_domhsh_validate - Validate a new domain mapping entry |
3728 | + * @entry: the entry to validate |
3729 | + * |
3730 | + * This function validates the new domain mapping entry to ensure that it is |
3731 | + * a valid entry. Returns zero on success, negative values on failure. |
3732 | + * |
3733 | + */ |
3734 | +static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry) |
3735 | +{ |
3736 | + struct netlbl_af4list *iter4; |
3737 | + struct netlbl_domaddr4_map *map4; |
3738 | +#if IS_ENABLED(CONFIG_IPV6) |
3739 | + struct netlbl_af6list *iter6; |
3740 | + struct netlbl_domaddr6_map *map6; |
3741 | +#endif /* IPv6 */ |
3742 | + |
3743 | + if (entry == NULL) |
3744 | + return -EINVAL; |
3745 | + |
3746 | + switch (entry->type) { |
3747 | + case NETLBL_NLTYPE_UNLABELED: |
3748 | + if (entry->type_def.cipsov4 != NULL || |
3749 | + entry->type_def.addrsel != NULL) |
3750 | + return -EINVAL; |
3751 | + break; |
3752 | + case NETLBL_NLTYPE_CIPSOV4: |
3753 | + if (entry->type_def.cipsov4 == NULL) |
3754 | + return -EINVAL; |
3755 | + break; |
3756 | + case NETLBL_NLTYPE_ADDRSELECT: |
3757 | + netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) { |
3758 | + map4 = netlbl_domhsh_addr4_entry(iter4); |
3759 | + switch (map4->type) { |
3760 | + case NETLBL_NLTYPE_UNLABELED: |
3761 | + if (map4->type_def.cipsov4 != NULL) |
3762 | + return -EINVAL; |
3763 | + break; |
3764 | + case NETLBL_NLTYPE_CIPSOV4: |
3765 | + if (map4->type_def.cipsov4 == NULL) |
3766 | + return -EINVAL; |
3767 | + break; |
3768 | + default: |
3769 | + return -EINVAL; |
3770 | + } |
3771 | + } |
3772 | +#if IS_ENABLED(CONFIG_IPV6) |
3773 | + netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) { |
3774 | + map6 = netlbl_domhsh_addr6_entry(iter6); |
3775 | + switch (map6->type) { |
3776 | + case NETLBL_NLTYPE_UNLABELED: |
3777 | + break; |
3778 | + default: |
3779 | + return -EINVAL; |
3780 | + } |
3781 | + } |
3782 | +#endif /* IPv6 */ |
3783 | + break; |
3784 | + default: |
3785 | + return -EINVAL; |
3786 | + } |
3787 | + |
3788 | + return 0; |
3789 | +} |
3790 | + |
3791 | /* |
3792 | * Domain Hash Table Functions |
3793 | */ |
3794 | @@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, |
3795 | struct netlbl_af6list *tmp6; |
3796 | #endif /* IPv6 */ |
3797 | |
3798 | + ret_val = netlbl_domhsh_validate(entry); |
3799 | + if (ret_val != 0) |
3800 | + return ret_val; |
3801 | + |
3802 | /* XXX - we can remove this RCU read lock as the spinlock protects the |
3803 | * entire function, but before we do we need to fixup the |
3804 | * netlbl_af[4,6]list RCU functions to do "the right thing" with |
3805 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
3806 | index f83e172..e50f72a 100644 |
3807 | --- a/net/packet/af_packet.c |
3808 | +++ b/net/packet/af_packet.c |
3809 | @@ -88,6 +88,7 @@ |
3810 | #include <linux/virtio_net.h> |
3811 | #include <linux/errqueue.h> |
3812 | #include <linux/net_tstamp.h> |
3813 | +#include <net/flow_keys.h> |
3814 | |
3815 | #ifdef CONFIG_INET |
3816 | #include <net/inet_common.h> |
3817 | @@ -1343,6 +1344,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, |
3818 | __be16 proto = 0; |
3819 | int err; |
3820 | int extra_len = 0; |
3821 | + struct flow_keys keys; |
3822 | |
3823 | /* |
3824 | * Get and verify the address. |
3825 | @@ -1443,6 +1445,11 @@ retry: |
3826 | if (unlikely(extra_len == 4)) |
3827 | skb->no_fcs = 1; |
3828 | |
3829 | + if (skb_flow_dissect(skb, &keys)) |
3830 | + skb_set_transport_header(skb, keys.thoff); |
3831 | + else |
3832 | + skb_reset_transport_header(skb); |
3833 | + |
3834 | dev_queue_xmit(skb); |
3835 | rcu_read_unlock(); |
3836 | return len; |
3837 | @@ -1849,6 +1856,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
3838 | struct page *page; |
3839 | void *data; |
3840 | int err; |
3841 | + struct flow_keys keys; |
3842 | |
3843 | ph.raw = frame; |
3844 | |
3845 | @@ -1874,6 +1882,11 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
3846 | skb_reserve(skb, hlen); |
3847 | skb_reset_network_header(skb); |
3848 | |
3849 | + if (skb_flow_dissect(skb, &keys)) |
3850 | + skb_set_transport_header(skb, keys.thoff); |
3851 | + else |
3852 | + skb_reset_transport_header(skb); |
3853 | + |
3854 | if (po->tp_tx_has_off) { |
3855 | int off_min, off_max, off; |
3856 | off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll); |
3857 | @@ -2130,6 +2143,7 @@ static int packet_snd(struct socket *sock, |
3858 | unsigned short gso_type = 0; |
3859 | int hlen, tlen; |
3860 | int extra_len = 0; |
3861 | + struct flow_keys keys; |
3862 | |
3863 | /* |
3864 | * Get and verify the address. |
3865 | @@ -2282,6 +2296,13 @@ static int packet_snd(struct socket *sock, |
3866 | len += vnet_hdr_len; |
3867 | } |
3868 | |
3869 | + if (skb->ip_summed == CHECKSUM_PARTIAL) |
3870 | + skb_set_transport_header(skb, skb_checksum_start_offset(skb)); |
3871 | + else if (skb_flow_dissect(skb, &keys)) |
3872 | + skb_set_transport_header(skb, keys.thoff); |
3873 | + else |
3874 | + skb_set_transport_header(skb, reserve); |
3875 | + |
3876 | if (unlikely(extra_len == 4)) |
3877 | skb->no_fcs = 1; |
3878 | |
3879 | @@ -2769,12 +2790,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, |
3880 | return -EOPNOTSUPP; |
3881 | |
3882 | uaddr->sa_family = AF_PACKET; |
3883 | + memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); |
3884 | rcu_read_lock(); |
3885 | dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); |
3886 | if (dev) |
3887 | - strncpy(uaddr->sa_data, dev->name, 14); |
3888 | - else |
3889 | - memset(uaddr->sa_data, 0, 14); |
3890 | + strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); |
3891 | rcu_read_unlock(); |
3892 | *uaddr_len = sizeof(*uaddr); |
3893 | |
3894 | diff --git a/net/sched/act_police.c b/net/sched/act_police.c |
3895 | index 823463a..189e3c5 100644 |
3896 | --- a/net/sched/act_police.c |
3897 | +++ b/net/sched/act_police.c |
3898 | @@ -231,14 +231,14 @@ override: |
3899 | } |
3900 | if (R_tab) { |
3901 | police->rate_present = true; |
3902 | - psched_ratecfg_precompute(&police->rate, R_tab->rate.rate); |
3903 | + psched_ratecfg_precompute(&police->rate, &R_tab->rate); |
3904 | qdisc_put_rtab(R_tab); |
3905 | } else { |
3906 | police->rate_present = false; |
3907 | } |
3908 | if (P_tab) { |
3909 | police->peak_present = true; |
3910 | - psched_ratecfg_precompute(&police->peak, P_tab->rate.rate); |
3911 | + psched_ratecfg_precompute(&police->peak, &P_tab->rate); |
3912 | qdisc_put_rtab(P_tab); |
3913 | } else { |
3914 | police->peak_present = false; |
3915 | @@ -376,9 +376,9 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) |
3916 | }; |
3917 | |
3918 | if (police->rate_present) |
3919 | - opt.rate.rate = psched_ratecfg_getrate(&police->rate); |
3920 | + psched_ratecfg_getrate(&opt.rate, &police->rate); |
3921 | if (police->peak_present) |
3922 | - opt.peakrate.rate = psched_ratecfg_getrate(&police->peak); |
3923 | + psched_ratecfg_getrate(&opt.peakrate, &police->peak); |
3924 | if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) |
3925 | goto nla_put_failure; |
3926 | if (police->tcfp_result && |
3927 | diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c |
3928 | index eac7e0e..2022408 100644 |
3929 | --- a/net/sched/sch_generic.c |
3930 | +++ b/net/sched/sch_generic.c |
3931 | @@ -898,14 +898,16 @@ void dev_shutdown(struct net_device *dev) |
3932 | WARN_ON(timer_pending(&dev->watchdog_timer)); |
3933 | } |
3934 | |
3935 | -void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate) |
3936 | +void psched_ratecfg_precompute(struct psched_ratecfg *r, |
3937 | + const struct tc_ratespec *conf) |
3938 | { |
3939 | u64 factor; |
3940 | u64 mult; |
3941 | int shift; |
3942 | |
3943 | - r->rate_bps = (u64)rate << 3; |
3944 | - r->shift = 0; |
3945 | + memset(r, 0, sizeof(*r)); |
3946 | + r->overhead = conf->overhead; |
3947 | + r->rate_bps = (u64)conf->rate << 3; |
3948 | r->mult = 1; |
3949 | /* |
3950 | * Calibrate mult, shift so that token counting is accurate |
3951 | diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c |
3952 | index 571f1d2..bf2063b 100644 |
3953 | --- a/net/sched/sch_htb.c |
3954 | +++ b/net/sched/sch_htb.c |
3955 | @@ -109,7 +109,7 @@ struct htb_class { |
3956 | } un; |
3957 | struct rb_node node[TC_HTB_NUMPRIO]; /* node for self or feed tree */ |
3958 | struct rb_node pq_node; /* node for event queue */ |
3959 | - psched_time_t pq_key; |
3960 | + s64 pq_key; |
3961 | |
3962 | int prio_activity; /* for which prios are we active */ |
3963 | enum htb_cmode cmode; /* current mode of the class */ |
3964 | @@ -121,10 +121,10 @@ struct htb_class { |
3965 | /* token bucket parameters */ |
3966 | struct psched_ratecfg rate; |
3967 | struct psched_ratecfg ceil; |
3968 | - s64 buffer, cbuffer; /* token bucket depth/rate */ |
3969 | - psched_tdiff_t mbuffer; /* max wait time */ |
3970 | - s64 tokens, ctokens; /* current number of tokens */ |
3971 | - psched_time_t t_c; /* checkpoint time */ |
3972 | + s64 buffer, cbuffer; /* token bucket depth/rate */ |
3973 | + s64 mbuffer; /* max wait time */ |
3974 | + s64 tokens, ctokens; /* current number of tokens */ |
3975 | + s64 t_c; /* checkpoint time */ |
3976 | }; |
3977 | |
3978 | struct htb_sched { |
3979 | @@ -141,15 +141,15 @@ struct htb_sched { |
3980 | struct rb_root wait_pq[TC_HTB_MAXDEPTH]; |
3981 | |
3982 | /* time of nearest event per level (row) */ |
3983 | - psched_time_t near_ev_cache[TC_HTB_MAXDEPTH]; |
3984 | + s64 near_ev_cache[TC_HTB_MAXDEPTH]; |
3985 | |
3986 | int defcls; /* class where unclassified flows go to */ |
3987 | |
3988 | /* filters for qdisc itself */ |
3989 | struct tcf_proto *filter_list; |
3990 | |
3991 | - int rate2quantum; /* quant = rate / rate2quantum */ |
3992 | - psched_time_t now; /* cached dequeue time */ |
3993 | + int rate2quantum; /* quant = rate / rate2quantum */ |
3994 | + s64 now; /* cached dequeue time */ |
3995 | struct qdisc_watchdog watchdog; |
3996 | |
3997 | /* non shaped skbs; let them go directly thru */ |
3998 | @@ -664,8 +664,8 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, |
3999 | * next pending event (0 for no event in pq, q->now for too many events). |
4000 | * Note: Applied are events whose have cl->pq_key <= q->now. |
4001 | */ |
4002 | -static psched_time_t htb_do_events(struct htb_sched *q, int level, |
4003 | - unsigned long start) |
4004 | +static s64 htb_do_events(struct htb_sched *q, int level, |
4005 | + unsigned long start) |
4006 | { |
4007 | /* don't run for longer than 2 jiffies; 2 is used instead of |
4008 | * 1 to simplify things when jiffy is going to be incremented |
4009 | @@ -857,7 +857,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) |
4010 | struct sk_buff *skb; |
4011 | struct htb_sched *q = qdisc_priv(sch); |
4012 | int level; |
4013 | - psched_time_t next_event; |
4014 | + s64 next_event; |
4015 | unsigned long start_at; |
4016 | |
4017 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ |
4018 | @@ -880,7 +880,7 @@ ok: |
4019 | for (level = 0; level < TC_HTB_MAXDEPTH; level++) { |
4020 | /* common case optimization - skip event handler quickly */ |
4021 | int m; |
4022 | - psched_time_t event; |
4023 | + s64 event; |
4024 | |
4025 | if (q->now >= q->near_ev_cache[level]) { |
4026 | event = htb_do_events(q, level, start_at); |
4027 | @@ -1089,9 +1089,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg, |
4028 | |
4029 | memset(&opt, 0, sizeof(opt)); |
4030 | |
4031 | - opt.rate.rate = psched_ratecfg_getrate(&cl->rate); |
4032 | + psched_ratecfg_getrate(&opt.rate, &cl->rate); |
4033 | opt.buffer = PSCHED_NS2TICKS(cl->buffer); |
4034 | - opt.ceil.rate = psched_ratecfg_getrate(&cl->ceil); |
4035 | + psched_ratecfg_getrate(&opt.ceil, &cl->ceil); |
4036 | opt.cbuffer = PSCHED_NS2TICKS(cl->cbuffer); |
4037 | opt.quantum = cl->quantum; |
4038 | opt.prio = cl->prio; |
4039 | @@ -1116,8 +1116,8 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d) |
4040 | |
4041 | if (!cl->level && cl->un.leaf.q) |
4042 | cl->qstats.qlen = cl->un.leaf.q->q.qlen; |
4043 | - cl->xstats.tokens = cl->tokens; |
4044 | - cl->xstats.ctokens = cl->ctokens; |
4045 | + cl->xstats.tokens = PSCHED_NS2TICKS(cl->tokens); |
4046 | + cl->xstats.ctokens = PSCHED_NS2TICKS(cl->ctokens); |
4047 | |
4048 | if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || |
4049 | gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 || |
4050 | @@ -1199,7 +1199,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, |
4051 | parent->un.leaf.q = new_q ? new_q : &noop_qdisc; |
4052 | parent->tokens = parent->buffer; |
4053 | parent->ctokens = parent->cbuffer; |
4054 | - parent->t_c = psched_get_time(); |
4055 | + parent->t_c = ktime_to_ns(ktime_get()); |
4056 | parent->cmode = HTB_CAN_SEND; |
4057 | } |
4058 | |
4059 | @@ -1416,8 +1416,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, |
4060 | /* set class to be in HTB_CAN_SEND state */ |
4061 | cl->tokens = PSCHED_TICKS2NS(hopt->buffer); |
4062 | cl->ctokens = PSCHED_TICKS2NS(hopt->cbuffer); |
4063 | - cl->mbuffer = 60 * PSCHED_TICKS_PER_SEC; /* 1min */ |
4064 | - cl->t_c = psched_get_time(); |
4065 | + cl->mbuffer = 60ULL * NSEC_PER_SEC; /* 1min */ |
4066 | + cl->t_c = ktime_to_ns(ktime_get()); |
4067 | cl->cmode = HTB_CAN_SEND; |
4068 | |
4069 | /* attach to the hash list and parent's family */ |
4070 | @@ -1458,8 +1458,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, |
4071 | cl->prio = TC_HTB_NUMPRIO - 1; |
4072 | } |
4073 | |
4074 | - psched_ratecfg_precompute(&cl->rate, hopt->rate.rate); |
4075 | - psched_ratecfg_precompute(&cl->ceil, hopt->ceil.rate); |
4076 | + psched_ratecfg_precompute(&cl->rate, &hopt->rate); |
4077 | + psched_ratecfg_precompute(&cl->ceil, &hopt->ceil); |
4078 | |
4079 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); |
4080 | cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer); |
4081 | diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c |
4082 | index c8388f3..e478d31 100644 |
4083 | --- a/net/sched/sch_tbf.c |
4084 | +++ b/net/sched/sch_tbf.c |
4085 | @@ -298,9 +298,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) |
4086 | q->tokens = q->buffer; |
4087 | q->ptokens = q->mtu; |
4088 | |
4089 | - psched_ratecfg_precompute(&q->rate, rtab->rate.rate); |
4090 | + psched_ratecfg_precompute(&q->rate, &rtab->rate); |
4091 | if (ptab) { |
4092 | - psched_ratecfg_precompute(&q->peak, ptab->rate.rate); |
4093 | + psched_ratecfg_precompute(&q->peak, &ptab->rate); |
4094 | q->peak_present = true; |
4095 | } else { |
4096 | q->peak_present = false; |
4097 | @@ -350,9 +350,9 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) |
4098 | goto nla_put_failure; |
4099 | |
4100 | opt.limit = q->limit; |
4101 | - opt.rate.rate = psched_ratecfg_getrate(&q->rate); |
4102 | + psched_ratecfg_getrate(&opt.rate, &q->rate); |
4103 | if (q->peak_present) |
4104 | - opt.peakrate.rate = psched_ratecfg_getrate(&q->peak); |
4105 | + psched_ratecfg_getrate(&opt.peakrate, &q->peak); |
4106 | else |
4107 | memset(&opt.peakrate, 0, sizeof(opt.peakrate)); |
4108 | opt.mtu = PSCHED_NS2TICKS(q->mtu); |
4109 | diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c |
4110 | index 01dca75..e9426bb 100644 |
4111 | --- a/net/sctp/outqueue.c |
4112 | +++ b/net/sctp/outqueue.c |
4113 | @@ -206,6 +206,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary, |
4114 | */ |
4115 | void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) |
4116 | { |
4117 | + memset(q, 0, sizeof(struct sctp_outq)); |
4118 | + |
4119 | q->asoc = asoc; |
4120 | INIT_LIST_HEAD(&q->out_chunk_list); |
4121 | INIT_LIST_HEAD(&q->control_chunk_list); |
4122 | @@ -213,13 +215,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) |
4123 | INIT_LIST_HEAD(&q->sacked); |
4124 | INIT_LIST_HEAD(&q->abandoned); |
4125 | |
4126 | - q->fast_rtx = 0; |
4127 | - q->outstanding_bytes = 0; |
4128 | q->empty = 1; |
4129 | - q->cork = 0; |
4130 | - |
4131 | - q->malloced = 0; |
4132 | - q->out_qlen = 0; |
4133 | } |
4134 | |
4135 | /* Free the outqueue structure and any related pending chunks. |
4136 | diff --git a/net/sctp/socket.c b/net/sctp/socket.c |
4137 | index b907073..02c43e4 100644 |
4138 | --- a/net/sctp/socket.c |
4139 | +++ b/net/sctp/socket.c |
4140 | @@ -4002,6 +4002,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) |
4141 | |
4142 | /* Release our hold on the endpoint. */ |
4143 | sp = sctp_sk(sk); |
4144 | + /* This could happen during socket init, thus we bail out |
4145 | + * early, since the rest of the below is not setup either. |
4146 | + */ |
4147 | + if (sp->ep == NULL) |
4148 | + return; |
4149 | + |
4150 | if (sp->do_auto_asconf) { |
4151 | sp->do_auto_asconf = 0; |
4152 | list_del(&sp->auto_asconf_list); |
4153 | diff --git a/net/socket.c b/net/socket.c |
4154 | index 88f759a..e216502 100644 |
4155 | --- a/net/socket.c |
4156 | +++ b/net/socket.c |
4157 | @@ -1978,7 +1978,7 @@ struct used_address { |
4158 | unsigned int name_len; |
4159 | }; |
4160 | |
4161 | -static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
4162 | +static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
4163 | struct msghdr *msg_sys, unsigned int flags, |
4164 | struct used_address *used_address) |
4165 | { |
4166 | @@ -2093,22 +2093,30 @@ out: |
4167 | * BSD sendmsg interface |
4168 | */ |
4169 | |
4170 | -SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) |
4171 | +long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) |
4172 | { |
4173 | int fput_needed, err; |
4174 | struct msghdr msg_sys; |
4175 | - struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); |
4176 | + struct socket *sock; |
4177 | |
4178 | + sock = sockfd_lookup_light(fd, &err, &fput_needed); |
4179 | if (!sock) |
4180 | goto out; |
4181 | |
4182 | - err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
4183 | + err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
4184 | |
4185 | fput_light(sock->file, fput_needed); |
4186 | out: |
4187 | return err; |
4188 | } |
4189 | |
4190 | +SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) |
4191 | +{ |
4192 | + if (flags & MSG_CMSG_COMPAT) |
4193 | + return -EINVAL; |
4194 | + return __sys_sendmsg(fd, msg, flags); |
4195 | +} |
4196 | + |
4197 | /* |
4198 | * Linux sendmmsg interface |
4199 | */ |
4200 | @@ -2139,15 +2147,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
4201 | |
4202 | while (datagrams < vlen) { |
4203 | if (MSG_CMSG_COMPAT & flags) { |
4204 | - err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
4205 | - &msg_sys, flags, &used_address); |
4206 | + err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
4207 | + &msg_sys, flags, &used_address); |
4208 | if (err < 0) |
4209 | break; |
4210 | err = __put_user(err, &compat_entry->msg_len); |
4211 | ++compat_entry; |
4212 | } else { |
4213 | - err = __sys_sendmsg(sock, (struct msghdr __user *)entry, |
4214 | - &msg_sys, flags, &used_address); |
4215 | + err = ___sys_sendmsg(sock, |
4216 | + (struct msghdr __user *)entry, |
4217 | + &msg_sys, flags, &used_address); |
4218 | if (err < 0) |
4219 | break; |
4220 | err = put_user(err, &entry->msg_len); |
4221 | @@ -2171,10 +2180,12 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
4222 | SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, |
4223 | unsigned int, vlen, unsigned int, flags) |
4224 | { |
4225 | + if (flags & MSG_CMSG_COMPAT) |
4226 | + return -EINVAL; |
4227 | return __sys_sendmmsg(fd, mmsg, vlen, flags); |
4228 | } |
4229 | |
4230 | -static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
4231 | +static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
4232 | struct msghdr *msg_sys, unsigned int flags, int nosec) |
4233 | { |
4234 | struct compat_msghdr __user *msg_compat = |
4235 | @@ -2266,23 +2277,31 @@ out: |
4236 | * BSD recvmsg interface |
4237 | */ |
4238 | |
4239 | -SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, |
4240 | - unsigned int, flags) |
4241 | +long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) |
4242 | { |
4243 | int fput_needed, err; |
4244 | struct msghdr msg_sys; |
4245 | - struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); |
4246 | + struct socket *sock; |
4247 | |
4248 | + sock = sockfd_lookup_light(fd, &err, &fput_needed); |
4249 | if (!sock) |
4250 | goto out; |
4251 | |
4252 | - err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0); |
4253 | + err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0); |
4254 | |
4255 | fput_light(sock->file, fput_needed); |
4256 | out: |
4257 | return err; |
4258 | } |
4259 | |
4260 | +SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, |
4261 | + unsigned int, flags) |
4262 | +{ |
4263 | + if (flags & MSG_CMSG_COMPAT) |
4264 | + return -EINVAL; |
4265 | + return __sys_recvmsg(fd, msg, flags); |
4266 | +} |
4267 | + |
4268 | /* |
4269 | * Linux recvmmsg interface |
4270 | */ |
4271 | @@ -2320,17 +2339,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
4272 | * No need to ask LSM for more than the first datagram. |
4273 | */ |
4274 | if (MSG_CMSG_COMPAT & flags) { |
4275 | - err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, |
4276 | - &msg_sys, flags & ~MSG_WAITFORONE, |
4277 | - datagrams); |
4278 | + err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, |
4279 | + &msg_sys, flags & ~MSG_WAITFORONE, |
4280 | + datagrams); |
4281 | if (err < 0) |
4282 | break; |
4283 | err = __put_user(err, &compat_entry->msg_len); |
4284 | ++compat_entry; |
4285 | } else { |
4286 | - err = __sys_recvmsg(sock, (struct msghdr __user *)entry, |
4287 | - &msg_sys, flags & ~MSG_WAITFORONE, |
4288 | - datagrams); |
4289 | + err = ___sys_recvmsg(sock, |
4290 | + (struct msghdr __user *)entry, |
4291 | + &msg_sys, flags & ~MSG_WAITFORONE, |
4292 | + datagrams); |
4293 | if (err < 0) |
4294 | break; |
4295 | err = put_user(err, &entry->msg_len); |
4296 | @@ -2397,6 +2417,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, |
4297 | int datagrams; |
4298 | struct timespec timeout_sys; |
4299 | |
4300 | + if (flags & MSG_CMSG_COMPAT) |
4301 | + return -EINVAL; |
4302 | + |
4303 | if (!timeout) |
4304 | return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); |
4305 | |
4306 | diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c |
4307 | index bcfda89..0cf003d 100644 |
4308 | --- a/net/xfrm/xfrm_output.c |
4309 | +++ b/net/xfrm/xfrm_output.c |
4310 | @@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) |
4311 | |
4312 | if (unlikely(x->km.state != XFRM_STATE_VALID)) { |
4313 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID); |
4314 | + err = -EINVAL; |
4315 | goto error; |
4316 | } |
4317 | |
4318 | diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c |
4319 | index 0d9c58f..44c1205 100644 |
4320 | --- a/sound/pci/hda/patch_cirrus.c |
4321 | +++ b/sound/pci/hda/patch_cirrus.c |
4322 | @@ -58,6 +58,7 @@ enum { |
4323 | CS420X_GPIO_23, |
4324 | CS420X_MBP101, |
4325 | CS420X_MBP81, |
4326 | + CS420X_MBA42, |
4327 | CS420X_AUTO, |
4328 | /* aliases */ |
4329 | CS420X_IMAC27_122 = CS420X_GPIO_23, |
4330 | @@ -345,6 +346,7 @@ static const struct hda_model_fixup cs420x_models[] = { |
4331 | { .id = CS420X_APPLE, .name = "apple" }, |
4332 | { .id = CS420X_MBP101, .name = "mbp101" }, |
4333 | { .id = CS420X_MBP81, .name = "mbp81" }, |
4334 | + { .id = CS420X_MBA42, .name = "mba42" }, |
4335 | {} |
4336 | }; |
4337 | |
4338 | @@ -360,6 +362,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { |
4339 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), |
4340 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), |
4341 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), |
4342 | + SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42), |
4343 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), |
4344 | {} /* terminator */ |
4345 | }; |
4346 | @@ -413,6 +416,20 @@ static const struct hda_pintbl mbp101_pincfgs[] = { |
4347 | {} /* terminator */ |
4348 | }; |
4349 | |
4350 | +static const struct hda_pintbl mba42_pincfgs[] = { |
4351 | + { 0x09, 0x012b4030 }, /* HP */ |
4352 | + { 0x0a, 0x400000f0 }, |
4353 | + { 0x0b, 0x90100120 }, /* speaker */ |
4354 | + { 0x0c, 0x400000f0 }, |
4355 | + { 0x0d, 0x90a00110 }, /* mic */ |
4356 | + { 0x0e, 0x400000f0 }, |
4357 | + { 0x0f, 0x400000f0 }, |
4358 | + { 0x10, 0x400000f0 }, |
4359 | + { 0x12, 0x400000f0 }, |
4360 | + { 0x15, 0x400000f0 }, |
4361 | + {} /* terminator */ |
4362 | +}; |
4363 | + |
4364 | static void cs420x_fixup_gpio_13(struct hda_codec *codec, |
4365 | const struct hda_fixup *fix, int action) |
4366 | { |
4367 | @@ -481,6 +498,12 @@ static const struct hda_fixup cs420x_fixups[] = { |
4368 | .chained = true, |
4369 | .chain_id = CS420X_GPIO_13, |
4370 | }, |
4371 | + [CS420X_MBA42] = { |
4372 | + .type = HDA_FIXUP_PINS, |
4373 | + .v.pins = mba42_pincfgs, |
4374 | + .chained = true, |
4375 | + .chain_id = CS420X_GPIO_13, |
4376 | + }, |
4377 | }; |
4378 | |
4379 | static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) |
4380 | diff --git a/sound/usb/card.c b/sound/usb/card.c |
4381 | index b79b7dc..13cb571 100644 |
4382 | --- a/sound/usb/card.c |
4383 | +++ b/sound/usb/card.c |
4384 | @@ -144,14 +144,32 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int |
4385 | return -EINVAL; |
4386 | } |
4387 | |
4388 | + alts = &iface->altsetting[0]; |
4389 | + altsd = get_iface_desc(alts); |
4390 | + |
4391 | + /* |
4392 | + * Android with both accessory and audio interfaces enabled gets the |
4393 | + * interface numbers wrong. |
4394 | + */ |
4395 | + if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) || |
4396 | + chip->usb_id == USB_ID(0x18d1, 0x2d05)) && |
4397 | + interface == 0 && |
4398 | + altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && |
4399 | + altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) { |
4400 | + interface = 2; |
4401 | + iface = usb_ifnum_to_if(dev, interface); |
4402 | + if (!iface) |
4403 | + return -EINVAL; |
4404 | + alts = &iface->altsetting[0]; |
4405 | + altsd = get_iface_desc(alts); |
4406 | + } |
4407 | + |
4408 | if (usb_interface_claimed(iface)) { |
4409 | snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", |
4410 | dev->devnum, ctrlif, interface); |
4411 | return -EINVAL; |
4412 | } |
4413 | |
4414 | - alts = &iface->altsetting[0]; |
4415 | - altsd = get_iface_desc(alts); |
4416 | if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || |
4417 | altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && |
4418 | altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { |
4419 | diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
4420 | index e5c7f9f..d543808 100644 |
4421 | --- a/sound/usb/mixer.c |
4422 | +++ b/sound/usb/mixer.c |
4423 | @@ -885,6 +885,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, |
4424 | |
4425 | case USB_ID(0x046d, 0x0808): |
4426 | case USB_ID(0x046d, 0x0809): |
4427 | + case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ |
4428 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ |
4429 | case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ |
4430 | case USB_ID(0x046d, 0x0991): |