Contents of /trunk/kernel-mcore/patches-3.0-r2/0101-3.0.2-all-fixes.patch
Parent Directory | Revision Log
Revision 1560 -
(show annotations)
(download)
Thu Nov 10 14:21:33 2011 UTC (12 years, 10 months ago) by niro
File size: 200534 byte(s)
Thu Nov 10 14:21:33 2011 UTC (12 years, 10 months ago) by niro
File size: 200534 byte(s)
3.0-mcore-r2, updated to linux-3.0.8
1 | diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c |
2 | index 85026537..466af40 100644 |
3 | --- a/arch/cris/arch-v10/drivers/sync_serial.c |
4 | +++ b/arch/cris/arch-v10/drivers/sync_serial.c |
5 | @@ -158,7 +158,7 @@ static int sync_serial_open(struct inode *inode, struct file *file); |
6 | static int sync_serial_release(struct inode *inode, struct file *file); |
7 | static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); |
8 | |
9 | -static int sync_serial_ioctl(struct file *file, |
10 | +static long sync_serial_ioctl(struct file *file, |
11 | unsigned int cmd, unsigned long arg); |
12 | static ssize_t sync_serial_write(struct file *file, const char *buf, |
13 | size_t count, loff_t *ppos); |
14 | @@ -625,11 +625,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) |
15 | *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; |
16 | DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); |
17 | } |
18 | - ret = 0; |
19 | + err = 0; |
20 | |
21 | out: |
22 | mutex_unlock(&sync_serial_mutex); |
23 | - return ret; |
24 | + return err; |
25 | } |
26 | |
27 | static int sync_serial_release(struct inode *inode, struct file *file) |
28 | diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c |
29 | index 907cfb5..ba0e596 100644 |
30 | --- a/arch/cris/arch-v10/kernel/irq.c |
31 | +++ b/arch/cris/arch-v10/kernel/irq.c |
32 | @@ -20,6 +20,9 @@ |
33 | #define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); |
34 | #define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); |
35 | |
36 | +extern void kgdb_init(void); |
37 | +extern void breakpoint(void); |
38 | + |
39 | /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is |
40 | * global just so that the kernel gdb can use it. |
41 | */ |
42 | diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h |
43 | index 29b74a1..332f19c 100644 |
44 | --- a/arch/cris/include/asm/thread_info.h |
45 | +++ b/arch/cris/include/asm/thread_info.h |
46 | @@ -11,8 +11,6 @@ |
47 | |
48 | #ifdef __KERNEL__ |
49 | |
50 | -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR |
51 | - |
52 | #ifndef __ASSEMBLY__ |
53 | #include <asm/types.h> |
54 | #include <asm/processor.h> |
55 | @@ -67,8 +65,10 @@ struct thread_info { |
56 | |
57 | #define init_thread_info (init_thread_union.thread_info) |
58 | |
59 | +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR |
60 | /* thread information allocation */ |
61 | -#define alloc_thread_info(tsk, node) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) |
62 | +#define alloc_thread_info_node(tsk, node) \ |
63 | + ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1)) |
64 | #define free_thread_info(ti) free_pages((unsigned long) (ti), 1) |
65 | |
66 | #endif /* !__ASSEMBLY__ */ |
67 | diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h |
68 | index f819559..26fd114 100644 |
69 | --- a/arch/parisc/include/asm/atomic.h |
70 | +++ b/arch/parisc/include/asm/atomic.h |
71 | @@ -259,10 +259,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
72 | |
73 | #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) |
74 | |
75 | -static __inline__ int |
76 | +static __inline__ s64 |
77 | __atomic64_add_return(s64 i, atomic64_t *v) |
78 | { |
79 | - int ret; |
80 | + s64 ret; |
81 | unsigned long flags; |
82 | _atomic_spin_lock_irqsave(v, flags); |
83 | |
84 | diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h |
85 | index 67a33cc..2388bdb 100644 |
86 | --- a/arch/parisc/include/asm/futex.h |
87 | +++ b/arch/parisc/include/asm/futex.h |
88 | @@ -5,11 +5,14 @@ |
89 | |
90 | #include <linux/futex.h> |
91 | #include <linux/uaccess.h> |
92 | +#include <asm/atomic.h> |
93 | #include <asm/errno.h> |
94 | |
95 | static inline int |
96 | futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
97 | { |
98 | + unsigned long int flags; |
99 | + u32 val; |
100 | int op = (encoded_op >> 28) & 7; |
101 | int cmp = (encoded_op >> 24) & 15; |
102 | int oparg = (encoded_op << 8) >> 20; |
103 | @@ -18,21 +21,58 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
104 | if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) |
105 | oparg = 1 << oparg; |
106 | |
107 | - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) |
108 | + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) |
109 | return -EFAULT; |
110 | |
111 | pagefault_disable(); |
112 | |
113 | + _atomic_spin_lock_irqsave(uaddr, flags); |
114 | + |
115 | switch (op) { |
116 | case FUTEX_OP_SET: |
117 | + /* *(int *)UADDR2 = OPARG; */ |
118 | + ret = get_user(oldval, uaddr); |
119 | + if (!ret) |
120 | + ret = put_user(oparg, uaddr); |
121 | + break; |
122 | case FUTEX_OP_ADD: |
123 | + /* *(int *)UADDR2 += OPARG; */ |
124 | + ret = get_user(oldval, uaddr); |
125 | + if (!ret) { |
126 | + val = oldval + oparg; |
127 | + ret = put_user(val, uaddr); |
128 | + } |
129 | + break; |
130 | case FUTEX_OP_OR: |
131 | + /* *(int *)UADDR2 |= OPARG; */ |
132 | + ret = get_user(oldval, uaddr); |
133 | + if (!ret) { |
134 | + val = oldval | oparg; |
135 | + ret = put_user(val, uaddr); |
136 | + } |
137 | + break; |
138 | case FUTEX_OP_ANDN: |
139 | + /* *(int *)UADDR2 &= ~OPARG; */ |
140 | + ret = get_user(oldval, uaddr); |
141 | + if (!ret) { |
142 | + val = oldval & ~oparg; |
143 | + ret = put_user(val, uaddr); |
144 | + } |
145 | + break; |
146 | case FUTEX_OP_XOR: |
147 | + /* *(int *)UADDR2 ^= OPARG; */ |
148 | + ret = get_user(oldval, uaddr); |
149 | + if (!ret) { |
150 | + val = oldval ^ oparg; |
151 | + ret = put_user(val, uaddr); |
152 | + } |
153 | + break; |
154 | default: |
155 | ret = -ENOSYS; |
156 | } |
157 | |
158 | + _atomic_spin_unlock_irqrestore(uaddr, flags); |
159 | + |
160 | pagefault_enable(); |
161 | |
162 | if (!ret) { |
163 | @@ -54,7 +94,9 @@ static inline int |
164 | futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
165 | u32 oldval, u32 newval) |
166 | { |
167 | + int ret; |
168 | u32 val; |
169 | + unsigned long flags; |
170 | |
171 | /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is |
172 | * our gateway page, and causes no end of trouble... |
173 | @@ -65,12 +107,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
174 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) |
175 | return -EFAULT; |
176 | |
177 | - if (get_user(val, uaddr)) |
178 | - return -EFAULT; |
179 | - if (val == oldval && put_user(newval, uaddr)) |
180 | - return -EFAULT; |
181 | + /* HPPA has no cmpxchg in hardware and therefore the |
182 | + * best we can do here is use an array of locks. The |
183 | + * lock selected is based on a hash of the userspace |
184 | + * address. This should scale to a couple of CPUs. |
185 | + */ |
186 | + |
187 | + _atomic_spin_lock_irqsave(uaddr, flags); |
188 | + |
189 | + ret = get_user(val, uaddr); |
190 | + |
191 | + if (!ret && val == oldval) |
192 | + ret = put_user(newval, uaddr); |
193 | + |
194 | *uval = val; |
195 | - return 0; |
196 | + |
197 | + _atomic_spin_unlock_irqrestore(uaddr, flags); |
198 | + |
199 | + return ret; |
200 | } |
201 | |
202 | #endif /*__KERNEL__*/ |
203 | diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h |
204 | index 3392de3..d61de64 100644 |
205 | --- a/arch/parisc/include/asm/unistd.h |
206 | +++ b/arch/parisc/include/asm/unistd.h |
207 | @@ -821,8 +821,9 @@ |
208 | #define __NR_open_by_handle_at (__NR_Linux + 326) |
209 | #define __NR_syncfs (__NR_Linux + 327) |
210 | #define __NR_setns (__NR_Linux + 328) |
211 | +#define __NR_sendmmsg (__NR_Linux + 329) |
212 | |
213 | -#define __NR_Linux_syscalls (__NR_setns + 1) |
214 | +#define __NR_Linux_syscalls (__NR_sendmmsg + 1) |
215 | |
216 | |
217 | #define __IGNORE_select /* newselect */ |
218 | diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S |
219 | index 34a4f5a..e66366f 100644 |
220 | --- a/arch/parisc/kernel/syscall_table.S |
221 | +++ b/arch/parisc/kernel/syscall_table.S |
222 | @@ -427,6 +427,7 @@ |
223 | ENTRY_COMP(open_by_handle_at) |
224 | ENTRY_SAME(syncfs) |
225 | ENTRY_SAME(setns) |
226 | + ENTRY_COMP(sendmmsg) |
227 | |
228 | /* Nothing yet */ |
229 | |
230 | diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c |
231 | index c016033..3b22142 100644 |
232 | --- a/arch/powerpc/kernel/prom_init.c |
233 | +++ b/arch/powerpc/kernel/prom_init.c |
234 | @@ -1020,7 +1020,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) |
235 | } |
236 | if (addr == 0) |
237 | return 0; |
238 | - RELOC(alloc_bottom) = addr; |
239 | + RELOC(alloc_bottom) = addr + size; |
240 | |
241 | prom_debug(" -> %x\n", addr); |
242 | prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); |
243 | @@ -1834,7 +1834,7 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, |
244 | chunk = alloc_up(room, 0); |
245 | if (chunk == 0) |
246 | prom_panic("No memory for flatten_device_tree (claim failed)"); |
247 | - *mem_end = RELOC(alloc_top); |
248 | + *mem_end = chunk + room; |
249 | } |
250 | |
251 | ret = (void *)*mem_start; |
252 | @@ -2053,7 +2053,7 @@ static void __init flatten_device_tree(void) |
253 | mem_start = (unsigned long)alloc_up(room, PAGE_SIZE); |
254 | if (mem_start == 0) |
255 | prom_panic("Can't allocate initial device-tree chunk\n"); |
256 | - mem_end = RELOC(alloc_top); |
257 | + mem_end = mem_start + room; |
258 | |
259 | /* Get root of tree */ |
260 | root = call_prom("peer", 1, 1, (phandle)0); |
261 | diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c |
262 | index e919007..0e86563 100644 |
263 | --- a/arch/powerpc/platforms/pseries/dtl.c |
264 | +++ b/arch/powerpc/platforms/pseries/dtl.c |
265 | @@ -181,7 +181,7 @@ static void dtl_stop(struct dtl *dtl) |
266 | |
267 | lppaca_of(dtl->cpu).dtl_enable_mask = 0x0; |
268 | |
269 | - unregister_dtl(hwcpu, __pa(dtl->buf)); |
270 | + unregister_dtl(hwcpu); |
271 | } |
272 | |
273 | static u64 dtl_current_index(struct dtl *dtl) |
274 | diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c |
275 | index 54cf3a4..1118cb7 100644 |
276 | --- a/arch/powerpc/platforms/pseries/kexec.c |
277 | +++ b/arch/powerpc/platforms/pseries/kexec.c |
278 | @@ -26,6 +26,17 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) |
279 | /* Don't risk a hypervisor call if we're crashing */ |
280 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { |
281 | unsigned long addr; |
282 | + int ret; |
283 | + |
284 | + if (get_lppaca()->dtl_enable_mask) { |
285 | + ret = unregister_dtl(hard_smp_processor_id()); |
286 | + if (ret) { |
287 | + pr_err("WARNING: DTL deregistration for cpu " |
288 | + "%d (hw %d) failed with %d\n", |
289 | + smp_processor_id(), |
290 | + hard_smp_processor_id(), ret); |
291 | + } |
292 | + } |
293 | |
294 | addr = __pa(get_slb_shadow()); |
295 | if (unregister_slb_shadow(hard_smp_processor_id(), addr)) |
296 | diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c |
297 | index 39e6e0a..ed96b37 100644 |
298 | --- a/arch/powerpc/platforms/pseries/lpar.c |
299 | +++ b/arch/powerpc/platforms/pseries/lpar.c |
300 | @@ -395,7 +395,7 @@ static void pSeries_lpar_hptab_clear(void) |
301 | unsigned long ptel; |
302 | } ptes[4]; |
303 | long lpar_rc; |
304 | - int i, j; |
305 | + unsigned long i, j; |
306 | |
307 | /* Read in batches of 4, |
308 | * invalidate only valid entries not in the VRMA |
309 | diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h |
310 | index 4bf2120..a6921ae 100644 |
311 | --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h |
312 | +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h |
313 | @@ -73,9 +73,9 @@ static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) |
314 | return vpa_call(0x3, cpu, vpa); |
315 | } |
316 | |
317 | -static inline long unregister_dtl(unsigned long cpu, unsigned long vpa) |
318 | +static inline long unregister_dtl(unsigned long cpu) |
319 | { |
320 | - return vpa_call(0x6, cpu, vpa); |
321 | + return vpa_call(0x6, cpu, 0); |
322 | } |
323 | |
324 | static inline long register_dtl(unsigned long cpu, unsigned long vpa) |
325 | diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h |
326 | index 38e9aa1..3fc595a 100644 |
327 | --- a/arch/sparc/include/asm/bitops_64.h |
328 | +++ b/arch/sparc/include/asm/bitops_64.h |
329 | @@ -26,61 +26,28 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr); |
330 | #define smp_mb__before_clear_bit() barrier() |
331 | #define smp_mb__after_clear_bit() barrier() |
332 | |
333 | -#include <asm-generic/bitops/ffz.h> |
334 | -#include <asm-generic/bitops/__ffs.h> |
335 | #include <asm-generic/bitops/fls.h> |
336 | #include <asm-generic/bitops/__fls.h> |
337 | #include <asm-generic/bitops/fls64.h> |
338 | |
339 | #ifdef __KERNEL__ |
340 | |
341 | +extern int ffs(int x); |
342 | +extern unsigned long __ffs(unsigned long); |
343 | + |
344 | +#include <asm-generic/bitops/ffz.h> |
345 | #include <asm-generic/bitops/sched.h> |
346 | -#include <asm-generic/bitops/ffs.h> |
347 | |
348 | /* |
349 | * hweightN: returns the hamming weight (i.e. the number |
350 | * of bits set) of a N-bit word |
351 | */ |
352 | |
353 | -#ifdef ULTRA_HAS_POPULATION_COUNT |
354 | - |
355 | -static inline unsigned int __arch_hweight64(unsigned long w) |
356 | -{ |
357 | - unsigned int res; |
358 | - |
359 | - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); |
360 | - return res; |
361 | -} |
362 | - |
363 | -static inline unsigned int __arch_hweight32(unsigned int w) |
364 | -{ |
365 | - unsigned int res; |
366 | - |
367 | - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff)); |
368 | - return res; |
369 | -} |
370 | +extern unsigned long __arch_hweight64(__u64 w); |
371 | +extern unsigned int __arch_hweight32(unsigned int w); |
372 | +extern unsigned int __arch_hweight16(unsigned int w); |
373 | +extern unsigned int __arch_hweight8(unsigned int w); |
374 | |
375 | -static inline unsigned int __arch_hweight16(unsigned int w) |
376 | -{ |
377 | - unsigned int res; |
378 | - |
379 | - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff)); |
380 | - return res; |
381 | -} |
382 | - |
383 | -static inline unsigned int __arch_hweight8(unsigned int w) |
384 | -{ |
385 | - unsigned int res; |
386 | - |
387 | - __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff)); |
388 | - return res; |
389 | -} |
390 | - |
391 | -#else |
392 | - |
393 | -#include <asm-generic/bitops/arch_hweight.h> |
394 | - |
395 | -#endif |
396 | #include <asm-generic/bitops/const_hweight.h> |
397 | #include <asm-generic/bitops/lock.h> |
398 | #endif /* __KERNEL__ */ |
399 | diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h |
400 | index e678803..7df8b7f 100644 |
401 | --- a/arch/sparc/include/asm/elf_64.h |
402 | +++ b/arch/sparc/include/asm/elf_64.h |
403 | @@ -59,15 +59,33 @@ |
404 | #define R_SPARC_6 45 |
405 | |
406 | /* Bits present in AT_HWCAP, primarily for Sparc32. */ |
407 | - |
408 | -#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ |
409 | -#define HWCAP_SPARC_STBAR 2 |
410 | -#define HWCAP_SPARC_SWAP 4 |
411 | -#define HWCAP_SPARC_MULDIV 8 |
412 | -#define HWCAP_SPARC_V9 16 |
413 | -#define HWCAP_SPARC_ULTRA3 32 |
414 | -#define HWCAP_SPARC_BLKINIT 64 |
415 | -#define HWCAP_SPARC_N2 128 |
416 | +#define HWCAP_SPARC_FLUSH 0x00000001 |
417 | +#define HWCAP_SPARC_STBAR 0x00000002 |
418 | +#define HWCAP_SPARC_SWAP 0x00000004 |
419 | +#define HWCAP_SPARC_MULDIV 0x00000008 |
420 | +#define HWCAP_SPARC_V9 0x00000010 |
421 | +#define HWCAP_SPARC_ULTRA3 0x00000020 |
422 | +#define HWCAP_SPARC_BLKINIT 0x00000040 |
423 | +#define HWCAP_SPARC_N2 0x00000080 |
424 | + |
425 | +/* Solaris compatible AT_HWCAP bits. */ |
426 | +#define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */ |
427 | +#define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */ |
428 | +#define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */ |
429 | +#define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */ |
430 | +#define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */ |
431 | +#define AV_SPARC_VIS 0x00002000 /* VIS insns available */ |
432 | +#define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */ |
433 | +#define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */ |
434 | +#define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */ |
435 | +#define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */ |
436 | +#define AV_SPARC_HPC 0x00040000 /* HPC insns available */ |
437 | +#define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */ |
438 | +#define AV_SPARC_TRANS 0x00100000 /* transaction insns available */ |
439 | +#define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */ |
440 | +#define AV_SPARC_IMA 0x00400000 /* integer multiply-add */ |
441 | +#define AV_SPARC_ASI_CACHE_SPARING \ |
442 | + 0x00800000 /* cache sparing ASIs available */ |
443 | |
444 | #define CORE_DUMP_USE_REGSET |
445 | |
446 | @@ -162,31 +180,8 @@ typedef struct { |
447 | #define ELF_ET_DYN_BASE 0x0000010000000000UL |
448 | #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL |
449 | |
450 | - |
451 | -/* This yields a mask that user programs can use to figure out what |
452 | - instruction set this cpu supports. */ |
453 | - |
454 | -/* On Ultra, we support all of the v8 capabilities. */ |
455 | -static inline unsigned int sparc64_elf_hwcap(void) |
456 | -{ |
457 | - unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | |
458 | - HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | |
459 | - HWCAP_SPARC_V9); |
460 | - |
461 | - if (tlb_type == cheetah || tlb_type == cheetah_plus) |
462 | - cap |= HWCAP_SPARC_ULTRA3; |
463 | - else if (tlb_type == hypervisor) { |
464 | - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || |
465 | - sun4v_chip_type == SUN4V_CHIP_NIAGARA2) |
466 | - cap |= HWCAP_SPARC_BLKINIT; |
467 | - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2) |
468 | - cap |= HWCAP_SPARC_N2; |
469 | - } |
470 | - |
471 | - return cap; |
472 | -} |
473 | - |
474 | -#define ELF_HWCAP sparc64_elf_hwcap(); |
475 | +extern unsigned long sparc64_elf_hwcap; |
476 | +#define ELF_HWCAP sparc64_elf_hwcap |
477 | |
478 | /* This yields a string that ld.so will use to load implementation |
479 | specific libraries for optimization. This is more specific in |
480 | diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h |
481 | index 7568640..015a761 100644 |
482 | --- a/arch/sparc/include/asm/hypervisor.h |
483 | +++ b/arch/sparc/include/asm/hypervisor.h |
484 | @@ -2927,6 +2927,13 @@ extern unsigned long sun4v_ncs_request(unsigned long request, |
485 | #define HV_FAST_FIRE_GET_PERFREG 0x120 |
486 | #define HV_FAST_FIRE_SET_PERFREG 0x121 |
487 | |
488 | +#define HV_FAST_REBOOT_DATA_SET 0x172 |
489 | + |
490 | +#ifndef __ASSEMBLY__ |
491 | +extern unsigned long sun4v_reboot_data_set(unsigned long ra, |
492 | + unsigned long len); |
493 | +#endif |
494 | + |
495 | /* Function numbers for HV_CORE_TRAP. */ |
496 | #define HV_CORE_SET_VER 0x00 |
497 | #define HV_CORE_PUTCHAR 0x01 |
498 | @@ -2940,16 +2947,23 @@ extern unsigned long sun4v_ncs_request(unsigned long request, |
499 | #define HV_GRP_CORE 0x0001 |
500 | #define HV_GRP_INTR 0x0002 |
501 | #define HV_GRP_SOFT_STATE 0x0003 |
502 | +#define HV_GRP_TM 0x0080 |
503 | #define HV_GRP_PCI 0x0100 |
504 | #define HV_GRP_LDOM 0x0101 |
505 | #define HV_GRP_SVC_CHAN 0x0102 |
506 | #define HV_GRP_NCS 0x0103 |
507 | #define HV_GRP_RNG 0x0104 |
508 | +#define HV_GRP_PBOOT 0x0105 |
509 | +#define HV_GRP_TPM 0x0107 |
510 | +#define HV_GRP_SDIO 0x0108 |
511 | +#define HV_GRP_SDIO_ERR 0x0109 |
512 | +#define HV_GRP_REBOOT_DATA 0x0110 |
513 | #define HV_GRP_NIAG_PERF 0x0200 |
514 | #define HV_GRP_FIRE_PERF 0x0201 |
515 | #define HV_GRP_N2_CPU 0x0202 |
516 | #define HV_GRP_NIU 0x0204 |
517 | #define HV_GRP_VF_CPU 0x0205 |
518 | +#define HV_GRP_KT_CPU 0x0209 |
519 | #define HV_GRP_DIAG 0x0300 |
520 | |
521 | #ifndef __ASSEMBLY__ |
522 | diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h |
523 | index f0d0c40..55a17c6 100644 |
524 | --- a/arch/sparc/include/asm/spitfire.h |
525 | +++ b/arch/sparc/include/asm/spitfire.h |
526 | @@ -42,6 +42,7 @@ |
527 | #define SUN4V_CHIP_INVALID 0x00 |
528 | #define SUN4V_CHIP_NIAGARA1 0x01 |
529 | #define SUN4V_CHIP_NIAGARA2 0x02 |
530 | +#define SUN4V_CHIP_NIAGARA3 0x03 |
531 | #define SUN4V_CHIP_UNKNOWN 0xff |
532 | |
533 | #ifndef __ASSEMBLY__ |
534 | diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h |
535 | index 83c571d..1a8afd1 100644 |
536 | --- a/arch/sparc/include/asm/tsb.h |
537 | +++ b/arch/sparc/include/asm/tsb.h |
538 | @@ -133,29 +133,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; |
539 | sub TSB, 0x8, TSB; \ |
540 | TSB_STORE(TSB, TAG); |
541 | |
542 | -#define KTSB_LOAD_QUAD(TSB, REG) \ |
543 | - ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; |
544 | - |
545 | -#define KTSB_STORE(ADDR, VAL) \ |
546 | - stxa VAL, [ADDR] ASI_N; |
547 | - |
548 | -#define KTSB_LOCK_TAG(TSB, REG1, REG2) \ |
549 | -99: lduwa [TSB] ASI_N, REG1; \ |
550 | - sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ |
551 | - andcc REG1, REG2, %g0; \ |
552 | - bne,pn %icc, 99b; \ |
553 | - nop; \ |
554 | - casa [TSB] ASI_N, REG1, REG2;\ |
555 | - cmp REG1, REG2; \ |
556 | - bne,pn %icc, 99b; \ |
557 | - nop; \ |
558 | - |
559 | -#define KTSB_WRITE(TSB, TTE, TAG) \ |
560 | - add TSB, 0x8, TSB; \ |
561 | - stxa TTE, [TSB] ASI_N; \ |
562 | - sub TSB, 0x8, TSB; \ |
563 | - stxa TAG, [TSB] ASI_N; |
564 | - |
565 | /* Do a kernel page table walk. Leaves physical PTE pointer in |
566 | * REG1. Jumps to FAIL_LABEL on early page table walk termination. |
567 | * VADDR will not be clobbered, but REG2 will. |
568 | @@ -239,6 +216,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; |
569 | (KERNEL_TSB_SIZE_BYTES / 16) |
570 | #define KERNEL_TSB4M_NENTRIES 4096 |
571 | |
572 | +#define KTSB_PHYS_SHIFT 15 |
573 | + |
574 | /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL |
575 | * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries |
576 | * and the found TTE will be left in REG1. REG3 and REG4 must |
577 | @@ -247,13 +226,22 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; |
578 | * VADDR and TAG will be preserved and not clobbered by this macro. |
579 | */ |
580 | #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ |
581 | - sethi %hi(swapper_tsb), REG1; \ |
582 | +661: sethi %hi(swapper_tsb), REG1; \ |
583 | or REG1, %lo(swapper_tsb), REG1; \ |
584 | + .section .swapper_tsb_phys_patch, "ax"; \ |
585 | + .word 661b; \ |
586 | + .previous; \ |
587 | +661: nop; \ |
588 | + .section .tsb_ldquad_phys_patch, "ax"; \ |
589 | + .word 661b; \ |
590 | + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ |
591 | + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ |
592 | + .previous; \ |
593 | srlx VADDR, PAGE_SHIFT, REG2; \ |
594 | and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ |
595 | sllx REG2, 4, REG2; \ |
596 | add REG1, REG2, REG2; \ |
597 | - KTSB_LOAD_QUAD(REG2, REG3); \ |
598 | + TSB_LOAD_QUAD(REG2, REG3); \ |
599 | cmp REG3, TAG; \ |
600 | be,a,pt %xcc, OK_LABEL; \ |
601 | mov REG4, REG1; |
602 | @@ -263,12 +251,21 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; |
603 | * we can make use of that for the index computation. |
604 | */ |
605 | #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ |
606 | - sethi %hi(swapper_4m_tsb), REG1; \ |
607 | +661: sethi %hi(swapper_4m_tsb), REG1; \ |
608 | or REG1, %lo(swapper_4m_tsb), REG1; \ |
609 | + .section .swapper_4m_tsb_phys_patch, "ax"; \ |
610 | + .word 661b; \ |
611 | + .previous; \ |
612 | +661: nop; \ |
613 | + .section .tsb_ldquad_phys_patch, "ax"; \ |
614 | + .word 661b; \ |
615 | + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ |
616 | + sllx REG1, KTSB_PHYS_SHIFT, REG1; \ |
617 | + .previous; \ |
618 | and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ |
619 | sllx REG2, 4, REG2; \ |
620 | add REG1, REG2, REG2; \ |
621 | - KTSB_LOAD_QUAD(REG2, REG3); \ |
622 | + TSB_LOAD_QUAD(REG2, REG3); \ |
623 | cmp REG3, TAG; \ |
624 | be,a,pt %xcc, OK_LABEL; \ |
625 | mov REG4, REG1; |
626 | diff --git a/arch/sparc/include/asm/xor_64.h b/arch/sparc/include/asm/xor_64.h |
627 | index bee4bf4..9ed6ff6 100644 |
628 | --- a/arch/sparc/include/asm/xor_64.h |
629 | +++ b/arch/sparc/include/asm/xor_64.h |
630 | @@ -65,6 +65,7 @@ static struct xor_block_template xor_block_niagara = { |
631 | #define XOR_SELECT_TEMPLATE(FASTEST) \ |
632 | ((tlb_type == hypervisor && \ |
633 | (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \ |
634 | - sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \ |
635 | + sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || \ |
636 | + sun4v_chip_type == SUN4V_CHIP_NIAGARA3)) ? \ |
637 | &xor_block_niagara : \ |
638 | &xor_block_VIS) |
639 | diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c |
640 | index 138dbbc..9810fd8 100644 |
641 | --- a/arch/sparc/kernel/cpu.c |
642 | +++ b/arch/sparc/kernel/cpu.c |
643 | @@ -396,6 +396,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) |
644 | , cpu_data(0).clock_tick |
645 | #endif |
646 | ); |
647 | + cpucap_info(m); |
648 | #ifdef CONFIG_SMP |
649 | smp_bogo(m); |
650 | #endif |
651 | @@ -474,11 +475,18 @@ static void __init sun4v_cpu_probe(void) |
652 | sparc_pmu_type = "niagara2"; |
653 | break; |
654 | |
655 | + case SUN4V_CHIP_NIAGARA3: |
656 | + sparc_cpu_type = "UltraSparc T3 (Niagara3)"; |
657 | + sparc_fpu_type = "UltraSparc T3 integrated FPU"; |
658 | + sparc_pmu_type = "niagara3"; |
659 | + break; |
660 | + |
661 | default: |
662 | printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", |
663 | prom_cpu_compatible); |
664 | sparc_cpu_type = "Unknown SUN4V CPU"; |
665 | sparc_fpu_type = "Unknown SUN4V FPU"; |
666 | + sparc_pmu_type = "Unknown SUN4V PMU"; |
667 | break; |
668 | } |
669 | } |
670 | diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c |
671 | index d91fd78..4197e8d 100644 |
672 | --- a/arch/sparc/kernel/cpumap.c |
673 | +++ b/arch/sparc/kernel/cpumap.c |
674 | @@ -324,6 +324,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) |
675 | switch (sun4v_chip_type) { |
676 | case SUN4V_CHIP_NIAGARA1: |
677 | case SUN4V_CHIP_NIAGARA2: |
678 | + case SUN4V_CHIP_NIAGARA3: |
679 | rover_inc_table = niagara_iterate_method; |
680 | break; |
681 | default: |
682 | diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c |
683 | index dd1342c..7429b47 100644 |
684 | --- a/arch/sparc/kernel/ds.c |
685 | +++ b/arch/sparc/kernel/ds.c |
686 | @@ -15,12 +15,15 @@ |
687 | #include <linux/reboot.h> |
688 | #include <linux/cpu.h> |
689 | |
690 | +#include <asm/hypervisor.h> |
691 | #include <asm/ldc.h> |
692 | #include <asm/vio.h> |
693 | #include <asm/mdesc.h> |
694 | #include <asm/head.h> |
695 | #include <asm/irq.h> |
696 | |
697 | +#include "kernel.h" |
698 | + |
699 | #define DRV_MODULE_NAME "ds" |
700 | #define PFX DRV_MODULE_NAME ": " |
701 | #define DRV_MODULE_VERSION "1.0" |
702 | @@ -828,18 +831,32 @@ void ldom_set_var(const char *var, const char *value) |
703 | } |
704 | } |
705 | |
706 | +static char full_boot_str[256] __attribute__((aligned(32))); |
707 | +static int reboot_data_supported; |
708 | + |
709 | void ldom_reboot(const char *boot_command) |
710 | { |
711 | /* Don't bother with any of this if the boot_command |
712 | * is empty. |
713 | */ |
714 | if (boot_command && strlen(boot_command)) { |
715 | - char full_boot_str[256]; |
716 | + unsigned long len; |
717 | |
718 | strcpy(full_boot_str, "boot "); |
719 | strcpy(full_boot_str + strlen("boot "), boot_command); |
720 | + len = strlen(full_boot_str); |
721 | |
722 | - ldom_set_var("reboot-command", full_boot_str); |
723 | + if (reboot_data_supported) { |
724 | + unsigned long ra = kimage_addr_to_ra(full_boot_str); |
725 | + unsigned long hv_ret; |
726 | + |
727 | + hv_ret = sun4v_reboot_data_set(ra, len); |
728 | + if (hv_ret != HV_EOK) |
729 | + pr_err("SUN4V: Unable to set reboot data " |
730 | + "hv_ret=%lu\n", hv_ret); |
731 | + } else { |
732 | + ldom_set_var("reboot-command", full_boot_str); |
733 | + } |
734 | } |
735 | sun4v_mach_sir(); |
736 | } |
737 | @@ -1237,6 +1254,16 @@ static struct vio_driver ds_driver = { |
738 | |
739 | static int __init ds_init(void) |
740 | { |
741 | + unsigned long hv_ret, major, minor; |
742 | + |
743 | + if (tlb_type == hypervisor) { |
744 | + hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor); |
745 | + if (hv_ret == HV_EOK) { |
746 | + pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n", |
747 | + major, minor); |
748 | + reboot_data_supported = 1; |
749 | + } |
750 | + } |
751 | kthread_run(ds_thread, NULL, "kldomd"); |
752 | |
753 | return vio_register_driver(&ds_driver); |
754 | diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h |
755 | index d1f1361..e27f8ea 100644 |
756 | --- a/arch/sparc/kernel/entry.h |
757 | +++ b/arch/sparc/kernel/entry.h |
758 | @@ -42,6 +42,20 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, |
759 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); |
760 | |
761 | #else /* CONFIG_SPARC32 */ |
762 | +struct popc_3insn_patch_entry { |
763 | + unsigned int addr; |
764 | + unsigned int insns[3]; |
765 | +}; |
766 | +extern struct popc_3insn_patch_entry __popc_3insn_patch, |
767 | + __popc_3insn_patch_end; |
768 | + |
769 | +struct popc_6insn_patch_entry { |
770 | + unsigned int addr; |
771 | + unsigned int insns[6]; |
772 | +}; |
773 | +extern struct popc_6insn_patch_entry __popc_6insn_patch, |
774 | + __popc_6insn_patch_end; |
775 | + |
776 | extern void __init per_cpu_patch(void); |
777 | extern void __init sun4v_patch(void); |
778 | extern void __init boot_cpu_id_too_large(int cpu); |
779 | diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S |
780 | index aa594c7..0cbab31 100644 |
781 | --- a/arch/sparc/kernel/head_64.S |
782 | +++ b/arch/sparc/kernel/head_64.S |
783 | @@ -132,6 +132,8 @@ prom_sun4v_name: |
784 | .asciz "sun4v" |
785 | prom_niagara_prefix: |
786 | .asciz "SUNW,UltraSPARC-T" |
787 | +prom_sparc_prefix: |
788 | + .asciz "SPARC-T" |
789 | .align 4 |
790 | prom_root_compatible: |
791 | .skip 64 |
792 | @@ -382,6 +384,22 @@ sun4v_chip_type: |
793 | 90: ldub [%g7], %g2 |
794 | ldub [%g1], %g4 |
795 | cmp %g2, %g4 |
796 | + bne,pn %icc, 89f |
797 | + add %g7, 1, %g7 |
798 | + subcc %g3, 1, %g3 |
799 | + bne,pt %xcc, 90b |
800 | + add %g1, 1, %g1 |
801 | + ba,pt %xcc, 91f |
802 | + nop |
803 | + |
804 | +89: sethi %hi(prom_cpu_compatible), %g1 |
805 | + or %g1, %lo(prom_cpu_compatible), %g1 |
806 | + sethi %hi(prom_sparc_prefix), %g7 |
807 | + or %g7, %lo(prom_sparc_prefix), %g7 |
808 | + mov 7, %g3 |
809 | +90: ldub [%g7], %g2 |
810 | + ldub [%g1], %g4 |
811 | + cmp %g2, %g4 |
812 | bne,pn %icc, 4f |
813 | add %g7, 1, %g7 |
814 | subcc %g3, 1, %g3 |
815 | @@ -390,6 +408,15 @@ sun4v_chip_type: |
816 | |
817 | sethi %hi(prom_cpu_compatible), %g1 |
818 | or %g1, %lo(prom_cpu_compatible), %g1 |
819 | + ldub [%g1 + 7], %g2 |
820 | + cmp %g2, '3' |
821 | + be,pt %xcc, 5f |
822 | + mov SUN4V_CHIP_NIAGARA3, %g4 |
823 | + ba,pt %xcc, 4f |
824 | + nop |
825 | + |
826 | +91: sethi %hi(prom_cpu_compatible), %g1 |
827 | + or %g1, %lo(prom_cpu_compatible), %g1 |
828 | ldub [%g1 + 17], %g2 |
829 | cmp %g2, '1' |
830 | be,pt %xcc, 5f |
831 | @@ -397,6 +424,7 @@ sun4v_chip_type: |
832 | cmp %g2, '2' |
833 | be,pt %xcc, 5f |
834 | mov SUN4V_CHIP_NIAGARA2, %g4 |
835 | + |
836 | 4: |
837 | mov SUN4V_CHIP_UNKNOWN, %g4 |
838 | 5: sethi %hi(sun4v_chip_type), %g2 |
839 | @@ -514,6 +542,9 @@ niagara_tlb_fixup: |
840 | cmp %g1, SUN4V_CHIP_NIAGARA2 |
841 | be,pt %xcc, niagara2_patch |
842 | nop |
843 | + cmp %g1, SUN4V_CHIP_NIAGARA3 |
844 | + be,pt %xcc, niagara2_patch |
845 | + nop |
846 | |
847 | call generic_patch_copyops |
848 | nop |
849 | @@ -528,7 +559,7 @@ niagara2_patch: |
850 | nop |
851 | call niagara_patch_bzero |
852 | nop |
853 | - call niagara2_patch_pageops |
854 | + call niagara_patch_pageops |
855 | nop |
856 | |
857 | ba,a,pt %xcc, 80f |
858 | diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c |
859 | index 7c60afb..c2d055d 100644 |
860 | --- a/arch/sparc/kernel/hvapi.c |
861 | +++ b/arch/sparc/kernel/hvapi.c |
862 | @@ -28,16 +28,23 @@ static struct api_info api_table[] = { |
863 | { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, |
864 | { .group = HV_GRP_INTR, }, |
865 | { .group = HV_GRP_SOFT_STATE, }, |
866 | + { .group = HV_GRP_TM, }, |
867 | { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, |
868 | { .group = HV_GRP_LDOM, }, |
869 | { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, |
870 | { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, |
871 | { .group = HV_GRP_RNG, }, |
872 | + { .group = HV_GRP_PBOOT, }, |
873 | + { .group = HV_GRP_TPM, }, |
874 | + { .group = HV_GRP_SDIO, }, |
875 | + { .group = HV_GRP_SDIO_ERR, }, |
876 | + { .group = HV_GRP_REBOOT_DATA, }, |
877 | { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, |
878 | { .group = HV_GRP_FIRE_PERF, }, |
879 | { .group = HV_GRP_N2_CPU, }, |
880 | { .group = HV_GRP_NIU, }, |
881 | { .group = HV_GRP_VF_CPU, }, |
882 | + { .group = HV_GRP_KT_CPU, }, |
883 | { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API }, |
884 | }; |
885 | |
886 | diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S |
887 | index 8a5f35f..58d60de 100644 |
888 | --- a/arch/sparc/kernel/hvcalls.S |
889 | +++ b/arch/sparc/kernel/hvcalls.S |
890 | @@ -798,3 +798,10 @@ ENTRY(sun4v_niagara2_setperf) |
891 | retl |
892 | nop |
893 | ENDPROC(sun4v_niagara2_setperf) |
894 | + |
895 | +ENTRY(sun4v_reboot_data_set) |
896 | + mov HV_FAST_REBOOT_DATA_SET, %o5 |
897 | + ta HV_FAST_TRAP |
898 | + retl |
899 | + nop |
900 | +ENDPROC(sun4v_reboot_data_set) |
901 | diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h |
902 | index 6f6544c..fd6c36b 100644 |
903 | --- a/arch/sparc/kernel/kernel.h |
904 | +++ b/arch/sparc/kernel/kernel.h |
905 | @@ -4,12 +4,27 @@ |
906 | #include <linux/interrupt.h> |
907 | |
908 | #include <asm/traps.h> |
909 | +#include <asm/head.h> |
910 | +#include <asm/io.h> |
911 | |
912 | /* cpu.c */ |
913 | extern const char *sparc_pmu_type; |
914 | extern unsigned int fsr_storage; |
915 | extern int ncpus_probed; |
916 | |
917 | +#ifdef CONFIG_SPARC64 |
918 | +/* setup_64.c */ |
919 | +struct seq_file; |
920 | +extern void cpucap_info(struct seq_file *); |
921 | + |
922 | +static inline unsigned long kimage_addr_to_ra(const char *p) |
923 | +{ |
924 | + unsigned long val = (unsigned long) p; |
925 | + |
926 | + return kern_base + (val - KERNBASE); |
927 | +} |
928 | +#endif |
929 | + |
930 | #ifdef CONFIG_SPARC32 |
931 | /* cpu.c */ |
932 | extern void cpu_probe(void); |
933 | diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S |
934 | index 1d36147..79f3103 100644 |
935 | --- a/arch/sparc/kernel/ktlb.S |
936 | +++ b/arch/sparc/kernel/ktlb.S |
937 | @@ -47,16 +47,16 @@ kvmap_itlb_tsb_miss: |
938 | kvmap_itlb_vmalloc_addr: |
939 | KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath) |
940 | |
941 | - KTSB_LOCK_TAG(%g1, %g2, %g7) |
942 | + TSB_LOCK_TAG(%g1, %g2, %g7) |
943 | |
944 | /* Load and check PTE. */ |
945 | ldxa [%g5] ASI_PHYS_USE_EC, %g5 |
946 | mov 1, %g7 |
947 | sllx %g7, TSB_TAG_INVALID_BIT, %g7 |
948 | brgez,a,pn %g5, kvmap_itlb_longpath |
949 | - KTSB_STORE(%g1, %g7) |
950 | + TSB_STORE(%g1, %g7) |
951 | |
952 | - KTSB_WRITE(%g1, %g5, %g6) |
953 | + TSB_WRITE(%g1, %g5, %g6) |
954 | |
955 | /* fallthrough to TLB load */ |
956 | |
957 | @@ -102,9 +102,9 @@ kvmap_itlb_longpath: |
958 | kvmap_itlb_obp: |
959 | OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath) |
960 | |
961 | - KTSB_LOCK_TAG(%g1, %g2, %g7) |
962 | + TSB_LOCK_TAG(%g1, %g2, %g7) |
963 | |
964 | - KTSB_WRITE(%g1, %g5, %g6) |
965 | + TSB_WRITE(%g1, %g5, %g6) |
966 | |
967 | ba,pt %xcc, kvmap_itlb_load |
968 | nop |
969 | @@ -112,17 +112,17 @@ kvmap_itlb_obp: |
970 | kvmap_dtlb_obp: |
971 | OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath) |
972 | |
973 | - KTSB_LOCK_TAG(%g1, %g2, %g7) |
974 | + TSB_LOCK_TAG(%g1, %g2, %g7) |
975 | |
976 | - KTSB_WRITE(%g1, %g5, %g6) |
977 | + TSB_WRITE(%g1, %g5, %g6) |
978 | |
979 | ba,pt %xcc, kvmap_dtlb_load |
980 | nop |
981 | |
982 | .align 32 |
983 | kvmap_dtlb_tsb4m_load: |
984 | - KTSB_LOCK_TAG(%g1, %g2, %g7) |
985 | - KTSB_WRITE(%g1, %g5, %g6) |
986 | + TSB_LOCK_TAG(%g1, %g2, %g7) |
987 | + TSB_WRITE(%g1, %g5, %g6) |
988 | ba,pt %xcc, kvmap_dtlb_load |
989 | nop |
990 | |
991 | @@ -222,16 +222,16 @@ kvmap_linear_patch: |
992 | kvmap_dtlb_vmalloc_addr: |
993 | KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath) |
994 | |
995 | - KTSB_LOCK_TAG(%g1, %g2, %g7) |
996 | + TSB_LOCK_TAG(%g1, %g2, %g7) |
997 | |
998 | /* Load and check PTE. */ |
999 | ldxa [%g5] ASI_PHYS_USE_EC, %g5 |
1000 | mov 1, %g7 |
1001 | sllx %g7, TSB_TAG_INVALID_BIT, %g7 |
1002 | brgez,a,pn %g5, kvmap_dtlb_longpath |
1003 | - KTSB_STORE(%g1, %g7) |
1004 | + TSB_STORE(%g1, %g7) |
1005 | |
1006 | - KTSB_WRITE(%g1, %g5, %g6) |
1007 | + TSB_WRITE(%g1, %g5, %g6) |
1008 | |
1009 | /* fallthrough to TLB load */ |
1010 | |
1011 | diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c |
1012 | index 42f28c7..acaebb6 100644 |
1013 | --- a/arch/sparc/kernel/mdesc.c |
1014 | +++ b/arch/sparc/kernel/mdesc.c |
1015 | @@ -508,6 +508,8 @@ const char *mdesc_node_name(struct mdesc_handle *hp, u64 node) |
1016 | } |
1017 | EXPORT_SYMBOL(mdesc_node_name); |
1018 | |
1019 | +static u64 max_cpus = 64; |
1020 | + |
1021 | static void __init report_platform_properties(void) |
1022 | { |
1023 | struct mdesc_handle *hp = mdesc_grab(); |
1024 | @@ -543,8 +545,10 @@ static void __init report_platform_properties(void) |
1025 | if (v) |
1026 | printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v); |
1027 | v = mdesc_get_property(hp, pn, "max-cpus", NULL); |
1028 | - if (v) |
1029 | - printk("PLATFORM: max-cpus [%llu]\n", *v); |
1030 | + if (v) { |
1031 | + max_cpus = *v; |
1032 | + printk("PLATFORM: max-cpus [%llu]\n", max_cpus); |
1033 | + } |
1034 | |
1035 | #ifdef CONFIG_SMP |
1036 | { |
1037 | @@ -715,7 +719,7 @@ static void __cpuinit set_proc_ids(struct mdesc_handle *hp) |
1038 | } |
1039 | |
1040 | static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, |
1041 | - unsigned char def) |
1042 | + unsigned long def, unsigned long max) |
1043 | { |
1044 | u64 val; |
1045 | |
1046 | @@ -726,6 +730,9 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, |
1047 | if (!val || val >= 64) |
1048 | goto use_default; |
1049 | |
1050 | + if (val > max) |
1051 | + val = max; |
1052 | + |
1053 | *mask = ((1U << val) * 64U) - 1U; |
1054 | return; |
1055 | |
1056 | @@ -736,19 +743,28 @@ use_default: |
1057 | static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, |
1058 | struct trap_per_cpu *tb) |
1059 | { |
1060 | + static int printed; |
1061 | const u64 *val; |
1062 | |
1063 | val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); |
1064 | - get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); |
1065 | + get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2)); |
1066 | |
1067 | val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); |
1068 | - get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); |
1069 | + get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8); |
1070 | |
1071 | val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); |
1072 | - get_one_mondo_bits(val, &tb->resum_qmask, 6); |
1073 | + get_one_mondo_bits(val, &tb->resum_qmask, 6, 7); |
1074 | |
1075 | val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); |
1076 | - get_one_mondo_bits(val, &tb->nonresum_qmask, 2); |
1077 | + get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2); |
1078 | + if (!printed++) { |
1079 | + pr_info("SUN4V: Mondo queue sizes " |
1080 | + "[cpu(%u) dev(%u) r(%u) nr(%u)]\n", |
1081 | + tb->cpu_mondo_qmask + 1, |
1082 | + tb->dev_mondo_qmask + 1, |
1083 | + tb->resum_qmask + 1, |
1084 | + tb->nonresum_qmask + 1); |
1085 | + } |
1086 | } |
1087 | |
1088 | static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) |
1089 | diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c |
1090 | index 8ac23e6..343b0f9 100644 |
1091 | --- a/arch/sparc/kernel/pcr.c |
1092 | +++ b/arch/sparc/kernel/pcr.c |
1093 | @@ -80,8 +80,11 @@ static void n2_pcr_write(u64 val) |
1094 | { |
1095 | unsigned long ret; |
1096 | |
1097 | - ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); |
1098 | - if (ret != HV_EOK) |
1099 | + if (val & PCR_N2_HTRACE) { |
1100 | + ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); |
1101 | + if (ret != HV_EOK) |
1102 | + write_pcr(val); |
1103 | + } else |
1104 | write_pcr(val); |
1105 | } |
1106 | |
1107 | @@ -106,6 +109,10 @@ static int __init register_perf_hsvc(void) |
1108 | perf_hsvc_group = HV_GRP_N2_CPU; |
1109 | break; |
1110 | |
1111 | + case SUN4V_CHIP_NIAGARA3: |
1112 | + perf_hsvc_group = HV_GRP_KT_CPU; |
1113 | + break; |
1114 | + |
1115 | default: |
1116 | return -ENODEV; |
1117 | } |
1118 | diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c |
1119 | index 2cb0e1c..6860d40 100644 |
1120 | --- a/arch/sparc/kernel/perf_event.c |
1121 | +++ b/arch/sparc/kernel/perf_event.c |
1122 | @@ -1301,7 +1301,8 @@ static bool __init supported_pmu(void) |
1123 | sparc_pmu = &niagara1_pmu; |
1124 | return true; |
1125 | } |
1126 | - if (!strcmp(sparc_pmu_type, "niagara2")) { |
1127 | + if (!strcmp(sparc_pmu_type, "niagara2") || |
1128 | + !strcmp(sparc_pmu_type, "niagara3")) { |
1129 | sparc_pmu = &niagara2_pmu; |
1130 | return true; |
1131 | } |
1132 | diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c |
1133 | index c4dd099..3e9daea 100644 |
1134 | --- a/arch/sparc/kernel/setup_64.c |
1135 | +++ b/arch/sparc/kernel/setup_64.c |
1136 | @@ -29,6 +29,7 @@ |
1137 | #include <linux/interrupt.h> |
1138 | #include <linux/cpu.h> |
1139 | #include <linux/initrd.h> |
1140 | +#include <linux/module.h> |
1141 | |
1142 | #include <asm/system.h> |
1143 | #include <asm/io.h> |
1144 | @@ -46,6 +47,8 @@ |
1145 | #include <asm/mmu.h> |
1146 | #include <asm/ns87303.h> |
1147 | #include <asm/btext.h> |
1148 | +#include <asm/elf.h> |
1149 | +#include <asm/mdesc.h> |
1150 | |
1151 | #ifdef CONFIG_IP_PNP |
1152 | #include <net/ipconfig.h> |
1153 | @@ -269,6 +272,40 @@ void __init sun4v_patch(void) |
1154 | sun4v_hvapi_init(); |
1155 | } |
1156 | |
1157 | +static void __init popc_patch(void) |
1158 | +{ |
1159 | + struct popc_3insn_patch_entry *p3; |
1160 | + struct popc_6insn_patch_entry *p6; |
1161 | + |
1162 | + p3 = &__popc_3insn_patch; |
1163 | + while (p3 < &__popc_3insn_patch_end) { |
1164 | + unsigned long i, addr = p3->addr; |
1165 | + |
1166 | + for (i = 0; i < 3; i++) { |
1167 | + *(unsigned int *) (addr + (i * 4)) = p3->insns[i]; |
1168 | + wmb(); |
1169 | + __asm__ __volatile__("flush %0" |
1170 | + : : "r" (addr + (i * 4))); |
1171 | + } |
1172 | + |
1173 | + p3++; |
1174 | + } |
1175 | + |
1176 | + p6 = &__popc_6insn_patch; |
1177 | + while (p6 < &__popc_6insn_patch_end) { |
1178 | + unsigned long i, addr = p6->addr; |
1179 | + |
1180 | + for (i = 0; i < 6; i++) { |
1181 | + *(unsigned int *) (addr + (i * 4)) = p6->insns[i]; |
1182 | + wmb(); |
1183 | + __asm__ __volatile__("flush %0" |
1184 | + : : "r" (addr + (i * 4))); |
1185 | + } |
1186 | + |
1187 | + p6++; |
1188 | + } |
1189 | +} |
1190 | + |
1191 | #ifdef CONFIG_SMP |
1192 | void __init boot_cpu_id_too_large(int cpu) |
1193 | { |
1194 | @@ -278,6 +315,154 @@ void __init boot_cpu_id_too_large(int cpu) |
1195 | } |
1196 | #endif |
1197 | |
1198 | +/* On Ultra, we support all of the v8 capabilities. */ |
1199 | +unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | |
1200 | + HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | |
1201 | + HWCAP_SPARC_V9); |
1202 | +EXPORT_SYMBOL(sparc64_elf_hwcap); |
1203 | + |
1204 | +static const char *hwcaps[] = { |
1205 | + "flush", "stbar", "swap", "muldiv", "v9", |
1206 | + "ultra3", "blkinit", "n2", |
1207 | + |
1208 | + /* These strings are as they appear in the machine description |
1209 | + * 'hwcap-list' property for cpu nodes. |
1210 | + */ |
1211 | + "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", |
1212 | + "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau", |
1213 | + "ima", "cspare", |
1214 | +}; |
1215 | + |
1216 | +void cpucap_info(struct seq_file *m) |
1217 | +{ |
1218 | + unsigned long caps = sparc64_elf_hwcap; |
1219 | + int i, printed = 0; |
1220 | + |
1221 | + seq_puts(m, "cpucaps\t\t: "); |
1222 | + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { |
1223 | + unsigned long bit = 1UL << i; |
1224 | + if (caps & bit) { |
1225 | + seq_printf(m, "%s%s", |
1226 | + printed ? "," : "", hwcaps[i]); |
1227 | + printed++; |
1228 | + } |
1229 | + } |
1230 | + seq_putc(m, '\n'); |
1231 | +} |
1232 | + |
1233 | +static void __init report_hwcaps(unsigned long caps) |
1234 | +{ |
1235 | + int i, printed = 0; |
1236 | + |
1237 | + printk(KERN_INFO "CPU CAPS: ["); |
1238 | + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { |
1239 | + unsigned long bit = 1UL << i; |
1240 | + if (caps & bit) { |
1241 | + printk(KERN_CONT "%s%s", |
1242 | + printed ? "," : "", hwcaps[i]); |
1243 | + if (++printed == 8) { |
1244 | + printk(KERN_CONT "]\n"); |
1245 | + printk(KERN_INFO "CPU CAPS: ["); |
1246 | + printed = 0; |
1247 | + } |
1248 | + } |
1249 | + } |
1250 | + printk(KERN_CONT "]\n"); |
1251 | +} |
1252 | + |
1253 | +static unsigned long __init mdesc_cpu_hwcap_list(void) |
1254 | +{ |
1255 | + struct mdesc_handle *hp; |
1256 | + unsigned long caps = 0; |
1257 | + const char *prop; |
1258 | + int len; |
1259 | + u64 pn; |
1260 | + |
1261 | + hp = mdesc_grab(); |
1262 | + if (!hp) |
1263 | + return 0; |
1264 | + |
1265 | + pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu"); |
1266 | + if (pn == MDESC_NODE_NULL) |
1267 | + goto out; |
1268 | + |
1269 | + prop = mdesc_get_property(hp, pn, "hwcap-list", &len); |
1270 | + if (!prop) |
1271 | + goto out; |
1272 | + |
1273 | + while (len) { |
1274 | + int i, plen; |
1275 | + |
1276 | + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { |
1277 | + unsigned long bit = 1UL << i; |
1278 | + |
1279 | + if (!strcmp(prop, hwcaps[i])) { |
1280 | + caps |= bit; |
1281 | + break; |
1282 | + } |
1283 | + } |
1284 | + |
1285 | + plen = strlen(prop) + 1; |
1286 | + prop += plen; |
1287 | + len -= plen; |
1288 | + } |
1289 | + |
1290 | +out: |
1291 | + mdesc_release(hp); |
1292 | + return caps; |
1293 | +} |
1294 | + |
1295 | +/* This yields a mask that user programs can use to figure out what |
1296 | + * instruction set this cpu supports. |
1297 | + */ |
1298 | +static void __init init_sparc64_elf_hwcap(void) |
1299 | +{ |
1300 | + unsigned long cap = sparc64_elf_hwcap; |
1301 | + unsigned long mdesc_caps; |
1302 | + |
1303 | + if (tlb_type == cheetah || tlb_type == cheetah_plus) |
1304 | + cap |= HWCAP_SPARC_ULTRA3; |
1305 | + else if (tlb_type == hypervisor) { |
1306 | + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || |
1307 | + sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
1308 | + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) |
1309 | + cap |= HWCAP_SPARC_BLKINIT; |
1310 | + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
1311 | + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) |
1312 | + cap |= HWCAP_SPARC_N2; |
1313 | + } |
1314 | + |
1315 | + cap |= (AV_SPARC_MUL32 | AV_SPARC_DIV32 | AV_SPARC_V8PLUS); |
1316 | + |
1317 | + mdesc_caps = mdesc_cpu_hwcap_list(); |
1318 | + if (!mdesc_caps) { |
1319 | + if (tlb_type == spitfire) |
1320 | + cap |= AV_SPARC_VIS; |
1321 | + if (tlb_type == cheetah || tlb_type == cheetah_plus) |
1322 | + cap |= AV_SPARC_VIS | AV_SPARC_VIS2; |
1323 | + if (tlb_type == cheetah_plus) |
1324 | + cap |= AV_SPARC_POPC; |
1325 | + if (tlb_type == hypervisor) { |
1326 | + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1) |
1327 | + cap |= AV_SPARC_ASI_BLK_INIT; |
1328 | + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
1329 | + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) |
1330 | + cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | |
1331 | + AV_SPARC_ASI_BLK_INIT | |
1332 | + AV_SPARC_POPC); |
1333 | + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3) |
1334 | + cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | |
1335 | + AV_SPARC_FMAF); |
1336 | + } |
1337 | + } |
1338 | + sparc64_elf_hwcap = cap | mdesc_caps; |
1339 | + |
1340 | + report_hwcaps(sparc64_elf_hwcap); |
1341 | + |
1342 | + if (sparc64_elf_hwcap & AV_SPARC_POPC) |
1343 | + popc_patch(); |
1344 | +} |
1345 | + |
1346 | void __init setup_arch(char **cmdline_p) |
1347 | { |
1348 | /* Initialize PROM console and command line. */ |
1349 | @@ -337,6 +522,7 @@ void __init setup_arch(char **cmdline_p) |
1350 | init_cur_cpu_trap(current_thread_info()); |
1351 | |
1352 | paging_init(); |
1353 | + init_sparc64_elf_hwcap(); |
1354 | } |
1355 | |
1356 | extern int stop_a_enabled; |
1357 | diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c |
1358 | index 372ad59..83b47ab 100644 |
1359 | --- a/arch/sparc/kernel/sparc_ksyms_64.c |
1360 | +++ b/arch/sparc/kernel/sparc_ksyms_64.c |
1361 | @@ -8,6 +8,7 @@ |
1362 | #include <linux/module.h> |
1363 | #include <linux/pci.h> |
1364 | #include <linux/init.h> |
1365 | +#include <linux/bitops.h> |
1366 | |
1367 | #include <asm/system.h> |
1368 | #include <asm/cpudata.h> |
1369 | @@ -38,5 +39,15 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); |
1370 | EXPORT_SYMBOL(sun4v_niagara2_getperf); |
1371 | EXPORT_SYMBOL(sun4v_niagara2_setperf); |
1372 | |
1373 | +/* from hweight.S */ |
1374 | +EXPORT_SYMBOL(__arch_hweight8); |
1375 | +EXPORT_SYMBOL(__arch_hweight16); |
1376 | +EXPORT_SYMBOL(__arch_hweight32); |
1377 | +EXPORT_SYMBOL(__arch_hweight64); |
1378 | + |
1379 | +/* from ffs_ffz.S */ |
1380 | +EXPORT_SYMBOL(ffs); |
1381 | +EXPORT_SYMBOL(__ffs); |
1382 | + |
1383 | /* Exporting a symbol from /init/main.c */ |
1384 | EXPORT_SYMBOL(saved_command_line); |
1385 | diff --git a/arch/sparc/kernel/sstate.c b/arch/sparc/kernel/sstate.c |
1386 | index 8cdbe59..c59af54 100644 |
1387 | --- a/arch/sparc/kernel/sstate.c |
1388 | +++ b/arch/sparc/kernel/sstate.c |
1389 | @@ -14,14 +14,9 @@ |
1390 | #include <asm/head.h> |
1391 | #include <asm/io.h> |
1392 | |
1393 | -static int hv_supports_soft_state; |
1394 | - |
1395 | -static unsigned long kimage_addr_to_ra(const char *p) |
1396 | -{ |
1397 | - unsigned long val = (unsigned long) p; |
1398 | +#include "kernel.h" |
1399 | |
1400 | - return kern_base + (val - KERNBASE); |
1401 | -} |
1402 | +static int hv_supports_soft_state; |
1403 | |
1404 | static void do_set_sstate(unsigned long state, const char *msg) |
1405 | { |
1406 | diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c |
1407 | index b2b019e..9043106 100644 |
1408 | --- a/arch/sparc/kernel/unaligned_64.c |
1409 | +++ b/arch/sparc/kernel/unaligned_64.c |
1410 | @@ -22,6 +22,7 @@ |
1411 | #include <linux/bitops.h> |
1412 | #include <linux/perf_event.h> |
1413 | #include <linux/ratelimit.h> |
1414 | +#include <linux/bitops.h> |
1415 | #include <asm/fpumacro.h> |
1416 | |
1417 | enum direction { |
1418 | @@ -373,16 +374,11 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) |
1419 | } |
1420 | } |
1421 | |
1422 | -static char popc_helper[] = { |
1423 | -0, 1, 1, 2, 1, 2, 2, 3, |
1424 | -1, 2, 2, 3, 2, 3, 3, 4, |
1425 | -}; |
1426 | - |
1427 | int handle_popc(u32 insn, struct pt_regs *regs) |
1428 | { |
1429 | - u64 value; |
1430 | - int ret, i, rd = ((insn >> 25) & 0x1f); |
1431 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; |
1432 | + int ret, rd = ((insn >> 25) & 0x1f); |
1433 | + u64 value; |
1434 | |
1435 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); |
1436 | if (insn & 0x2000) { |
1437 | @@ -392,10 +388,7 @@ int handle_popc(u32 insn, struct pt_regs *regs) |
1438 | maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); |
1439 | value = fetch_reg(insn & 0x1f, regs); |
1440 | } |
1441 | - for (ret = 0, i = 0; i < 16; i++) { |
1442 | - ret += popc_helper[value & 0xf]; |
1443 | - value >>= 4; |
1444 | - } |
1445 | + ret = hweight64(value); |
1446 | if (rd < 16) { |
1447 | if (rd) |
1448 | regs->u_regs[rd] = ret; |
1449 | diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S |
1450 | index c022075..0e16056 100644 |
1451 | --- a/arch/sparc/kernel/vmlinux.lds.S |
1452 | +++ b/arch/sparc/kernel/vmlinux.lds.S |
1453 | @@ -107,7 +107,26 @@ SECTIONS |
1454 | *(.sun4v_2insn_patch) |
1455 | __sun4v_2insn_patch_end = .; |
1456 | } |
1457 | - |
1458 | + .swapper_tsb_phys_patch : { |
1459 | + __swapper_tsb_phys_patch = .; |
1460 | + *(.swapper_tsb_phys_patch) |
1461 | + __swapper_tsb_phys_patch_end = .; |
1462 | + } |
1463 | + .swapper_4m_tsb_phys_patch : { |
1464 | + __swapper_4m_tsb_phys_patch = .; |
1465 | + *(.swapper_4m_tsb_phys_patch) |
1466 | + __swapper_4m_tsb_phys_patch_end = .; |
1467 | + } |
1468 | + .popc_3insn_patch : { |
1469 | + __popc_3insn_patch = .; |
1470 | + *(.popc_3insn_patch) |
1471 | + __popc_3insn_patch_end = .; |
1472 | + } |
1473 | + .popc_6insn_patch : { |
1474 | + __popc_6insn_patch = .; |
1475 | + *(.popc_6insn_patch) |
1476 | + __popc_6insn_patch_end = .; |
1477 | + } |
1478 | PERCPU_SECTION(SMP_CACHE_BYTES) |
1479 | |
1480 | . = ALIGN(PAGE_SIZE); |
1481 | diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile |
1482 | index 7f01b8f..a3fc437 100644 |
1483 | --- a/arch/sparc/lib/Makefile |
1484 | +++ b/arch/sparc/lib/Makefile |
1485 | @@ -31,13 +31,13 @@ lib-$(CONFIG_SPARC64) += NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o |
1486 | lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o |
1487 | |
1488 | lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o |
1489 | -lib-$(CONFIG_SPARC64) += NG2patch.o NG2page.o |
1490 | +lib-$(CONFIG_SPARC64) += NG2patch.o |
1491 | |
1492 | lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o |
1493 | lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o |
1494 | |
1495 | lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o |
1496 | -lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o |
1497 | +lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o |
1498 | |
1499 | obj-y += iomap.o |
1500 | obj-$(CONFIG_SPARC32) += atomic32.o |
1501 | diff --git a/arch/sparc/lib/NG2page.S b/arch/sparc/lib/NG2page.S |
1502 | deleted file mode 100644 |
1503 | index 73b6b7c..0000000 |
1504 | --- a/arch/sparc/lib/NG2page.S |
1505 | +++ /dev/null |
1506 | @@ -1,61 +0,0 @@ |
1507 | -/* NG2page.S: Niagara-2 optimized clear and copy page. |
1508 | - * |
1509 | - * Copyright (C) 2007 (davem@davemloft.net) |
1510 | - */ |
1511 | - |
1512 | -#include <asm/asi.h> |
1513 | -#include <asm/page.h> |
1514 | -#include <asm/visasm.h> |
1515 | - |
1516 | - .text |
1517 | - .align 32 |
1518 | - |
1519 | - /* This is heavily simplified from the sun4u variants |
1520 | - * because Niagara-2 does not have any D-cache aliasing issues. |
1521 | - */ |
1522 | -NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ |
1523 | - prefetch [%o1 + 0x00], #one_read |
1524 | - prefetch [%o1 + 0x40], #one_read |
1525 | - VISEntryHalf |
1526 | - set PAGE_SIZE, %g7 |
1527 | - sub %o0, %o1, %g3 |
1528 | -1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
1529 | - subcc %g7, 64, %g7 |
1530 | - ldda [%o1] ASI_BLK_P, %f0 |
1531 | - stda %f0, [%o1 + %g3] ASI_BLK_P |
1532 | - add %o1, 64, %o1 |
1533 | - bne,pt %xcc, 1b |
1534 | - prefetch [%o1 + 0x40], #one_read |
1535 | - membar #Sync |
1536 | - VISExitHalf |
1537 | - retl |
1538 | - nop |
1539 | - |
1540 | -#define BRANCH_ALWAYS 0x10680000 |
1541 | -#define NOP 0x01000000 |
1542 | -#define NG_DO_PATCH(OLD, NEW) \ |
1543 | - sethi %hi(NEW), %g1; \ |
1544 | - or %g1, %lo(NEW), %g1; \ |
1545 | - sethi %hi(OLD), %g2; \ |
1546 | - or %g2, %lo(OLD), %g2; \ |
1547 | - sub %g1, %g2, %g1; \ |
1548 | - sethi %hi(BRANCH_ALWAYS), %g3; \ |
1549 | - sll %g1, 11, %g1; \ |
1550 | - srl %g1, 11 + 2, %g1; \ |
1551 | - or %g3, %lo(BRANCH_ALWAYS), %g3; \ |
1552 | - or %g3, %g1, %g3; \ |
1553 | - stw %g3, [%g2]; \ |
1554 | - sethi %hi(NOP), %g3; \ |
1555 | - or %g3, %lo(NOP), %g3; \ |
1556 | - stw %g3, [%g2 + 0x4]; \ |
1557 | - flush %g2; |
1558 | - |
1559 | - .globl niagara2_patch_pageops |
1560 | - .type niagara2_patch_pageops,#function |
1561 | -niagara2_patch_pageops: |
1562 | - NG_DO_PATCH(copy_user_page, NG2copy_user_page) |
1563 | - NG_DO_PATCH(_clear_page, NGclear_page) |
1564 | - NG_DO_PATCH(clear_user_page, NGclear_user_page) |
1565 | - retl |
1566 | - nop |
1567 | - .size niagara2_patch_pageops,.-niagara2_patch_pageops |
1568 | diff --git a/arch/sparc/lib/NGpage.S b/arch/sparc/lib/NGpage.S |
1569 | index 428920d..b9e790b 100644 |
1570 | --- a/arch/sparc/lib/NGpage.S |
1571 | +++ b/arch/sparc/lib/NGpage.S |
1572 | @@ -16,55 +16,91 @@ |
1573 | */ |
1574 | |
1575 | NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ |
1576 | - prefetch [%o1 + 0x00], #one_read |
1577 | - mov 8, %g1 |
1578 | - mov 16, %g2 |
1579 | - mov 24, %g3 |
1580 | + save %sp, -192, %sp |
1581 | + rd %asi, %g3 |
1582 | + wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi |
1583 | set PAGE_SIZE, %g7 |
1584 | + prefetch [%i1 + 0x00], #one_read |
1585 | + prefetch [%i1 + 0x40], #one_read |
1586 | |
1587 | -1: ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 |
1588 | - ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 |
1589 | - prefetch [%o1 + 0x40], #one_read |
1590 | - add %o1, 32, %o1 |
1591 | - stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P |
1592 | - stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P |
1593 | - ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 |
1594 | - stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P |
1595 | - stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
1596 | - ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 |
1597 | - add %o1, 32, %o1 |
1598 | - add %o0, 32, %o0 |
1599 | - stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P |
1600 | - stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P |
1601 | - stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P |
1602 | - stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
1603 | - subcc %g7, 64, %g7 |
1604 | +1: prefetch [%i1 + 0x80], #one_read |
1605 | + prefetch [%i1 + 0xc0], #one_read |
1606 | + ldda [%i1 + 0x00] %asi, %o2 |
1607 | + ldda [%i1 + 0x10] %asi, %o4 |
1608 | + ldda [%i1 + 0x20] %asi, %l2 |
1609 | + ldda [%i1 + 0x30] %asi, %l4 |
1610 | + stxa %o2, [%i0 + 0x00] %asi |
1611 | + stxa %o3, [%i0 + 0x08] %asi |
1612 | + stxa %o4, [%i0 + 0x10] %asi |
1613 | + stxa %o5, [%i0 + 0x18] %asi |
1614 | + stxa %l2, [%i0 + 0x20] %asi |
1615 | + stxa %l3, [%i0 + 0x28] %asi |
1616 | + stxa %l4, [%i0 + 0x30] %asi |
1617 | + stxa %l5, [%i0 + 0x38] %asi |
1618 | + ldda [%i1 + 0x40] %asi, %o2 |
1619 | + ldda [%i1 + 0x50] %asi, %o4 |
1620 | + ldda [%i1 + 0x60] %asi, %l2 |
1621 | + ldda [%i1 + 0x70] %asi, %l4 |
1622 | + stxa %o2, [%i0 + 0x40] %asi |
1623 | + stxa %o3, [%i0 + 0x48] %asi |
1624 | + stxa %o4, [%i0 + 0x50] %asi |
1625 | + stxa %o5, [%i0 + 0x58] %asi |
1626 | + stxa %l2, [%i0 + 0x60] %asi |
1627 | + stxa %l3, [%i0 + 0x68] %asi |
1628 | + stxa %l4, [%i0 + 0x70] %asi |
1629 | + stxa %l5, [%i0 + 0x78] %asi |
1630 | + add %i1, 128, %i1 |
1631 | + subcc %g7, 128, %g7 |
1632 | bne,pt %xcc, 1b |
1633 | - add %o0, 32, %o0 |
1634 | + add %i0, 128, %i0 |
1635 | + wr %g3, 0x0, %asi |
1636 | membar #Sync |
1637 | - retl |
1638 | - nop |
1639 | + ret |
1640 | + restore |
1641 | |
1642 | - .globl NGclear_page, NGclear_user_page |
1643 | + .align 32 |
1644 | NGclear_page: /* %o0=dest */ |
1645 | NGclear_user_page: /* %o0=dest, %o1=vaddr */ |
1646 | - mov 8, %g1 |
1647 | - mov 16, %g2 |
1648 | - mov 24, %g3 |
1649 | + rd %asi, %g3 |
1650 | + wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi |
1651 | set PAGE_SIZE, %g7 |
1652 | |
1653 | -1: stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P |
1654 | - stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P |
1655 | - stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P |
1656 | - stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
1657 | - add %o0, 32, %o0 |
1658 | - stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P |
1659 | - stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P |
1660 | - stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P |
1661 | - stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
1662 | - subcc %g7, 64, %g7 |
1663 | +1: stxa %g0, [%o0 + 0x00] %asi |
1664 | + stxa %g0, [%o0 + 0x08] %asi |
1665 | + stxa %g0, [%o0 + 0x10] %asi |
1666 | + stxa %g0, [%o0 + 0x18] %asi |
1667 | + stxa %g0, [%o0 + 0x20] %asi |
1668 | + stxa %g0, [%o0 + 0x28] %asi |
1669 | + stxa %g0, [%o0 + 0x30] %asi |
1670 | + stxa %g0, [%o0 + 0x38] %asi |
1671 | + stxa %g0, [%o0 + 0x40] %asi |
1672 | + stxa %g0, [%o0 + 0x48] %asi |
1673 | + stxa %g0, [%o0 + 0x50] %asi |
1674 | + stxa %g0, [%o0 + 0x58] %asi |
1675 | + stxa %g0, [%o0 + 0x60] %asi |
1676 | + stxa %g0, [%o0 + 0x68] %asi |
1677 | + stxa %g0, [%o0 + 0x70] %asi |
1678 | + stxa %g0, [%o0 + 0x78] %asi |
1679 | + stxa %g0, [%o0 + 0x80] %asi |
1680 | + stxa %g0, [%o0 + 0x88] %asi |
1681 | + stxa %g0, [%o0 + 0x90] %asi |
1682 | + stxa %g0, [%o0 + 0x98] %asi |
1683 | + stxa %g0, [%o0 + 0xa0] %asi |
1684 | + stxa %g0, [%o0 + 0xa8] %asi |
1685 | + stxa %g0, [%o0 + 0xb0] %asi |
1686 | + stxa %g0, [%o0 + 0xb8] %asi |
1687 | + stxa %g0, [%o0 + 0xc0] %asi |
1688 | + stxa %g0, [%o0 + 0xc8] %asi |
1689 | + stxa %g0, [%o0 + 0xd0] %asi |
1690 | + stxa %g0, [%o0 + 0xd8] %asi |
1691 | + stxa %g0, [%o0 + 0xe0] %asi |
1692 | + stxa %g0, [%o0 + 0xe8] %asi |
1693 | + stxa %g0, [%o0 + 0xf0] %asi |
1694 | + stxa %g0, [%o0 + 0xf8] %asi |
1695 | + subcc %g7, 256, %g7 |
1696 | bne,pt %xcc, 1b |
1697 | - add %o0, 32, %o0 |
1698 | + add %o0, 256, %o0 |
1699 | + wr %g3, 0x0, %asi |
1700 | membar #Sync |
1701 | retl |
1702 | nop |
1703 | diff --git a/arch/sparc/lib/ffs.S b/arch/sparc/lib/ffs.S |
1704 | new file mode 100644 |
1705 | index 0000000..b39389f |
1706 | --- /dev/null |
1707 | +++ b/arch/sparc/lib/ffs.S |
1708 | @@ -0,0 +1,84 @@ |
1709 | +#include <linux/linkage.h> |
1710 | + |
1711 | + .register %g2,#scratch |
1712 | + |
1713 | + .text |
1714 | + .align 32 |
1715 | + |
1716 | +ENTRY(ffs) |
1717 | + brnz,pt %o0, 1f |
1718 | + mov 1, %o1 |
1719 | + retl |
1720 | + clr %o0 |
1721 | + nop |
1722 | + nop |
1723 | +ENTRY(__ffs) |
1724 | + sllx %o0, 32, %g1 /* 1 */ |
1725 | + srlx %o0, 32, %g2 |
1726 | + |
1727 | + clr %o1 /* 2 */ |
1728 | + movrz %g1, %g2, %o0 |
1729 | + |
1730 | + movrz %g1, 32, %o1 /* 3 */ |
1731 | +1: clr %o2 |
1732 | + |
1733 | + sllx %o0, (64 - 16), %g1 /* 4 */ |
1734 | + srlx %o0, 16, %g2 |
1735 | + |
1736 | + movrz %g1, %g2, %o0 /* 5 */ |
1737 | + clr %o3 |
1738 | + |
1739 | + movrz %g1, 16, %o2 /* 6 */ |
1740 | + clr %o4 |
1741 | + |
1742 | + and %o0, 0xff, %g1 /* 7 */ |
1743 | + srlx %o0, 8, %g2 |
1744 | + |
1745 | + movrz %g1, %g2, %o0 /* 8 */ |
1746 | + clr %o5 |
1747 | + |
1748 | + movrz %g1, 8, %o3 /* 9 */ |
1749 | + add %o2, %o1, %o2 |
1750 | + |
1751 | + and %o0, 0xf, %g1 /* 10 */ |
1752 | + srlx %o0, 4, %g2 |
1753 | + |
1754 | + movrz %g1, %g2, %o0 /* 11 */ |
1755 | + add %o2, %o3, %o2 |
1756 | + |
1757 | + movrz %g1, 4, %o4 /* 12 */ |
1758 | + |
1759 | + and %o0, 0x3, %g1 /* 13 */ |
1760 | + srlx %o0, 2, %g2 |
1761 | + |
1762 | + movrz %g1, %g2, %o0 /* 14 */ |
1763 | + add %o2, %o4, %o2 |
1764 | + |
1765 | + movrz %g1, 2, %o5 /* 15 */ |
1766 | + |
1767 | + and %o0, 0x1, %g1 /* 16 */ |
1768 | + |
1769 | + add %o2, %o5, %o2 /* 17 */ |
1770 | + xor %g1, 0x1, %g1 |
1771 | + |
1772 | + retl /* 18 */ |
1773 | + add %o2, %g1, %o0 |
1774 | +ENDPROC(ffs) |
1775 | +ENDPROC(__ffs) |
1776 | + |
1777 | + .section .popc_6insn_patch, "ax" |
1778 | + .word ffs |
1779 | + brz,pn %o0, 98f |
1780 | + neg %o0, %g1 |
1781 | + xnor %o0, %g1, %o1 |
1782 | + popc %o1, %o0 |
1783 | +98: retl |
1784 | + nop |
1785 | + .word __ffs |
1786 | + neg %o0, %g1 |
1787 | + xnor %o0, %g1, %o1 |
1788 | + popc %o1, %o0 |
1789 | + retl |
1790 | + sub %o0, 1, %o0 |
1791 | + nop |
1792 | + .previous |
1793 | diff --git a/arch/sparc/lib/hweight.S b/arch/sparc/lib/hweight.S |
1794 | new file mode 100644 |
1795 | index 0000000..95414e0 |
1796 | --- /dev/null |
1797 | +++ b/arch/sparc/lib/hweight.S |
1798 | @@ -0,0 +1,51 @@ |
1799 | +#include <linux/linkage.h> |
1800 | + |
1801 | + .text |
1802 | + .align 32 |
1803 | +ENTRY(__arch_hweight8) |
1804 | + ba,pt %xcc, __sw_hweight8 |
1805 | + nop |
1806 | + nop |
1807 | +ENDPROC(__arch_hweight8) |
1808 | + .section .popc_3insn_patch, "ax" |
1809 | + .word __arch_hweight8 |
1810 | + sllx %o0, 64-8, %g1 |
1811 | + retl |
1812 | + popc %g1, %o0 |
1813 | + .previous |
1814 | + |
1815 | +ENTRY(__arch_hweight16) |
1816 | + ba,pt %xcc, __sw_hweight16 |
1817 | + nop |
1818 | + nop |
1819 | +ENDPROC(__arch_hweight16) |
1820 | + .section .popc_3insn_patch, "ax" |
1821 | + .word __arch_hweight16 |
1822 | + sllx %o0, 64-16, %g1 |
1823 | + retl |
1824 | + popc %g1, %o0 |
1825 | + .previous |
1826 | + |
1827 | +ENTRY(__arch_hweight32) |
1828 | + ba,pt %xcc, __sw_hweight32 |
1829 | + nop |
1830 | + nop |
1831 | +ENDPROC(__arch_hweight32) |
1832 | + .section .popc_3insn_patch, "ax" |
1833 | + .word __arch_hweight32 |
1834 | + sllx %o0, 64-32, %g1 |
1835 | + retl |
1836 | + popc %g1, %o0 |
1837 | + .previous |
1838 | + |
1839 | +ENTRY(__arch_hweight64) |
1840 | + ba,pt %xcc, __sw_hweight64 |
1841 | + nop |
1842 | + nop |
1843 | +ENDPROC(__arch_hweight64) |
1844 | + .section .popc_3insn_patch, "ax" |
1845 | + .word __arch_hweight64 |
1846 | + retl |
1847 | + popc %o0, %o0 |
1848 | + nop |
1849 | + .previous |
1850 | diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c |
1851 | index 3fd8e18..581531d 100644 |
1852 | --- a/arch/sparc/mm/init_64.c |
1853 | +++ b/arch/sparc/mm/init_64.c |
1854 | @@ -1597,6 +1597,44 @@ static void __init tsb_phys_patch(void) |
1855 | static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; |
1856 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; |
1857 | |
1858 | +static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) |
1859 | +{ |
1860 | + pa >>= KTSB_PHYS_SHIFT; |
1861 | + |
1862 | + while (start < end) { |
1863 | + unsigned int *ia = (unsigned int *)(unsigned long)*start; |
1864 | + |
1865 | + ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); |
1866 | + __asm__ __volatile__("flush %0" : : "r" (ia)); |
1867 | + |
1868 | + ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); |
1869 | + __asm__ __volatile__("flush %0" : : "r" (ia + 1)); |
1870 | + |
1871 | + start++; |
1872 | + } |
1873 | +} |
1874 | + |
1875 | +static void ktsb_phys_patch(void) |
1876 | +{ |
1877 | + extern unsigned int __swapper_tsb_phys_patch; |
1878 | + extern unsigned int __swapper_tsb_phys_patch_end; |
1879 | + unsigned long ktsb_pa; |
1880 | + |
1881 | + ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE); |
1882 | + patch_one_ktsb_phys(&__swapper_tsb_phys_patch, |
1883 | + &__swapper_tsb_phys_patch_end, ktsb_pa); |
1884 | +#ifndef CONFIG_DEBUG_PAGEALLOC |
1885 | + { |
1886 | + extern unsigned int __swapper_4m_tsb_phys_patch; |
1887 | + extern unsigned int __swapper_4m_tsb_phys_patch_end; |
1888 | + ktsb_pa = (kern_base + |
1889 | + ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); |
1890 | + patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch, |
1891 | + &__swapper_4m_tsb_phys_patch_end, ktsb_pa); |
1892 | + } |
1893 | +#endif |
1894 | +} |
1895 | + |
1896 | static void __init sun4v_ktsb_init(void) |
1897 | { |
1898 | unsigned long ktsb_pa; |
1899 | @@ -1716,8 +1754,10 @@ void __init paging_init(void) |
1900 | sun4u_pgprot_init(); |
1901 | |
1902 | if (tlb_type == cheetah_plus || |
1903 | - tlb_type == hypervisor) |
1904 | + tlb_type == hypervisor) { |
1905 | tsb_phys_patch(); |
1906 | + ktsb_phys_patch(); |
1907 | + } |
1908 | |
1909 | if (tlb_type == hypervisor) { |
1910 | sun4v_patch_tlb_handlers(); |
1911 | diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile |
1912 | index 17c565d..a6575b9 100644 |
1913 | --- a/arch/x86/xen/Makefile |
1914 | +++ b/arch/x86/xen/Makefile |
1915 | @@ -18,5 +18,5 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ |
1916 | obj-$(CONFIG_SMP) += smp.o |
1917 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o |
1918 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o |
1919 | - |
1920 | +obj-$(CONFIG_XEN_DOM0) += vga.o |
1921 | obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o |
1922 | diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c |
1923 | index 5525163..5325742 100644 |
1924 | --- a/arch/x86/xen/enlighten.c |
1925 | +++ b/arch/x86/xen/enlighten.c |
1926 | @@ -1248,6 +1248,14 @@ asmlinkage void __init xen_start_kernel(void) |
1927 | if (pci_xen) |
1928 | x86_init.pci.arch_init = pci_xen_init; |
1929 | } else { |
1930 | + const struct dom0_vga_console_info *info = |
1931 | + (void *)((char *)xen_start_info + |
1932 | + xen_start_info->console.dom0.info_off); |
1933 | + |
1934 | + xen_init_vga(info, xen_start_info->console.dom0.info_size); |
1935 | + xen_start_info->console.domU.mfn = 0; |
1936 | + xen_start_info->console.domU.evtchn = 0; |
1937 | + |
1938 | /* Make sure ACS will be enabled */ |
1939 | pci_request_acs(); |
1940 | } |
1941 | diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c |
1942 | new file mode 100644 |
1943 | index 0000000..1cd7f4d |
1944 | --- /dev/null |
1945 | +++ b/arch/x86/xen/vga.c |
1946 | @@ -0,0 +1,67 @@ |
1947 | +#include <linux/screen_info.h> |
1948 | +#include <linux/init.h> |
1949 | + |
1950 | +#include <asm/bootparam.h> |
1951 | +#include <asm/setup.h> |
1952 | + |
1953 | +#include <xen/interface/xen.h> |
1954 | + |
1955 | +#include "xen-ops.h" |
1956 | + |
1957 | +void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size) |
1958 | +{ |
1959 | + struct screen_info *screen_info = &boot_params.screen_info; |
1960 | + |
1961 | + /* This is drawn from a dump from vgacon:startup in |
1962 | + * standard Linux. */ |
1963 | + screen_info->orig_video_mode = 3; |
1964 | + screen_info->orig_video_isVGA = 1; |
1965 | + screen_info->orig_video_lines = 25; |
1966 | + screen_info->orig_video_cols = 80; |
1967 | + screen_info->orig_video_ega_bx = 3; |
1968 | + screen_info->orig_video_points = 16; |
1969 | + screen_info->orig_y = screen_info->orig_video_lines - 1; |
1970 | + |
1971 | + switch (info->video_type) { |
1972 | + case XEN_VGATYPE_TEXT_MODE_3: |
1973 | + if (size < offsetof(struct dom0_vga_console_info, u.text_mode_3) |
1974 | + + sizeof(info->u.text_mode_3)) |
1975 | + break; |
1976 | + screen_info->orig_video_lines = info->u.text_mode_3.rows; |
1977 | + screen_info->orig_video_cols = info->u.text_mode_3.columns; |
1978 | + screen_info->orig_x = info->u.text_mode_3.cursor_x; |
1979 | + screen_info->orig_y = info->u.text_mode_3.cursor_y; |
1980 | + screen_info->orig_video_points = |
1981 | + info->u.text_mode_3.font_height; |
1982 | + break; |
1983 | + |
1984 | + case XEN_VGATYPE_VESA_LFB: |
1985 | + if (size < offsetof(struct dom0_vga_console_info, |
1986 | + u.vesa_lfb.gbl_caps)) |
1987 | + break; |
1988 | + screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB; |
1989 | + screen_info->lfb_width = info->u.vesa_lfb.width; |
1990 | + screen_info->lfb_height = info->u.vesa_lfb.height; |
1991 | + screen_info->lfb_depth = info->u.vesa_lfb.bits_per_pixel; |
1992 | + screen_info->lfb_base = info->u.vesa_lfb.lfb_base; |
1993 | + screen_info->lfb_size = info->u.vesa_lfb.lfb_size; |
1994 | + screen_info->lfb_linelength = info->u.vesa_lfb.bytes_per_line; |
1995 | + screen_info->red_size = info->u.vesa_lfb.red_size; |
1996 | + screen_info->red_pos = info->u.vesa_lfb.red_pos; |
1997 | + screen_info->green_size = info->u.vesa_lfb.green_size; |
1998 | + screen_info->green_pos = info->u.vesa_lfb.green_pos; |
1999 | + screen_info->blue_size = info->u.vesa_lfb.blue_size; |
2000 | + screen_info->blue_pos = info->u.vesa_lfb.blue_pos; |
2001 | + screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size; |
2002 | + screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos; |
2003 | + if (size >= offsetof(struct dom0_vga_console_info, |
2004 | + u.vesa_lfb.gbl_caps) |
2005 | + + sizeof(info->u.vesa_lfb.gbl_caps)) |
2006 | + screen_info->capabilities = info->u.vesa_lfb.gbl_caps; |
2007 | + if (size >= offsetof(struct dom0_vga_console_info, |
2008 | + u.vesa_lfb.mode_attrs) |
2009 | + + sizeof(info->u.vesa_lfb.mode_attrs)) |
2010 | + screen_info->vesa_attributes = info->u.vesa_lfb.mode_attrs; |
2011 | + break; |
2012 | + } |
2013 | +} |
2014 | diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h |
2015 | index 97dfdc8..b095739 100644 |
2016 | --- a/arch/x86/xen/xen-ops.h |
2017 | +++ b/arch/x86/xen/xen-ops.h |
2018 | @@ -88,6 +88,17 @@ static inline void xen_uninit_lock_cpu(int cpu) |
2019 | } |
2020 | #endif |
2021 | |
2022 | +struct dom0_vga_console_info; |
2023 | + |
2024 | +#ifdef CONFIG_XEN_DOM0 |
2025 | +void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size); |
2026 | +#else |
2027 | +static inline void __init xen_init_vga(const struct dom0_vga_console_info *info, |
2028 | + size_t size) |
2029 | +{ |
2030 | +} |
2031 | +#endif |
2032 | + |
2033 | /* Declare an asm function, along with symbols needed to make it |
2034 | inlineable */ |
2035 | #define DECL_ASM(ret, name, ...) \ |
2036 | diff --git a/crypto/md5.c b/crypto/md5.c |
2037 | index 30efc7d..7febeaa 100644 |
2038 | --- a/crypto/md5.c |
2039 | +++ b/crypto/md5.c |
2040 | @@ -21,99 +21,9 @@ |
2041 | #include <linux/module.h> |
2042 | #include <linux/string.h> |
2043 | #include <linux/types.h> |
2044 | +#include <linux/cryptohash.h> |
2045 | #include <asm/byteorder.h> |
2046 | |
2047 | -#define F1(x, y, z) (z ^ (x & (y ^ z))) |
2048 | -#define F2(x, y, z) F1(z, x, y) |
2049 | -#define F3(x, y, z) (x ^ y ^ z) |
2050 | -#define F4(x, y, z) (y ^ (x | ~z)) |
2051 | - |
2052 | -#define MD5STEP(f, w, x, y, z, in, s) \ |
2053 | - (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) |
2054 | - |
2055 | -static void md5_transform(u32 *hash, u32 const *in) |
2056 | -{ |
2057 | - u32 a, b, c, d; |
2058 | - |
2059 | - a = hash[0]; |
2060 | - b = hash[1]; |
2061 | - c = hash[2]; |
2062 | - d = hash[3]; |
2063 | - |
2064 | - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); |
2065 | - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); |
2066 | - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); |
2067 | - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); |
2068 | - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); |
2069 | - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); |
2070 | - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); |
2071 | - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); |
2072 | - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); |
2073 | - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); |
2074 | - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); |
2075 | - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); |
2076 | - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); |
2077 | - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); |
2078 | - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); |
2079 | - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); |
2080 | - |
2081 | - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); |
2082 | - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); |
2083 | - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); |
2084 | - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); |
2085 | - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); |
2086 | - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); |
2087 | - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); |
2088 | - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); |
2089 | - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); |
2090 | - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); |
2091 | - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); |
2092 | - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); |
2093 | - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); |
2094 | - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); |
2095 | - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); |
2096 | - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); |
2097 | - |
2098 | - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); |
2099 | - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); |
2100 | - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); |
2101 | - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); |
2102 | - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); |
2103 | - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); |
2104 | - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); |
2105 | - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); |
2106 | - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); |
2107 | - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); |
2108 | - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); |
2109 | - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); |
2110 | - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); |
2111 | - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); |
2112 | - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); |
2113 | - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); |
2114 | - |
2115 | - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); |
2116 | - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); |
2117 | - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); |
2118 | - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); |
2119 | - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); |
2120 | - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); |
2121 | - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); |
2122 | - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); |
2123 | - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); |
2124 | - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); |
2125 | - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); |
2126 | - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); |
2127 | - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); |
2128 | - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); |
2129 | - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); |
2130 | - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); |
2131 | - |
2132 | - hash[0] += a; |
2133 | - hash[1] += b; |
2134 | - hash[2] += c; |
2135 | - hash[3] += d; |
2136 | -} |
2137 | - |
2138 | /* XXX: this stuff can be optimized */ |
2139 | static inline void le32_to_cpu_array(u32 *buf, unsigned int words) |
2140 | { |
2141 | diff --git a/drivers/char/random.c b/drivers/char/random.c |
2142 | index d4ddeba..c35a785 100644 |
2143 | --- a/drivers/char/random.c |
2144 | +++ b/drivers/char/random.c |
2145 | @@ -1300,330 +1300,14 @@ ctl_table random_table[] = { |
2146 | }; |
2147 | #endif /* CONFIG_SYSCTL */ |
2148 | |
2149 | -/******************************************************************** |
2150 | - * |
2151 | - * Random functions for networking |
2152 | - * |
2153 | - ********************************************************************/ |
2154 | - |
2155 | -/* |
2156 | - * TCP initial sequence number picking. This uses the random number |
2157 | - * generator to pick an initial secret value. This value is hashed |
2158 | - * along with the TCP endpoint information to provide a unique |
2159 | - * starting point for each pair of TCP endpoints. This defeats |
2160 | - * attacks which rely on guessing the initial TCP sequence number. |
2161 | - * This algorithm was suggested by Steve Bellovin. |
2162 | - * |
2163 | - * Using a very strong hash was taking an appreciable amount of the total |
2164 | - * TCP connection establishment time, so this is a weaker hash, |
2165 | - * compensated for by changing the secret periodically. |
2166 | - */ |
2167 | - |
2168 | -/* F, G and H are basic MD4 functions: selection, majority, parity */ |
2169 | -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) |
2170 | -#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z))) |
2171 | -#define H(x, y, z) ((x) ^ (y) ^ (z)) |
2172 | - |
2173 | -/* |
2174 | - * The generic round function. The application is so specific that |
2175 | - * we don't bother protecting all the arguments with parens, as is generally |
2176 | - * good macro practice, in favor of extra legibility. |
2177 | - * Rotation is separate from addition to prevent recomputation |
2178 | - */ |
2179 | -#define ROUND(f, a, b, c, d, x, s) \ |
2180 | - (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s))) |
2181 | -#define K1 0 |
2182 | -#define K2 013240474631UL |
2183 | -#define K3 015666365641UL |
2184 | +static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; |
2185 | |
2186 | -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
2187 | - |
2188 | -static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12]) |
2189 | +static int __init random_int_secret_init(void) |
2190 | { |
2191 | - __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; |
2192 | - |
2193 | - /* Round 1 */ |
2194 | - ROUND(F, a, b, c, d, in[ 0] + K1, 3); |
2195 | - ROUND(F, d, a, b, c, in[ 1] + K1, 7); |
2196 | - ROUND(F, c, d, a, b, in[ 2] + K1, 11); |
2197 | - ROUND(F, b, c, d, a, in[ 3] + K1, 19); |
2198 | - ROUND(F, a, b, c, d, in[ 4] + K1, 3); |
2199 | - ROUND(F, d, a, b, c, in[ 5] + K1, 7); |
2200 | - ROUND(F, c, d, a, b, in[ 6] + K1, 11); |
2201 | - ROUND(F, b, c, d, a, in[ 7] + K1, 19); |
2202 | - ROUND(F, a, b, c, d, in[ 8] + K1, 3); |
2203 | - ROUND(F, d, a, b, c, in[ 9] + K1, 7); |
2204 | - ROUND(F, c, d, a, b, in[10] + K1, 11); |
2205 | - ROUND(F, b, c, d, a, in[11] + K1, 19); |
2206 | - |
2207 | - /* Round 2 */ |
2208 | - ROUND(G, a, b, c, d, in[ 1] + K2, 3); |
2209 | - ROUND(G, d, a, b, c, in[ 3] + K2, 5); |
2210 | - ROUND(G, c, d, a, b, in[ 5] + K2, 9); |
2211 | - ROUND(G, b, c, d, a, in[ 7] + K2, 13); |
2212 | - ROUND(G, a, b, c, d, in[ 9] + K2, 3); |
2213 | - ROUND(G, d, a, b, c, in[11] + K2, 5); |
2214 | - ROUND(G, c, d, a, b, in[ 0] + K2, 9); |
2215 | - ROUND(G, b, c, d, a, in[ 2] + K2, 13); |
2216 | - ROUND(G, a, b, c, d, in[ 4] + K2, 3); |
2217 | - ROUND(G, d, a, b, c, in[ 6] + K2, 5); |
2218 | - ROUND(G, c, d, a, b, in[ 8] + K2, 9); |
2219 | - ROUND(G, b, c, d, a, in[10] + K2, 13); |
2220 | - |
2221 | - /* Round 3 */ |
2222 | - ROUND(H, a, b, c, d, in[ 3] + K3, 3); |
2223 | - ROUND(H, d, a, b, c, in[ 7] + K3, 9); |
2224 | - ROUND(H, c, d, a, b, in[11] + K3, 11); |
2225 | - ROUND(H, b, c, d, a, in[ 2] + K3, 15); |
2226 | - ROUND(H, a, b, c, d, in[ 6] + K3, 3); |
2227 | - ROUND(H, d, a, b, c, in[10] + K3, 9); |
2228 | - ROUND(H, c, d, a, b, in[ 1] + K3, 11); |
2229 | - ROUND(H, b, c, d, a, in[ 5] + K3, 15); |
2230 | - ROUND(H, a, b, c, d, in[ 9] + K3, 3); |
2231 | - ROUND(H, d, a, b, c, in[ 0] + K3, 9); |
2232 | - ROUND(H, c, d, a, b, in[ 4] + K3, 11); |
2233 | - ROUND(H, b, c, d, a, in[ 8] + K3, 15); |
2234 | - |
2235 | - return buf[1] + b; /* "most hashed" word */ |
2236 | - /* Alternative: return sum of all words? */ |
2237 | -} |
2238 | -#endif |
2239 | - |
2240 | -#undef ROUND |
2241 | -#undef F |
2242 | -#undef G |
2243 | -#undef H |
2244 | -#undef K1 |
2245 | -#undef K2 |
2246 | -#undef K3 |
2247 | - |
2248 | -/* This should not be decreased so low that ISNs wrap too fast. */ |
2249 | -#define REKEY_INTERVAL (300 * HZ) |
2250 | -/* |
2251 | - * Bit layout of the tcp sequence numbers (before adding current time): |
2252 | - * bit 24-31: increased after every key exchange |
2253 | - * bit 0-23: hash(source,dest) |
2254 | - * |
2255 | - * The implementation is similar to the algorithm described |
2256 | - * in the Appendix of RFC 1185, except that |
2257 | - * - it uses a 1 MHz clock instead of a 250 kHz clock |
2258 | - * - it performs a rekey every 5 minutes, which is equivalent |
2259 | - * to a (source,dest) tulple dependent forward jump of the |
2260 | - * clock by 0..2^(HASH_BITS+1) |
2261 | - * |
2262 | - * Thus the average ISN wraparound time is 68 minutes instead of |
2263 | - * 4.55 hours. |
2264 | - * |
2265 | - * SMP cleanup and lock avoidance with poor man's RCU. |
2266 | - * Manfred Spraul <manfred@colorfullife.com> |
2267 | - * |
2268 | - */ |
2269 | -#define COUNT_BITS 8 |
2270 | -#define COUNT_MASK ((1 << COUNT_BITS) - 1) |
2271 | -#define HASH_BITS 24 |
2272 | -#define HASH_MASK ((1 << HASH_BITS) - 1) |
2273 | - |
2274 | -static struct keydata { |
2275 | - __u32 count; /* already shifted to the final position */ |
2276 | - __u32 secret[12]; |
2277 | -} ____cacheline_aligned ip_keydata[2]; |
2278 | - |
2279 | -static unsigned int ip_cnt; |
2280 | - |
2281 | -static void rekey_seq_generator(struct work_struct *work); |
2282 | - |
2283 | -static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator); |
2284 | - |
2285 | -/* |
2286 | - * Lock avoidance: |
2287 | - * The ISN generation runs lockless - it's just a hash over random data. |
2288 | - * State changes happen every 5 minutes when the random key is replaced. |
2289 | - * Synchronization is performed by having two copies of the hash function |
2290 | - * state and rekey_seq_generator always updates the inactive copy. |
2291 | - * The copy is then activated by updating ip_cnt. |
2292 | - * The implementation breaks down if someone blocks the thread |
2293 | - * that processes SYN requests for more than 5 minutes. Should never |
2294 | - * happen, and even if that happens only a not perfectly compliant |
2295 | - * ISN is generated, nothing fatal. |
2296 | - */ |
2297 | -static void rekey_seq_generator(struct work_struct *work) |
2298 | -{ |
2299 | - struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)]; |
2300 | - |
2301 | - get_random_bytes(keyptr->secret, sizeof(keyptr->secret)); |
2302 | - keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS; |
2303 | - smp_wmb(); |
2304 | - ip_cnt++; |
2305 | - schedule_delayed_work(&rekey_work, |
2306 | - round_jiffies_relative(REKEY_INTERVAL)); |
2307 | -} |
2308 | - |
2309 | -static inline struct keydata *get_keyptr(void) |
2310 | -{ |
2311 | - struct keydata *keyptr = &ip_keydata[ip_cnt & 1]; |
2312 | - |
2313 | - smp_rmb(); |
2314 | - |
2315 | - return keyptr; |
2316 | -} |
2317 | - |
2318 | -static __init int seqgen_init(void) |
2319 | -{ |
2320 | - rekey_seq_generator(NULL); |
2321 | + get_random_bytes(random_int_secret, sizeof(random_int_secret)); |
2322 | return 0; |
2323 | } |
2324 | -late_initcall(seqgen_init); |
2325 | - |
2326 | -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
2327 | -__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
2328 | - __be16 sport, __be16 dport) |
2329 | -{ |
2330 | - __u32 seq; |
2331 | - __u32 hash[12]; |
2332 | - struct keydata *keyptr = get_keyptr(); |
2333 | - |
2334 | - /* The procedure is the same as for IPv4, but addresses are longer. |
2335 | - * Thus we must use twothirdsMD4Transform. |
2336 | - */ |
2337 | - |
2338 | - memcpy(hash, saddr, 16); |
2339 | - hash[4] = ((__force u16)sport << 16) + (__force u16)dport; |
2340 | - memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); |
2341 | - |
2342 | - seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK; |
2343 | - seq += keyptr->count; |
2344 | - |
2345 | - seq += ktime_to_ns(ktime_get_real()); |
2346 | - |
2347 | - return seq; |
2348 | -} |
2349 | -EXPORT_SYMBOL(secure_tcpv6_sequence_number); |
2350 | -#endif |
2351 | - |
2352 | -/* The code below is shamelessly stolen from secure_tcp_sequence_number(). |
2353 | - * All blames to Andrey V. Savochkin <saw@msu.ru>. |
2354 | - */ |
2355 | -__u32 secure_ip_id(__be32 daddr) |
2356 | -{ |
2357 | - struct keydata *keyptr; |
2358 | - __u32 hash[4]; |
2359 | - |
2360 | - keyptr = get_keyptr(); |
2361 | - |
2362 | - /* |
2363 | - * Pick a unique starting offset for each IP destination. |
2364 | - * The dest ip address is placed in the starting vector, |
2365 | - * which is then hashed with random data. |
2366 | - */ |
2367 | - hash[0] = (__force __u32)daddr; |
2368 | - hash[1] = keyptr->secret[9]; |
2369 | - hash[2] = keyptr->secret[10]; |
2370 | - hash[3] = keyptr->secret[11]; |
2371 | - |
2372 | - return half_md4_transform(hash, keyptr->secret); |
2373 | -} |
2374 | - |
2375 | -#ifdef CONFIG_INET |
2376 | - |
2377 | -__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, |
2378 | - __be16 sport, __be16 dport) |
2379 | -{ |
2380 | - __u32 seq; |
2381 | - __u32 hash[4]; |
2382 | - struct keydata *keyptr = get_keyptr(); |
2383 | - |
2384 | - /* |
2385 | - * Pick a unique starting offset for each TCP connection endpoints |
2386 | - * (saddr, daddr, sport, dport). |
2387 | - * Note that the words are placed into the starting vector, which is |
2388 | - * then mixed with a partial MD4 over random data. |
2389 | - */ |
2390 | - hash[0] = (__force u32)saddr; |
2391 | - hash[1] = (__force u32)daddr; |
2392 | - hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
2393 | - hash[3] = keyptr->secret[11]; |
2394 | - |
2395 | - seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK; |
2396 | - seq += keyptr->count; |
2397 | - /* |
2398 | - * As close as possible to RFC 793, which |
2399 | - * suggests using a 250 kHz clock. |
2400 | - * Further reading shows this assumes 2 Mb/s networks. |
2401 | - * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. |
2402 | - * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but |
2403 | - * we also need to limit the resolution so that the u32 seq |
2404 | - * overlaps less than one time per MSL (2 minutes). |
2405 | - * Choosing a clock of 64 ns period is OK. (period of 274 s) |
2406 | - */ |
2407 | - seq += ktime_to_ns(ktime_get_real()) >> 6; |
2408 | - |
2409 | - return seq; |
2410 | -} |
2411 | - |
2412 | -/* Generate secure starting point for ephemeral IPV4 transport port search */ |
2413 | -u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) |
2414 | -{ |
2415 | - struct keydata *keyptr = get_keyptr(); |
2416 | - u32 hash[4]; |
2417 | - |
2418 | - /* |
2419 | - * Pick a unique starting offset for each ephemeral port search |
2420 | - * (saddr, daddr, dport) and 48bits of random data. |
2421 | - */ |
2422 | - hash[0] = (__force u32)saddr; |
2423 | - hash[1] = (__force u32)daddr; |
2424 | - hash[2] = (__force u32)dport ^ keyptr->secret[10]; |
2425 | - hash[3] = keyptr->secret[11]; |
2426 | - |
2427 | - return half_md4_transform(hash, keyptr->secret); |
2428 | -} |
2429 | -EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); |
2430 | - |
2431 | -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
2432 | -u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
2433 | - __be16 dport) |
2434 | -{ |
2435 | - struct keydata *keyptr = get_keyptr(); |
2436 | - u32 hash[12]; |
2437 | - |
2438 | - memcpy(hash, saddr, 16); |
2439 | - hash[4] = (__force u32)dport; |
2440 | - memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); |
2441 | - |
2442 | - return twothirdsMD4Transform((const __u32 *)daddr, hash); |
2443 | -} |
2444 | -#endif |
2445 | - |
2446 | -#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) |
2447 | -/* Similar to secure_tcp_sequence_number but generate a 48 bit value |
2448 | - * bit's 32-47 increase every key exchange |
2449 | - * 0-31 hash(source, dest) |
2450 | - */ |
2451 | -u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, |
2452 | - __be16 sport, __be16 dport) |
2453 | -{ |
2454 | - u64 seq; |
2455 | - __u32 hash[4]; |
2456 | - struct keydata *keyptr = get_keyptr(); |
2457 | - |
2458 | - hash[0] = (__force u32)saddr; |
2459 | - hash[1] = (__force u32)daddr; |
2460 | - hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
2461 | - hash[3] = keyptr->secret[11]; |
2462 | - |
2463 | - seq = half_md4_transform(hash, keyptr->secret); |
2464 | - seq |= ((u64)keyptr->count) << (32 - HASH_BITS); |
2465 | - |
2466 | - seq += ktime_to_ns(ktime_get_real()); |
2467 | - seq &= (1ull << 48) - 1; |
2468 | - |
2469 | - return seq; |
2470 | -} |
2471 | -EXPORT_SYMBOL(secure_dccp_sequence_number); |
2472 | -#endif |
2473 | - |
2474 | -#endif /* CONFIG_INET */ |
2475 | - |
2476 | +late_initcall(random_int_secret_init); |
2477 | |
2478 | /* |
2479 | * Get a random word for internal kernel use only. Similar to urandom but |
2480 | @@ -1631,17 +1315,15 @@ EXPORT_SYMBOL(secure_dccp_sequence_number); |
2481 | * value is not cryptographically secure but for several uses the cost of |
2482 | * depleting entropy is too high |
2483 | */ |
2484 | -DEFINE_PER_CPU(__u32 [4], get_random_int_hash); |
2485 | +DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); |
2486 | unsigned int get_random_int(void) |
2487 | { |
2488 | - struct keydata *keyptr; |
2489 | __u32 *hash = get_cpu_var(get_random_int_hash); |
2490 | - int ret; |
2491 | + unsigned int ret; |
2492 | |
2493 | - keyptr = get_keyptr(); |
2494 | hash[0] += current->pid + jiffies + get_cycles(); |
2495 | - |
2496 | - ret = half_md4_transform(hash, keyptr->secret); |
2497 | + md5_transform(hash, random_int_secret); |
2498 | + ret = hash[0]; |
2499 | put_cpu_var(get_random_int_hash); |
2500 | |
2501 | return ret; |
2502 | diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c |
2503 | index 0929219..1bbb85b 100644 |
2504 | --- a/drivers/gpu/drm/drm_edid.c |
2505 | +++ b/drivers/gpu/drm/drm_edid.c |
2506 | @@ -127,6 +127,23 @@ static const u8 edid_header[] = { |
2507 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 |
2508 | }; |
2509 | |
2510 | + /* |
2511 | + * Sanity check the header of the base EDID block. Return 8 if the header |
2512 | + * is perfect, down to 0 if it's totally wrong. |
2513 | + */ |
2514 | +int drm_edid_header_is_valid(const u8 *raw_edid) |
2515 | +{ |
2516 | + int i, score = 0; |
2517 | + |
2518 | + for (i = 0; i < sizeof(edid_header); i++) |
2519 | + if (raw_edid[i] == edid_header[i]) |
2520 | + score++; |
2521 | + |
2522 | + return score; |
2523 | +} |
2524 | +EXPORT_SYMBOL(drm_edid_header_is_valid); |
2525 | + |
2526 | + |
2527 | /* |
2528 | * Sanity check the EDID block (base or extension). Return 0 if the block |
2529 | * doesn't check out, or 1 if it's valid. |
2530 | @@ -139,12 +156,7 @@ drm_edid_block_valid(u8 *raw_edid) |
2531 | struct edid *edid = (struct edid *)raw_edid; |
2532 | |
2533 | if (raw_edid[0] == 0x00) { |
2534 | - int score = 0; |
2535 | - |
2536 | - for (i = 0; i < sizeof(edid_header); i++) |
2537 | - if (raw_edid[i] == edid_header[i]) |
2538 | - score++; |
2539 | - |
2540 | + int score = drm_edid_header_is_valid(raw_edid); |
2541 | if (score == 8) ; |
2542 | else if (score >= 6) { |
2543 | DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); |
2544 | diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c |
2545 | index 296fbd6..7eef6e1 100644 |
2546 | --- a/drivers/gpu/drm/i915/i915_dma.c |
2547 | +++ b/drivers/gpu/drm/i915/i915_dma.c |
2548 | @@ -61,7 +61,6 @@ static void i915_write_hws_pga(struct drm_device *dev) |
2549 | static int i915_init_phys_hws(struct drm_device *dev) |
2550 | { |
2551 | drm_i915_private_t *dev_priv = dev->dev_private; |
2552 | - struct intel_ring_buffer *ring = LP_RING(dev_priv); |
2553 | |
2554 | /* Program Hardware Status Page */ |
2555 | dev_priv->status_page_dmah = |
2556 | @@ -71,10 +70,9 @@ static int i915_init_phys_hws(struct drm_device *dev) |
2557 | DRM_ERROR("Can not allocate hardware status page\n"); |
2558 | return -ENOMEM; |
2559 | } |
2560 | - ring->status_page.page_addr = |
2561 | - (void __force __iomem *)dev_priv->status_page_dmah->vaddr; |
2562 | |
2563 | - memset_io(ring->status_page.page_addr, 0, PAGE_SIZE); |
2564 | + memset_io((void __force __iomem *)dev_priv->status_page_dmah->vaddr, |
2565 | + 0, PAGE_SIZE); |
2566 | |
2567 | i915_write_hws_pga(dev); |
2568 | |
2569 | diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c |
2570 | index 3b03f85..9b1d669 100644 |
2571 | --- a/drivers/gpu/drm/i915/i915_irq.c |
2572 | +++ b/drivers/gpu/drm/i915/i915_irq.c |
2573 | @@ -306,12 +306,15 @@ static void i915_hotplug_work_func(struct work_struct *work) |
2574 | struct drm_mode_config *mode_config = &dev->mode_config; |
2575 | struct intel_encoder *encoder; |
2576 | |
2577 | + mutex_lock(&mode_config->mutex); |
2578 | DRM_DEBUG_KMS("running encoder hotplug functions\n"); |
2579 | |
2580 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) |
2581 | if (encoder->hot_plug) |
2582 | encoder->hot_plug(encoder); |
2583 | |
2584 | + mutex_unlock(&mode_config->mutex); |
2585 | + |
2586 | /* Just fire off a uevent and let userspace tell us what to do */ |
2587 | drm_helper_hpd_irq_event(dev); |
2588 | } |
2589 | diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c |
2590 | index 0f1c799..5609c06 100644 |
2591 | --- a/drivers/gpu/drm/i915/intel_display.c |
2592 | +++ b/drivers/gpu/drm/i915/intel_display.c |
2593 | @@ -2699,14 +2699,18 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) |
2594 | I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size); |
2595 | } |
2596 | |
2597 | + /* |
2598 | + * On ILK+ LUT must be loaded before the pipe is running but with |
2599 | + * clocks enabled |
2600 | + */ |
2601 | + intel_crtc_load_lut(crtc); |
2602 | + |
2603 | intel_enable_pipe(dev_priv, pipe, is_pch_port); |
2604 | intel_enable_plane(dev_priv, plane, pipe); |
2605 | |
2606 | if (is_pch_port) |
2607 | ironlake_pch_enable(crtc); |
2608 | |
2609 | - intel_crtc_load_lut(crtc); |
2610 | - |
2611 | mutex_lock(&dev->struct_mutex); |
2612 | intel_update_fbc(dev); |
2613 | mutex_unlock(&dev->struct_mutex); |
2614 | diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c |
2615 | index a06ff07..05f500c 100644 |
2616 | --- a/drivers/gpu/drm/i915/intel_panel.c |
2617 | +++ b/drivers/gpu/drm/i915/intel_panel.c |
2618 | @@ -83,11 +83,15 @@ intel_pch_panel_fitting(struct drm_device *dev, |
2619 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; |
2620 | if (scaled_width > scaled_height) { /* pillar */ |
2621 | width = scaled_height / mode->vdisplay; |
2622 | + if (width & 1) |
2623 | + width++; |
2624 | x = (adjusted_mode->hdisplay - width + 1) / 2; |
2625 | y = 0; |
2626 | height = adjusted_mode->vdisplay; |
2627 | } else if (scaled_width < scaled_height) { /* letter */ |
2628 | height = scaled_width / mode->hdisplay; |
2629 | + if (height & 1) |
2630 | + height++; |
2631 | y = (adjusted_mode->vdisplay - height + 1) / 2; |
2632 | x = 0; |
2633 | width = adjusted_mode->hdisplay; |
2634 | diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c |
2635 | index 95c4b14..1f61fc7 100644 |
2636 | --- a/drivers/gpu/drm/i915/intel_ringbuffer.c |
2637 | +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c |
2638 | @@ -1319,6 +1319,9 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) |
2639 | ring->get_seqno = pc_render_get_seqno; |
2640 | } |
2641 | |
2642 | + if (!I915_NEED_GFX_HWS(dev)) |
2643 | + ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; |
2644 | + |
2645 | ring->dev = dev; |
2646 | INIT_LIST_HEAD(&ring->active_list); |
2647 | INIT_LIST_HEAD(&ring->request_list); |
2648 | diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c |
2649 | index 9792d4f..6d6b5f1 100644 |
2650 | --- a/drivers/gpu/drm/radeon/radeon_connectors.c |
2651 | +++ b/drivers/gpu/drm/radeon/radeon_connectors.c |
2652 | @@ -430,6 +430,45 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr |
2653 | return 0; |
2654 | } |
2655 | |
2656 | +/* |
2657 | + * Some integrated ATI Radeon chipset implementations (e. g. |
2658 | + * Asus M2A-VM HDMI) may indicate the availability of a DDC, |
2659 | + * even when there's no monitor connected. For these connectors |
2660 | + * following DDC probe extension will be applied: check also for the |
2661 | + * availability of EDID with at least a correct EDID header. Only then, |
2662 | + * DDC is assumed to be available. This prevents drm_get_edid() and |
2663 | + * drm_edid_block_valid() from periodically dumping data and kernel |
2664 | + * errors into the logs and onto the terminal. |
2665 | + */ |
2666 | +static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, |
2667 | + uint32_t supported_device, |
2668 | + int connector_type) |
2669 | +{ |
2670 | + /* Asus M2A-VM HDMI board sends data to i2c bus even, |
2671 | + * if HDMI add-on card is not plugged in or HDMI is disabled in |
2672 | + * BIOS. Valid DDC can only be assumed, if also a valid EDID header |
2673 | + * can be retrieved via i2c bus during DDC probe */ |
2674 | + if ((dev->pdev->device == 0x791e) && |
2675 | + (dev->pdev->subsystem_vendor == 0x1043) && |
2676 | + (dev->pdev->subsystem_device == 0x826d)) { |
2677 | + if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && |
2678 | + (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
2679 | + return true; |
2680 | + } |
2681 | + /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus |
2682 | + * for a DVI connector that is not implemented */ |
2683 | + if ((dev->pdev->device == 0x796e) && |
2684 | + (dev->pdev->subsystem_vendor == 0x1019) && |
2685 | + (dev->pdev->subsystem_device == 0x2615)) { |
2686 | + if ((connector_type == DRM_MODE_CONNECTOR_DVID) && |
2687 | + (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
2688 | + return true; |
2689 | + } |
2690 | + |
2691 | + /* Default: no EDID header probe required for DDC probing */ |
2692 | + return false; |
2693 | +} |
2694 | + |
2695 | static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, |
2696 | struct drm_connector *connector) |
2697 | { |
2698 | @@ -661,7 +700,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) |
2699 | ret = connector_status_disconnected; |
2700 | |
2701 | if (radeon_connector->ddc_bus) |
2702 | - dret = radeon_ddc_probe(radeon_connector); |
2703 | + dret = radeon_ddc_probe(radeon_connector, |
2704 | + radeon_connector->requires_extended_probe); |
2705 | if (dret) { |
2706 | if (radeon_connector->edid) { |
2707 | kfree(radeon_connector->edid); |
2708 | @@ -833,7 +873,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) |
2709 | bool dret = false; |
2710 | |
2711 | if (radeon_connector->ddc_bus) |
2712 | - dret = radeon_ddc_probe(radeon_connector); |
2713 | + dret = radeon_ddc_probe(radeon_connector, |
2714 | + radeon_connector->requires_extended_probe); |
2715 | if (dret) { |
2716 | if (radeon_connector->edid) { |
2717 | kfree(radeon_connector->edid); |
2718 | @@ -1251,7 +1292,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) |
2719 | if (radeon_dp_getdpcd(radeon_connector)) |
2720 | ret = connector_status_connected; |
2721 | } else { |
2722 | - if (radeon_ddc_probe(radeon_connector)) |
2723 | + if (radeon_ddc_probe(radeon_connector, |
2724 | + radeon_connector->requires_extended_probe)) |
2725 | ret = connector_status_connected; |
2726 | } |
2727 | } |
2728 | @@ -1406,6 +1448,9 @@ radeon_add_atom_connector(struct drm_device *dev, |
2729 | radeon_connector->shared_ddc = shared_ddc; |
2730 | radeon_connector->connector_object_id = connector_object_id; |
2731 | radeon_connector->hpd = *hpd; |
2732 | + radeon_connector->requires_extended_probe = |
2733 | + radeon_connector_needs_extended_probe(rdev, supported_device, |
2734 | + connector_type); |
2735 | radeon_connector->router = *router; |
2736 | if (router->ddc_valid || router->cd_valid) { |
2737 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); |
2738 | @@ -1752,6 +1797,9 @@ radeon_add_legacy_connector(struct drm_device *dev, |
2739 | radeon_connector->devices = supported_device; |
2740 | radeon_connector->connector_object_id = connector_object_id; |
2741 | radeon_connector->hpd = *hpd; |
2742 | + radeon_connector->requires_extended_probe = |
2743 | + radeon_connector_needs_extended_probe(rdev, supported_device, |
2744 | + connector_type); |
2745 | switch (connector_type) { |
2746 | case DRM_MODE_CONNECTOR_VGA: |
2747 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
2748 | diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c |
2749 | index 7cfaa7e..440e6ec 100644 |
2750 | --- a/drivers/gpu/drm/radeon/radeon_device.c |
2751 | +++ b/drivers/gpu/drm/radeon/radeon_device.c |
2752 | @@ -704,8 +704,9 @@ int radeon_device_init(struct radeon_device *rdev, |
2753 | rdev->gpu_lockup = false; |
2754 | rdev->accel_working = false; |
2755 | |
2756 | - DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n", |
2757 | - radeon_family_name[rdev->family], pdev->vendor, pdev->device); |
2758 | + DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", |
2759 | + radeon_family_name[rdev->family], pdev->vendor, pdev->device, |
2760 | + pdev->subsystem_vendor, pdev->subsystem_device); |
2761 | |
2762 | /* mutex initialization are all done here so we |
2763 | * can recall function without having locking issues */ |
2764 | diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c |
2765 | index 292f73f..ed085ce 100644 |
2766 | --- a/drivers/gpu/drm/radeon/radeon_display.c |
2767 | +++ b/drivers/gpu/drm/radeon/radeon_display.c |
2768 | @@ -777,8 +777,17 @@ static int radeon_ddc_dump(struct drm_connector *connector) |
2769 | if (!radeon_connector->ddc_bus) |
2770 | return -1; |
2771 | edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); |
2772 | + /* Log EDID retrieval status here. In particular with regard to |
2773 | + * connectors with requires_extended_probe flag set, that will prevent |
2774 | + * function radeon_dvi_detect() to fetch EDID on this connector, |
2775 | + * as long as there is no valid EDID header found */ |
2776 | if (edid) { |
2777 | + DRM_INFO("Radeon display connector %s: Found valid EDID", |
2778 | + drm_get_connector_name(connector)); |
2779 | kfree(edid); |
2780 | + } else { |
2781 | + DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID", |
2782 | + drm_get_connector_name(connector)); |
2783 | } |
2784 | return ret; |
2785 | } |
2786 | diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c |
2787 | index 781196d..6c111c1 100644 |
2788 | --- a/drivers/gpu/drm/radeon/radeon_i2c.c |
2789 | +++ b/drivers/gpu/drm/radeon/radeon_i2c.c |
2790 | @@ -32,17 +32,17 @@ |
2791 | * radeon_ddc_probe |
2792 | * |
2793 | */ |
2794 | -bool radeon_ddc_probe(struct radeon_connector *radeon_connector) |
2795 | +bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) |
2796 | { |
2797 | - u8 out_buf[] = { 0x0, 0x0}; |
2798 | - u8 buf[2]; |
2799 | + u8 out = 0x0; |
2800 | + u8 buf[8]; |
2801 | int ret; |
2802 | struct i2c_msg msgs[] = { |
2803 | { |
2804 | .addr = 0x50, |
2805 | .flags = 0, |
2806 | .len = 1, |
2807 | - .buf = out_buf, |
2808 | + .buf = &out, |
2809 | }, |
2810 | { |
2811 | .addr = 0x50, |
2812 | @@ -52,15 +52,31 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) |
2813 | } |
2814 | }; |
2815 | |
2816 | + /* Read 8 bytes from i2c for extended probe of EDID header */ |
2817 | + if (requires_extended_probe) |
2818 | + msgs[1].len = 8; |
2819 | + |
2820 | /* on hw with routers, select right port */ |
2821 | if (radeon_connector->router.ddc_valid) |
2822 | radeon_router_select_ddc_port(radeon_connector); |
2823 | |
2824 | ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); |
2825 | - if (ret == 2) |
2826 | - return true; |
2827 | - |
2828 | - return false; |
2829 | + if (ret != 2) |
2830 | + /* Couldn't find an accessible DDC on this connector */ |
2831 | + return false; |
2832 | + if (requires_extended_probe) { |
2833 | + /* Probe also for valid EDID header |
2834 | + * EDID header starts with: |
2835 | + * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. |
2836 | + * Only the first 6 bytes must be valid as |
2837 | + * drm_edid_block_valid() can fix the last 2 bytes */ |
2838 | + if (drm_edid_header_is_valid(buf) < 6) { |
2839 | + /* Couldn't find an accessible EDID on this |
2840 | + * connector */ |
2841 | + return false; |
2842 | + } |
2843 | + } |
2844 | + return true; |
2845 | } |
2846 | |
2847 | /* bit banging i2c */ |
2848 | diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h |
2849 | index 6df4e3c..d09031c 100644 |
2850 | --- a/drivers/gpu/drm/radeon/radeon_mode.h |
2851 | +++ b/drivers/gpu/drm/radeon/radeon_mode.h |
2852 | @@ -438,6 +438,9 @@ struct radeon_connector { |
2853 | struct radeon_i2c_chan *ddc_bus; |
2854 | /* some systems have an hdmi and vga port with a shared ddc line */ |
2855 | bool shared_ddc; |
2856 | + /* for some Radeon chip families we apply an additional EDID header |
2857 | + check as part of the DDC probe */ |
2858 | + bool requires_extended_probe; |
2859 | bool use_digital; |
2860 | /* we need to mind the EDID between detect |
2861 | and get modes due to analog/digital/tvencoder */ |
2862 | @@ -514,7 +517,8 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, |
2863 | u8 val); |
2864 | extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); |
2865 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); |
2866 | -extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); |
2867 | +extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, |
2868 | + bool requires_extended_probe); |
2869 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); |
2870 | |
2871 | extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); |
2872 | diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c |
2873 | index 9798811..b145b5a 100644 |
2874 | --- a/drivers/isdn/i4l/isdn_net.c |
2875 | +++ b/drivers/isdn/i4l/isdn_net.c |
2876 | @@ -2531,6 +2531,9 @@ static void _isdn_setup(struct net_device *dev) |
2877 | |
2878 | /* Setup the generic properties */ |
2879 | dev->flags = IFF_NOARP|IFF_POINTOPOINT; |
2880 | + |
2881 | + /* isdn prepends a header in the tx path, can't share skbs */ |
2882 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
2883 | dev->header_ops = NULL; |
2884 | dev->netdev_ops = &isdn_netdev_ops; |
2885 | |
2886 | diff --git a/drivers/net/Makefile b/drivers/net/Makefile |
2887 | index 776a478..d5ce011 100644 |
2888 | --- a/drivers/net/Makefile |
2889 | +++ b/drivers/net/Makefile |
2890 | @@ -283,6 +283,7 @@ obj-$(CONFIG_USB_HSO) += usb/ |
2891 | obj-$(CONFIG_USB_USBNET) += usb/ |
2892 | obj-$(CONFIG_USB_ZD1201) += usb/ |
2893 | obj-$(CONFIG_USB_IPHETH) += usb/ |
2894 | +obj-$(CONFIG_USB_CDC_PHONET) += usb/ |
2895 | |
2896 | obj-$(CONFIG_WLAN) += wireless/ |
2897 | obj-$(CONFIG_NET_TULIP) += tulip/ |
2898 | diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c |
2899 | index 63c22b0..9ea2f21 100644 |
2900 | --- a/drivers/net/bonding/bond_main.c |
2901 | +++ b/drivers/net/bonding/bond_main.c |
2902 | @@ -1625,8 +1625,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) |
2903 | |
2904 | if (slave_dev->type != ARPHRD_ETHER) |
2905 | bond_setup_by_slave(bond_dev, slave_dev); |
2906 | - else |
2907 | + else { |
2908 | ether_setup(bond_dev); |
2909 | + bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
2910 | + } |
2911 | |
2912 | netdev_bonding_change(bond_dev, |
2913 | NETDEV_POST_TYPE_CHANGE); |
2914 | @@ -4398,7 +4400,7 @@ static void bond_setup(struct net_device *bond_dev) |
2915 | bond_dev->tx_queue_len = 0; |
2916 | bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; |
2917 | bond_dev->priv_flags |= IFF_BONDING; |
2918 | - bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
2919 | + bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
2920 | |
2921 | /* At first, we block adding VLANs. That's the only way to |
2922 | * prevent problems that occur when adding VLANs over an |
2923 | diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c |
2924 | index 88fcb25..0624610 100644 |
2925 | --- a/drivers/net/bonding/bond_sysfs.c |
2926 | +++ b/drivers/net/bonding/bond_sysfs.c |
2927 | @@ -992,6 +992,7 @@ static ssize_t bonding_store_primary(struct device *d, |
2928 | int i; |
2929 | struct slave *slave; |
2930 | struct bonding *bond = to_bond(d); |
2931 | + char ifname[IFNAMSIZ]; |
2932 | |
2933 | if (!rtnl_trylock()) |
2934 | return restart_syscall(); |
2935 | @@ -1002,32 +1003,33 @@ static ssize_t bonding_store_primary(struct device *d, |
2936 | if (!USES_PRIMARY(bond->params.mode)) { |
2937 | pr_info("%s: Unable to set primary slave; %s is in mode %d\n", |
2938 | bond->dev->name, bond->dev->name, bond->params.mode); |
2939 | - } else { |
2940 | - bond_for_each_slave(bond, slave, i) { |
2941 | - if (strnicmp |
2942 | - (slave->dev->name, buf, |
2943 | - strlen(slave->dev->name)) == 0) { |
2944 | - pr_info("%s: Setting %s as primary slave.\n", |
2945 | - bond->dev->name, slave->dev->name); |
2946 | - bond->primary_slave = slave; |
2947 | - strcpy(bond->params.primary, slave->dev->name); |
2948 | - bond_select_active_slave(bond); |
2949 | - goto out; |
2950 | - } |
2951 | - } |
2952 | + goto out; |
2953 | + } |
2954 | |
2955 | - /* if we got here, then we didn't match the name of any slave */ |
2956 | + sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ |
2957 | |
2958 | - if (strlen(buf) == 0 || buf[0] == '\n') { |
2959 | - pr_info("%s: Setting primary slave to None.\n", |
2960 | - bond->dev->name); |
2961 | - bond->primary_slave = NULL; |
2962 | - bond_select_active_slave(bond); |
2963 | - } else { |
2964 | - pr_info("%s: Unable to set %.*s as primary slave as it is not a slave.\n", |
2965 | - bond->dev->name, (int)strlen(buf) - 1, buf); |
2966 | + /* check to see if we are clearing primary */ |
2967 | + if (!strlen(ifname) || buf[0] == '\n') { |
2968 | + pr_info("%s: Setting primary slave to None.\n", |
2969 | + bond->dev->name); |
2970 | + bond->primary_slave = NULL; |
2971 | + bond_select_active_slave(bond); |
2972 | + goto out; |
2973 | + } |
2974 | + |
2975 | + bond_for_each_slave(bond, slave, i) { |
2976 | + if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { |
2977 | + pr_info("%s: Setting %s as primary slave.\n", |
2978 | + bond->dev->name, slave->dev->name); |
2979 | + bond->primary_slave = slave; |
2980 | + strcpy(bond->params.primary, slave->dev->name); |
2981 | + bond_select_active_slave(bond); |
2982 | + goto out; |
2983 | } |
2984 | } |
2985 | + |
2986 | + pr_info("%s: Unable to set %.*s as primary slave.\n", |
2987 | + bond->dev->name, (int)strlen(buf) - 1, buf); |
2988 | out: |
2989 | write_unlock_bh(&bond->curr_slave_lock); |
2990 | read_unlock(&bond->lock); |
2991 | @@ -1162,6 +1164,7 @@ static ssize_t bonding_store_active_slave(struct device *d, |
2992 | struct slave *old_active = NULL; |
2993 | struct slave *new_active = NULL; |
2994 | struct bonding *bond = to_bond(d); |
2995 | + char ifname[IFNAMSIZ]; |
2996 | |
2997 | if (!rtnl_trylock()) |
2998 | return restart_syscall(); |
2999 | @@ -1170,56 +1173,62 @@ static ssize_t bonding_store_active_slave(struct device *d, |
3000 | read_lock(&bond->lock); |
3001 | write_lock_bh(&bond->curr_slave_lock); |
3002 | |
3003 | - if (!USES_PRIMARY(bond->params.mode)) |
3004 | + if (!USES_PRIMARY(bond->params.mode)) { |
3005 | pr_info("%s: Unable to change active slave; %s is in mode %d\n", |
3006 | bond->dev->name, bond->dev->name, bond->params.mode); |
3007 | - else { |
3008 | - bond_for_each_slave(bond, slave, i) { |
3009 | - if (strnicmp |
3010 | - (slave->dev->name, buf, |
3011 | - strlen(slave->dev->name)) == 0) { |
3012 | - old_active = bond->curr_active_slave; |
3013 | - new_active = slave; |
3014 | - if (new_active == old_active) { |
3015 | - /* do nothing */ |
3016 | - pr_info("%s: %s is already the current active slave.\n", |
3017 | + goto out; |
3018 | + } |
3019 | + |
3020 | + sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ |
3021 | + |
3022 | + /* check to see if we are clearing active */ |
3023 | + if (!strlen(ifname) || buf[0] == '\n') { |
3024 | + pr_info("%s: Clearing current active slave.\n", |
3025 | + bond->dev->name); |
3026 | + bond->curr_active_slave = NULL; |
3027 | + bond_select_active_slave(bond); |
3028 | + goto out; |
3029 | + } |
3030 | + |
3031 | + bond_for_each_slave(bond, slave, i) { |
3032 | + if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { |
3033 | + old_active = bond->curr_active_slave; |
3034 | + new_active = slave; |
3035 | + if (new_active == old_active) { |
3036 | + /* do nothing */ |
3037 | + pr_info("%s: %s is already the current" |
3038 | + " active slave.\n", |
3039 | + bond->dev->name, |
3040 | + slave->dev->name); |
3041 | + goto out; |
3042 | + } |
3043 | + else { |
3044 | + if ((new_active) && |
3045 | + (old_active) && |
3046 | + (new_active->link == BOND_LINK_UP) && |
3047 | + IS_UP(new_active->dev)) { |
3048 | + pr_info("%s: Setting %s as active" |
3049 | + " slave.\n", |
3050 | bond->dev->name, |
3051 | slave->dev->name); |
3052 | - goto out; |
3053 | + bond_change_active_slave(bond, |
3054 | + new_active); |
3055 | } |
3056 | else { |
3057 | - if ((new_active) && |
3058 | - (old_active) && |
3059 | - (new_active->link == BOND_LINK_UP) && |
3060 | - IS_UP(new_active->dev)) { |
3061 | - pr_info("%s: Setting %s as active slave.\n", |
3062 | - bond->dev->name, |
3063 | - slave->dev->name); |
3064 | - bond_change_active_slave(bond, new_active); |
3065 | - } |
3066 | - else { |
3067 | - pr_info("%s: Could not set %s as active slave; either %s is down or the link is down.\n", |
3068 | - bond->dev->name, |
3069 | - slave->dev->name, |
3070 | - slave->dev->name); |
3071 | - } |
3072 | - goto out; |
3073 | + pr_info("%s: Could not set %s as" |
3074 | + " active slave; either %s is" |
3075 | + " down or the link is down.\n", |
3076 | + bond->dev->name, |
3077 | + slave->dev->name, |
3078 | + slave->dev->name); |
3079 | } |
3080 | + goto out; |
3081 | } |
3082 | } |
3083 | - |
3084 | - /* if we got here, then we didn't match the name of any slave */ |
3085 | - |
3086 | - if (strlen(buf) == 0 || buf[0] == '\n') { |
3087 | - pr_info("%s: Setting active slave to None.\n", |
3088 | - bond->dev->name); |
3089 | - bond->primary_slave = NULL; |
3090 | - bond_select_active_slave(bond); |
3091 | - } else { |
3092 | - pr_info("%s: Unable to set %.*s as active slave as it is not a slave.\n", |
3093 | - bond->dev->name, (int)strlen(buf) - 1, buf); |
3094 | - } |
3095 | } |
3096 | + |
3097 | + pr_info("%s: Unable to set %.*s as active slave.\n", |
3098 | + bond->dev->name, (int)strlen(buf) - 1, buf); |
3099 | out: |
3100 | write_unlock_bh(&bond->curr_slave_lock); |
3101 | read_unlock(&bond->lock); |
3102 | diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c |
3103 | index dd8ab05..8d28602 100644 |
3104 | --- a/drivers/net/e1000e/lib.c |
3105 | +++ b/drivers/net/e1000e/lib.c |
3106 | @@ -190,7 +190,8 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) |
3107 | /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ |
3108 | if (!((nvm_data & NVM_COMPAT_LOM) || |
3109 | (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || |
3110 | - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD))) |
3111 | + (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) || |
3112 | + (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES))) |
3113 | goto out; |
3114 | |
3115 | ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, |
3116 | diff --git a/drivers/net/gianfar_ptp.c b/drivers/net/gianfar_ptp.c |
3117 | index d8e1753..c413479 100644 |
3118 | --- a/drivers/net/gianfar_ptp.c |
3119 | +++ b/drivers/net/gianfar_ptp.c |
3120 | @@ -193,14 +193,9 @@ static void set_alarm(struct etsects *etsects) |
3121 | /* Caller must hold etsects->lock. */ |
3122 | static void set_fipers(struct etsects *etsects) |
3123 | { |
3124 | - u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl); |
3125 | - |
3126 | - gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl & (~TE)); |
3127 | - gfar_write(&etsects->regs->tmr_prsc, etsects->tmr_prsc); |
3128 | + set_alarm(etsects); |
3129 | gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); |
3130 | gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); |
3131 | - set_alarm(etsects); |
3132 | - gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|TE); |
3133 | } |
3134 | |
3135 | /* |
3136 | @@ -511,7 +506,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) |
3137 | gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); |
3138 | gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); |
3139 | set_alarm(etsects); |
3140 | - gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE); |
3141 | + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE|FRD); |
3142 | |
3143 | spin_unlock_irqrestore(&etsects->lock, flags); |
3144 | |
3145 | diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c |
3146 | index 4fecaed..2b98461 100644 |
3147 | --- a/drivers/net/ifb.c |
3148 | +++ b/drivers/net/ifb.c |
3149 | @@ -145,7 +145,7 @@ static void ifb_setup(struct net_device *dev) |
3150 | |
3151 | dev->flags |= IFF_NOARP; |
3152 | dev->flags &= ~IFF_MULTICAST; |
3153 | - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
3154 | + dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
3155 | random_ether_addr(dev->dev_addr); |
3156 | } |
3157 | |
3158 | diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c |
3159 | index d6aeaa5..2f3c48d 100644 |
3160 | --- a/drivers/net/macvlan.c |
3161 | +++ b/drivers/net/macvlan.c |
3162 | @@ -547,7 +547,7 @@ void macvlan_common_setup(struct net_device *dev) |
3163 | { |
3164 | ether_setup(dev); |
3165 | |
3166 | - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
3167 | + dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
3168 | dev->netdev_ops = &macvlan_netdev_ops; |
3169 | dev->destructor = free_netdev; |
3170 | dev->header_ops = &macvlan_hard_header_ops, |
3171 | diff --git a/drivers/net/niu.c b/drivers/net/niu.c |
3172 | index cc25bff..2f8c351 100644 |
3173 | --- a/drivers/net/niu.c |
3174 | +++ b/drivers/net/niu.c |
3175 | @@ -9196,7 +9196,7 @@ static int __devinit niu_ldg_init(struct niu *np) |
3176 | |
3177 | first_chan = 0; |
3178 | for (i = 0; i < port; i++) |
3179 | - first_chan += parent->rxchan_per_port[port]; |
3180 | + first_chan += parent->rxchan_per_port[i]; |
3181 | num_chan = parent->rxchan_per_port[port]; |
3182 | |
3183 | for (i = first_chan; i < (first_chan + num_chan); i++) { |
3184 | @@ -9212,7 +9212,7 @@ static int __devinit niu_ldg_init(struct niu *np) |
3185 | |
3186 | first_chan = 0; |
3187 | for (i = 0; i < port; i++) |
3188 | - first_chan += parent->txchan_per_port[port]; |
3189 | + first_chan += parent->txchan_per_port[i]; |
3190 | num_chan = parent->txchan_per_port[port]; |
3191 | for (i = first_chan; i < (first_chan + num_chan); i++) { |
3192 | err = niu_ldg_assign_ldn(np, parent, |
3193 | diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c |
3194 | index 2cd8dc5..cb6e0b4 100644 |
3195 | --- a/drivers/net/phy/dp83640.c |
3196 | +++ b/drivers/net/phy/dp83640.c |
3197 | @@ -34,8 +34,7 @@ |
3198 | #define PAGESEL 0x13 |
3199 | #define LAYER4 0x02 |
3200 | #define LAYER2 0x01 |
3201 | -#define MAX_RXTS 4 |
3202 | -#define MAX_TXTS 4 |
3203 | +#define MAX_RXTS 64 |
3204 | #define N_EXT_TS 1 |
3205 | #define PSF_PTPVER 2 |
3206 | #define PSF_EVNT 0x4000 |
3207 | @@ -218,7 +217,7 @@ static void phy2rxts(struct phy_rxts *p, struct rxts *rxts) |
3208 | rxts->seqid = p->seqid; |
3209 | rxts->msgtype = (p->msgtype >> 12) & 0xf; |
3210 | rxts->hash = p->msgtype & 0x0fff; |
3211 | - rxts->tmo = jiffies + HZ; |
3212 | + rxts->tmo = jiffies + 2; |
3213 | } |
3214 | |
3215 | static u64 phy2txts(struct phy_txts *p) |
3216 | diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c |
3217 | index 5990621..5f838ef 100644 |
3218 | --- a/drivers/net/r8169.c |
3219 | +++ b/drivers/net/r8169.c |
3220 | @@ -236,6 +236,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { |
3221 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, |
3222 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, |
3223 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, |
3224 | + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, |
3225 | { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, |
3226 | { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, |
3227 | { PCI_VENDOR_ID_LINKSYS, 0x1032, |
3228 | diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c |
3229 | index b436e00..f6d26ab 100644 |
3230 | --- a/drivers/net/sis190.c |
3231 | +++ b/drivers/net/sis190.c |
3232 | @@ -1824,6 +1824,16 @@ static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
3233 | generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); |
3234 | } |
3235 | |
3236 | +static int sis190_mac_addr(struct net_device *dev, void *p) |
3237 | +{ |
3238 | + int rc; |
3239 | + |
3240 | + rc = eth_mac_addr(dev, p); |
3241 | + if (!rc) |
3242 | + sis190_init_rxfilter(dev); |
3243 | + return rc; |
3244 | +} |
3245 | + |
3246 | static const struct net_device_ops sis190_netdev_ops = { |
3247 | .ndo_open = sis190_open, |
3248 | .ndo_stop = sis190_close, |
3249 | @@ -1832,7 +1842,7 @@ static const struct net_device_ops sis190_netdev_ops = { |
3250 | .ndo_tx_timeout = sis190_tx_timeout, |
3251 | .ndo_set_multicast_list = sis190_set_rx_mode, |
3252 | .ndo_change_mtu = eth_change_mtu, |
3253 | - .ndo_set_mac_address = eth_mac_addr, |
3254 | + .ndo_set_mac_address = sis190_mac_addr, |
3255 | .ndo_validate_addr = eth_validate_addr, |
3256 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3257 | .ndo_poll_controller = sis190_netpoll, |
3258 | diff --git a/drivers/net/tun.c b/drivers/net/tun.c |
3259 | index 5235f48..fb50e5a 100644 |
3260 | --- a/drivers/net/tun.c |
3261 | +++ b/drivers/net/tun.c |
3262 | @@ -528,6 +528,7 @@ static void tun_net_init(struct net_device *dev) |
3263 | dev->netdev_ops = &tap_netdev_ops; |
3264 | /* Ethernet TAP Device */ |
3265 | ether_setup(dev); |
3266 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
3267 | |
3268 | random_ether_addr(dev->dev_addr); |
3269 | |
3270 | diff --git a/drivers/net/veth.c b/drivers/net/veth.c |
3271 | index 8461576..4bf7c6d 100644 |
3272 | --- a/drivers/net/veth.c |
3273 | +++ b/drivers/net/veth.c |
3274 | @@ -262,6 +262,8 @@ static void veth_setup(struct net_device *dev) |
3275 | { |
3276 | ether_setup(dev); |
3277 | |
3278 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
3279 | + |
3280 | dev->netdev_ops = &veth_netdev_ops; |
3281 | dev->ethtool_ops = &veth_ethtool_ops; |
3282 | dev->features |= NETIF_F_LLTX; |
3283 | diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c |
3284 | index fc433f2..13f9997 100644 |
3285 | --- a/drivers/net/wan/hdlc_fr.c |
3286 | +++ b/drivers/net/wan/hdlc_fr.c |
3287 | @@ -1083,9 +1083,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) |
3288 | |
3289 | used = pvc_is_used(pvc); |
3290 | |
3291 | - if (type == ARPHRD_ETHER) |
3292 | + if (type == ARPHRD_ETHER) { |
3293 | dev = alloc_netdev(0, "pvceth%d", ether_setup); |
3294 | - else |
3295 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
3296 | + } else |
3297 | dev = alloc_netdev(0, "pvc%d", pvc_setup); |
3298 | |
3299 | if (!dev) { |
3300 | diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c |
3301 | index 55cf71f..e1b3e3c 100644 |
3302 | --- a/drivers/net/wireless/airo.c |
3303 | +++ b/drivers/net/wireless/airo.c |
3304 | @@ -2823,6 +2823,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, |
3305 | dev->wireless_data = &ai->wireless_data; |
3306 | dev->irq = irq; |
3307 | dev->base_addr = port; |
3308 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
3309 | |
3310 | SET_NETDEV_DEV(dev, dmdev); |
3311 | |
3312 | diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c |
3313 | index f344cc2..c32f9d1 100644 |
3314 | --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c |
3315 | +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c |
3316 | @@ -309,11 +309,7 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, |
3317 | u8 i; |
3318 | u32 val; |
3319 | |
3320 | - if (ah->is_pciexpress != true) |
3321 | - return; |
3322 | - |
3323 | - /* Do not touch SerDes registers */ |
3324 | - if (ah->config.pcie_powersave_enable == 2) |
3325 | + if (ah->is_pciexpress != true || ah->aspm_enabled != true) |
3326 | return; |
3327 | |
3328 | /* Nothing to do on restore for 11N */ |
3329 | diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |
3330 | index ff8150e..7e07f0f 100644 |
3331 | --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |
3332 | +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |
3333 | @@ -306,7 +306,7 @@ static const struct ar9300_eeprom ar9300_default = { |
3334 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3335 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
3336 | |
3337 | - { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
3338 | + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, |
3339 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3340 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3341 | |
3342 | @@ -883,7 +883,7 @@ static const struct ar9300_eeprom ar9300_x113 = { |
3343 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3344 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
3345 | |
3346 | - { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
3347 | + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, |
3348 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3349 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3350 | |
3351 | @@ -2039,7 +2039,7 @@ static const struct ar9300_eeprom ar9300_x112 = { |
3352 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3353 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
3354 | |
3355 | - { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
3356 | + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, |
3357 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3358 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
3359 | |
3360 | diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c |
3361 | index 392bf0f..7e02fb4 100644 |
3362 | --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c |
3363 | +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c |
3364 | @@ -351,11 +351,7 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, |
3365 | int restore, |
3366 | int power_off) |
3367 | { |
3368 | - if (ah->is_pciexpress != true) |
3369 | - return; |
3370 | - |
3371 | - /* Do not touch SerDes registers */ |
3372 | - if (ah->config.pcie_powersave_enable == 2) |
3373 | + if (ah->is_pciexpress != true || ah->aspm_enabled != true) |
3374 | return; |
3375 | |
3376 | /* Nothing to do on restore for 11N */ |
3377 | diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h |
3378 | index 443090d..efdbe98 100644 |
3379 | --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h |
3380 | +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h |
3381 | @@ -848,7 +848,7 @@ |
3382 | #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) |
3383 | #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) |
3384 | #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) |
3385 | -#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2)) |
3386 | +#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2)) |
3387 | |
3388 | /* |
3389 | * Channel 2 Register Map |
3390 | diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c |
3391 | index 1be7c8b..03900ca 100644 |
3392 | --- a/drivers/net/wireless/ath/ath9k/hw.c |
3393 | +++ b/drivers/net/wireless/ath/ath9k/hw.c |
3394 | @@ -299,6 +299,14 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) |
3395 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
3396 | } |
3397 | |
3398 | +static void ath9k_hw_aspm_init(struct ath_hw *ah) |
3399 | +{ |
3400 | + struct ath_common *common = ath9k_hw_common(ah); |
3401 | + |
3402 | + if (common->bus_ops->aspm_init) |
3403 | + common->bus_ops->aspm_init(common); |
3404 | +} |
3405 | + |
3406 | /* This should work for all families including legacy */ |
3407 | static bool ath9k_hw_chip_test(struct ath_hw *ah) |
3408 | { |
3409 | @@ -359,7 +367,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) |
3410 | ah->config.additional_swba_backoff = 0; |
3411 | ah->config.ack_6mb = 0x0; |
3412 | ah->config.cwm_ignore_extcca = 0; |
3413 | - ah->config.pcie_powersave_enable = 0; |
3414 | ah->config.pcie_clock_req = 0; |
3415 | ah->config.pcie_waen = 0; |
3416 | ah->config.analog_shiftreg = 1; |
3417 | @@ -577,7 +584,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) |
3418 | |
3419 | |
3420 | if (ah->is_pciexpress) |
3421 | - ath9k_hw_configpcipowersave(ah, 0, 0); |
3422 | + ath9k_hw_aspm_init(ah); |
3423 | else |
3424 | ath9k_hw_disablepcie(ah); |
3425 | |
3426 | diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h |
3427 | index 4b157c5..939cc9d 100644 |
3428 | --- a/drivers/net/wireless/ath/ath9k/hw.h |
3429 | +++ b/drivers/net/wireless/ath/ath9k/hw.h |
3430 | @@ -215,7 +215,6 @@ struct ath9k_ops_config { |
3431 | int additional_swba_backoff; |
3432 | int ack_6mb; |
3433 | u32 cwm_ignore_extcca; |
3434 | - u8 pcie_powersave_enable; |
3435 | bool pcieSerDesWrite; |
3436 | u8 pcie_clock_req; |
3437 | u32 pcie_waen; |
3438 | @@ -671,6 +670,7 @@ struct ath_hw { |
3439 | |
3440 | bool sw_mgmt_crypto; |
3441 | bool is_pciexpress; |
3442 | + bool aspm_enabled; |
3443 | bool is_monitoring; |
3444 | bool need_an_top2_fixup; |
3445 | u16 tx_trig_level; |
3446 | @@ -870,6 +870,7 @@ struct ath_bus_ops { |
3447 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); |
3448 | void (*bt_coex_prep)(struct ath_common *common); |
3449 | void (*extn_synch_en)(struct ath_common *common); |
3450 | + void (*aspm_init)(struct ath_common *common); |
3451 | }; |
3452 | |
3453 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) |
3454 | diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c |
3455 | index 45c585a..5a9fd21 100644 |
3456 | --- a/drivers/net/wireless/ath/ath9k/init.c |
3457 | +++ b/drivers/net/wireless/ath/ath9k/init.c |
3458 | @@ -665,8 +665,10 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) |
3459 | static void ath9k_init_txpower_limits(struct ath_softc *sc) |
3460 | { |
3461 | struct ath_hw *ah = sc->sc_ah; |
3462 | + struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
3463 | struct ath9k_channel *curchan = ah->curchan; |
3464 | |
3465 | + ah->txchainmask = common->tx_chainmask; |
3466 | if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) |
3467 | ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); |
3468 | if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) |
3469 | diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c |
3470 | index 3bad0b2..be4ea13 100644 |
3471 | --- a/drivers/net/wireless/ath/ath9k/pci.c |
3472 | +++ b/drivers/net/wireless/ath/ath9k/pci.c |
3473 | @@ -16,6 +16,7 @@ |
3474 | |
3475 | #include <linux/nl80211.h> |
3476 | #include <linux/pci.h> |
3477 | +#include <linux/pci-aspm.h> |
3478 | #include <linux/ath9k_platform.h> |
3479 | #include "ath9k.h" |
3480 | |
3481 | @@ -115,12 +116,38 @@ static void ath_pci_extn_synch_enable(struct ath_common *common) |
3482 | pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); |
3483 | } |
3484 | |
3485 | +static void ath_pci_aspm_init(struct ath_common *common) |
3486 | +{ |
3487 | + struct ath_softc *sc = (struct ath_softc *) common->priv; |
3488 | + struct ath_hw *ah = sc->sc_ah; |
3489 | + struct pci_dev *pdev = to_pci_dev(sc->dev); |
3490 | + struct pci_dev *parent; |
3491 | + int pos; |
3492 | + u8 aspm; |
3493 | + |
3494 | + if (!pci_is_pcie(pdev)) |
3495 | + return; |
3496 | + |
3497 | + parent = pdev->bus->self; |
3498 | + if (WARN_ON(!parent)) |
3499 | + return; |
3500 | + |
3501 | + pos = pci_pcie_cap(parent); |
3502 | + pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); |
3503 | + if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { |
3504 | + ah->aspm_enabled = true; |
3505 | + /* Initialize PCIe PM and SERDES registers. */ |
3506 | + ath9k_hw_configpcipowersave(ah, 0, 0); |
3507 | + } |
3508 | +} |
3509 | + |
3510 | static const struct ath_bus_ops ath_pci_bus_ops = { |
3511 | .ath_bus_type = ATH_PCI, |
3512 | .read_cachesize = ath_pci_read_cachesize, |
3513 | .eeprom_read = ath_pci_eeprom_read, |
3514 | .bt_coex_prep = ath_pci_bt_coex_prep, |
3515 | .extn_synch_en = ath_pci_extn_synch_enable, |
3516 | + .aspm_init = ath_pci_aspm_init, |
3517 | }; |
3518 | |
3519 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
3520 | diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c |
3521 | index d508482..89a116f 100644 |
3522 | --- a/drivers/net/wireless/hostap/hostap_main.c |
3523 | +++ b/drivers/net/wireless/hostap/hostap_main.c |
3524 | @@ -855,6 +855,7 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local, |
3525 | |
3526 | iface = netdev_priv(dev); |
3527 | ether_setup(dev); |
3528 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
3529 | |
3530 | /* kernel callbacks */ |
3531 | if (iface) { |
3532 | diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c |
3533 | index d096dc2..dcc1552 100644 |
3534 | --- a/drivers/net/wireless/iwlegacy/iwl-3945.c |
3535 | +++ b/drivers/net/wireless/iwlegacy/iwl-3945.c |
3536 | @@ -1747,7 +1747,11 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) |
3537 | } |
3538 | |
3539 | memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); |
3540 | - |
3541 | + /* |
3542 | + * We do not commit tx power settings while channel changing, |
3543 | + * do it now if tx power changed. |
3544 | + */ |
3545 | + iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); |
3546 | return 0; |
3547 | } |
3548 | |
3549 | diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c |
3550 | index facc94e..0a1babb 100644 |
3551 | --- a/drivers/net/wireless/iwlegacy/iwl-4965.c |
3552 | +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c |
3553 | @@ -1237,7 +1237,12 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c |
3554 | |
3555 | memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); |
3556 | iwl_legacy_print_rx_config_cmd(priv, ctx); |
3557 | - goto set_tx_power; |
3558 | + /* |
3559 | + * We do not commit tx power settings while channel changing, |
3560 | + * do it now if tx power changed. |
3561 | + */ |
3562 | + iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); |
3563 | + return 0; |
3564 | } |
3565 | |
3566 | /* If we are currently associated and the new config requires |
3567 | @@ -1317,7 +1322,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c |
3568 | |
3569 | iwl4965_init_sensitivity(priv); |
3570 | |
3571 | -set_tx_power: |
3572 | /* If we issue a new RXON command which required a tune then we must |
3573 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
3574 | ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); |
3575 | diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c |
3576 | index e816c27..f1c3f49 100644 |
3577 | --- a/drivers/net/wireless/iwlwifi/iwl-5000.c |
3578 | +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c |
3579 | @@ -421,6 +421,7 @@ static struct iwl_base_params iwl5000_base_params = { |
3580 | .chain_noise_scale = 1000, |
3581 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
3582 | .max_event_log_size = 512, |
3583 | + .no_idle_support = true, |
3584 | }; |
3585 | static struct iwl_ht_params iwl5000_ht_params = { |
3586 | .ht_greenfield_support = true, |
3587 | diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h |
3588 | index a54d416..b76996a 100644 |
3589 | --- a/drivers/net/wireless/iwlwifi/iwl-core.h |
3590 | +++ b/drivers/net/wireless/iwlwifi/iwl-core.h |
3591 | @@ -195,6 +195,7 @@ struct iwl_mod_params { |
3592 | * @temperature_kelvin: temperature report by uCode in kelvin |
3593 | * @max_event_log_size: size of event log buffer size for ucode event logging |
3594 | * @shadow_reg_enable: HW shadhow register bit |
3595 | + * @no_idle_support: do not support idle mode |
3596 | */ |
3597 | struct iwl_base_params { |
3598 | int eeprom_size; |
3599 | @@ -216,6 +217,7 @@ struct iwl_base_params { |
3600 | bool temperature_kelvin; |
3601 | u32 max_event_log_size; |
3602 | const bool shadow_reg_enable; |
3603 | + const bool no_idle_support; |
3604 | }; |
3605 | /* |
3606 | * @advanced_bt_coexist: support advanced bt coexist |
3607 | diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c |
3608 | index 595c930..4a05a6a 100644 |
3609 | --- a/drivers/net/wireless/iwlwifi/iwl-power.c |
3610 | +++ b/drivers/net/wireless/iwlwifi/iwl-power.c |
3611 | @@ -355,7 +355,8 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, |
3612 | |
3613 | dtimper = priv->hw->conf.ps_dtim_period ?: 1; |
3614 | |
3615 | - if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
3616 | + if (!priv->cfg->base_params->no_idle_support && |
3617 | + priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
3618 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); |
3619 | else if (iwl_tt_is_low_power_state(priv)) { |
3620 | /* in thermal throttling low power state */ |
3621 | diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c |
3622 | index 2a6aa85..5a45228 100644 |
3623 | --- a/drivers/net/wireless/rt2x00/rt2800lib.c |
3624 | +++ b/drivers/net/wireless/rt2x00/rt2800lib.c |
3625 | @@ -784,8 +784,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) |
3626 | /* |
3627 | * Add space for the TXWI in front of the skb. |
3628 | */ |
3629 | - skb_push(entry->skb, TXWI_DESC_SIZE); |
3630 | - memset(entry->skb, 0, TXWI_DESC_SIZE); |
3631 | + memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE); |
3632 | |
3633 | /* |
3634 | * Register descriptor details in skb frame descriptor. |
3635 | diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c |
3636 | index 93bec14..a76fdbe 100644 |
3637 | --- a/drivers/net/wireless/rt2x00/rt2x00mac.c |
3638 | +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c |
3639 | @@ -113,7 +113,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
3640 | * due to possible race conditions in mac80211. |
3641 | */ |
3642 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
3643 | - goto exit_fail; |
3644 | + goto exit_free_skb; |
3645 | |
3646 | /* |
3647 | * Use the ATIM queue if appropriate and present. |
3648 | @@ -127,7 +127,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
3649 | ERROR(rt2x00dev, |
3650 | "Attempt to send packet over invalid queue %d.\n" |
3651 | "Please file bug report to %s.\n", qid, DRV_PROJECT); |
3652 | - goto exit_fail; |
3653 | + goto exit_free_skb; |
3654 | } |
3655 | |
3656 | /* |
3657 | @@ -159,6 +159,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
3658 | |
3659 | exit_fail: |
3660 | rt2x00queue_pause_queue(queue); |
3661 | + exit_free_skb: |
3662 | dev_kfree_skb_any(skb); |
3663 | } |
3664 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); |
3665 | diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c |
3666 | index 254b64b..c872a23 100644 |
3667 | --- a/drivers/net/wireless/rtlwifi/pci.c |
3668 | +++ b/drivers/net/wireless/rtlwifi/pci.c |
3669 | @@ -1709,15 +1709,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, |
3670 | pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); |
3671 | pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); |
3672 | |
3673 | - /*find bridge info */ |
3674 | - pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; |
3675 | - for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { |
3676 | - if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { |
3677 | - pcipriv->ndis_adapter.pcibridge_vendor = tmp; |
3678 | - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3679 | - ("Pci Bridge Vendor is found index: %d\n", |
3680 | - tmp)); |
3681 | - break; |
3682 | + if (bridge_pdev) { |
3683 | + /*find bridge info if available */ |
3684 | + pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; |
3685 | + for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { |
3686 | + if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { |
3687 | + pcipriv->ndis_adapter.pcibridge_vendor = tmp; |
3688 | + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3689 | + ("Pci Bridge Vendor is found index:" |
3690 | + " %d\n", tmp)); |
3691 | + break; |
3692 | + } |
3693 | } |
3694 | } |
3695 | |
3696 | diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c |
3697 | index 3c7857c..e1678b9 100644 |
3698 | --- a/drivers/platform/x86/asus-wmi.c |
3699 | +++ b/drivers/platform/x86/asus-wmi.c |
3700 | @@ -797,8 +797,8 @@ exit: |
3701 | * Hwmon device |
3702 | */ |
3703 | static ssize_t asus_hwmon_pwm1(struct device *dev, |
3704 | - struct device_attribute *attr, |
3705 | - char *buf) |
3706 | + struct device_attribute *attr, |
3707 | + char *buf) |
3708 | { |
3709 | struct asus_wmi *asus = dev_get_drvdata(dev); |
3710 | u32 value; |
3711 | @@ -809,7 +809,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev, |
3712 | if (err < 0) |
3713 | return err; |
3714 | |
3715 | - value |= 0xFF; |
3716 | + value &= 0xFF; |
3717 | |
3718 | if (value == 1) /* Low Speed */ |
3719 | value = 85; |
3720 | @@ -869,7 +869,7 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, |
3721 | * - reverved bits are non-zero |
3722 | * - sfun and presence bit are not set |
3723 | */ |
3724 | - if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 |
3725 | + if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 |
3726 | || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) |
3727 | ok = false; |
3728 | } |
3729 | @@ -904,6 +904,7 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus) |
3730 | pr_err("Could not register asus hwmon device\n"); |
3731 | return PTR_ERR(hwmon); |
3732 | } |
3733 | + dev_set_drvdata(hwmon, asus); |
3734 | asus->hwmon_device = hwmon; |
3735 | result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); |
3736 | if (result) |
3737 | @@ -1164,14 +1165,18 @@ ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); |
3738 | static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, |
3739 | const char *buf, size_t count) |
3740 | { |
3741 | - int value; |
3742 | + int value, rv; |
3743 | |
3744 | if (!count || sscanf(buf, "%i", &value) != 1) |
3745 | return -EINVAL; |
3746 | if (value < 0 || value > 2) |
3747 | return -EINVAL; |
3748 | |
3749 | - return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); |
3750 | + rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); |
3751 | + if (rv < 0) |
3752 | + return rv; |
3753 | + |
3754 | + return count; |
3755 | } |
3756 | |
3757 | static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); |
3758 | diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c |
3759 | index efa0255..1da606c 100644 |
3760 | --- a/drivers/scsi/mpt2sas/mpt2sas_base.c |
3761 | +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c |
3762 | @@ -94,7 +94,7 @@ module_param(diag_buffer_enable, int, 0); |
3763 | MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " |
3764 | "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); |
3765 | |
3766 | -int mpt2sas_fwfault_debug; |
3767 | +static int mpt2sas_fwfault_debug; |
3768 | MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " |
3769 | "and halt firmware - (default=0)"); |
3770 | |
3771 | @@ -857,7 +857,7 @@ _base_interrupt(int irq, void *bus_id) |
3772 | completed_cmds = 0; |
3773 | cb_idx = 0xFF; |
3774 | do { |
3775 | - rd.word = rpf->Words; |
3776 | + rd.word = le64_to_cpu(rpf->Words); |
3777 | if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) |
3778 | goto out; |
3779 | reply = 0; |
3780 | @@ -906,7 +906,7 @@ _base_interrupt(int irq, void *bus_id) |
3781 | |
3782 | next: |
3783 | |
3784 | - rpf->Words = ULLONG_MAX; |
3785 | + rpf->Words = cpu_to_le64(ULLONG_MAX); |
3786 | ioc->reply_post_host_index = (ioc->reply_post_host_index == |
3787 | (ioc->reply_post_queue_depth - 1)) ? 0 : |
3788 | ioc->reply_post_host_index + 1; |
3789 | @@ -1817,7 +1817,9 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) |
3790 | char desc[16]; |
3791 | u8 revision; |
3792 | u32 iounit_pg1_flags; |
3793 | + u32 bios_version; |
3794 | |
3795 | + bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); |
3796 | pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); |
3797 | strncpy(desc, ioc->manu_pg0.ChipName, 16); |
3798 | printk(MPT2SAS_INFO_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), " |
3799 | @@ -1828,10 +1830,10 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) |
3800 | (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, |
3801 | ioc->facts.FWVersion.Word & 0x000000FF, |
3802 | revision, |
3803 | - (ioc->bios_pg3.BiosVersion & 0xFF000000) >> 24, |
3804 | - (ioc->bios_pg3.BiosVersion & 0x00FF0000) >> 16, |
3805 | - (ioc->bios_pg3.BiosVersion & 0x0000FF00) >> 8, |
3806 | - ioc->bios_pg3.BiosVersion & 0x000000FF); |
3807 | + (bios_version & 0xFF000000) >> 24, |
3808 | + (bios_version & 0x00FF0000) >> 16, |
3809 | + (bios_version & 0x0000FF00) >> 8, |
3810 | + bios_version & 0x000000FF); |
3811 | |
3812 | _base_display_dell_branding(ioc); |
3813 | _base_display_intel_branding(ioc); |
3814 | @@ -2150,7 +2152,7 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) |
3815 | static int |
3816 | _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
3817 | { |
3818 | - Mpi2IOCFactsReply_t *facts; |
3819 | + struct mpt2sas_facts *facts; |
3820 | u32 queue_size, queue_diff; |
3821 | u16 max_sge_elements; |
3822 | u16 num_of_reply_frames; |
3823 | @@ -2783,7 +2785,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, |
3824 | int i; |
3825 | u8 failed; |
3826 | u16 dummy; |
3827 | - u32 *mfp; |
3828 | + __le32 *mfp; |
3829 | |
3830 | /* make sure doorbell is not in use */ |
3831 | if ((readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { |
3832 | @@ -2871,7 +2873,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, |
3833 | writel(0, &ioc->chip->HostInterruptStatus); |
3834 | |
3835 | if (ioc->logging_level & MPT_DEBUG_INIT) { |
3836 | - mfp = (u32 *)reply; |
3837 | + mfp = (__le32 *)reply; |
3838 | printk(KERN_INFO "\toffset:data\n"); |
3839 | for (i = 0; i < reply_bytes/4; i++) |
3840 | printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, |
3841 | @@ -3097,7 +3099,8 @@ static int |
3842 | _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag) |
3843 | { |
3844 | Mpi2PortFactsRequest_t mpi_request; |
3845 | - Mpi2PortFactsReply_t mpi_reply, *pfacts; |
3846 | + Mpi2PortFactsReply_t mpi_reply; |
3847 | + struct mpt2sas_port_facts *pfacts; |
3848 | int mpi_reply_sz, mpi_request_sz, r; |
3849 | |
3850 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3851 | @@ -3139,7 +3142,8 @@ static int |
3852 | _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
3853 | { |
3854 | Mpi2IOCFactsRequest_t mpi_request; |
3855 | - Mpi2IOCFactsReply_t mpi_reply, *facts; |
3856 | + Mpi2IOCFactsReply_t mpi_reply; |
3857 | + struct mpt2sas_facts *facts; |
3858 | int mpi_reply_sz, mpi_request_sz, r; |
3859 | |
3860 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
3861 | @@ -3225,17 +3229,6 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
3862 | mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION); |
3863 | mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); |
3864 | |
3865 | - /* In MPI Revision I (0xA), the SystemReplyFrameSize(offset 0x18) was |
3866 | - * removed and made reserved. For those with older firmware will need |
3867 | - * this fix. It was decided that the Reply and Request frame sizes are |
3868 | - * the same. |
3869 | - */ |
3870 | - if ((ioc->facts.HeaderVersion >> 8) < 0xA) { |
3871 | - mpi_request.Reserved7 = cpu_to_le16(ioc->reply_sz); |
3872 | -/* mpi_request.SystemReplyFrameSize = |
3873 | - * cpu_to_le16(ioc->reply_sz); |
3874 | - */ |
3875 | - } |
3876 | |
3877 | mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4); |
3878 | mpi_request.ReplyDescriptorPostQueueDepth = |
3879 | @@ -3243,25 +3236,17 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
3880 | mpi_request.ReplyFreeQueueDepth = |
3881 | cpu_to_le16(ioc->reply_free_queue_depth); |
3882 | |
3883 | -#if BITS_PER_LONG > 32 |
3884 | mpi_request.SenseBufferAddressHigh = |
3885 | - cpu_to_le32(ioc->sense_dma >> 32); |
3886 | + cpu_to_le32((u64)ioc->sense_dma >> 32); |
3887 | mpi_request.SystemReplyAddressHigh = |
3888 | - cpu_to_le32(ioc->reply_dma >> 32); |
3889 | + cpu_to_le32((u64)ioc->reply_dma >> 32); |
3890 | mpi_request.SystemRequestFrameBaseAddress = |
3891 | - cpu_to_le64(ioc->request_dma); |
3892 | + cpu_to_le64((u64)ioc->request_dma); |
3893 | mpi_request.ReplyFreeQueueAddress = |
3894 | - cpu_to_le64(ioc->reply_free_dma); |
3895 | + cpu_to_le64((u64)ioc->reply_free_dma); |
3896 | mpi_request.ReplyDescriptorPostQueueAddress = |
3897 | - cpu_to_le64(ioc->reply_post_free_dma); |
3898 | -#else |
3899 | - mpi_request.SystemRequestFrameBaseAddress = |
3900 | - cpu_to_le32(ioc->request_dma); |
3901 | - mpi_request.ReplyFreeQueueAddress = |
3902 | - cpu_to_le32(ioc->reply_free_dma); |
3903 | - mpi_request.ReplyDescriptorPostQueueAddress = |
3904 | - cpu_to_le32(ioc->reply_post_free_dma); |
3905 | -#endif |
3906 | + cpu_to_le64((u64)ioc->reply_post_free_dma); |
3907 | + |
3908 | |
3909 | /* This time stamp specifies number of milliseconds |
3910 | * since epoch ~ midnight January 1, 1970. |
3911 | @@ -3271,10 +3256,10 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
3912 | (current_time.tv_usec / 1000)); |
3913 | |
3914 | if (ioc->logging_level & MPT_DEBUG_INIT) { |
3915 | - u32 *mfp; |
3916 | + __le32 *mfp; |
3917 | int i; |
3918 | |
3919 | - mfp = (u32 *)&mpi_request; |
3920 | + mfp = (__le32 *)&mpi_request; |
3921 | printk(KERN_INFO "\toffset:data\n"); |
3922 | for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) |
3923 | printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, |
3924 | @@ -3759,7 +3744,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
3925 | |
3926 | /* initialize Reply Post Free Queue */ |
3927 | for (i = 0; i < ioc->reply_post_queue_depth; i++) |
3928 | - ioc->reply_post_free[i].Words = ULLONG_MAX; |
3929 | + ioc->reply_post_free[i].Words = cpu_to_le64(ULLONG_MAX); |
3930 | |
3931 | r = _base_send_ioc_init(ioc, sleep_flag); |
3932 | if (r) |
3933 | diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h |
3934 | index dcc289c..451dc1c 100644 |
3935 | --- a/drivers/scsi/mpt2sas/mpt2sas_base.h |
3936 | +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h |
3937 | @@ -541,6 +541,53 @@ struct _tr_list { |
3938 | |
3939 | typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); |
3940 | |
3941 | +/* IOC Facts and Port Facts converted from little endian to cpu */ |
3942 | +union mpi2_version_union { |
3943 | + MPI2_VERSION_STRUCT Struct; |
3944 | + u32 Word; |
3945 | +}; |
3946 | + |
3947 | +struct mpt2sas_facts { |
3948 | + u16 MsgVersion; |
3949 | + u16 HeaderVersion; |
3950 | + u8 IOCNumber; |
3951 | + u8 VP_ID; |
3952 | + u8 VF_ID; |
3953 | + u16 IOCExceptions; |
3954 | + u16 IOCStatus; |
3955 | + u32 IOCLogInfo; |
3956 | + u8 MaxChainDepth; |
3957 | + u8 WhoInit; |
3958 | + u8 NumberOfPorts; |
3959 | + u8 MaxMSIxVectors; |
3960 | + u16 RequestCredit; |
3961 | + u16 ProductID; |
3962 | + u32 IOCCapabilities; |
3963 | + union mpi2_version_union FWVersion; |
3964 | + u16 IOCRequestFrameSize; |
3965 | + u16 Reserved3; |
3966 | + u16 MaxInitiators; |
3967 | + u16 MaxTargets; |
3968 | + u16 MaxSasExpanders; |
3969 | + u16 MaxEnclosures; |
3970 | + u16 ProtocolFlags; |
3971 | + u16 HighPriorityCredit; |
3972 | + u16 MaxReplyDescriptorPostQueueDepth; |
3973 | + u8 ReplyFrameSize; |
3974 | + u8 MaxVolumes; |
3975 | + u16 MaxDevHandle; |
3976 | + u16 MaxPersistentEntries; |
3977 | + u16 MinDevHandle; |
3978 | +}; |
3979 | + |
3980 | +struct mpt2sas_port_facts { |
3981 | + u8 PortNumber; |
3982 | + u8 VP_ID; |
3983 | + u8 VF_ID; |
3984 | + u8 PortType; |
3985 | + u16 MaxPostedCmdBuffers; |
3986 | +}; |
3987 | + |
3988 | /** |
3989 | * struct MPT2SAS_ADAPTER - per adapter struct |
3990 | * @list: ioc_list |
3991 | @@ -749,8 +796,8 @@ struct MPT2SAS_ADAPTER { |
3992 | u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; |
3993 | |
3994 | /* static config pages */ |
3995 | - Mpi2IOCFactsReply_t facts; |
3996 | - Mpi2PortFactsReply_t *pfacts; |
3997 | + struct mpt2sas_facts facts; |
3998 | + struct mpt2sas_port_facts *pfacts; |
3999 | Mpi2ManufacturingPage0_t manu_pg0; |
4000 | Mpi2BiosPage2_t bios_pg2; |
4001 | Mpi2BiosPage3_t bios_pg3; |
4002 | @@ -840,7 +887,7 @@ struct MPT2SAS_ADAPTER { |
4003 | |
4004 | /* reply free queue */ |
4005 | u16 reply_free_queue_depth; |
4006 | - u32 *reply_free; |
4007 | + __le32 *reply_free; |
4008 | dma_addr_t reply_free_dma; |
4009 | struct dma_pool *reply_free_dma_pool; |
4010 | u32 reply_free_host_index; |
4011 | diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c |
4012 | index 437c2d9..d1c3bba 100644 |
4013 | --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c |
4014 | +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c |
4015 | @@ -2706,13 +2706,13 @@ static DEVICE_ATTR(ioc_reset_count, S_IRUGO, |
4016 | _ctl_ioc_reset_count_show, NULL); |
4017 | |
4018 | struct DIAG_BUFFER_START { |
4019 | - u32 Size; |
4020 | - u32 DiagVersion; |
4021 | + __le32 Size; |
4022 | + __le32 DiagVersion; |
4023 | u8 BufferType; |
4024 | u8 Reserved[3]; |
4025 | - u32 Reserved1; |
4026 | - u32 Reserved2; |
4027 | - u32 Reserved3; |
4028 | + __le32 Reserved1; |
4029 | + __le32 Reserved2; |
4030 | + __le32 Reserved3; |
4031 | }; |
4032 | /** |
4033 | * _ctl_host_trace_buffer_size_show - host buffer size (trace only) |
4034 | diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h |
4035 | index 3dcddfe..9731f8e 100644 |
4036 | --- a/drivers/scsi/mpt2sas/mpt2sas_debug.h |
4037 | +++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h |
4038 | @@ -164,7 +164,7 @@ static inline void |
4039 | _debug_dump_mf(void *mpi_request, int sz) |
4040 | { |
4041 | int i; |
4042 | - u32 *mfp = (u32 *)mpi_request; |
4043 | + __le32 *mfp = (__le32 *)mpi_request; |
4044 | |
4045 | printk(KERN_INFO "mf:\n\t"); |
4046 | for (i = 0; i < sz; i++) { |
4047 | diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c |
4048 | index a7dbc68..e327a3c 100644 |
4049 | --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c |
4050 | +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c |
4051 | @@ -1956,7 +1956,7 @@ _scsih_slave_configure(struct scsi_device *sdev) |
4052 | case MPI2_RAID_VOL_TYPE_RAID1E: |
4053 | qdepth = MPT2SAS_RAID_QUEUE_DEPTH; |
4054 | if (ioc->manu_pg10.OEMIdentifier && |
4055 | - (ioc->manu_pg10.GenericFlags0 & |
4056 | + (le32_to_cpu(ioc->manu_pg10.GenericFlags0) & |
4057 | MFG10_GF0_R10_DISPLAY) && |
4058 | !(raid_device->num_pds % 2)) |
4059 | r_level = "RAID10"; |
4060 | @@ -4598,7 +4598,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) |
4061 | Mpi2SasEnclosurePage0_t enclosure_pg0; |
4062 | u32 ioc_status; |
4063 | u16 parent_handle; |
4064 | - __le64 sas_address, sas_address_parent = 0; |
4065 | + u64 sas_address, sas_address_parent = 0; |
4066 | int i; |
4067 | unsigned long flags; |
4068 | struct _sas_port *mpt2sas_port = NULL; |
4069 | @@ -5404,7 +5404,7 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, |
4070 | { |
4071 | struct MPT2SAS_TARGET *target_priv_data; |
4072 | struct _sas_device *sas_device; |
4073 | - __le64 sas_address; |
4074 | + u64 sas_address; |
4075 | unsigned long flags; |
4076 | Mpi2EventDataSasDeviceStatusChange_t *event_data = |
4077 | fw_event->event_data; |
4078 | @@ -6566,7 +6566,7 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc) |
4079 | Mpi2ExpanderPage0_t expander_pg0; |
4080 | Mpi2ConfigReply_t mpi_reply; |
4081 | u16 ioc_status; |
4082 | - __le64 sas_address; |
4083 | + u64 sas_address; |
4084 | u16 handle; |
4085 | |
4086 | printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); |
4087 | @@ -7505,7 +7505,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) |
4088 | { |
4089 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
4090 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); |
4091 | - u32 device_state; |
4092 | + pci_power_t device_state; |
4093 | |
4094 | mpt2sas_base_stop_watchdog(ioc); |
4095 | scsi_block_requests(shost); |
4096 | @@ -7532,7 +7532,7 @@ _scsih_resume(struct pci_dev *pdev) |
4097 | { |
4098 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
4099 | struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); |
4100 | - u32 device_state = pdev->current_state; |
4101 | + pci_power_t device_state = pdev->current_state; |
4102 | int r; |
4103 | |
4104 | printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, previous " |
4105 | diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c |
4106 | index cb1cdec..15c7980 100644 |
4107 | --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c |
4108 | +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c |
4109 | @@ -299,7 +299,6 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, |
4110 | void *data_out = NULL; |
4111 | dma_addr_t data_out_dma; |
4112 | u32 sz; |
4113 | - u64 *sas_address_le; |
4114 | u16 wait_state_count; |
4115 | |
4116 | if (ioc->shost_recovery || ioc->pci_error_recovery) { |
4117 | @@ -372,8 +371,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, |
4118 | mpi_request->PhysicalPort = 0xFF; |
4119 | mpi_request->VF_ID = 0; /* TODO */ |
4120 | mpi_request->VP_ID = 0; |
4121 | - sas_address_le = (u64 *)&mpi_request->SASAddress; |
4122 | - *sas_address_le = cpu_to_le64(sas_address); |
4123 | + mpi_request->SASAddress = cpu_to_le64(sas_address); |
4124 | mpi_request->RequestDataLength = |
4125 | cpu_to_le16(sizeof(struct rep_manu_request)); |
4126 | psge = &mpi_request->SGL; |
4127 | @@ -1049,14 +1047,14 @@ struct phy_error_log_reply{ |
4128 | u8 function; /* 0x11 */ |
4129 | u8 function_result; |
4130 | u8 response_length; |
4131 | - u16 expander_change_count; |
4132 | + __be16 expander_change_count; |
4133 | u8 reserved_1[3]; |
4134 | u8 phy_identifier; |
4135 | u8 reserved_2[2]; |
4136 | - u32 invalid_dword; |
4137 | - u32 running_disparity_error; |
4138 | - u32 loss_of_dword_sync; |
4139 | - u32 phy_reset_problem; |
4140 | + __be32 invalid_dword; |
4141 | + __be32 running_disparity_error; |
4142 | + __be32 loss_of_dword_sync; |
4143 | + __be32 phy_reset_problem; |
4144 | }; |
4145 | |
4146 | /** |
4147 | @@ -1085,7 +1083,6 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, |
4148 | void *data_out = NULL; |
4149 | dma_addr_t data_out_dma; |
4150 | u32 sz; |
4151 | - u64 *sas_address_le; |
4152 | u16 wait_state_count; |
4153 | |
4154 | if (ioc->shost_recovery || ioc->pci_error_recovery) { |
4155 | @@ -1160,8 +1157,7 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, |
4156 | mpi_request->PhysicalPort = 0xFF; |
4157 | mpi_request->VF_ID = 0; /* TODO */ |
4158 | mpi_request->VP_ID = 0; |
4159 | - sas_address_le = (u64 *)&mpi_request->SASAddress; |
4160 | - *sas_address_le = cpu_to_le64(phy->identify.sas_address); |
4161 | + mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); |
4162 | mpi_request->RequestDataLength = |
4163 | cpu_to_le16(sizeof(struct phy_error_log_request)); |
4164 | psge = &mpi_request->SGL; |
4165 | @@ -1406,7 +1402,6 @@ _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, |
4166 | void *data_out = NULL; |
4167 | dma_addr_t data_out_dma; |
4168 | u32 sz; |
4169 | - u64 *sas_address_le; |
4170 | u16 wait_state_count; |
4171 | |
4172 | if (ioc->shost_recovery) { |
4173 | @@ -1486,8 +1481,7 @@ _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, |
4174 | mpi_request->PhysicalPort = 0xFF; |
4175 | mpi_request->VF_ID = 0; /* TODO */ |
4176 | mpi_request->VP_ID = 0; |
4177 | - sas_address_le = (u64 *)&mpi_request->SASAddress; |
4178 | - *sas_address_le = cpu_to_le64(phy->identify.sas_address); |
4179 | + mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); |
4180 | mpi_request->RequestDataLength = |
4181 | cpu_to_le16(sizeof(struct phy_error_log_request)); |
4182 | psge = &mpi_request->SGL; |
4183 | @@ -1914,7 +1908,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, |
4184 | mpi_request->PhysicalPort = 0xFF; |
4185 | mpi_request->VF_ID = 0; /* TODO */ |
4186 | mpi_request->VP_ID = 0; |
4187 | - *((u64 *)&mpi_request->SASAddress) = (rphy) ? |
4188 | + mpi_request->SASAddress = (rphy) ? |
4189 | cpu_to_le64(rphy->identify.sas_address) : |
4190 | cpu_to_le64(ioc->sas_hba.sas_address); |
4191 | mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); |
4192 | diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
4193 | index aa97efc..62487a7 100644 |
4194 | --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
4195 | +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
4196 | @@ -6198,6 +6198,7 @@ int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname) |
4197 | |
4198 | ether_setup(dev); |
4199 | init_netdev(dev, ap_ifname); |
4200 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
4201 | |
4202 | if (register_netdev(dev)) { |
4203 | AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n")); |
4204 | diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c |
4205 | index bc4b12c..fc7e57b 100644 |
4206 | --- a/fs/cifs/cifsfs.c |
4207 | +++ b/fs/cifs/cifsfs.c |
4208 | @@ -581,6 +581,10 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) |
4209 | mutex_unlock(&dir->i_mutex); |
4210 | dput(dentry); |
4211 | dentry = child; |
4212 | + if (!dentry->d_inode) { |
4213 | + dput(dentry); |
4214 | + dentry = ERR_PTR(-ENOENT); |
4215 | + } |
4216 | } while (!IS_ERR(dentry)); |
4217 | _FreeXid(xid); |
4218 | kfree(full_path); |
4219 | diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c |
4220 | index 9b018c8..a7b2dcd 100644 |
4221 | --- a/fs/cifs/inode.c |
4222 | +++ b/fs/cifs/inode.c |
4223 | @@ -764,20 +764,10 @@ char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, |
4224 | if (full_path == NULL) |
4225 | return full_path; |
4226 | |
4227 | - if (dfsplen) { |
4228 | + if (dfsplen) |
4229 | strncpy(full_path, tcon->treeName, dfsplen); |
4230 | - /* switch slash direction in prepath depending on whether |
4231 | - * windows or posix style path names |
4232 | - */ |
4233 | - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { |
4234 | - int i; |
4235 | - for (i = 0; i < dfsplen; i++) { |
4236 | - if (full_path[i] == '\\') |
4237 | - full_path[i] = '/'; |
4238 | - } |
4239 | - } |
4240 | - } |
4241 | strncpy(full_path + dfsplen, vol->prepath, pplen); |
4242 | + convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
4243 | full_path[dfsplen + pplen] = 0; /* add trailing null */ |
4244 | return full_path; |
4245 | } |
4246 | diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c |
4247 | index 147aa22..c1b9c4b 100644 |
4248 | --- a/fs/cifs/transport.c |
4249 | +++ b/fs/cifs/transport.c |
4250 | @@ -362,6 +362,8 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, |
4251 | mid = AllocMidQEntry(hdr, server); |
4252 | if (mid == NULL) { |
4253 | mutex_unlock(&server->srv_mutex); |
4254 | + atomic_dec(&server->inFlight); |
4255 | + wake_up(&server->request_q); |
4256 | return -ENOMEM; |
4257 | } |
4258 | |
4259 | diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c |
4260 | index 9f1bb74..b4a6bef 100644 |
4261 | --- a/fs/ecryptfs/main.c |
4262 | +++ b/fs/ecryptfs/main.c |
4263 | @@ -175,6 +175,7 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, |
4264 | ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, |
4265 | ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, |
4266 | ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, |
4267 | + ecryptfs_opt_check_dev_ruid, |
4268 | ecryptfs_opt_err }; |
4269 | |
4270 | static const match_table_t tokens = { |
4271 | @@ -191,6 +192,7 @@ static const match_table_t tokens = { |
4272 | {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, |
4273 | {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, |
4274 | {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, |
4275 | + {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"}, |
4276 | {ecryptfs_opt_err, NULL} |
4277 | }; |
4278 | |
4279 | @@ -236,6 +238,7 @@ static void ecryptfs_init_mount_crypt_stat( |
4280 | * ecryptfs_parse_options |
4281 | * @sb: The ecryptfs super block |
4282 | * @options: The options passed to the kernel |
4283 | + * @check_ruid: set to 1 if device uid should be checked against the ruid |
4284 | * |
4285 | * Parse mount options: |
4286 | * debug=N - ecryptfs_verbosity level for debug output |
4287 | @@ -251,7 +254,8 @@ static void ecryptfs_init_mount_crypt_stat( |
4288 | * |
4289 | * Returns zero on success; non-zero on error |
4290 | */ |
4291 | -static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
4292 | +static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, |
4293 | + uid_t *check_ruid) |
4294 | { |
4295 | char *p; |
4296 | int rc = 0; |
4297 | @@ -276,6 +280,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
4298 | char *cipher_key_bytes_src; |
4299 | char *fn_cipher_key_bytes_src; |
4300 | |
4301 | + *check_ruid = 0; |
4302 | + |
4303 | if (!options) { |
4304 | rc = -EINVAL; |
4305 | goto out; |
4306 | @@ -380,6 +386,9 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
4307 | mount_crypt_stat->flags |= |
4308 | ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; |
4309 | break; |
4310 | + case ecryptfs_opt_check_dev_ruid: |
4311 | + *check_ruid = 1; |
4312 | + break; |
4313 | case ecryptfs_opt_err: |
4314 | default: |
4315 | printk(KERN_WARNING |
4316 | @@ -475,6 +484,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags |
4317 | const char *err = "Getting sb failed"; |
4318 | struct inode *inode; |
4319 | struct path path; |
4320 | + uid_t check_ruid; |
4321 | int rc; |
4322 | |
4323 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
4324 | @@ -483,7 +493,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags |
4325 | goto out; |
4326 | } |
4327 | |
4328 | - rc = ecryptfs_parse_options(sbi, raw_data); |
4329 | + rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); |
4330 | if (rc) { |
4331 | err = "Error parsing options"; |
4332 | goto out; |
4333 | @@ -521,6 +531,15 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags |
4334 | "known incompatibilities\n"); |
4335 | goto out_free; |
4336 | } |
4337 | + |
4338 | + if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) { |
4339 | + rc = -EPERM; |
4340 | + printk(KERN_ERR "Mount of device (uid: %d) not owned by " |
4341 | + "requested user (uid: %d)\n", |
4342 | + path.dentry->d_inode->i_uid, current_uid()); |
4343 | + goto out_free; |
4344 | + } |
4345 | + |
4346 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); |
4347 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
4348 | s->s_blocksize = path.dentry->d_sb->s_blocksize; |
4349 | diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c |
4350 | index 85d4309..3745f7c 100644 |
4351 | --- a/fs/ecryptfs/read_write.c |
4352 | +++ b/fs/ecryptfs/read_write.c |
4353 | @@ -39,15 +39,16 @@ |
4354 | int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, |
4355 | loff_t offset, size_t size) |
4356 | { |
4357 | - struct ecryptfs_inode_info *inode_info; |
4358 | + struct file *lower_file; |
4359 | mm_segment_t fs_save; |
4360 | ssize_t rc; |
4361 | |
4362 | - inode_info = ecryptfs_inode_to_private(ecryptfs_inode); |
4363 | - BUG_ON(!inode_info->lower_file); |
4364 | + lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
4365 | + if (!lower_file) |
4366 | + return -EIO; |
4367 | fs_save = get_fs(); |
4368 | set_fs(get_ds()); |
4369 | - rc = vfs_write(inode_info->lower_file, data, size, &offset); |
4370 | + rc = vfs_write(lower_file, data, size, &offset); |
4371 | set_fs(fs_save); |
4372 | mark_inode_dirty_sync(ecryptfs_inode); |
4373 | return rc; |
4374 | @@ -225,15 +226,16 @@ out: |
4375 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, |
4376 | struct inode *ecryptfs_inode) |
4377 | { |
4378 | - struct ecryptfs_inode_info *inode_info = |
4379 | - ecryptfs_inode_to_private(ecryptfs_inode); |
4380 | + struct file *lower_file; |
4381 | mm_segment_t fs_save; |
4382 | ssize_t rc; |
4383 | |
4384 | - BUG_ON(!inode_info->lower_file); |
4385 | + lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
4386 | + if (!lower_file) |
4387 | + return -EIO; |
4388 | fs_save = get_fs(); |
4389 | set_fs(get_ds()); |
4390 | - rc = vfs_read(inode_info->lower_file, data, size, &offset); |
4391 | + rc = vfs_read(lower_file, data, size, &offset); |
4392 | set_fs(fs_save); |
4393 | return rc; |
4394 | } |
4395 | diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c |
4396 | index 34b6d9b..e5a7111 100644 |
4397 | --- a/fs/ext3/namei.c |
4398 | +++ b/fs/ext3/namei.c |
4399 | @@ -2210,9 +2210,11 @@ static int ext3_symlink (struct inode * dir, |
4400 | /* |
4401 | * For non-fast symlinks, we just allocate inode and put it on |
4402 | * orphan list in the first transaction => we need bitmap, |
4403 | - * group descriptor, sb, inode block, quota blocks. |
4404 | + * group descriptor, sb, inode block, quota blocks, and |
4405 | + * possibly selinux xattr blocks. |
4406 | */ |
4407 | - credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); |
4408 | + credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + |
4409 | + EXT3_XATTR_TRANS_BLOCKS; |
4410 | } else { |
4411 | /* |
4412 | * Fast symlink. We have to add entry to directory |
4413 | diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c |
4414 | index b754b77..458a394 100644 |
4415 | --- a/fs/ext4/namei.c |
4416 | +++ b/fs/ext4/namei.c |
4417 | @@ -2264,9 +2264,11 @@ static int ext4_symlink(struct inode *dir, |
4418 | /* |
4419 | * For non-fast symlinks, we just allocate inode and put it on |
4420 | * orphan list in the first transaction => we need bitmap, |
4421 | - * group descriptor, sb, inode block, quota blocks. |
4422 | + * group descriptor, sb, inode block, quota blocks, and |
4423 | + * possibly selinux xattr blocks. |
4424 | */ |
4425 | - credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); |
4426 | + credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + |
4427 | + EXT4_XATTR_TRANS_BLOCKS; |
4428 | } else { |
4429 | /* |
4430 | * Fast symlink. We have to add entry to directory |
4431 | diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h |
4432 | index 33d12f8..0ec3687 100644 |
4433 | --- a/include/drm/drm_crtc.h |
4434 | +++ b/include/drm/drm_crtc.h |
4435 | @@ -802,6 +802,7 @@ extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev, |
4436 | extern int drm_add_modes_noedid(struct drm_connector *connector, |
4437 | int hdisplay, int vdisplay); |
4438 | |
4439 | +extern int drm_edid_header_is_valid(const u8 *raw_edid); |
4440 | extern bool drm_edid_is_valid(struct edid *edid); |
4441 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, |
4442 | int hsize, int vsize, int fresh); |
4443 | diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h |
4444 | index c4d6dbf..28c0d11 100644 |
4445 | --- a/include/drm/i915_drm.h |
4446 | +++ b/include/drm/i915_drm.h |
4447 | @@ -237,7 +237,7 @@ typedef struct _drm_i915_sarea { |
4448 | #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) |
4449 | #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id) |
4450 | #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) |
4451 | -#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image) |
4452 | +#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image) |
4453 | #define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) |
4454 | |
4455 | /* Allow drivers to submit batchbuffers directly to hardware, relying |
4456 | diff --git a/include/linux/cryptohash.h b/include/linux/cryptohash.h |
4457 | index ec78a4b..d2984fb 100644 |
4458 | --- a/include/linux/cryptohash.h |
4459 | +++ b/include/linux/cryptohash.h |
4460 | @@ -8,6 +8,11 @@ |
4461 | void sha_init(__u32 *buf); |
4462 | void sha_transform(__u32 *digest, const char *data, __u32 *W); |
4463 | |
4464 | +#define MD5_DIGEST_WORDS 4 |
4465 | +#define MD5_MESSAGE_BYTES 64 |
4466 | + |
4467 | +void md5_transform(__u32 *hash, __u32 const *in); |
4468 | + |
4469 | __u32 half_md4_transform(__u32 buf[4], __u32 const in[8]); |
4470 | |
4471 | #endif |
4472 | diff --git a/include/linux/if.h b/include/linux/if.h |
4473 | index 3bc63e6..03489ca 100644 |
4474 | --- a/include/linux/if.h |
4475 | +++ b/include/linux/if.h |
4476 | @@ -76,6 +76,8 @@ |
4477 | #define IFF_BRIDGE_PORT 0x4000 /* device used as bridge port */ |
4478 | #define IFF_OVS_DATAPATH 0x8000 /* device used as Open vSwitch |
4479 | * datapath port */ |
4480 | +#define IFF_TX_SKB_SHARING 0x10000 /* The interface supports sharing |
4481 | + * skbs on transmit */ |
4482 | |
4483 | #define IF_GET_IFACE 0x0001 /* for querying only */ |
4484 | #define IF_GET_PROTO 0x0002 |
4485 | diff --git a/include/linux/mm.h b/include/linux/mm.h |
4486 | index 1036614..ec6e33d 100644 |
4487 | --- a/include/linux/mm.h |
4488 | +++ b/include/linux/mm.h |
4489 | @@ -959,6 +959,8 @@ int invalidate_inode_page(struct page *page); |
4490 | #ifdef CONFIG_MMU |
4491 | extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, |
4492 | unsigned long address, unsigned int flags); |
4493 | +extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, |
4494 | + unsigned long address, unsigned int fault_flags); |
4495 | #else |
4496 | static inline int handle_mm_fault(struct mm_struct *mm, |
4497 | struct vm_area_struct *vma, unsigned long address, |
4498 | @@ -968,6 +970,14 @@ static inline int handle_mm_fault(struct mm_struct *mm, |
4499 | BUG(); |
4500 | return VM_FAULT_SIGBUS; |
4501 | } |
4502 | +static inline int fixup_user_fault(struct task_struct *tsk, |
4503 | + struct mm_struct *mm, unsigned long address, |
4504 | + unsigned int fault_flags) |
4505 | +{ |
4506 | + /* should never happen if there's no MMU */ |
4507 | + BUG(); |
4508 | + return -EFAULT; |
4509 | +} |
4510 | #endif |
4511 | |
4512 | extern int make_pages_present(unsigned long addr, unsigned long end); |
4513 | @@ -985,8 +995,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
4514 | int get_user_pages_fast(unsigned long start, int nr_pages, int write, |
4515 | struct page **pages); |
4516 | struct page *get_dump_page(unsigned long addr); |
4517 | -extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, |
4518 | - unsigned long address, unsigned int fault_flags); |
4519 | |
4520 | extern int try_to_release_page(struct page * page, gfp_t gfp_mask); |
4521 | extern void do_invalidatepage(struct page *page, unsigned long offset); |
4522 | diff --git a/include/linux/random.h b/include/linux/random.h |
4523 | index fb7ab9d..d13059f 100644 |
4524 | --- a/include/linux/random.h |
4525 | +++ b/include/linux/random.h |
4526 | @@ -57,17 +57,6 @@ extern void add_interrupt_randomness(int irq); |
4527 | extern void get_random_bytes(void *buf, int nbytes); |
4528 | void generate_random_uuid(unsigned char uuid_out[16]); |
4529 | |
4530 | -extern __u32 secure_ip_id(__be32 daddr); |
4531 | -extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); |
4532 | -extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
4533 | - __be16 dport); |
4534 | -extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, |
4535 | - __be16 sport, __be16 dport); |
4536 | -extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
4537 | - __be16 sport, __be16 dport); |
4538 | -extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, |
4539 | - __be16 sport, __be16 dport); |
4540 | - |
4541 | #ifndef MODULE |
4542 | extern const struct file_operations random_fops, urandom_fops; |
4543 | #endif |
4544 | diff --git a/include/net/ipv6.h b/include/net/ipv6.h |
4545 | index c033ed0..3b5ac1f 100644 |
4546 | --- a/include/net/ipv6.h |
4547 | +++ b/include/net/ipv6.h |
4548 | @@ -463,17 +463,7 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add |
4549 | return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); |
4550 | } |
4551 | |
4552 | -static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr) |
4553 | -{ |
4554 | - static u32 ipv6_fragmentation_id = 1; |
4555 | - static DEFINE_SPINLOCK(ip6_id_lock); |
4556 | - |
4557 | - spin_lock_bh(&ip6_id_lock); |
4558 | - fhdr->identification = htonl(ipv6_fragmentation_id); |
4559 | - if (++ipv6_fragmentation_id == 0) |
4560 | - ipv6_fragmentation_id = 1; |
4561 | - spin_unlock_bh(&ip6_id_lock); |
4562 | -} |
4563 | +extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); |
4564 | |
4565 | /* |
4566 | * Prototypes exported by ipv6 |
4567 | diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h |
4568 | new file mode 100644 |
4569 | index 0000000..d97f689 |
4570 | --- /dev/null |
4571 | +++ b/include/net/secure_seq.h |
4572 | @@ -0,0 +1,20 @@ |
4573 | +#ifndef _NET_SECURE_SEQ |
4574 | +#define _NET_SECURE_SEQ |
4575 | + |
4576 | +#include <linux/types.h> |
4577 | + |
4578 | +extern __u32 secure_ip_id(__be32 daddr); |
4579 | +extern __u32 secure_ipv6_id(const __be32 daddr[4]); |
4580 | +extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); |
4581 | +extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
4582 | + __be16 dport); |
4583 | +extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, |
4584 | + __be16 sport, __be16 dport); |
4585 | +extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
4586 | + __be16 sport, __be16 dport); |
4587 | +extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, |
4588 | + __be16 sport, __be16 dport); |
4589 | +extern u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
4590 | + __be16 sport, __be16 dport); |
4591 | + |
4592 | +#endif /* _NET_SECURE_SEQ */ |
4593 | diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h |
4594 | index 5271a74..45ce307 100644 |
4595 | --- a/include/net/transp_v6.h |
4596 | +++ b/include/net/transp_v6.h |
4597 | @@ -14,6 +14,8 @@ extern struct proto tcpv6_prot; |
4598 | |
4599 | struct flowi6; |
4600 | |
4601 | +extern void initialize_hashidentrnd(void); |
4602 | + |
4603 | /* extension headers */ |
4604 | extern int ipv6_exthdrs_init(void); |
4605 | extern void ipv6_exthdrs_exit(void); |
4606 | diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h |
4607 | index 70213b4..6acd9ce 100644 |
4608 | --- a/include/xen/interface/xen.h |
4609 | +++ b/include/xen/interface/xen.h |
4610 | @@ -450,6 +450,45 @@ struct start_info { |
4611 | int8_t cmd_line[MAX_GUEST_CMDLINE]; |
4612 | }; |
4613 | |
4614 | +struct dom0_vga_console_info { |
4615 | + uint8_t video_type; |
4616 | +#define XEN_VGATYPE_TEXT_MODE_3 0x03 |
4617 | +#define XEN_VGATYPE_VESA_LFB 0x23 |
4618 | + |
4619 | + union { |
4620 | + struct { |
4621 | + /* Font height, in pixels. */ |
4622 | + uint16_t font_height; |
4623 | + /* Cursor location (column, row). */ |
4624 | + uint16_t cursor_x, cursor_y; |
4625 | + /* Number of rows and columns (dimensions in characters). */ |
4626 | + uint16_t rows, columns; |
4627 | + } text_mode_3; |
4628 | + |
4629 | + struct { |
4630 | + /* Width and height, in pixels. */ |
4631 | + uint16_t width, height; |
4632 | + /* Bytes per scan line. */ |
4633 | + uint16_t bytes_per_line; |
4634 | + /* Bits per pixel. */ |
4635 | + uint16_t bits_per_pixel; |
4636 | + /* LFB physical address, and size (in units of 64kB). */ |
4637 | + uint32_t lfb_base; |
4638 | + uint32_t lfb_size; |
4639 | + /* RGB mask offsets and sizes, as defined by VBE 1.2+ */ |
4640 | + uint8_t red_pos, red_size; |
4641 | + uint8_t green_pos, green_size; |
4642 | + uint8_t blue_pos, blue_size; |
4643 | + uint8_t rsvd_pos, rsvd_size; |
4644 | + |
4645 | + /* VESA capabilities (offset 0xa, VESA command 0x4f00). */ |
4646 | + uint32_t gbl_caps; |
4647 | + /* Mode attributes (offset 0x0, VESA command 0x4f01). */ |
4648 | + uint16_t mode_attrs; |
4649 | + } vesa_lfb; |
4650 | + } u; |
4651 | +}; |
4652 | + |
4653 | /* These flags are passed in the 'flags' field of start_info_t. */ |
4654 | #define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */ |
4655 | #define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ |
4656 | diff --git a/kernel/futex.c b/kernel/futex.c |
4657 | index 7a0a4ed..8b6da25 100644 |
4658 | --- a/kernel/futex.c |
4659 | +++ b/kernel/futex.c |
4660 | @@ -218,6 +218,8 @@ static void drop_futex_key_refs(union futex_key *key) |
4661 | * @uaddr: virtual address of the futex |
4662 | * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED |
4663 | * @key: address where result is stored. |
4664 | + * @rw: mapping needs to be read/write (values: VERIFY_READ, |
4665 | + * VERIFY_WRITE) |
4666 | * |
4667 | * Returns a negative error code or 0 |
4668 | * The key words are stored in *key on success. |
4669 | @@ -229,12 +231,12 @@ static void drop_futex_key_refs(union futex_key *key) |
4670 | * lock_page() might sleep, the caller should not hold a spinlock. |
4671 | */ |
4672 | static int |
4673 | -get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) |
4674 | +get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) |
4675 | { |
4676 | unsigned long address = (unsigned long)uaddr; |
4677 | struct mm_struct *mm = current->mm; |
4678 | struct page *page, *page_head; |
4679 | - int err; |
4680 | + int err, ro = 0; |
4681 | |
4682 | /* |
4683 | * The futex address must be "naturally" aligned. |
4684 | @@ -262,8 +264,18 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) |
4685 | |
4686 | again: |
4687 | err = get_user_pages_fast(address, 1, 1, &page); |
4688 | + /* |
4689 | + * If write access is not required (eg. FUTEX_WAIT), try |
4690 | + * and get read-only access. |
4691 | + */ |
4692 | + if (err == -EFAULT && rw == VERIFY_READ) { |
4693 | + err = get_user_pages_fast(address, 1, 0, &page); |
4694 | + ro = 1; |
4695 | + } |
4696 | if (err < 0) |
4697 | return err; |
4698 | + else |
4699 | + err = 0; |
4700 | |
4701 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
4702 | page_head = page; |
4703 | @@ -305,6 +317,13 @@ again: |
4704 | if (!page_head->mapping) { |
4705 | unlock_page(page_head); |
4706 | put_page(page_head); |
4707 | + /* |
4708 | + * ZERO_PAGE pages don't have a mapping. Avoid a busy loop |
4709 | + * trying to find one. RW mapping would have COW'd (and thus |
4710 | + * have a mapping) so this page is RO and won't ever change. |
4711 | + */ |
4712 | + if ((page_head == ZERO_PAGE(address))) |
4713 | + return -EFAULT; |
4714 | goto again; |
4715 | } |
4716 | |
4717 | @@ -316,6 +335,15 @@ again: |
4718 | * the object not the particular process. |
4719 | */ |
4720 | if (PageAnon(page_head)) { |
4721 | + /* |
4722 | + * A RO anonymous page will never change and thus doesn't make |
4723 | + * sense for futex operations. |
4724 | + */ |
4725 | + if (ro) { |
4726 | + err = -EFAULT; |
4727 | + goto out; |
4728 | + } |
4729 | + |
4730 | key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ |
4731 | key->private.mm = mm; |
4732 | key->private.address = address; |
4733 | @@ -327,9 +355,10 @@ again: |
4734 | |
4735 | get_futex_key_refs(key); |
4736 | |
4737 | +out: |
4738 | unlock_page(page_head); |
4739 | put_page(page_head); |
4740 | - return 0; |
4741 | + return err; |
4742 | } |
4743 | |
4744 | static inline void put_futex_key(union futex_key *key) |
4745 | @@ -940,7 +969,7 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) |
4746 | if (!bitset) |
4747 | return -EINVAL; |
4748 | |
4749 | - ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); |
4750 | + ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_READ); |
4751 | if (unlikely(ret != 0)) |
4752 | goto out; |
4753 | |
4754 | @@ -986,10 +1015,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, |
4755 | int ret, op_ret; |
4756 | |
4757 | retry: |
4758 | - ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); |
4759 | + ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ); |
4760 | if (unlikely(ret != 0)) |
4761 | goto out; |
4762 | - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
4763 | + ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); |
4764 | if (unlikely(ret != 0)) |
4765 | goto out_put_key1; |
4766 | |
4767 | @@ -1243,10 +1272,11 @@ retry: |
4768 | pi_state = NULL; |
4769 | } |
4770 | |
4771 | - ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); |
4772 | + ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ); |
4773 | if (unlikely(ret != 0)) |
4774 | goto out; |
4775 | - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
4776 | + ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, |
4777 | + requeue_pi ? VERIFY_WRITE : VERIFY_READ); |
4778 | if (unlikely(ret != 0)) |
4779 | goto out_put_key1; |
4780 | |
4781 | @@ -1790,7 +1820,7 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, |
4782 | * while the syscall executes. |
4783 | */ |
4784 | retry: |
4785 | - ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); |
4786 | + ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key, VERIFY_READ); |
4787 | if (unlikely(ret != 0)) |
4788 | return ret; |
4789 | |
4790 | @@ -1941,7 +1971,7 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, int detect, |
4791 | } |
4792 | |
4793 | retry: |
4794 | - ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key); |
4795 | + ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key, VERIFY_WRITE); |
4796 | if (unlikely(ret != 0)) |
4797 | goto out; |
4798 | |
4799 | @@ -2060,7 +2090,7 @@ retry: |
4800 | if ((uval & FUTEX_TID_MASK) != vpid) |
4801 | return -EPERM; |
4802 | |
4803 | - ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); |
4804 | + ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_WRITE); |
4805 | if (unlikely(ret != 0)) |
4806 | goto out; |
4807 | |
4808 | @@ -2249,7 +2279,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, |
4809 | debug_rt_mutex_init_waiter(&rt_waiter); |
4810 | rt_waiter.task = NULL; |
4811 | |
4812 | - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
4813 | + ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); |
4814 | if (unlikely(ret != 0)) |
4815 | goto out; |
4816 | |
4817 | diff --git a/lib/Makefile b/lib/Makefile |
4818 | index 6b597fd..578414a 100644 |
4819 | --- a/lib/Makefile |
4820 | +++ b/lib/Makefile |
4821 | @@ -10,7 +10,7 @@ endif |
4822 | lib-y := ctype.o string.o vsprintf.o cmdline.o \ |
4823 | rbtree.o radix-tree.o dump_stack.o timerqueue.o\ |
4824 | idr.o int_sqrt.o extable.o prio_tree.o \ |
4825 | - sha1.o irq_regs.o reciprocal_div.o argv_split.o \ |
4826 | + sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ |
4827 | proportions.o prio_heap.o ratelimit.o show_mem.o \ |
4828 | is_single_threaded.o plist.o decompress.o find_next_bit.o |
4829 | |
4830 | diff --git a/lib/md5.c b/lib/md5.c |
4831 | new file mode 100644 |
4832 | index 0000000..c777180 |
4833 | --- /dev/null |
4834 | +++ b/lib/md5.c |
4835 | @@ -0,0 +1,95 @@ |
4836 | +#include <linux/kernel.h> |
4837 | +#include <linux/module.h> |
4838 | +#include <linux/cryptohash.h> |
4839 | + |
4840 | +#define F1(x, y, z) (z ^ (x & (y ^ z))) |
4841 | +#define F2(x, y, z) F1(z, x, y) |
4842 | +#define F3(x, y, z) (x ^ y ^ z) |
4843 | +#define F4(x, y, z) (y ^ (x | ~z)) |
4844 | + |
4845 | +#define MD5STEP(f, w, x, y, z, in, s) \ |
4846 | + (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) |
4847 | + |
4848 | +void md5_transform(__u32 *hash, __u32 const *in) |
4849 | +{ |
4850 | + u32 a, b, c, d; |
4851 | + |
4852 | + a = hash[0]; |
4853 | + b = hash[1]; |
4854 | + c = hash[2]; |
4855 | + d = hash[3]; |
4856 | + |
4857 | + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); |
4858 | + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); |
4859 | + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); |
4860 | + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); |
4861 | + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); |
4862 | + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); |
4863 | + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); |
4864 | + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); |
4865 | + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); |
4866 | + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); |
4867 | + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); |
4868 | + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); |
4869 | + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); |
4870 | + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); |
4871 | + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); |
4872 | + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); |
4873 | + |
4874 | + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); |
4875 | + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); |
4876 | + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); |
4877 | + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); |
4878 | + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); |
4879 | + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); |
4880 | + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); |
4881 | + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); |
4882 | + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); |
4883 | + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); |
4884 | + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); |
4885 | + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); |
4886 | + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); |
4887 | + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); |
4888 | + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); |
4889 | + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); |
4890 | + |
4891 | + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); |
4892 | + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); |
4893 | + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); |
4894 | + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); |
4895 | + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); |
4896 | + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); |
4897 | + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); |
4898 | + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); |
4899 | + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); |
4900 | + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); |
4901 | + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); |
4902 | + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); |
4903 | + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); |
4904 | + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); |
4905 | + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); |
4906 | + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); |
4907 | + |
4908 | + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); |
4909 | + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); |
4910 | + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); |
4911 | + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); |
4912 | + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); |
4913 | + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); |
4914 | + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); |
4915 | + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); |
4916 | + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); |
4917 | + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); |
4918 | + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); |
4919 | + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); |
4920 | + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); |
4921 | + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); |
4922 | + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); |
4923 | + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); |
4924 | + |
4925 | + hash[0] += a; |
4926 | + hash[1] += b; |
4927 | + hash[2] += c; |
4928 | + hash[3] += d; |
4929 | +} |
4930 | +EXPORT_SYMBOL(md5_transform); |
4931 | diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c |
4932 | index 6e82148..5b4f51d 100644 |
4933 | --- a/net/8021q/vlan_dev.c |
4934 | +++ b/net/8021q/vlan_dev.c |
4935 | @@ -694,7 +694,7 @@ void vlan_setup(struct net_device *dev) |
4936 | ether_setup(dev); |
4937 | |
4938 | dev->priv_flags |= IFF_802_1Q_VLAN; |
4939 | - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
4940 | + dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
4941 | dev->tx_queue_len = 0; |
4942 | |
4943 | dev->netdev_ops = &vlan_netdev_ops; |
4944 | diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c |
4945 | index 8c100c9..d4f5dff 100644 |
4946 | --- a/net/bluetooth/bnep/netdev.c |
4947 | +++ b/net/bluetooth/bnep/netdev.c |
4948 | @@ -231,6 +231,7 @@ void bnep_net_setup(struct net_device *dev) |
4949 | dev->addr_len = ETH_ALEN; |
4950 | |
4951 | ether_setup(dev); |
4952 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
4953 | dev->netdev_ops = &bnep_netdev_ops; |
4954 | |
4955 | dev->watchdog_timeo = HZ * 2; |
4956 | diff --git a/net/core/Makefile b/net/core/Makefile |
4957 | index 8a04dd2..0d357b1 100644 |
4958 | --- a/net/core/Makefile |
4959 | +++ b/net/core/Makefile |
4960 | @@ -3,7 +3,7 @@ |
4961 | # |
4962 | |
4963 | obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ |
4964 | - gen_stats.o gen_estimator.o net_namespace.o |
4965 | + gen_stats.o gen_estimator.o net_namespace.o secure_seq.o |
4966 | |
4967 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
4968 | |
4969 | diff --git a/net/core/link_watch.c b/net/core/link_watch.c |
4970 | index a7b3421..357bd4e 100644 |
4971 | --- a/net/core/link_watch.c |
4972 | +++ b/net/core/link_watch.c |
4973 | @@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent) |
4974 | return; |
4975 | |
4976 | /* It's already running which is good enough. */ |
4977 | - if (!cancel_delayed_work(&linkwatch_work)) |
4978 | + if (!__cancel_delayed_work(&linkwatch_work)) |
4979 | return; |
4980 | |
4981 | /* Otherwise we reschedule it again for immediate execution. */ |
4982 | diff --git a/net/core/pktgen.c b/net/core/pktgen.c |
4983 | index f76079c..e35a6fb 100644 |
4984 | --- a/net/core/pktgen.c |
4985 | +++ b/net/core/pktgen.c |
4986 | @@ -1070,7 +1070,9 @@ static ssize_t pktgen_if_write(struct file *file, |
4987 | len = num_arg(&user_buffer[i], 10, &value); |
4988 | if (len < 0) |
4989 | return len; |
4990 | - |
4991 | + if ((value > 0) && |
4992 | + (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) |
4993 | + return -ENOTSUPP; |
4994 | i += len; |
4995 | pkt_dev->clone_skb = value; |
4996 | |
4997 | @@ -3555,7 +3557,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) |
4998 | pkt_dev->min_pkt_size = ETH_ZLEN; |
4999 | pkt_dev->max_pkt_size = ETH_ZLEN; |
5000 | pkt_dev->nfrags = 0; |
5001 | - pkt_dev->clone_skb = pg_clone_skb_d; |
5002 | pkt_dev->delay = pg_delay_d; |
5003 | pkt_dev->count = pg_count_d; |
5004 | pkt_dev->sofar = 0; |
5005 | @@ -3563,7 +3564,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) |
5006 | pkt_dev->udp_src_max = 9; |
5007 | pkt_dev->udp_dst_min = 9; |
5008 | pkt_dev->udp_dst_max = 9; |
5009 | - |
5010 | pkt_dev->vlan_p = 0; |
5011 | pkt_dev->vlan_cfi = 0; |
5012 | pkt_dev->vlan_id = 0xffff; |
5013 | @@ -3575,6 +3575,8 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) |
5014 | err = pktgen_setup_dev(pkt_dev, ifname); |
5015 | if (err) |
5016 | goto out1; |
5017 | + if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING) |
5018 | + pkt_dev->clone_skb = pg_clone_skb_d; |
5019 | |
5020 | pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, |
5021 | &pktgen_if_fops, pkt_dev); |
5022 | diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c |
5023 | new file mode 100644 |
5024 | index 0000000..45329d7 |
5025 | --- /dev/null |
5026 | +++ b/net/core/secure_seq.c |
5027 | @@ -0,0 +1,184 @@ |
5028 | +#include <linux/kernel.h> |
5029 | +#include <linux/init.h> |
5030 | +#include <linux/cryptohash.h> |
5031 | +#include <linux/module.h> |
5032 | +#include <linux/cache.h> |
5033 | +#include <linux/random.h> |
5034 | +#include <linux/hrtimer.h> |
5035 | +#include <linux/ktime.h> |
5036 | +#include <linux/string.h> |
5037 | + |
5038 | +#include <net/secure_seq.h> |
5039 | + |
5040 | +static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; |
5041 | + |
5042 | +static int __init net_secret_init(void) |
5043 | +{ |
5044 | + get_random_bytes(net_secret, sizeof(net_secret)); |
5045 | + return 0; |
5046 | +} |
5047 | +late_initcall(net_secret_init); |
5048 | + |
5049 | +static u32 seq_scale(u32 seq) |
5050 | +{ |
5051 | + /* |
5052 | + * As close as possible to RFC 793, which |
5053 | + * suggests using a 250 kHz clock. |
5054 | + * Further reading shows this assumes 2 Mb/s networks. |
5055 | + * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. |
5056 | + * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but |
5057 | + * we also need to limit the resolution so that the u32 seq |
5058 | + * overlaps less than one time per MSL (2 minutes). |
5059 | + * Choosing a clock of 64 ns period is OK. (period of 274 s) |
5060 | + */ |
5061 | + return seq + (ktime_to_ns(ktime_get_real()) >> 6); |
5062 | +} |
5063 | + |
5064 | +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
5065 | +__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
5066 | + __be16 sport, __be16 dport) |
5067 | +{ |
5068 | + u32 secret[MD5_MESSAGE_BYTES / 4]; |
5069 | + u32 hash[MD5_DIGEST_WORDS]; |
5070 | + u32 i; |
5071 | + |
5072 | + memcpy(hash, saddr, 16); |
5073 | + for (i = 0; i < 4; i++) |
5074 | + secret[i] = net_secret[i] + daddr[i]; |
5075 | + secret[4] = net_secret[4] + |
5076 | + (((__force u16)sport << 16) + (__force u16)dport); |
5077 | + for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) |
5078 | + secret[i] = net_secret[i]; |
5079 | + |
5080 | + md5_transform(hash, secret); |
5081 | + |
5082 | + return seq_scale(hash[0]); |
5083 | +} |
5084 | +EXPORT_SYMBOL(secure_tcpv6_sequence_number); |
5085 | + |
5086 | +u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
5087 | + __be16 dport) |
5088 | +{ |
5089 | + u32 secret[MD5_MESSAGE_BYTES / 4]; |
5090 | + u32 hash[MD5_DIGEST_WORDS]; |
5091 | + u32 i; |
5092 | + |
5093 | + memcpy(hash, saddr, 16); |
5094 | + for (i = 0; i < 4; i++) |
5095 | + secret[i] = net_secret[i] + (__force u32) daddr[i]; |
5096 | + secret[4] = net_secret[4] + (__force u32)dport; |
5097 | + for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) |
5098 | + secret[i] = net_secret[i]; |
5099 | + |
5100 | + md5_transform(hash, secret); |
5101 | + |
5102 | + return hash[0]; |
5103 | +} |
5104 | +#endif |
5105 | + |
5106 | +#ifdef CONFIG_INET |
5107 | +__u32 secure_ip_id(__be32 daddr) |
5108 | +{ |
5109 | + u32 hash[MD5_DIGEST_WORDS]; |
5110 | + |
5111 | + hash[0] = (__force __u32) daddr; |
5112 | + hash[1] = net_secret[13]; |
5113 | + hash[2] = net_secret[14]; |
5114 | + hash[3] = net_secret[15]; |
5115 | + |
5116 | + md5_transform(hash, net_secret); |
5117 | + |
5118 | + return hash[0]; |
5119 | +} |
5120 | + |
5121 | +__u32 secure_ipv6_id(const __be32 daddr[4]) |
5122 | +{ |
5123 | + __u32 hash[4]; |
5124 | + |
5125 | + memcpy(hash, daddr, 16); |
5126 | + md5_transform(hash, net_secret); |
5127 | + |
5128 | + return hash[0]; |
5129 | +} |
5130 | + |
5131 | +__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, |
5132 | + __be16 sport, __be16 dport) |
5133 | +{ |
5134 | + u32 hash[MD5_DIGEST_WORDS]; |
5135 | + |
5136 | + hash[0] = (__force u32)saddr; |
5137 | + hash[1] = (__force u32)daddr; |
5138 | + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
5139 | + hash[3] = net_secret[15]; |
5140 | + |
5141 | + md5_transform(hash, net_secret); |
5142 | + |
5143 | + return seq_scale(hash[0]); |
5144 | +} |
5145 | + |
5146 | +u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) |
5147 | +{ |
5148 | + u32 hash[MD5_DIGEST_WORDS]; |
5149 | + |
5150 | + hash[0] = (__force u32)saddr; |
5151 | + hash[1] = (__force u32)daddr; |
5152 | + hash[2] = (__force u32)dport ^ net_secret[14]; |
5153 | + hash[3] = net_secret[15]; |
5154 | + |
5155 | + md5_transform(hash, net_secret); |
5156 | + |
5157 | + return hash[0]; |
5158 | +} |
5159 | +EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); |
5160 | +#endif |
5161 | + |
5162 | +#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) |
5163 | +u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, |
5164 | + __be16 sport, __be16 dport) |
5165 | +{ |
5166 | + u32 hash[MD5_DIGEST_WORDS]; |
5167 | + u64 seq; |
5168 | + |
5169 | + hash[0] = (__force u32)saddr; |
5170 | + hash[1] = (__force u32)daddr; |
5171 | + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
5172 | + hash[3] = net_secret[15]; |
5173 | + |
5174 | + md5_transform(hash, net_secret); |
5175 | + |
5176 | + seq = hash[0] | (((u64)hash[1]) << 32); |
5177 | + seq += ktime_to_ns(ktime_get_real()); |
5178 | + seq &= (1ull << 48) - 1; |
5179 | + |
5180 | + return seq; |
5181 | +} |
5182 | +EXPORT_SYMBOL(secure_dccp_sequence_number); |
5183 | + |
5184 | +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
5185 | +u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
5186 | + __be16 sport, __be16 dport) |
5187 | +{ |
5188 | + u32 secret[MD5_MESSAGE_BYTES / 4]; |
5189 | + u32 hash[MD5_DIGEST_WORDS]; |
5190 | + u64 seq; |
5191 | + u32 i; |
5192 | + |
5193 | + memcpy(hash, saddr, 16); |
5194 | + for (i = 0; i < 4; i++) |
5195 | + secret[i] = net_secret[i] + daddr[i]; |
5196 | + secret[4] = net_secret[4] + |
5197 | + (((__force u16)sport << 16) + (__force u16)dport); |
5198 | + for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) |
5199 | + secret[i] = net_secret[i]; |
5200 | + |
5201 | + md5_transform(hash, secret); |
5202 | + |
5203 | + seq = hash[0] | (((u64)hash[1]) << 32); |
5204 | + seq += ktime_to_ns(ktime_get_real()); |
5205 | + seq &= (1ull << 48) - 1; |
5206 | + |
5207 | + return seq; |
5208 | +} |
5209 | +EXPORT_SYMBOL(secure_dccpv6_sequence_number); |
5210 | +#endif |
5211 | +#endif |
5212 | diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c |
5213 | index 8c36adf..332639b 100644 |
5214 | --- a/net/dccp/ipv4.c |
5215 | +++ b/net/dccp/ipv4.c |
5216 | @@ -26,6 +26,7 @@ |
5217 | #include <net/timewait_sock.h> |
5218 | #include <net/tcp_states.h> |
5219 | #include <net/xfrm.h> |
5220 | +#include <net/secure_seq.h> |
5221 | |
5222 | #include "ackvec.h" |
5223 | #include "ccid.h" |
5224 | diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c |
5225 | index 8dc4348..b74f761 100644 |
5226 | --- a/net/dccp/ipv6.c |
5227 | +++ b/net/dccp/ipv6.c |
5228 | @@ -29,6 +29,7 @@ |
5229 | #include <net/transp_v6.h> |
5230 | #include <net/ip6_checksum.h> |
5231 | #include <net/xfrm.h> |
5232 | +#include <net/secure_seq.h> |
5233 | |
5234 | #include "dccp.h" |
5235 | #include "ipv6.h" |
5236 | @@ -69,13 +70,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) |
5237 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); |
5238 | } |
5239 | |
5240 | -static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
5241 | - __be16 sport, __be16 dport ) |
5242 | -{ |
5243 | - return secure_tcpv6_sequence_number(saddr, daddr, sport, dport); |
5244 | -} |
5245 | - |
5246 | -static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb) |
5247 | +static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) |
5248 | { |
5249 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, |
5250 | ipv6_hdr(skb)->saddr.s6_addr32, |
5251 | diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c |
5252 | index 44d2b42..2780e9b 100644 |
5253 | --- a/net/ethernet/eth.c |
5254 | +++ b/net/ethernet/eth.c |
5255 | @@ -340,6 +340,7 @@ void ether_setup(struct net_device *dev) |
5256 | dev->addr_len = ETH_ALEN; |
5257 | dev->tx_queue_len = 1000; /* Ethernet wants good queues */ |
5258 | dev->flags = IFF_BROADCAST|IFF_MULTICAST; |
5259 | + dev->priv_flags = IFF_TX_SKB_SHARING; |
5260 | |
5261 | memset(dev->broadcast, 0xFF, ETH_ALEN); |
5262 | |
5263 | diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c |
5264 | index 0d4a184..4155abc 100644 |
5265 | --- a/net/ipv4/devinet.c |
5266 | +++ b/net/ipv4/devinet.c |
5267 | @@ -1134,15 +1134,15 @@ static void inetdev_send_gratuitous_arp(struct net_device *dev, |
5268 | struct in_device *in_dev) |
5269 | |
5270 | { |
5271 | - struct in_ifaddr *ifa = in_dev->ifa_list; |
5272 | - |
5273 | - if (!ifa) |
5274 | - return; |
5275 | + struct in_ifaddr *ifa; |
5276 | |
5277 | - arp_send(ARPOP_REQUEST, ETH_P_ARP, |
5278 | - ifa->ifa_local, dev, |
5279 | - ifa->ifa_local, NULL, |
5280 | - dev->dev_addr, NULL); |
5281 | + for (ifa = in_dev->ifa_list; ifa; |
5282 | + ifa = ifa->ifa_next) { |
5283 | + arp_send(ARPOP_REQUEST, ETH_P_ARP, |
5284 | + ifa->ifa_local, dev, |
5285 | + ifa->ifa_local, NULL, |
5286 | + dev->dev_addr, NULL); |
5287 | + } |
5288 | } |
5289 | |
5290 | /* Called only under RTNL semaphore */ |
5291 | diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c |
5292 | index c6933f2..3e3f75d 100644 |
5293 | --- a/net/ipv4/gre.c |
5294 | +++ b/net/ipv4/gre.c |
5295 | @@ -15,6 +15,7 @@ |
5296 | #include <linux/kmod.h> |
5297 | #include <linux/skbuff.h> |
5298 | #include <linux/in.h> |
5299 | +#include <linux/ip.h> |
5300 | #include <linux/netdevice.h> |
5301 | #include <linux/version.h> |
5302 | #include <linux/spinlock.h> |
5303 | @@ -97,27 +98,17 @@ drop: |
5304 | static void gre_err(struct sk_buff *skb, u32 info) |
5305 | { |
5306 | const struct gre_protocol *proto; |
5307 | - u8 ver; |
5308 | - |
5309 | - if (!pskb_may_pull(skb, 12)) |
5310 | - goto drop; |
5311 | + const struct iphdr *iph = (const struct iphdr *)skb->data; |
5312 | + u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f; |
5313 | |
5314 | - ver = skb->data[1]&0x7f; |
5315 | if (ver >= GREPROTO_MAX) |
5316 | - goto drop; |
5317 | + return; |
5318 | |
5319 | rcu_read_lock(); |
5320 | proto = rcu_dereference(gre_proto[ver]); |
5321 | - if (!proto || !proto->err_handler) |
5322 | - goto drop_unlock; |
5323 | - proto->err_handler(skb, info); |
5324 | - rcu_read_unlock(); |
5325 | - return; |
5326 | - |
5327 | -drop_unlock: |
5328 | + if (proto && proto->err_handler) |
5329 | + proto->err_handler(skb, info); |
5330 | rcu_read_unlock(); |
5331 | -drop: |
5332 | - kfree_skb(skb); |
5333 | } |
5334 | |
5335 | static const struct net_protocol net_gre_protocol = { |
5336 | diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c |
5337 | index 5395e45..23ef31b 100644 |
5338 | --- a/net/ipv4/icmp.c |
5339 | +++ b/net/ipv4/icmp.c |
5340 | @@ -380,6 +380,7 @@ static struct rtable *icmp_route_lookup(struct net *net, |
5341 | struct icmp_bxm *param) |
5342 | { |
5343 | struct rtable *rt, *rt2; |
5344 | + struct flowi4 fl4_dec; |
5345 | int err; |
5346 | |
5347 | memset(fl4, 0, sizeof(*fl4)); |
5348 | @@ -408,19 +409,19 @@ static struct rtable *icmp_route_lookup(struct net *net, |
5349 | } else |
5350 | return rt; |
5351 | |
5352 | - err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(fl4), AF_INET); |
5353 | + err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4_dec), AF_INET); |
5354 | if (err) |
5355 | goto relookup_failed; |
5356 | |
5357 | - if (inet_addr_type(net, fl4->saddr) == RTN_LOCAL) { |
5358 | - rt2 = __ip_route_output_key(net, fl4); |
5359 | + if (inet_addr_type(net, fl4_dec.saddr) == RTN_LOCAL) { |
5360 | + rt2 = __ip_route_output_key(net, &fl4_dec); |
5361 | if (IS_ERR(rt2)) |
5362 | err = PTR_ERR(rt2); |
5363 | } else { |
5364 | struct flowi4 fl4_2 = {}; |
5365 | unsigned long orefdst; |
5366 | |
5367 | - fl4_2.daddr = fl4->saddr; |
5368 | + fl4_2.daddr = fl4_dec.saddr; |
5369 | rt2 = ip_route_output_key(net, &fl4_2); |
5370 | if (IS_ERR(rt2)) { |
5371 | err = PTR_ERR(rt2); |
5372 | @@ -428,7 +429,7 @@ static struct rtable *icmp_route_lookup(struct net *net, |
5373 | } |
5374 | /* Ugh! */ |
5375 | orefdst = skb_in->_skb_refdst; /* save old refdst */ |
5376 | - err = ip_route_input(skb_in, fl4->daddr, fl4->saddr, |
5377 | + err = ip_route_input(skb_in, fl4_dec.daddr, fl4_dec.saddr, |
5378 | RT_TOS(tos), rt2->dst.dev); |
5379 | |
5380 | dst_release(&rt2->dst); |
5381 | @@ -440,10 +441,11 @@ static struct rtable *icmp_route_lookup(struct net *net, |
5382 | goto relookup_failed; |
5383 | |
5384 | rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst, |
5385 | - flowi4_to_flowi(fl4), NULL, |
5386 | + flowi4_to_flowi(&fl4_dec), NULL, |
5387 | XFRM_LOOKUP_ICMP); |
5388 | if (!IS_ERR(rt2)) { |
5389 | dst_release(&rt->dst); |
5390 | + memcpy(fl4, &fl4_dec, sizeof(*fl4)); |
5391 | rt = rt2; |
5392 | } else if (PTR_ERR(rt2) == -EPERM) { |
5393 | if (rt) |
5394 | diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c |
5395 | index f1d27f6..283c0a2 100644 |
5396 | --- a/net/ipv4/igmp.c |
5397 | +++ b/net/ipv4/igmp.c |
5398 | @@ -1718,7 +1718,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, |
5399 | |
5400 | pmc->sfcount[sfmode]--; |
5401 | for (j=0; j<i; j++) |
5402 | - (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); |
5403 | + (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]); |
5404 | } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { |
5405 | #ifdef CONFIG_IP_MULTICAST |
5406 | struct ip_sf_list *psf; |
5407 | diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c |
5408 | index 3c0369a..984ec65 100644 |
5409 | --- a/net/ipv4/inet_hashtables.c |
5410 | +++ b/net/ipv4/inet_hashtables.c |
5411 | @@ -21,6 +21,7 @@ |
5412 | |
5413 | #include <net/inet_connection_sock.h> |
5414 | #include <net/inet_hashtables.h> |
5415 | +#include <net/secure_seq.h> |
5416 | #include <net/ip.h> |
5417 | |
5418 | /* |
5419 | diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c |
5420 | index ce616d9..6877645 100644 |
5421 | --- a/net/ipv4/inetpeer.c |
5422 | +++ b/net/ipv4/inetpeer.c |
5423 | @@ -19,6 +19,7 @@ |
5424 | #include <linux/net.h> |
5425 | #include <net/ip.h> |
5426 | #include <net/inetpeer.h> |
5427 | +#include <net/secure_seq.h> |
5428 | |
5429 | /* |
5430 | * Theory of operations. |
5431 | diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c |
5432 | index 84f26e8..0c99db4 100644 |
5433 | --- a/net/ipv4/ip_output.c |
5434 | +++ b/net/ipv4/ip_output.c |
5435 | @@ -734,7 +734,7 @@ static inline int ip_ufo_append_data(struct sock *sk, |
5436 | int getfrag(void *from, char *to, int offset, int len, |
5437 | int odd, struct sk_buff *skb), |
5438 | void *from, int length, int hh_len, int fragheaderlen, |
5439 | - int transhdrlen, int mtu, unsigned int flags) |
5440 | + int transhdrlen, int maxfraglen, unsigned int flags) |
5441 | { |
5442 | struct sk_buff *skb; |
5443 | int err; |
5444 | @@ -767,7 +767,7 @@ static inline int ip_ufo_append_data(struct sock *sk, |
5445 | skb->csum = 0; |
5446 | |
5447 | /* specify the length of each IP datagram fragment */ |
5448 | - skb_shinfo(skb)->gso_size = mtu - fragheaderlen; |
5449 | + skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen; |
5450 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; |
5451 | __skb_queue_tail(queue, skb); |
5452 | } |
5453 | @@ -831,7 +831,7 @@ static int __ip_append_data(struct sock *sk, |
5454 | (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { |
5455 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, |
5456 | hh_len, fragheaderlen, transhdrlen, |
5457 | - mtu, flags); |
5458 | + maxfraglen, flags); |
5459 | if (err) |
5460 | goto error; |
5461 | return 0; |
5462 | diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c |
5463 | index 30a7763..f81af8d 100644 |
5464 | --- a/net/ipv4/ipmr.c |
5465 | +++ b/net/ipv4/ipmr.c |
5466 | @@ -1796,7 +1796,7 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb) |
5467 | struct flowi4 fl4 = { |
5468 | .daddr = iph->daddr, |
5469 | .saddr = iph->saddr, |
5470 | - .flowi4_tos = iph->tos, |
5471 | + .flowi4_tos = RT_TOS(iph->tos), |
5472 | .flowi4_oif = rt->rt_oif, |
5473 | .flowi4_iif = rt->rt_iif, |
5474 | .flowi4_mark = rt->rt_mark, |
5475 | diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c |
5476 | index 3e61faf..f52d41e 100644 |
5477 | --- a/net/ipv4/netfilter/nf_nat_proto_common.c |
5478 | +++ b/net/ipv4/netfilter/nf_nat_proto_common.c |
5479 | @@ -12,6 +12,7 @@ |
5480 | #include <linux/ip.h> |
5481 | |
5482 | #include <linux/netfilter.h> |
5483 | +#include <net/secure_seq.h> |
5484 | #include <net/netfilter/nf_nat.h> |
5485 | #include <net/netfilter/nf_nat_core.h> |
5486 | #include <net/netfilter/nf_nat_rule.h> |
5487 | diff --git a/net/ipv4/route.c b/net/ipv4/route.c |
5488 | index aa13ef1..cdabdbf 100644 |
5489 | --- a/net/ipv4/route.c |
5490 | +++ b/net/ipv4/route.c |
5491 | @@ -108,6 +108,7 @@ |
5492 | #ifdef CONFIG_SYSCTL |
5493 | #include <linux/sysctl.h> |
5494 | #endif |
5495 | +#include <net/secure_seq.h> |
5496 | |
5497 | #define RT_FL_TOS(oldflp4) \ |
5498 | ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) |
5499 | @@ -725,6 +726,7 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) |
5500 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
5501 | (rt1->rt_mark ^ rt2->rt_mark) | |
5502 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | |
5503 | + (rt1->rt_route_iif ^ rt2->rt_route_iif) | |
5504 | (rt1->rt_oif ^ rt2->rt_oif) | |
5505 | (rt1->rt_iif ^ rt2->rt_iif)) == 0; |
5506 | } |
5507 | @@ -1703,7 +1705,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt) |
5508 | memset(&fl4, 0, sizeof(fl4)); |
5509 | fl4.daddr = iph->daddr; |
5510 | fl4.saddr = iph->saddr; |
5511 | - fl4.flowi4_tos = iph->tos; |
5512 | + fl4.flowi4_tos = RT_TOS(iph->tos); |
5513 | fl4.flowi4_oif = rt->dst.dev->ifindex; |
5514 | fl4.flowi4_iif = skb->dev->ifindex; |
5515 | fl4.flowi4_mark = skb->mark; |
5516 | @@ -2281,8 +2283,8 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, |
5517 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | |
5518 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | |
5519 | (rth->rt_iif ^ iif) | |
5520 | - rth->rt_oif | |
5521 | (rth->rt_key_tos ^ tos)) == 0 && |
5522 | + rt_is_input_route(rth) && |
5523 | rth->rt_mark == skb->mark && |
5524 | net_eq(dev_net(rth->dst.dev), net) && |
5525 | !rt_is_expired(rth)) { |
5526 | diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
5527 | index 708dc20..b3e6956 100644 |
5528 | --- a/net/ipv4/tcp_ipv4.c |
5529 | +++ b/net/ipv4/tcp_ipv4.c |
5530 | @@ -72,6 +72,7 @@ |
5531 | #include <net/timewait_sock.h> |
5532 | #include <net/xfrm.h> |
5533 | #include <net/netdma.h> |
5534 | +#include <net/secure_seq.h> |
5535 | |
5536 | #include <linux/inet.h> |
5537 | #include <linux/ipv6.h> |
5538 | diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c |
5539 | index 3b5669a..5591236 100644 |
5540 | --- a/net/ipv6/af_inet6.c |
5541 | +++ b/net/ipv6/af_inet6.c |
5542 | @@ -1078,6 +1078,8 @@ static int __init inet6_init(void) |
5543 | goto out; |
5544 | } |
5545 | |
5546 | + initialize_hashidentrnd(); |
5547 | + |
5548 | err = proto_register(&tcpv6_prot, 1); |
5549 | if (err) |
5550 | goto out; |
5551 | diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c |
5552 | index b531972..73f1a00 100644 |
5553 | --- a/net/ipv6/inet6_hashtables.c |
5554 | +++ b/net/ipv6/inet6_hashtables.c |
5555 | @@ -20,6 +20,7 @@ |
5556 | #include <net/inet_connection_sock.h> |
5557 | #include <net/inet_hashtables.h> |
5558 | #include <net/inet6_hashtables.h> |
5559 | +#include <net/secure_seq.h> |
5560 | #include <net/ip.h> |
5561 | |
5562 | int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) |
5563 | diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
5564 | index 9d4b165..1661296 100644 |
5565 | --- a/net/ipv6/ip6_output.c |
5566 | +++ b/net/ipv6/ip6_output.c |
5567 | @@ -596,6 +596,35 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) |
5568 | return offset; |
5569 | } |
5570 | |
5571 | +static u32 hashidentrnd __read_mostly; |
5572 | +#define FID_HASH_SZ 16 |
5573 | +static u32 ipv6_fragmentation_id[FID_HASH_SZ]; |
5574 | + |
5575 | +void __init initialize_hashidentrnd(void) |
5576 | +{ |
5577 | + get_random_bytes(&hashidentrnd, sizeof(hashidentrnd)); |
5578 | +} |
5579 | + |
5580 | +static u32 __ipv6_select_ident(const struct in6_addr *addr) |
5581 | +{ |
5582 | + u32 newid, oldid, hash = jhash2((u32 *)addr, 4, hashidentrnd); |
5583 | + u32 *pid = &ipv6_fragmentation_id[hash % FID_HASH_SZ]; |
5584 | + |
5585 | + do { |
5586 | + oldid = *pid; |
5587 | + newid = oldid + 1; |
5588 | + if (!(hash + newid)) |
5589 | + newid++; |
5590 | + } while (cmpxchg(pid, oldid, newid) != oldid); |
5591 | + |
5592 | + return hash + newid; |
5593 | +} |
5594 | + |
5595 | +void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) |
5596 | +{ |
5597 | + fhdr->identification = htonl(__ipv6_select_ident(&rt->rt6i_dst.addr)); |
5598 | +} |
5599 | + |
5600 | int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
5601 | { |
5602 | struct sk_buff *frag; |
5603 | @@ -680,7 +709,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
5604 | skb_reset_network_header(skb); |
5605 | memcpy(skb_network_header(skb), tmp_hdr, hlen); |
5606 | |
5607 | - ipv6_select_ident(fh); |
5608 | + ipv6_select_ident(fh, rt); |
5609 | fh->nexthdr = nexthdr; |
5610 | fh->reserved = 0; |
5611 | fh->frag_off = htons(IP6_MF); |
5612 | @@ -826,7 +855,7 @@ slow_path: |
5613 | fh->nexthdr = nexthdr; |
5614 | fh->reserved = 0; |
5615 | if (!frag_id) { |
5616 | - ipv6_select_ident(fh); |
5617 | + ipv6_select_ident(fh, rt); |
5618 | frag_id = fh->identification; |
5619 | } else |
5620 | fh->identification = frag_id; |
5621 | @@ -1072,7 +1101,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, |
5622 | int getfrag(void *from, char *to, int offset, int len, |
5623 | int odd, struct sk_buff *skb), |
5624 | void *from, int length, int hh_len, int fragheaderlen, |
5625 | - int transhdrlen, int mtu,unsigned int flags) |
5626 | + int transhdrlen, int mtu,unsigned int flags, |
5627 | + struct rt6_info *rt) |
5628 | |
5629 | { |
5630 | struct sk_buff *skb; |
5631 | @@ -1116,7 +1146,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, |
5632 | skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - |
5633 | sizeof(struct frag_hdr)) & ~7; |
5634 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; |
5635 | - ipv6_select_ident(&fhdr); |
5636 | + ipv6_select_ident(&fhdr, rt); |
5637 | skb_shinfo(skb)->ip6_frag_id = fhdr.identification; |
5638 | __skb_queue_tail(&sk->sk_write_queue, skb); |
5639 | |
5640 | @@ -1282,7 +1312,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, |
5641 | |
5642 | err = ip6_ufo_append_data(sk, getfrag, from, length, |
5643 | hh_len, fragheaderlen, |
5644 | - transhdrlen, mtu, flags); |
5645 | + transhdrlen, mtu, flags, rt); |
5646 | if (err) |
5647 | goto error; |
5648 | return 0; |
5649 | diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c |
5650 | index 87551ca..7c43e86 100644 |
5651 | --- a/net/ipv6/tcp_ipv6.c |
5652 | +++ b/net/ipv6/tcp_ipv6.c |
5653 | @@ -61,6 +61,7 @@ |
5654 | #include <net/timewait_sock.h> |
5655 | #include <net/netdma.h> |
5656 | #include <net/inet_common.h> |
5657 | +#include <net/secure_seq.h> |
5658 | |
5659 | #include <asm/uaccess.h> |
5660 | |
5661 | diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c |
5662 | index 328985c..29213b5 100644 |
5663 | --- a/net/ipv6/udp.c |
5664 | +++ b/net/ipv6/udp.c |
5665 | @@ -1359,7 +1359,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features) |
5666 | fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); |
5667 | fptr->nexthdr = nexthdr; |
5668 | fptr->reserved = 0; |
5669 | - ipv6_select_ident(fptr); |
5670 | + ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb)); |
5671 | |
5672 | /* Fragment the skb. ipv6 header and the remaining fields of the |
5673 | * fragment header are updated in ipv6_gso_segment() |
5674 | diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c |
5675 | index a8193f5..d2726a7 100644 |
5676 | --- a/net/l2tp/l2tp_eth.c |
5677 | +++ b/net/l2tp/l2tp_eth.c |
5678 | @@ -103,7 +103,7 @@ static struct net_device_ops l2tp_eth_netdev_ops = { |
5679 | static void l2tp_eth_dev_setup(struct net_device *dev) |
5680 | { |
5681 | ether_setup(dev); |
5682 | - |
5683 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
5684 | dev->netdev_ops = &l2tp_eth_netdev_ops; |
5685 | dev->destructor = free_netdev; |
5686 | } |
5687 | diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c |
5688 | index dee30ae..895eec1 100644 |
5689 | --- a/net/mac80211/iface.c |
5690 | +++ b/net/mac80211/iface.c |
5691 | @@ -699,6 +699,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { |
5692 | static void ieee80211_if_setup(struct net_device *dev) |
5693 | { |
5694 | ether_setup(dev); |
5695 | + dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
5696 | dev->netdev_ops = &ieee80211_dataif_ops; |
5697 | dev->destructor = free_netdev; |
5698 | } |
5699 | diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c |
5700 | index 699c79a..a178cb3 100644 |
5701 | --- a/net/netfilter/ipvs/ip_vs_ctl.c |
5702 | +++ b/net/netfilter/ipvs/ip_vs_ctl.c |
5703 | @@ -3771,6 +3771,7 @@ err_sock: |
5704 | void ip_vs_control_cleanup(void) |
5705 | { |
5706 | EnterFunction(2); |
5707 | + unregister_netdevice_notifier(&ip_vs_dst_notifier); |
5708 | ip_vs_genl_unregister(); |
5709 | nf_unregister_sockopt(&ip_vs_sockopts); |
5710 | LeaveFunction(2); |
5711 | diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c |
5712 | index b6ea6af..69400e3 100644 |
5713 | --- a/net/sched/sch_sfq.c |
5714 | +++ b/net/sched/sch_sfq.c |
5715 | @@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) |
5716 | /* Return Congestion Notification only if we dropped a packet |
5717 | * from this flow. |
5718 | */ |
5719 | - return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; |
5720 | + if (qlen != slot->qlen) |
5721 | + return NET_XMIT_CN; |
5722 | + |
5723 | + /* As we dropped a packet, better let upper stack know this */ |
5724 | + qdisc_tree_decrease_qlen(sch, 1); |
5725 | + return NET_XMIT_SUCCESS; |
5726 | } |
5727 | |
5728 | static struct sk_buff * |
5729 | diff --git a/net/socket.c b/net/socket.c |
5730 | index 02dc82d..ed46dbb 100644 |
5731 | --- a/net/socket.c |
5732 | +++ b/net/socket.c |
5733 | @@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) |
5734 | #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) |
5735 | #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) |
5736 | |
5737 | +struct used_address { |
5738 | + struct sockaddr_storage name; |
5739 | + unsigned int name_len; |
5740 | +}; |
5741 | + |
5742 | static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
5743 | - struct msghdr *msg_sys, unsigned flags, int nosec) |
5744 | + struct msghdr *msg_sys, unsigned flags, |
5745 | + struct used_address *used_address) |
5746 | { |
5747 | struct compat_msghdr __user *msg_compat = |
5748 | (struct compat_msghdr __user *)msg; |
5749 | @@ -1953,8 +1959,28 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
5750 | |
5751 | if (sock->file->f_flags & O_NONBLOCK) |
5752 | msg_sys->msg_flags |= MSG_DONTWAIT; |
5753 | - err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, |
5754 | - total_len); |
5755 | + /* |
5756 | + * If this is sendmmsg() and current destination address is same as |
5757 | + * previously succeeded address, omit asking LSM's decision. |
5758 | + * used_address->name_len is initialized to UINT_MAX so that the first |
5759 | + * destination address never matches. |
5760 | + */ |
5761 | + if (used_address && used_address->name_len == msg_sys->msg_namelen && |
5762 | + !memcmp(&used_address->name, msg->msg_name, |
5763 | + used_address->name_len)) { |
5764 | + err = sock_sendmsg_nosec(sock, msg_sys, total_len); |
5765 | + goto out_freectl; |
5766 | + } |
5767 | + err = sock_sendmsg(sock, msg_sys, total_len); |
5768 | + /* |
5769 | + * If this is sendmmsg() and sending to current destination address was |
5770 | + * successful, remember it. |
5771 | + */ |
5772 | + if (used_address && err >= 0) { |
5773 | + used_address->name_len = msg_sys->msg_namelen; |
5774 | + memcpy(&used_address->name, msg->msg_name, |
5775 | + used_address->name_len); |
5776 | + } |
5777 | |
5778 | out_freectl: |
5779 | if (ctl_buf != ctl) |
5780 | @@ -1979,7 +2005,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) |
5781 | if (!sock) |
5782 | goto out; |
5783 | |
5784 | - err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); |
5785 | + err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
5786 | |
5787 | fput_light(sock->file, fput_needed); |
5788 | out: |
5789 | @@ -1998,6 +2024,10 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
5790 | struct mmsghdr __user *entry; |
5791 | struct compat_mmsghdr __user *compat_entry; |
5792 | struct msghdr msg_sys; |
5793 | + struct used_address used_address; |
5794 | + |
5795 | + if (vlen > UIO_MAXIOV) |
5796 | + vlen = UIO_MAXIOV; |
5797 | |
5798 | datagrams = 0; |
5799 | |
5800 | @@ -2005,27 +2035,22 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
5801 | if (!sock) |
5802 | return err; |
5803 | |
5804 | - err = sock_error(sock->sk); |
5805 | - if (err) |
5806 | - goto out_put; |
5807 | - |
5808 | + used_address.name_len = UINT_MAX; |
5809 | entry = mmsg; |
5810 | compat_entry = (struct compat_mmsghdr __user *)mmsg; |
5811 | + err = 0; |
5812 | |
5813 | while (datagrams < vlen) { |
5814 | - /* |
5815 | - * No need to ask LSM for more than the first datagram. |
5816 | - */ |
5817 | if (MSG_CMSG_COMPAT & flags) { |
5818 | err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
5819 | - &msg_sys, flags, datagrams); |
5820 | + &msg_sys, flags, &used_address); |
5821 | if (err < 0) |
5822 | break; |
5823 | err = __put_user(err, &compat_entry->msg_len); |
5824 | ++compat_entry; |
5825 | } else { |
5826 | err = __sys_sendmsg(sock, (struct msghdr __user *)entry, |
5827 | - &msg_sys, flags, datagrams); |
5828 | + &msg_sys, flags, &used_address); |
5829 | if (err < 0) |
5830 | break; |
5831 | err = put_user(err, &entry->msg_len); |
5832 | @@ -2037,29 +2062,11 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
5833 | ++datagrams; |
5834 | } |
5835 | |
5836 | -out_put: |
5837 | fput_light(sock->file, fput_needed); |
5838 | |
5839 | - if (err == 0) |
5840 | - return datagrams; |
5841 | - |
5842 | - if (datagrams != 0) { |
5843 | - /* |
5844 | - * We may send less entries than requested (vlen) if the |
5845 | - * sock is non blocking... |
5846 | - */ |
5847 | - if (err != -EAGAIN) { |
5848 | - /* |
5849 | - * ... or if sendmsg returns an error after we |
5850 | - * send some datagrams, where we record the |
5851 | - * error to return on the next call or if the |
5852 | - * app asks about it using getsockopt(SO_ERROR). |
5853 | - */ |
5854 | - sock->sk->sk_err = -err; |
5855 | - } |
5856 | - |
5857 | + /* We only return an error if no datagrams were able to be sent */ |
5858 | + if (datagrams != 0) |
5859 | return datagrams; |
5860 | - } |
5861 | |
5862 | return err; |
5863 | } |
5864 | diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c |
5865 | index 58064d9..791ab2e 100644 |
5866 | --- a/net/xfrm/xfrm_algo.c |
5867 | +++ b/net/xfrm/xfrm_algo.c |
5868 | @@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = { |
5869 | .desc = { |
5870 | .sadb_alg_id = SADB_X_EALG_AESCTR, |
5871 | .sadb_alg_ivlen = 8, |
5872 | - .sadb_alg_minbits = 128, |
5873 | - .sadb_alg_maxbits = 256 |
5874 | + .sadb_alg_minbits = 160, |
5875 | + .sadb_alg_maxbits = 288 |
5876 | } |
5877 | }, |
5878 | }; |
5879 | diff --git a/sound/core/timer.c b/sound/core/timer.c |
5880 | index 7c1cbf0..950eed0 100644 |
5881 | --- a/sound/core/timer.c |
5882 | +++ b/sound/core/timer.c |
5883 | @@ -531,6 +531,8 @@ int snd_timer_stop(struct snd_timer_instance *timeri) |
5884 | if (err < 0) |
5885 | return err; |
5886 | timer = timeri->timer; |
5887 | + if (!timer) |
5888 | + return -EINVAL; |
5889 | spin_lock_irqsave(&timer->lock, flags); |
5890 | timeri->cticks = timeri->ticks; |
5891 | timeri->pticks = 0; |
5892 | diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c |
5893 | index ff29380..c49317c 100644 |
5894 | --- a/sound/soc/codecs/sgtl5000.c |
5895 | +++ b/sound/soc/codecs/sgtl5000.c |
5896 | @@ -33,73 +33,31 @@ |
5897 | #define SGTL5000_DAP_REG_OFFSET 0x0100 |
5898 | #define SGTL5000_MAX_REG_OFFSET 0x013A |
5899 | |
5900 | -/* default value of sgtl5000 registers except DAP */ |
5901 | -static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = { |
5902 | - 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */ |
5903 | - 0x0000, /* 0x0002, CHIP_DIG_POWER. */ |
5904 | - 0x0008, /* 0x0004, CHIP_CKL_CTRL */ |
5905 | - 0x0010, /* 0x0006, CHIP_I2S_CTRL */ |
5906 | - 0x0000, /* 0x0008, reserved */ |
5907 | - 0x0008, /* 0x000A, CHIP_SSS_CTRL */ |
5908 | - 0x0000, /* 0x000C, reserved */ |
5909 | - 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */ |
5910 | - 0x3c3c, /* 0x0010, CHIP_DAC_VOL */ |
5911 | - 0x0000, /* 0x0012, reserved */ |
5912 | - 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */ |
5913 | - 0x0000, /* 0x0016, reserved */ |
5914 | - 0x0000, /* 0x0018, reserved */ |
5915 | - 0x0000, /* 0x001A, reserved */ |
5916 | - 0x0000, /* 0x001E, reserved */ |
5917 | - 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */ |
5918 | - 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */ |
5919 | - 0x0111, /* 0x0024, CHIP_ANN_CTRL */ |
5920 | - 0x0000, /* 0x0026, CHIP_LINREG_CTRL */ |
5921 | - 0x0000, /* 0x0028, CHIP_REF_CTRL */ |
5922 | - 0x0000, /* 0x002A, CHIP_MIC_CTRL */ |
5923 | - 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */ |
5924 | - 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */ |
5925 | - 0x7060, /* 0x0030, CHIP_ANA_POWER */ |
5926 | - 0x5000, /* 0x0032, CHIP_PLL_CTRL */ |
5927 | - 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */ |
5928 | - 0x0000, /* 0x0036, CHIP_ANA_STATUS */ |
5929 | - 0x0000, /* 0x0038, reserved */ |
5930 | - 0x0000, /* 0x003A, CHIP_ANA_TEST2 */ |
5931 | - 0x0000, /* 0x003C, CHIP_SHORT_CTRL */ |
5932 | - 0x0000, /* reserved */ |
5933 | -}; |
5934 | - |
5935 | -/* default value of dap registers */ |
5936 | -static const u16 sgtl5000_dap_regs[] = { |
5937 | - 0x0000, /* 0x0100, DAP_CONTROL */ |
5938 | - 0x0000, /* 0x0102, DAP_PEQ */ |
5939 | - 0x0040, /* 0x0104, DAP_BASS_ENHANCE */ |
5940 | - 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */ |
5941 | - 0x0000, /* 0x0108, DAP_AUDIO_EQ */ |
5942 | - 0x0040, /* 0x010A, DAP_SGTL_SURROUND */ |
5943 | - 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */ |
5944 | - 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */ |
5945 | - 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */ |
5946 | - 0x0000, /* 0x0112, reserved */ |
5947 | - 0x0000, /* 0x0114, reserved */ |
5948 | - 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */ |
5949 | - 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */ |
5950 | - 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */ |
5951 | - 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */ |
5952 | - 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */ |
5953 | - 0x8000, /* 0x0120, DAP_MAIN_CHAN */ |
5954 | - 0x0000, /* 0x0122, DAP_MIX_CHAN */ |
5955 | - 0x0510, /* 0x0124, DAP_AVC_CTRL */ |
5956 | - 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */ |
5957 | - 0x0028, /* 0x0128, DAP_AVC_ATTACK */ |
5958 | - 0x0050, /* 0x012A, DAP_AVC_DECAY */ |
5959 | - 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */ |
5960 | - 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */ |
5961 | - 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */ |
5962 | - 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */ |
5963 | - 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */ |
5964 | - 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */ |
5965 | - 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */ |
5966 | - 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */ |
5967 | +/* default value of sgtl5000 registers */ |
5968 | +static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = { |
5969 | + [SGTL5000_CHIP_CLK_CTRL] = 0x0008, |
5970 | + [SGTL5000_CHIP_I2S_CTRL] = 0x0010, |
5971 | + [SGTL5000_CHIP_SSS_CTRL] = 0x0008, |
5972 | + [SGTL5000_CHIP_DAC_VOL] = 0x3c3c, |
5973 | + [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f, |
5974 | + [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818, |
5975 | + [SGTL5000_CHIP_ANA_CTRL] = 0x0111, |
5976 | + [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404, |
5977 | + [SGTL5000_CHIP_ANA_POWER] = 0x7060, |
5978 | + [SGTL5000_CHIP_PLL_CTRL] = 0x5000, |
5979 | + [SGTL5000_DAP_BASS_ENHANCE] = 0x0040, |
5980 | + [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f, |
5981 | + [SGTL5000_DAP_SURROUND] = 0x0040, |
5982 | + [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f, |
5983 | + [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f, |
5984 | + [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f, |
5985 | + [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f, |
5986 | + [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f, |
5987 | + [SGTL5000_DAP_MAIN_CHAN] = 0x8000, |
5988 | + [SGTL5000_DAP_AVC_CTRL] = 0x0510, |
5989 | + [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473, |
5990 | + [SGTL5000_DAP_AVC_ATTACK] = 0x0028, |
5991 | + [SGTL5000_DAP_AVC_DECAY] = 0x0050, |
5992 | }; |
5993 | |
5994 | /* regulator supplies for sgtl5000, VDDD is an optional external supply */ |
5995 | @@ -1022,12 +980,10 @@ static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state) |
5996 | static int sgtl5000_restore_regs(struct snd_soc_codec *codec) |
5997 | { |
5998 | u16 *cache = codec->reg_cache; |
5999 | - int i; |
6000 | - int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1; |
6001 | + u16 reg; |
6002 | |
6003 | /* restore regular registers */ |
6004 | - for (i = 0; i < regular_regs; i++) { |
6005 | - int reg = i << 1; |
6006 | + for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { |
6007 | |
6008 | /* this regs depends on the others */ |
6009 | if (reg == SGTL5000_CHIP_ANA_POWER || |
6010 | @@ -1037,35 +993,31 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) |
6011 | reg == SGTL5000_CHIP_CLK_CTRL) |
6012 | continue; |
6013 | |
6014 | - snd_soc_write(codec, reg, cache[i]); |
6015 | + snd_soc_write(codec, reg, cache[reg]); |
6016 | } |
6017 | |
6018 | /* restore dap registers */ |
6019 | - for (i = SGTL5000_DAP_REG_OFFSET >> 1; |
6020 | - i < SGTL5000_MAX_REG_OFFSET >> 1; i++) { |
6021 | - int reg = i << 1; |
6022 | - |
6023 | - snd_soc_write(codec, reg, cache[i]); |
6024 | - } |
6025 | + for (reg = SGTL5000_DAP_REG_OFFSET; reg < SGTL5000_MAX_REG_OFFSET; reg += 2) |
6026 | + snd_soc_write(codec, reg, cache[reg]); |
6027 | |
6028 | /* |
6029 | * restore power and other regs according |
6030 | * to set_power() and set_clock() |
6031 | */ |
6032 | snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, |
6033 | - cache[SGTL5000_CHIP_LINREG_CTRL >> 1]); |
6034 | + cache[SGTL5000_CHIP_LINREG_CTRL]); |
6035 | |
6036 | snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, |
6037 | - cache[SGTL5000_CHIP_ANA_POWER >> 1]); |
6038 | + cache[SGTL5000_CHIP_ANA_POWER]); |
6039 | |
6040 | snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, |
6041 | - cache[SGTL5000_CHIP_CLK_CTRL >> 1]); |
6042 | + cache[SGTL5000_CHIP_CLK_CTRL]); |
6043 | |
6044 | snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL, |
6045 | - cache[SGTL5000_CHIP_REF_CTRL >> 1]); |
6046 | + cache[SGTL5000_CHIP_REF_CTRL]); |
6047 | |
6048 | snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL, |
6049 | - cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]); |
6050 | + cache[SGTL5000_CHIP_LINE_OUT_CTRL]); |
6051 | return 0; |
6052 | } |
6053 | |
6054 | @@ -1460,16 +1412,6 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, |
6055 | if (!sgtl5000) |
6056 | return -ENOMEM; |
6057 | |
6058 | - /* |
6059 | - * copy DAP default values to default value array. |
6060 | - * sgtl5000 register space has a big hole, merge it |
6061 | - * at init phase makes life easy. |
6062 | - * FIXME: should we drop 'const' of sgtl5000_regs? |
6063 | - */ |
6064 | - memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)), |
6065 | - sgtl5000_dap_regs, |
6066 | - SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET); |
6067 | - |
6068 | i2c_set_clientdata(client, sgtl5000); |
6069 | |
6070 | ret = snd_soc_register_codec(&client->dev, |
6071 | diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c |
6072 | index 4432ef7..a213813 100644 |
6073 | --- a/sound/usb/caiaq/input.c |
6074 | +++ b/sound/usb/caiaq/input.c |
6075 | @@ -30,7 +30,7 @@ static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; |
6076 | static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, |
6077 | KEY_5, KEY_6, KEY_7 }; |
6078 | static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, |
6079 | - KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; |
6080 | + KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 }; |
6081 | |
6082 | static unsigned short keycode_kore[] = { |
6083 | KEY_FN_F1, /* "menu" */ |
6084 | diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c |
6085 | index b0ef9f5..05842c8 100644 |
6086 | --- a/sound/usb/endpoint.c |
6087 | +++ b/sound/usb/endpoint.c |
6088 | @@ -352,7 +352,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) |
6089 | continue; |
6090 | } |
6091 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || |
6092 | - ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) { |
6093 | + ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { |
6094 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", |
6095 | dev->devnum, iface_no, altno); |
6096 | continue; |
6097 | diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
6098 | index c22fa76..c04d7c7 100644 |
6099 | --- a/sound/usb/mixer.c |
6100 | +++ b/sound/usb/mixer.c |
6101 | @@ -1191,6 +1191,11 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void |
6102 | |
6103 | if (state->mixer->protocol == UAC_VERSION_1) { |
6104 | csize = hdr->bControlSize; |
6105 | + if (!csize) { |
6106 | + snd_printdd(KERN_ERR "usbaudio: unit %u: " |
6107 | + "invalid bControlSize == 0\n", unitid); |
6108 | + return -EINVAL; |
6109 | + } |
6110 | channels = (hdr->bLength - 7) / csize - 1; |
6111 | bmaControls = hdr->bmaControls; |
6112 | } else { |
6113 | @@ -1934,15 +1939,13 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) |
6114 | struct mixer_build state; |
6115 | int err; |
6116 | const struct usbmix_ctl_map *map; |
6117 | - struct usb_host_interface *hostif; |
6118 | void *p; |
6119 | |
6120 | - hostif = mixer->chip->ctrl_intf; |
6121 | memset(&state, 0, sizeof(state)); |
6122 | state.chip = mixer->chip; |
6123 | state.mixer = mixer; |
6124 | - state.buffer = hostif->extra; |
6125 | - state.buflen = hostif->extralen; |
6126 | + state.buffer = mixer->hostif->extra; |
6127 | + state.buflen = mixer->hostif->extralen; |
6128 | |
6129 | /* check the mapping table */ |
6130 | for (map = usbmix_ctl_maps; map->id; map++) { |
6131 | @@ -1955,7 +1958,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) |
6132 | } |
6133 | |
6134 | p = NULL; |
6135 | - while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) { |
6136 | + while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen, |
6137 | + p, UAC_OUTPUT_TERMINAL)) != NULL) { |
6138 | if (mixer->protocol == UAC_VERSION_1) { |
6139 | struct uac1_output_terminal_descriptor *desc = p; |
6140 | |
6141 | @@ -2162,17 +2166,15 @@ int snd_usb_mixer_activate(struct usb_mixer_interface *mixer) |
6142 | /* create the handler for the optional status interrupt endpoint */ |
6143 | static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) |
6144 | { |
6145 | - struct usb_host_interface *hostif; |
6146 | struct usb_endpoint_descriptor *ep; |
6147 | void *transfer_buffer; |
6148 | int buffer_length; |
6149 | unsigned int epnum; |
6150 | |
6151 | - hostif = mixer->chip->ctrl_intf; |
6152 | /* we need one interrupt input endpoint */ |
6153 | - if (get_iface_desc(hostif)->bNumEndpoints < 1) |
6154 | + if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1) |
6155 | return 0; |
6156 | - ep = get_endpoint(hostif, 0); |
6157 | + ep = get_endpoint(mixer->hostif, 0); |
6158 | if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep)) |
6159 | return 0; |
6160 | |
6161 | @@ -2202,7 +2204,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, |
6162 | }; |
6163 | struct usb_mixer_interface *mixer; |
6164 | struct snd_info_entry *entry; |
6165 | - struct usb_host_interface *host_iface; |
6166 | int err; |
6167 | |
6168 | strcpy(chip->card->mixername, "USB Mixer"); |
6169 | @@ -2219,8 +2220,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, |
6170 | return -ENOMEM; |
6171 | } |
6172 | |
6173 | - host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; |
6174 | - switch (get_iface_desc(host_iface)->bInterfaceProtocol) { |
6175 | + mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; |
6176 | + switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) { |
6177 | case UAC_VERSION_1: |
6178 | default: |
6179 | mixer->protocol = UAC_VERSION_1; |
6180 | diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h |
6181 | index ae1a14d..81b2d8a 100644 |
6182 | --- a/sound/usb/mixer.h |
6183 | +++ b/sound/usb/mixer.h |
6184 | @@ -3,6 +3,7 @@ |
6185 | |
6186 | struct usb_mixer_interface { |
6187 | struct snd_usb_audio *chip; |
6188 | + struct usb_host_interface *hostif; |
6189 | struct list_head list; |
6190 | unsigned int ignore_ctl_error; |
6191 | struct urb *urb; |