Annotation of /trunk/kernel-mcore/patches-3.0-r1/0101-3.0.2-all-fixes.patch
Parent Directory | Revision Log
Revision 1542 -
(hide annotations)
(download)
Thu Sep 29 11:51:27 2011 UTC (13 years ago) by niro
File size: 200534 byte(s)
Thu Sep 29 11:51:27 2011 UTC (13 years ago) by niro
File size: 200534 byte(s)
3.0-mcore-r1
1 | niro | 1542 | 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; |