1 |
Author: mpagano |
2 |
Date: 2011-08-29 15:03:18 +0000 (Mon, 29 Aug 2011) |
3 |
New Revision: 1968 |
4 |
|
5 |
Removed: |
6 |
genpatches-2.6/trunk/3.1/1000_linux-3.0.1.patch |
7 |
genpatches-2.6/trunk/3.1/1001_linux-3.0.2.patch |
8 |
genpatches-2.6/trunk/3.1/1002_linux-3.0.3.patch |
9 |
genpatches-2.6/trunk/3.1/1800_fix-zcache-build.patch |
10 |
Modified: |
11 |
genpatches-2.6/trunk/3.1/0000_README |
12 |
Log: |
13 |
Get 3.1 genpatches ready for new release |
14 |
|
15 |
Modified: genpatches-2.6/trunk/3.1/0000_README |
16 |
=================================================================== |
17 |
--- genpatches-2.6/trunk/3.1/0000_README 2011-08-29 15:02:13 UTC (rev 1967) |
18 |
+++ genpatches-2.6/trunk/3.1/0000_README 2011-08-29 15:03:18 UTC (rev 1968) |
19 |
@@ -39,22 +39,6 @@ |
20 |
Individual Patch Descriptions: |
21 |
-------------------------------------------------------------------------- |
22 |
|
23 |
-Patch: 1000_linux-3.0.1.patch |
24 |
-From: http://www.kernel.org |
25 |
-Desc: Linux 3.0.1 |
26 |
- |
27 |
-Patch: 1001_linux-3.0.2.patch |
28 |
-From: http://www.kernel.org |
29 |
-Desc: Linux 3.0.2 |
30 |
- |
31 |
-Patch: 1002_linux-3.0.3.patch |
32 |
-From: http://www.kernel.org |
33 |
-Desc: Linux 3.0.3 |
34 |
- |
35 |
-Patch: 1800_fix-zcache-build.patch |
36 |
-From: http://bugs.gentoo.org/show_bug.cgi?id=376325 |
37 |
-Desc: Fix zcache build error |
38 |
- |
39 |
Patch: 4200_fbcondecor-0.9.6.patch |
40 |
From: http://dev.gentoo.org/~spock |
41 |
Desc: Bootsplash successor by Michal Januszewski ported by Alexxy |
42 |
|
43 |
Deleted: genpatches-2.6/trunk/3.1/1000_linux-3.0.1.patch |
44 |
=================================================================== |
45 |
--- genpatches-2.6/trunk/3.1/1000_linux-3.0.1.patch 2011-08-29 15:02:13 UTC (rev 1967) |
46 |
+++ genpatches-2.6/trunk/3.1/1000_linux-3.0.1.patch 2011-08-29 15:03:18 UTC (rev 1968) |
47 |
@@ -1,3665 +0,0 @@ |
48 |
-diff --git a/Makefile b/Makefile |
49 |
-index 6a5bdad..f124b18 100644 |
50 |
---- a/Makefile |
51 |
-+++ b/Makefile |
52 |
-@@ -1,6 +1,6 @@ |
53 |
- VERSION = 3 |
54 |
- PATCHLEVEL = 0 |
55 |
--SUBLEVEL = 0 |
56 |
-+SUBLEVEL = 1 |
57 |
- EXTRAVERSION = |
58 |
- NAME = Sneaky Weasel |
59 |
- |
60 |
-diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c |
61 |
-index 818e74e..f20d1b5 100644 |
62 |
---- a/arch/alpha/kernel/time.c |
63 |
-+++ b/arch/alpha/kernel/time.c |
64 |
-@@ -91,7 +91,7 @@ DEFINE_PER_CPU(u8, irq_work_pending); |
65 |
- #define test_irq_work_pending() __get_cpu_var(irq_work_pending) |
66 |
- #define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0 |
67 |
- |
68 |
--void set_irq_work_pending(void) |
69 |
-+void arch_irq_work_raise(void) |
70 |
- { |
71 |
- set_irq_work_pending_flag(); |
72 |
- } |
73 |
-diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c |
74 |
-index b2248e7..8a03487 100644 |
75 |
---- a/arch/arm/mach-pxa/cm-x300.c |
76 |
-+++ b/arch/arm/mach-pxa/cm-x300.c |
77 |
-@@ -161,10 +161,10 @@ static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = { |
78 |
- GPIO99_GPIO, /* Ethernet IRQ */ |
79 |
- |
80 |
- /* RTC GPIOs */ |
81 |
-- GPIO95_GPIO, /* RTC CS */ |
82 |
-- GPIO96_GPIO, /* RTC WR */ |
83 |
-- GPIO97_GPIO, /* RTC RD */ |
84 |
-- GPIO98_GPIO, /* RTC IO */ |
85 |
-+ GPIO95_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC CS */ |
86 |
-+ GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC WR */ |
87 |
-+ GPIO97_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC RD */ |
88 |
-+ GPIO98_GPIO, /* RTC IO */ |
89 |
- |
90 |
- /* Standard I2C */ |
91 |
- GPIO21_I2C_SCL, |
92 |
-diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c |
93 |
-index 4e6ee94..cc6a9d5 100644 |
94 |
---- a/arch/powerpc/kernel/crash.c |
95 |
-+++ b/arch/powerpc/kernel/crash.c |
96 |
-@@ -242,12 +242,8 @@ static void crash_kexec_wait_realmode(int cpu) |
97 |
- |
98 |
- while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { |
99 |
- barrier(); |
100 |
-- if (!cpu_possible(i)) { |
101 |
-+ if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0)) |
102 |
- break; |
103 |
-- } |
104 |
-- if (!cpu_online(i)) { |
105 |
-- break; |
106 |
-- } |
107 |
- msecs--; |
108 |
- mdelay(1); |
109 |
- } |
110 |
-diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c |
111 |
-index f33acfd..03b29a6 100644 |
112 |
---- a/arch/powerpc/kernel/time.c |
113 |
-+++ b/arch/powerpc/kernel/time.c |
114 |
-@@ -544,7 +544,7 @@ DEFINE_PER_CPU(u8, irq_work_pending); |
115 |
- |
116 |
- #endif /* 32 vs 64 bit */ |
117 |
- |
118 |
--void set_irq_work_pending(void) |
119 |
-+void arch_irq_work_raise(void) |
120 |
- { |
121 |
- preempt_disable(); |
122 |
- set_irq_work_pending_flag(); |
123 |
-diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c |
124 |
-index 3f6a89b..041e87c 100644 |
125 |
---- a/arch/powerpc/platforms/pseries/hvconsole.c |
126 |
-+++ b/arch/powerpc/platforms/pseries/hvconsole.c |
127 |
-@@ -73,7 +73,7 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count) |
128 |
- if (ret == H_SUCCESS) |
129 |
- return count; |
130 |
- if (ret == H_BUSY) |
131 |
-- return 0; |
132 |
-+ return -EAGAIN; |
133 |
- return -EIO; |
134 |
- } |
135 |
- |
136 |
-diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h |
137 |
-index 485b4f1..23a9d89 100644 |
138 |
---- a/arch/x86/include/asm/msr-index.h |
139 |
-+++ b/arch/x86/include/asm/msr-index.h |
140 |
-@@ -259,6 +259,9 @@ |
141 |
- #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 |
142 |
- |
143 |
- #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 |
144 |
-+#define ENERGY_PERF_BIAS_PERFORMANCE 0 |
145 |
-+#define ENERGY_PERF_BIAS_NORMAL 6 |
146 |
-+#define ENERGY_PERF_BIAS_POWERSWAVE 15 |
147 |
- |
148 |
- #define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1 |
149 |
- |
150 |
-diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c |
151 |
-index 1edf5ba..da0d779 100644 |
152 |
---- a/arch/x86/kernel/cpu/intel.c |
153 |
-+++ b/arch/x86/kernel/cpu/intel.c |
154 |
-@@ -456,6 +456,24 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) |
155 |
- |
156 |
- if (cpu_has(c, X86_FEATURE_VMX)) |
157 |
- detect_vmx_virtcap(c); |
158 |
-+ |
159 |
-+ /* |
160 |
-+ * Initialize MSR_IA32_ENERGY_PERF_BIAS if BIOS did not. |
161 |
-+ * x86_energy_perf_policy(8) is available to change it at run-time |
162 |
-+ */ |
163 |
-+ if (cpu_has(c, X86_FEATURE_EPB)) { |
164 |
-+ u64 epb; |
165 |
-+ |
166 |
-+ rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); |
167 |
-+ if ((epb & 0xF) == 0) { |
168 |
-+ printk_once(KERN_WARNING, "x86: updated energy_perf_bias" |
169 |
-+ " to 'normal' from 'performance'\n" |
170 |
-+ "You can view and update epb via utility," |
171 |
-+ " such as x86_energy_perf_policy(8)\n"); |
172 |
-+ epb = (epb & ~0xF) | ENERGY_PERF_BIAS_NORMAL; |
173 |
-+ wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); |
174 |
-+ } |
175 |
-+ } |
176 |
- } |
177 |
- |
178 |
- #ifdef CONFIG_X86_32 |
179 |
-diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S |
180 |
-index 4123553..36818f8 100644 |
181 |
---- a/arch/x86/kernel/relocate_kernel_32.S |
182 |
-+++ b/arch/x86/kernel/relocate_kernel_32.S |
183 |
-@@ -97,6 +97,8 @@ relocate_kernel: |
184 |
- ret |
185 |
- |
186 |
- identity_mapped: |
187 |
-+ /* set return address to 0 if not preserving context */ |
188 |
-+ pushl $0 |
189 |
- /* store the start address on the stack */ |
190 |
- pushl %edx |
191 |
- |
192 |
-diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S |
193 |
-index 4de8f5b..7a6f3b3 100644 |
194 |
---- a/arch/x86/kernel/relocate_kernel_64.S |
195 |
-+++ b/arch/x86/kernel/relocate_kernel_64.S |
196 |
-@@ -100,6 +100,8 @@ relocate_kernel: |
197 |
- ret |
198 |
- |
199 |
- identity_mapped: |
200 |
-+ /* set return address to 0 if not preserving context */ |
201 |
-+ pushq $0 |
202 |
- /* store the start address on the stack */ |
203 |
- pushq %rdx |
204 |
- |
205 |
-diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c |
206 |
-index a5b64ab..32f78eb 100644 |
207 |
---- a/arch/x86/oprofile/backtrace.c |
208 |
-+++ b/arch/x86/oprofile/backtrace.c |
209 |
-@@ -11,10 +11,12 @@ |
210 |
- #include <linux/oprofile.h> |
211 |
- #include <linux/sched.h> |
212 |
- #include <linux/mm.h> |
213 |
-+#include <linux/compat.h> |
214 |
-+#include <linux/highmem.h> |
215 |
-+ |
216 |
- #include <asm/ptrace.h> |
217 |
- #include <asm/uaccess.h> |
218 |
- #include <asm/stacktrace.h> |
219 |
--#include <linux/compat.h> |
220 |
- |
221 |
- static int backtrace_stack(void *data, char *name) |
222 |
- { |
223 |
-@@ -36,17 +38,53 @@ static struct stacktrace_ops backtrace_ops = { |
224 |
- .walk_stack = print_context_stack, |
225 |
- }; |
226 |
- |
227 |
-+/* from arch/x86/kernel/cpu/perf_event.c: */ |
228 |
-+ |
229 |
-+/* |
230 |
-+ * best effort, GUP based copy_from_user() that assumes IRQ or NMI context |
231 |
-+ */ |
232 |
-+static unsigned long |
233 |
-+copy_from_user_nmi(void *to, const void __user *from, unsigned long n) |
234 |
-+{ |
235 |
-+ unsigned long offset, addr = (unsigned long)from; |
236 |
-+ unsigned long size, len = 0; |
237 |
-+ struct page *page; |
238 |
-+ void *map; |
239 |
-+ int ret; |
240 |
-+ |
241 |
-+ do { |
242 |
-+ ret = __get_user_pages_fast(addr, 1, 0, &page); |
243 |
-+ if (!ret) |
244 |
-+ break; |
245 |
-+ |
246 |
-+ offset = addr & (PAGE_SIZE - 1); |
247 |
-+ size = min(PAGE_SIZE - offset, n - len); |
248 |
-+ |
249 |
-+ map = kmap_atomic(page); |
250 |
-+ memcpy(to, map+offset, size); |
251 |
-+ kunmap_atomic(map); |
252 |
-+ put_page(page); |
253 |
-+ |
254 |
-+ len += size; |
255 |
-+ to += size; |
256 |
-+ addr += size; |
257 |
-+ |
258 |
-+ } while (len < n); |
259 |
-+ |
260 |
-+ return len; |
261 |
-+} |
262 |
-+ |
263 |
- #ifdef CONFIG_COMPAT |
264 |
- static struct stack_frame_ia32 * |
265 |
- dump_user_backtrace_32(struct stack_frame_ia32 *head) |
266 |
- { |
267 |
-+ /* Also check accessibility of one struct frame_head beyond: */ |
268 |
- struct stack_frame_ia32 bufhead[2]; |
269 |
- struct stack_frame_ia32 *fp; |
270 |
-+ unsigned long bytes; |
271 |
- |
272 |
-- /* Also check accessibility of one struct frame_head beyond */ |
273 |
-- if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) |
274 |
-- return NULL; |
275 |
-- if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) |
276 |
-+ bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); |
277 |
-+ if (bytes != sizeof(bufhead)) |
278 |
- return NULL; |
279 |
- |
280 |
- fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame); |
281 |
-@@ -87,12 +125,12 @@ x86_backtrace_32(struct pt_regs * const regs, unsigned int depth) |
282 |
- |
283 |
- static struct stack_frame *dump_user_backtrace(struct stack_frame *head) |
284 |
- { |
285 |
-+ /* Also check accessibility of one struct frame_head beyond: */ |
286 |
- struct stack_frame bufhead[2]; |
287 |
-+ unsigned long bytes; |
288 |
- |
289 |
-- /* Also check accessibility of one struct stack_frame beyond */ |
290 |
-- if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) |
291 |
-- return NULL; |
292 |
-- if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) |
293 |
-+ bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead)); |
294 |
-+ if (bytes != sizeof(bufhead)) |
295 |
- return NULL; |
296 |
- |
297 |
- oprofile_add_trace(bufhead[0].return_address); |
298 |
-diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c |
299 |
-index c72c947..a0d042a 100644 |
300 |
---- a/arch/xtensa/kernel/ptrace.c |
301 |
-+++ b/arch/xtensa/kernel/ptrace.c |
302 |
-@@ -147,6 +147,9 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs) |
303 |
- elf_xtregs_t *xtregs = uregs; |
304 |
- int ret = 0; |
305 |
- |
306 |
-+ if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t))) |
307 |
-+ return -EFAULT; |
308 |
-+ |
309 |
- #if XTENSA_HAVE_COPROCESSORS |
310 |
- /* Flush all coprocessors before we overwrite them. */ |
311 |
- coprocessor_flush_all(ti); |
312 |
-diff --git a/block/blk-core.c b/block/blk-core.c |
313 |
-index d2f8f40..1d49e1c 100644 |
314 |
---- a/block/blk-core.c |
315 |
-+++ b/block/blk-core.c |
316 |
-@@ -839,6 +839,9 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask) |
317 |
- { |
318 |
- struct request *rq; |
319 |
- |
320 |
-+ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) |
321 |
-+ return NULL; |
322 |
-+ |
323 |
- BUG_ON(rw != READ && rw != WRITE); |
324 |
- |
325 |
- spin_lock_irq(q->queue_lock); |
326 |
-diff --git a/block/blk-exec.c b/block/blk-exec.c |
327 |
-index 8a0e7ec..a1ebceb 100644 |
328 |
---- a/block/blk-exec.c |
329 |
-+++ b/block/blk-exec.c |
330 |
-@@ -50,6 +50,13 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, |
331 |
- { |
332 |
- int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; |
333 |
- |
334 |
-+ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { |
335 |
-+ rq->errors = -ENXIO; |
336 |
-+ if (rq->end_io) |
337 |
-+ rq->end_io(rq, rq->errors); |
338 |
-+ return; |
339 |
-+ } |
340 |
-+ |
341 |
- rq->rq_disk = bd_disk; |
342 |
- rq->end_io = done; |
343 |
- WARN_ON(irqs_disabled()); |
344 |
-diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h |
345 |
-index 16b4d58..c049548 100644 |
346 |
---- a/drivers/block/cciss.h |
347 |
-+++ b/drivers/block/cciss.h |
348 |
-@@ -223,7 +223,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) |
349 |
- h->ctlr, c->busaddr); |
350 |
- #endif /* CCISS_DEBUG */ |
351 |
- writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); |
352 |
-- readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); |
353 |
-+ readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); |
354 |
- h->commands_outstanding++; |
355 |
- if ( h->commands_outstanding > h->max_outstanding) |
356 |
- h->max_outstanding = h->commands_outstanding; |
357 |
-diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c |
358 |
-index b1c1177..e6ad3bb 100644 |
359 |
---- a/drivers/firewire/core-cdev.c |
360 |
-+++ b/drivers/firewire/core-cdev.c |
361 |
-@@ -253,14 +253,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file) |
362 |
- init_waitqueue_head(&client->wait); |
363 |
- init_waitqueue_head(&client->tx_flush_wait); |
364 |
- INIT_LIST_HEAD(&client->phy_receiver_link); |
365 |
-+ INIT_LIST_HEAD(&client->link); |
366 |
- kref_init(&client->kref); |
367 |
- |
368 |
- file->private_data = client; |
369 |
- |
370 |
-- mutex_lock(&device->client_list_mutex); |
371 |
-- list_add_tail(&client->link, &device->client_list); |
372 |
-- mutex_unlock(&device->client_list_mutex); |
373 |
-- |
374 |
- return nonseekable_open(inode, file); |
375 |
- } |
376 |
- |
377 |
-@@ -451,15 +448,20 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg) |
378 |
- if (ret != 0) |
379 |
- return -EFAULT; |
380 |
- |
381 |
-+ mutex_lock(&client->device->client_list_mutex); |
382 |
-+ |
383 |
- client->bus_reset_closure = a->bus_reset_closure; |
384 |
- if (a->bus_reset != 0) { |
385 |
- fill_bus_reset_event(&bus_reset, client); |
386 |
-- if (copy_to_user(u64_to_uptr(a->bus_reset), |
387 |
-- &bus_reset, sizeof(bus_reset))) |
388 |
-- return -EFAULT; |
389 |
-+ ret = copy_to_user(u64_to_uptr(a->bus_reset), |
390 |
-+ &bus_reset, sizeof(bus_reset)); |
391 |
- } |
392 |
-+ if (ret == 0 && list_empty(&client->link)) |
393 |
-+ list_add_tail(&client->link, &client->device->client_list); |
394 |
- |
395 |
-- return 0; |
396 |
-+ mutex_unlock(&client->device->client_list_mutex); |
397 |
-+ |
398 |
-+ return ret ? -EFAULT : 0; |
399 |
- } |
400 |
- |
401 |
- static int add_client_resource(struct client *client, |
402 |
-@@ -1583,7 +1585,7 @@ static int dispatch_ioctl(struct client *client, |
403 |
- if (_IOC_TYPE(cmd) != '#' || |
404 |
- _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) || |
405 |
- _IOC_SIZE(cmd) > sizeof(buffer)) |
406 |
-- return -EINVAL; |
407 |
-+ return -ENOTTY; |
408 |
- |
409 |
- if (_IOC_DIR(cmd) == _IOC_READ) |
410 |
- memset(&buffer, 0, _IOC_SIZE(cmd)); |
411 |
-diff --git a/drivers/firmware/sigma.c b/drivers/firmware/sigma.c |
412 |
-index c19cd2c..f10fc52 100644 |
413 |
---- a/drivers/firmware/sigma.c |
414 |
-+++ b/drivers/firmware/sigma.c |
415 |
-@@ -11,6 +11,7 @@ |
416 |
- #include <linux/firmware.h> |
417 |
- #include <linux/kernel.h> |
418 |
- #include <linux/i2c.h> |
419 |
-+#include <linux/module.h> |
420 |
- #include <linux/sigma.h> |
421 |
- |
422 |
- /* Return: 0==OK, <0==error, =1 ==no more actions */ |
423 |
-@@ -113,3 +114,5 @@ int process_sigma_firmware(struct i2c_client *client, const char *name) |
424 |
- return ret; |
425 |
- } |
426 |
- EXPORT_SYMBOL(process_sigma_firmware); |
427 |
-+ |
428 |
-+MODULE_LICENSE("GPL"); |
429 |
-diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c |
430 |
-index 8c0f9e3..645b84b 100644 |
431 |
---- a/drivers/gpu/drm/radeon/atombios_dp.c |
432 |
-+++ b/drivers/gpu/drm/radeon/atombios_dp.c |
433 |
-@@ -627,6 +627,7 @@ struct radeon_dp_link_train_info { |
434 |
- u8 train_set[4]; |
435 |
- u8 link_status[DP_LINK_STATUS_SIZE]; |
436 |
- u8 tries; |
437 |
-+ bool use_dpencoder; |
438 |
- }; |
439 |
- |
440 |
- static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) |
441 |
-@@ -646,7 +647,7 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) |
442 |
- int rtp = 0; |
443 |
- |
444 |
- /* set training pattern on the source */ |
445 |
-- if (ASIC_IS_DCE4(dp_info->rdev)) { |
446 |
-+ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) { |
447 |
- switch (tp) { |
448 |
- case DP_TRAINING_PATTERN_1: |
449 |
- rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1; |
450 |
-@@ -706,7 +707,7 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) |
451 |
- radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); |
452 |
- |
453 |
- /* start training on the source */ |
454 |
-- if (ASIC_IS_DCE4(dp_info->rdev)) |
455 |
-+ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) |
456 |
- atombios_dig_encoder_setup(dp_info->encoder, |
457 |
- ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); |
458 |
- else |
459 |
-@@ -731,7 +732,7 @@ static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info |
460 |
- DP_TRAINING_PATTERN_DISABLE); |
461 |
- |
462 |
- /* disable the training pattern on the source */ |
463 |
-- if (ASIC_IS_DCE4(dp_info->rdev)) |
464 |
-+ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) |
465 |
- atombios_dig_encoder_setup(dp_info->encoder, |
466 |
- ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0); |
467 |
- else |
468 |
-@@ -869,7 +870,8 @@ void radeon_dp_link_train(struct drm_encoder *encoder, |
469 |
- struct radeon_connector *radeon_connector; |
470 |
- struct radeon_connector_atom_dig *dig_connector; |
471 |
- struct radeon_dp_link_train_info dp_info; |
472 |
-- u8 tmp; |
473 |
-+ int index; |
474 |
-+ u8 tmp, frev, crev; |
475 |
- |
476 |
- if (!radeon_encoder->enc_priv) |
477 |
- return; |
478 |
-@@ -884,6 +886,18 @@ void radeon_dp_link_train(struct drm_encoder *encoder, |
479 |
- (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP)) |
480 |
- return; |
481 |
- |
482 |
-+ /* DPEncoderService newer than 1.1 can't program properly the |
483 |
-+ * training pattern. When facing such version use the |
484 |
-+ * DIGXEncoderControl (X== 1 | 2) |
485 |
-+ */ |
486 |
-+ dp_info.use_dpencoder = true; |
487 |
-+ index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); |
488 |
-+ if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) { |
489 |
-+ if (crev > 1) { |
490 |
-+ dp_info.use_dpencoder = false; |
491 |
-+ } |
492 |
-+ } |
493 |
-+ |
494 |
- dp_info.enc_id = 0; |
495 |
- if (dig->dig_encoder) |
496 |
- dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; |
497 |
-diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c |
498 |
-index e459467..a74217c 100644 |
499 |
---- a/drivers/gpu/drm/radeon/radeon_combios.c |
500 |
-+++ b/drivers/gpu/drm/radeon/radeon_combios.c |
501 |
-@@ -779,7 +779,8 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) |
502 |
- } |
503 |
- } |
504 |
- } |
505 |
-- } else if (rdev->family >= CHIP_R200) { |
506 |
-+ } else if ((rdev->family == CHIP_R200) || |
507 |
-+ (rdev->family >= CHIP_R300)) { |
508 |
- /* 0x68 */ |
509 |
- i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); |
510 |
- rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); |
511 |
-diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c |
512 |
-index aaa19dc..6fabe89 100644 |
513 |
---- a/drivers/gpu/drm/radeon/radeon_pm.c |
514 |
-+++ b/drivers/gpu/drm/radeon/radeon_pm.c |
515 |
-@@ -594,6 +594,9 @@ int radeon_pm_init(struct radeon_device *rdev) |
516 |
- if (rdev->pm.default_vddc) |
517 |
- radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, |
518 |
- SET_VOLTAGE_TYPE_ASIC_VDDC); |
519 |
-+ if (rdev->pm.default_vddci) |
520 |
-+ radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, |
521 |
-+ SET_VOLTAGE_TYPE_ASIC_VDDCI); |
522 |
- if (rdev->pm.default_sclk) |
523 |
- radeon_set_engine_clock(rdev, rdev->pm.default_sclk); |
524 |
- if (rdev->pm.default_mclk) |
525 |
-diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c |
526 |
-index ee165fd..7d5109b 100644 |
527 |
---- a/drivers/infiniband/ulp/srp/ib_srp.c |
528 |
-+++ b/drivers/infiniband/ulp/srp/ib_srp.c |
529 |
-@@ -2127,6 +2127,8 @@ static ssize_t srp_create_target(struct device *dev, |
530 |
- return -ENOMEM; |
531 |
- |
532 |
- target_host->transportt = ib_srp_transport_template; |
533 |
-+ target_host->max_channel = 0; |
534 |
-+ target_host->max_id = 1; |
535 |
- target_host->max_lun = SRP_MAX_LUN; |
536 |
- target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb; |
537 |
- |
538 |
-diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c |
539 |
-index 2067288..ad2eba4 100644 |
540 |
---- a/drivers/md/dm-io.c |
541 |
-+++ b/drivers/md/dm-io.c |
542 |
-@@ -38,6 +38,8 @@ struct io { |
543 |
- struct dm_io_client *client; |
544 |
- io_notify_fn callback; |
545 |
- void *context; |
546 |
-+ void *vma_invalidate_address; |
547 |
-+ unsigned long vma_invalidate_size; |
548 |
- } __attribute__((aligned(DM_IO_MAX_REGIONS))); |
549 |
- |
550 |
- static struct kmem_cache *_dm_io_cache; |
551 |
-@@ -116,6 +118,10 @@ static void dec_count(struct io *io, unsigned int region, int error) |
552 |
- set_bit(region, &io->error_bits); |
553 |
- |
554 |
- if (atomic_dec_and_test(&io->count)) { |
555 |
-+ if (io->vma_invalidate_size) |
556 |
-+ invalidate_kernel_vmap_range(io->vma_invalidate_address, |
557 |
-+ io->vma_invalidate_size); |
558 |
-+ |
559 |
- if (io->sleeper) |
560 |
- wake_up_process(io->sleeper); |
561 |
- |
562 |
-@@ -159,6 +165,9 @@ struct dpages { |
563 |
- |
564 |
- unsigned context_u; |
565 |
- void *context_ptr; |
566 |
-+ |
567 |
-+ void *vma_invalidate_address; |
568 |
-+ unsigned long vma_invalidate_size; |
569 |
- }; |
570 |
- |
571 |
- /* |
572 |
-@@ -377,6 +386,9 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, |
573 |
- io->sleeper = current; |
574 |
- io->client = client; |
575 |
- |
576 |
-+ io->vma_invalidate_address = dp->vma_invalidate_address; |
577 |
-+ io->vma_invalidate_size = dp->vma_invalidate_size; |
578 |
-+ |
579 |
- dispatch_io(rw, num_regions, where, dp, io, 1); |
580 |
- |
581 |
- while (1) { |
582 |
-@@ -415,13 +427,21 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, |
583 |
- io->callback = fn; |
584 |
- io->context = context; |
585 |
- |
586 |
-+ io->vma_invalidate_address = dp->vma_invalidate_address; |
587 |
-+ io->vma_invalidate_size = dp->vma_invalidate_size; |
588 |
-+ |
589 |
- dispatch_io(rw, num_regions, where, dp, io, 0); |
590 |
- return 0; |
591 |
- } |
592 |
- |
593 |
--static int dp_init(struct dm_io_request *io_req, struct dpages *dp) |
594 |
-+static int dp_init(struct dm_io_request *io_req, struct dpages *dp, |
595 |
-+ unsigned long size) |
596 |
- { |
597 |
- /* Set up dpages based on memory type */ |
598 |
-+ |
599 |
-+ dp->vma_invalidate_address = NULL; |
600 |
-+ dp->vma_invalidate_size = 0; |
601 |
-+ |
602 |
- switch (io_req->mem.type) { |
603 |
- case DM_IO_PAGE_LIST: |
604 |
- list_dp_init(dp, io_req->mem.ptr.pl, io_req->mem.offset); |
605 |
-@@ -432,6 +452,11 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp) |
606 |
- break; |
607 |
- |
608 |
- case DM_IO_VMA: |
609 |
-+ flush_kernel_vmap_range(io_req->mem.ptr.vma, size); |
610 |
-+ if ((io_req->bi_rw & RW_MASK) == READ) { |
611 |
-+ dp->vma_invalidate_address = io_req->mem.ptr.vma; |
612 |
-+ dp->vma_invalidate_size = size; |
613 |
-+ } |
614 |
- vm_dp_init(dp, io_req->mem.ptr.vma); |
615 |
- break; |
616 |
- |
617 |
-@@ -460,7 +485,7 @@ int dm_io(struct dm_io_request *io_req, unsigned num_regions, |
618 |
- int r; |
619 |
- struct dpages dp; |
620 |
- |
621 |
-- r = dp_init(io_req, &dp); |
622 |
-+ r = dp_init(io_req, &dp, (unsigned long)where->count << SECTOR_SHIFT); |
623 |
- if (r) |
624 |
- return r; |
625 |
- |
626 |
-diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c |
627 |
-index aa4e570..209991b 100644 |
628 |
---- a/drivers/md/dm-mpath.c |
629 |
-+++ b/drivers/md/dm-mpath.c |
630 |
-@@ -807,6 +807,11 @@ static int parse_features(struct arg_set *as, struct multipath *m) |
631 |
- if (!argc) |
632 |
- return 0; |
633 |
- |
634 |
-+ if (argc > as->argc) { |
635 |
-+ ti->error = "not enough arguments for features"; |
636 |
-+ return -EINVAL; |
637 |
-+ } |
638 |
-+ |
639 |
- do { |
640 |
- param_name = shift(as); |
641 |
- argc--; |
642 |
-diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c |
643 |
-index 135c2f1..e4ecadf 100644 |
644 |
---- a/drivers/md/dm-snap-persistent.c |
645 |
-+++ b/drivers/md/dm-snap-persistent.c |
646 |
-@@ -753,7 +753,7 @@ static int persistent_commit_merge(struct dm_exception_store *store, |
647 |
- for (i = 0; i < nr_merged; i++) |
648 |
- clear_exception(ps, ps->current_committed - 1 - i); |
649 |
- |
650 |
-- r = area_io(ps, WRITE); |
651 |
-+ r = area_io(ps, WRITE_FLUSH_FUA); |
652 |
- if (r < 0) |
653 |
- return r; |
654 |
- |
655 |
-diff --git a/drivers/md/dm.c b/drivers/md/dm.c |
656 |
-index 0cf68b4..41abc6d 100644 |
657 |
---- a/drivers/md/dm.c |
658 |
-+++ b/drivers/md/dm.c |
659 |
-@@ -37,6 +37,8 @@ static const char *_name = DM_NAME; |
660 |
- static unsigned int major = 0; |
661 |
- static unsigned int _major = 0; |
662 |
- |
663 |
-+static DEFINE_IDR(_minor_idr); |
664 |
-+ |
665 |
- static DEFINE_SPINLOCK(_minor_lock); |
666 |
- /* |
667 |
- * For bio-based dm. |
668 |
-@@ -313,6 +315,12 @@ static void __exit dm_exit(void) |
669 |
- |
670 |
- while (i--) |
671 |
- _exits[i](); |
672 |
-+ |
673 |
-+ /* |
674 |
-+ * Should be empty by this point. |
675 |
-+ */ |
676 |
-+ idr_remove_all(&_minor_idr); |
677 |
-+ idr_destroy(&_minor_idr); |
678 |
- } |
679 |
- |
680 |
- /* |
681 |
-@@ -1705,8 +1713,6 @@ static int dm_any_congested(void *congested_data, int bdi_bits) |
682 |
- /*----------------------------------------------------------------- |
683 |
- * An IDR is used to keep track of allocated minor numbers. |
684 |
- *---------------------------------------------------------------*/ |
685 |
--static DEFINE_IDR(_minor_idr); |
686 |
-- |
687 |
- static void free_minor(int minor) |
688 |
- { |
689 |
- spin_lock(&_minor_lock); |
690 |
-diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig |
691 |
-index 4e349cd..3546474 100644 |
692 |
---- a/drivers/misc/Kconfig |
693 |
-+++ b/drivers/misc/Kconfig |
694 |
-@@ -245,8 +245,7 @@ config SGI_XP |
695 |
- |
696 |
- config CS5535_MFGPT |
697 |
- tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support" |
698 |
-- depends on PCI |
699 |
-- depends on X86 |
700 |
-+ depends on PCI && X86 && MFD_CS5535 |
701 |
- default n |
702 |
- help |
703 |
- This driver provides access to MFGPT functionality for other |
704 |
-diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c |
705 |
-index a19967d..ba31abe 100644 |
706 |
---- a/drivers/mmc/host/sdhci-esdhc-imx.c |
707 |
-+++ b/drivers/mmc/host/sdhci-esdhc-imx.c |
708 |
-@@ -74,7 +74,7 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) |
709 |
- if (boarddata && gpio_is_valid(boarddata->cd_gpio) |
710 |
- && gpio_get_value(boarddata->cd_gpio)) |
711 |
- /* no card, if a valid gpio says so... */ |
712 |
-- val &= SDHCI_CARD_PRESENT; |
713 |
-+ val &= ~SDHCI_CARD_PRESENT; |
714 |
- else |
715 |
- /* ... in all other cases assume card is present */ |
716 |
- val |= SDHCI_CARD_PRESENT; |
717 |
-diff --git a/drivers/net/jme.c b/drivers/net/jme.c |
718 |
-index b5b174a..1973814 100644 |
719 |
---- a/drivers/net/jme.c |
720 |
-+++ b/drivers/net/jme.c |
721 |
-@@ -753,20 +753,28 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i) |
722 |
- struct jme_ring *rxring = &(jme->rxring[0]); |
723 |
- struct jme_buffer_info *rxbi = rxring->bufinf + i; |
724 |
- struct sk_buff *skb; |
725 |
-+ dma_addr_t mapping; |
726 |
- |
727 |
- skb = netdev_alloc_skb(jme->dev, |
728 |
- jme->dev->mtu + RX_EXTRA_LEN); |
729 |
- if (unlikely(!skb)) |
730 |
- return -ENOMEM; |
731 |
- |
732 |
-+ mapping = pci_map_page(jme->pdev, virt_to_page(skb->data), |
733 |
-+ offset_in_page(skb->data), skb_tailroom(skb), |
734 |
-+ PCI_DMA_FROMDEVICE); |
735 |
-+ if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) { |
736 |
-+ dev_kfree_skb(skb); |
737 |
-+ return -ENOMEM; |
738 |
-+ } |
739 |
-+ |
740 |
-+ if (likely(rxbi->mapping)) |
741 |
-+ pci_unmap_page(jme->pdev, rxbi->mapping, |
742 |
-+ rxbi->len, PCI_DMA_FROMDEVICE); |
743 |
-+ |
744 |
- rxbi->skb = skb; |
745 |
- rxbi->len = skb_tailroom(skb); |
746 |
-- rxbi->mapping = pci_map_page(jme->pdev, |
747 |
-- virt_to_page(skb->data), |
748 |
-- offset_in_page(skb->data), |
749 |
-- rxbi->len, |
750 |
-- PCI_DMA_FROMDEVICE); |
751 |
-- |
752 |
-+ rxbi->mapping = mapping; |
753 |
- return 0; |
754 |
- } |
755 |
- |
756 |
-diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c |
757 |
-index 10d71f7..1f99249 100644 |
758 |
---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c |
759 |
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c |
760 |
-@@ -629,8 +629,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, |
761 |
- rxs->rs_status |= ATH9K_RXERR_DECRYPT; |
762 |
- else if (rxsp->status11 & AR_MichaelErr) |
763 |
- rxs->rs_status |= ATH9K_RXERR_MIC; |
764 |
-- |
765 |
-- if (rxsp->status11 & AR_KeyMiss) |
766 |
-+ else if (rxsp->status11 & AR_KeyMiss) |
767 |
- rxs->rs_status |= ATH9K_RXERR_DECRYPT; |
768 |
- } |
769 |
- |
770 |
-diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c |
771 |
-index c2091f1..b6b523a 100644 |
772 |
---- a/drivers/net/wireless/ath/ath9k/mac.c |
773 |
-+++ b/drivers/net/wireless/ath/ath9k/mac.c |
774 |
-@@ -645,8 +645,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, |
775 |
- rs->rs_status |= ATH9K_RXERR_DECRYPT; |
776 |
- else if (ads.ds_rxstatus8 & AR_MichaelErr) |
777 |
- rs->rs_status |= ATH9K_RXERR_MIC; |
778 |
-- |
779 |
-- if (ads.ds_rxstatus8 & AR_KeyMiss) |
780 |
-+ else if (ads.ds_rxstatus8 & AR_KeyMiss) |
781 |
- rs->rs_status |= ATH9K_RXERR_DECRYPT; |
782 |
- } |
783 |
- |
784 |
-diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c |
785 |
-index cc4a54f..55cd3e1 100644 |
786 |
---- a/drivers/net/wireless/rt2x00/rt2800pci.c |
787 |
-+++ b/drivers/net/wireless/rt2x00/rt2800pci.c |
788 |
-@@ -1158,6 +1158,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { |
789 |
- #endif |
790 |
- #ifdef CONFIG_RT2800PCI_RT53XX |
791 |
- { PCI_DEVICE(0x1814, 0x5390) }, |
792 |
-+ { PCI_DEVICE(0x1814, 0x539f) }, |
793 |
- #endif |
794 |
- { 0, } |
795 |
- }; |
796 |
-diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c |
797 |
-index c7576ec..3bee79e 100644 |
798 |
---- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c |
799 |
-+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c |
800 |
-@@ -104,7 +104,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, |
801 |
- tx_agc[RF90_PATH_A] = 0x10101010; |
802 |
- tx_agc[RF90_PATH_B] = 0x10101010; |
803 |
- } else if (rtlpriv->dm.dynamic_txhighpower_lvl == |
804 |
-- TXHIGHPWRLEVEL_LEVEL1) { |
805 |
-+ TXHIGHPWRLEVEL_LEVEL2) { |
806 |
- tx_agc[RF90_PATH_A] = 0x00000000; |
807 |
- tx_agc[RF90_PATH_B] = 0x00000000; |
808 |
- } else{ |
809 |
-diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c |
810 |
-index 692671b..d549bbc 100644 |
811 |
---- a/drivers/pci/pci.c |
812 |
-+++ b/drivers/pci/pci.c |
813 |
-@@ -1905,7 +1905,7 @@ void pci_enable_ari(struct pci_dev *dev) |
814 |
- { |
815 |
- int pos; |
816 |
- u32 cap; |
817 |
-- u16 ctrl; |
818 |
-+ u16 flags, ctrl; |
819 |
- struct pci_dev *bridge; |
820 |
- |
821 |
- if (!pci_is_pcie(dev) || dev->devfn) |
822 |
-@@ -1923,6 +1923,11 @@ void pci_enable_ari(struct pci_dev *dev) |
823 |
- if (!pos) |
824 |
- return; |
825 |
- |
826 |
-+ /* ARI is a PCIe v2 feature */ |
827 |
-+ pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags); |
828 |
-+ if ((flags & PCI_EXP_FLAGS_VERS) < 2) |
829 |
-+ return; |
830 |
-+ |
831 |
- pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); |
832 |
- if (!(cap & PCI_EXP_DEVCAP2_ARI)) |
833 |
- return; |
834 |
-diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
835 |
-index 02145e9..1196f61 100644 |
836 |
---- a/drivers/pci/quirks.c |
837 |
-+++ b/drivers/pci/quirks.c |
838 |
-@@ -2758,6 +2758,29 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) |
839 |
- |
840 |
- dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n"); |
841 |
- dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); |
842 |
-+ |
843 |
-+ /* |
844 |
-+ * RICOH 0xe823 SD/MMC card reader fails to recognize |
845 |
-+ * certain types of SD/MMC cards. Lowering the SD base |
846 |
-+ * clock frequency from 200Mhz to 50Mhz fixes this issue. |
847 |
-+ * |
848 |
-+ * 0x150 - SD2.0 mode enable for changing base clock |
849 |
-+ * frequency to 50Mhz |
850 |
-+ * 0xe1 - Base clock frequency |
851 |
-+ * 0x32 - 50Mhz new clock frequency |
852 |
-+ * 0xf9 - Key register for 0x150 |
853 |
-+ * 0xfc - key register for 0xe1 |
854 |
-+ */ |
855 |
-+ if (dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { |
856 |
-+ pci_write_config_byte(dev, 0xf9, 0xfc); |
857 |
-+ pci_write_config_byte(dev, 0x150, 0x10); |
858 |
-+ pci_write_config_byte(dev, 0xf9, 0x00); |
859 |
-+ pci_write_config_byte(dev, 0xfc, 0x01); |
860 |
-+ pci_write_config_byte(dev, 0xe1, 0x32); |
861 |
-+ pci_write_config_byte(dev, 0xfc, 0x00); |
862 |
-+ |
863 |
-+ dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n"); |
864 |
-+ } |
865 |
- } |
866 |
- DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); |
867 |
- DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); |
868 |
-diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c |
869 |
-index df68618..3195dbd 100644 |
870 |
---- a/drivers/rtc/interface.c |
871 |
-+++ b/drivers/rtc/interface.c |
872 |
-@@ -636,6 +636,29 @@ void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task) |
873 |
- } |
874 |
- EXPORT_SYMBOL_GPL(rtc_irq_unregister); |
875 |
- |
876 |
-+static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled) |
877 |
-+{ |
878 |
-+ /* |
879 |
-+ * We unconditionally cancel the timer here, because otherwise |
880 |
-+ * we could run into BUG_ON(timer->state != HRTIMER_STATE_CALLBACK); |
881 |
-+ * when we manage to start the timer before the callback |
882 |
-+ * returns HRTIMER_RESTART. |
883 |
-+ * |
884 |
-+ * We cannot use hrtimer_cancel() here as a running callback |
885 |
-+ * could be blocked on rtc->irq_task_lock and hrtimer_cancel() |
886 |
-+ * would spin forever. |
887 |
-+ */ |
888 |
-+ if (hrtimer_try_to_cancel(&rtc->pie_timer) < 0) |
889 |
-+ return -1; |
890 |
-+ |
891 |
-+ if (enabled) { |
892 |
-+ ktime_t period = ktime_set(0, NSEC_PER_SEC / rtc->irq_freq); |
893 |
-+ |
894 |
-+ hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL); |
895 |
-+ } |
896 |
-+ return 0; |
897 |
-+} |
898 |
-+ |
899 |
- /** |
900 |
- * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs |
901 |
- * @rtc: the rtc device |
902 |
-@@ -651,21 +674,21 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled |
903 |
- int err = 0; |
904 |
- unsigned long flags; |
905 |
- |
906 |
-+retry: |
907 |
- spin_lock_irqsave(&rtc->irq_task_lock, flags); |
908 |
- if (rtc->irq_task != NULL && task == NULL) |
909 |
- err = -EBUSY; |
910 |
- if (rtc->irq_task != task) |
911 |
- err = -EACCES; |
912 |
-- |
913 |
-- if (enabled) { |
914 |
-- ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); |
915 |
-- hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL); |
916 |
-- } else { |
917 |
-- hrtimer_cancel(&rtc->pie_timer); |
918 |
-+ if (!err) { |
919 |
-+ if (rtc_update_hrtimer(rtc, enabled) < 0) { |
920 |
-+ spin_unlock_irqrestore(&rtc->irq_task_lock, flags); |
921 |
-+ cpu_relax(); |
922 |
-+ goto retry; |
923 |
-+ } |
924 |
-+ rtc->pie_enabled = enabled; |
925 |
- } |
926 |
-- rtc->pie_enabled = enabled; |
927 |
- spin_unlock_irqrestore(&rtc->irq_task_lock, flags); |
928 |
-- |
929 |
- return err; |
930 |
- } |
931 |
- EXPORT_SYMBOL_GPL(rtc_irq_set_state); |
932 |
-@@ -685,22 +708,20 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) |
933 |
- int err = 0; |
934 |
- unsigned long flags; |
935 |
- |
936 |
-- if (freq <= 0) |
937 |
-+ if (freq <= 0 || freq > 5000) |
938 |
- return -EINVAL; |
939 |
-- |
940 |
-+retry: |
941 |
- spin_lock_irqsave(&rtc->irq_task_lock, flags); |
942 |
- if (rtc->irq_task != NULL && task == NULL) |
943 |
- err = -EBUSY; |
944 |
- if (rtc->irq_task != task) |
945 |
- err = -EACCES; |
946 |
-- if (err == 0) { |
947 |
-+ if (!err) { |
948 |
- rtc->irq_freq = freq; |
949 |
-- if (rtc->pie_enabled) { |
950 |
-- ktime_t period; |
951 |
-- hrtimer_cancel(&rtc->pie_timer); |
952 |
-- period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); |
953 |
-- hrtimer_start(&rtc->pie_timer, period, |
954 |
-- HRTIMER_MODE_REL); |
955 |
-+ if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) { |
956 |
-+ spin_unlock_irqrestore(&rtc->irq_task_lock, flags); |
957 |
-+ cpu_relax(); |
958 |
-+ goto retry; |
959 |
- } |
960 |
- } |
961 |
- spin_unlock_irqrestore(&rtc->irq_task_lock, flags); |
962 |
-diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c |
963 |
-index 2fc31aa..75259fe 100644 |
964 |
---- a/drivers/rtc/rtc-tegra.c |
965 |
-+++ b/drivers/rtc/rtc-tegra.c |
966 |
-@@ -343,7 +343,7 @@ static int __devinit tegra_rtc_probe(struct platform_device *pdev) |
967 |
- |
968 |
- /* set context info. */ |
969 |
- info->pdev = pdev; |
970 |
-- info->tegra_rtc_lock = __SPIN_LOCK_UNLOCKED(info->tegra_rtc_lock); |
971 |
-+ spin_lock_init(&info->tegra_rtc_lock); |
972 |
- |
973 |
- platform_set_drvdata(pdev, info); |
974 |
- |
975 |
-diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h |
976 |
-index 6d8dcd4..7f53cea 100644 |
977 |
---- a/drivers/scsi/hpsa.h |
978 |
-+++ b/drivers/scsi/hpsa.h |
979 |
-@@ -214,7 +214,7 @@ static void SA5_submit_command(struct ctlr_info *h, |
980 |
- dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr, |
981 |
- c->Header.Tag.lower); |
982 |
- writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); |
983 |
-- (void) readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); |
984 |
-+ (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); |
985 |
- h->commands_outstanding++; |
986 |
- if (h->commands_outstanding > h->max_outstanding) |
987 |
- h->max_outstanding = h->commands_outstanding; |
988 |
-diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c |
989 |
-index 874e29d..f84084b 100644 |
990 |
---- a/drivers/scsi/libsas/sas_expander.c |
991 |
-+++ b/drivers/scsi/libsas/sas_expander.c |
992 |
-@@ -849,6 +849,9 @@ static struct domain_device *sas_ex_discover_expander( |
993 |
- |
994 |
- res = sas_discover_expander(child); |
995 |
- if (res) { |
996 |
-+ spin_lock_irq(&parent->port->dev_list_lock); |
997 |
-+ list_del(&child->dev_list_node); |
998 |
-+ spin_unlock_irq(&parent->port->dev_list_lock); |
999 |
- kfree(child); |
1000 |
- return NULL; |
1001 |
- } |
1002 |
-diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c |
1003 |
-index fca6a89..d079f9a 100644 |
1004 |
---- a/drivers/scsi/pmcraid.c |
1005 |
-+++ b/drivers/scsi/pmcraid.c |
1006 |
-@@ -3871,6 +3871,9 @@ static long pmcraid_ioctl_passthrough( |
1007 |
- pmcraid_err("couldn't build passthrough ioadls\n"); |
1008 |
- goto out_free_buffer; |
1009 |
- } |
1010 |
-+ } else if (request_size < 0) { |
1011 |
-+ rc = -EINVAL; |
1012 |
-+ goto out_free_buffer; |
1013 |
- } |
1014 |
- |
1015 |
- /* If data is being written into the device, copy the data from user |
1016 |
-diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c |
1017 |
-index 82e9e5c..cf8dfab 100644 |
1018 |
---- a/drivers/scsi/scsi_devinfo.c |
1019 |
-+++ b/drivers/scsi/scsi_devinfo.c |
1020 |
-@@ -197,6 +197,7 @@ static struct { |
1021 |
- {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, |
1022 |
- {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, |
1023 |
- {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, |
1024 |
-+ {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, |
1025 |
- {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, |
1026 |
- {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, |
1027 |
- {"INSITE", "I325VM", NULL, BLIST_KEY}, |
1028 |
-@@ -243,6 +244,7 @@ static struct { |
1029 |
- {"Tornado-", "F4", "*", BLIST_NOREPORTLUN}, |
1030 |
- {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, |
1031 |
- {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, |
1032 |
-+ {"Traxdata", "CDR4120", NULL, BLIST_NOLUN}, /* locks up */ |
1033 |
- {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, |
1034 |
- {"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN}, |
1035 |
- {"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN}, |
1036 |
-diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c |
1037 |
-index ec1803a..28d9c9d 100644 |
1038 |
---- a/drivers/scsi/scsi_lib.c |
1039 |
-+++ b/drivers/scsi/scsi_lib.c |
1040 |
-@@ -213,6 +213,8 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, |
1041 |
- int ret = DRIVER_ERROR << 24; |
1042 |
- |
1043 |
- req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); |
1044 |
-+ if (!req) |
1045 |
-+ return ret; |
1046 |
- |
1047 |
- if (bufflen && blk_rq_map_kern(sdev->request_queue, req, |
1048 |
- buffer, bufflen, __GFP_WAIT)) |
1049 |
-diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c |
1050 |
-index eb7a3e8..eba183c 100644 |
1051 |
---- a/drivers/scsi/ses.c |
1052 |
-+++ b/drivers/scsi/ses.c |
1053 |
-@@ -160,6 +160,10 @@ static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev, |
1054 |
- return NULL; |
1055 |
- } |
1056 |
- |
1057 |
-+/* For device slot and array device slot elements, byte 3 bit 6 |
1058 |
-+ * is "fault sensed" while byte 3 bit 5 is "fault reqstd". As this |
1059 |
-+ * code stands these bits are shifted 4 positions right so in |
1060 |
-+ * sysfs they will appear as bits 2 and 1 respectively. Strange. */ |
1061 |
- static void ses_get_fault(struct enclosure_device *edev, |
1062 |
- struct enclosure_component *ecomp) |
1063 |
- { |
1064 |
-@@ -181,7 +185,7 @@ static int ses_set_fault(struct enclosure_device *edev, |
1065 |
- /* zero is disabled */ |
1066 |
- break; |
1067 |
- case ENCLOSURE_SETTING_ENABLED: |
1068 |
-- desc[2] = 0x02; |
1069 |
-+ desc[3] = 0x20; |
1070 |
- break; |
1071 |
- default: |
1072 |
- /* SES doesn't do the SGPIO blink settings */ |
1073 |
-diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c |
1074 |
-index 4778e27..5fc97d2 100644 |
1075 |
---- a/drivers/scsi/sr.c |
1076 |
-+++ b/drivers/scsi/sr.c |
1077 |
-@@ -221,14 +221,33 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi, |
1078 |
- return 0; |
1079 |
- |
1080 |
- events = sr_get_events(cd->device); |
1081 |
-+ cd->get_event_changed |= events & DISK_EVENT_MEDIA_CHANGE; |
1082 |
-+ |
1083 |
-+ /* |
1084 |
-+ * If earlier GET_EVENT_STATUS_NOTIFICATION and TUR did not agree |
1085 |
-+ * for several times in a row. We rely on TUR only for this likely |
1086 |
-+ * broken device, to prevent generating incorrect media changed |
1087 |
-+ * events for every open(). |
1088 |
-+ */ |
1089 |
-+ if (cd->ignore_get_event) { |
1090 |
-+ events &= ~DISK_EVENT_MEDIA_CHANGE; |
1091 |
-+ goto do_tur; |
1092 |
-+ } |
1093 |
-+ |
1094 |
- /* |
1095 |
- * GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE |
1096 |
- * is being cleared. Note that there are devices which hang |
1097 |
- * if asked to execute TUR repeatedly. |
1098 |
- */ |
1099 |
-- if (!(clearing & DISK_EVENT_MEDIA_CHANGE)) |
1100 |
-- goto skip_tur; |
1101 |
-+ if (cd->device->changed) { |
1102 |
-+ events |= DISK_EVENT_MEDIA_CHANGE; |
1103 |
-+ cd->device->changed = 0; |
1104 |
-+ cd->tur_changed = true; |
1105 |
-+ } |
1106 |
- |
1107 |
-+ if (!(clearing & DISK_EVENT_MEDIA_CHANGE)) |
1108 |
-+ return events; |
1109 |
-+do_tur: |
1110 |
- /* let's see whether the media is there with TUR */ |
1111 |
- last_present = cd->media_present; |
1112 |
- ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); |
1113 |
-@@ -242,12 +261,31 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi, |
1114 |
- (scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a); |
1115 |
- |
1116 |
- if (last_present != cd->media_present) |
1117 |
-- events |= DISK_EVENT_MEDIA_CHANGE; |
1118 |
--skip_tur: |
1119 |
-+ cd->device->changed = 1; |
1120 |
-+ |
1121 |
- if (cd->device->changed) { |
1122 |
- events |= DISK_EVENT_MEDIA_CHANGE; |
1123 |
- cd->device->changed = 0; |
1124 |
-+ cd->tur_changed = true; |
1125 |
-+ } |
1126 |
-+ |
1127 |
-+ if (cd->ignore_get_event) |
1128 |
-+ return events; |
1129 |
-+ |
1130 |
-+ /* check whether GET_EVENT is reporting spurious MEDIA_CHANGE */ |
1131 |
-+ if (!cd->tur_changed) { |
1132 |
-+ if (cd->get_event_changed) { |
1133 |
-+ if (cd->tur_mismatch++ > 8) { |
1134 |
-+ sdev_printk(KERN_WARNING, cd->device, |
1135 |
-+ "GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n"); |
1136 |
-+ cd->ignore_get_event = true; |
1137 |
-+ } |
1138 |
-+ } else { |
1139 |
-+ cd->tur_mismatch = 0; |
1140 |
-+ } |
1141 |
- } |
1142 |
-+ cd->tur_changed = false; |
1143 |
-+ cd->get_event_changed = false; |
1144 |
- |
1145 |
- return events; |
1146 |
- } |
1147 |
-diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h |
1148 |
-index e036f1d..37c8f6b 100644 |
1149 |
---- a/drivers/scsi/sr.h |
1150 |
-+++ b/drivers/scsi/sr.h |
1151 |
-@@ -41,6 +41,13 @@ typedef struct scsi_cd { |
1152 |
- unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ |
1153 |
- unsigned readcd_cdda:1; /* reading audio data using READ_CD */ |
1154 |
- unsigned media_present:1; /* media is present */ |
1155 |
-+ |
1156 |
-+ /* GET_EVENT spurious event handling, blk layer guarantees exclusion */ |
1157 |
-+ int tur_mismatch; /* nr of get_event TUR mismatches */ |
1158 |
-+ bool tur_changed:1; /* changed according to TUR */ |
1159 |
-+ bool get_event_changed:1; /* changed according to GET_EVENT */ |
1160 |
-+ bool ignore_get_event:1; /* GET_EVENT is unreliable, use TUR */ |
1161 |
-+ |
1162 |
- struct cdrom_device_info cdi; |
1163 |
- /* We hold gendisk and scsi_device references on probe and use |
1164 |
- * the refs on this kref to decide when to release them */ |
1165 |
-diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
1166 |
-index 48dd9e3..aa97efc 100644 |
1167 |
---- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
1168 |
-+++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
1169 |
-@@ -954,9 +954,13 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, |
1170 |
- const char *filename; |
1171 |
- const struct firmware *fw_entry; |
1172 |
- u32 fw_entry_size; |
1173 |
-+ u8 **buf; |
1174 |
-+ size_t *buf_len; |
1175 |
- |
1176 |
- switch (file) { |
1177 |
- case AR6K_OTP_FILE: |
1178 |
-+ buf = &ar->fw_otp; |
1179 |
-+ buf_len = &ar->fw_otp_len; |
1180 |
- if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { |
1181 |
- filename = AR6003_REV1_OTP_FILE; |
1182 |
- } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { |
1183 |
-@@ -970,6 +974,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, |
1184 |
- break; |
1185 |
- |
1186 |
- case AR6K_FIRMWARE_FILE: |
1187 |
-+ buf = &ar->fw; |
1188 |
-+ buf_len = &ar->fw_len; |
1189 |
- if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { |
1190 |
- filename = AR6003_REV1_FIRMWARE_FILE; |
1191 |
- } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { |
1192 |
-@@ -1028,6 +1034,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, |
1193 |
- break; |
1194 |
- |
1195 |
- case AR6K_PATCH_FILE: |
1196 |
-+ buf = &ar->fw_patch; |
1197 |
-+ buf_len = &ar->fw_patch_len; |
1198 |
- if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { |
1199 |
- filename = AR6003_REV1_PATCH_FILE; |
1200 |
- } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { |
1201 |
-@@ -1041,6 +1049,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, |
1202 |
- break; |
1203 |
- |
1204 |
- case AR6K_BOARD_DATA_FILE: |
1205 |
-+ buf = &ar->fw_data; |
1206 |
-+ buf_len = &ar->fw_data_len; |
1207 |
- if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { |
1208 |
- filename = AR6003_REV1_BOARD_DATA_FILE; |
1209 |
- } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { |
1210 |
-@@ -1057,23 +1067,29 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, |
1211 |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file)); |
1212 |
- return A_ERROR; |
1213 |
- } |
1214 |
-- if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) |
1215 |
-- { |
1216 |
-- AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename)); |
1217 |
-- return A_ENOENT; |
1218 |
-+ |
1219 |
-+ if (*buf == NULL) { |
1220 |
-+ if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) { |
1221 |
-+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename)); |
1222 |
-+ return A_ENOENT; |
1223 |
-+ } |
1224 |
-+ |
1225 |
-+ *buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); |
1226 |
-+ *buf_len = fw_entry->size; |
1227 |
-+ A_RELEASE_FIRMWARE(fw_entry); |
1228 |
- } |
1229 |
- |
1230 |
- #ifdef SOFTMAC_FILE_USED |
1231 |
-- if (file==AR6K_BOARD_DATA_FILE && fw_entry->data) { |
1232 |
-- ar6000_softmac_update(ar, (u8 *)fw_entry->data, fw_entry->size); |
1233 |
-+ if (file==AR6K_BOARD_DATA_FILE && *buf_len) { |
1234 |
-+ ar6000_softmac_update(ar, *buf, *buf_len); |
1235 |
- } |
1236 |
- #endif |
1237 |
- |
1238 |
- |
1239 |
-- fw_entry_size = fw_entry->size; |
1240 |
-+ fw_entry_size = *buf_len; |
1241 |
- |
1242 |
- /* Load extended board data for AR6003 */ |
1243 |
-- if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) { |
1244 |
-+ if ((file==AR6K_BOARD_DATA_FILE) && *buf) { |
1245 |
- u32 board_ext_address; |
1246 |
- u32 board_ext_data_size; |
1247 |
- u32 board_data_size; |
1248 |
-@@ -1089,14 +1105,13 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, |
1249 |
- AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address)); |
1250 |
- |
1251 |
- /* check whether the target has allocated memory for extended board data and file contains extended board data */ |
1252 |
-- if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) { |
1253 |
-+ if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) { |
1254 |
- u32 param; |
1255 |
- |
1256 |
-- status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(fw_entry->data + board_data_size), board_ext_data_size); |
1257 |
-+ status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size); |
1258 |
- |
1259 |
- if (status) { |
1260 |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); |
1261 |
-- A_RELEASE_FIRMWARE(fw_entry); |
1262 |
- return A_ERROR; |
1263 |
- } |
1264 |
- |
1265 |
-@@ -1110,17 +1125,16 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, |
1266 |
- } |
1267 |
- |
1268 |
- if (compressed) { |
1269 |
-- status = BMIFastDownload(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size); |
1270 |
-+ status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size); |
1271 |
- } else { |
1272 |
-- status = BMIWriteMemory(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size); |
1273 |
-+ status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size); |
1274 |
- } |
1275 |
- |
1276 |
- if (status) { |
1277 |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); |
1278 |
-- A_RELEASE_FIRMWARE(fw_entry); |
1279 |
- return A_ERROR; |
1280 |
- } |
1281 |
-- A_RELEASE_FIRMWARE(fw_entry); |
1282 |
-+ |
1283 |
- return 0; |
1284 |
- } |
1285 |
- |
1286 |
-@@ -2088,6 +2102,11 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) |
1287 |
- ar6000_remove_ap_interface(); |
1288 |
- #endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ |
1289 |
- |
1290 |
-+ kfree(ar->fw_otp); |
1291 |
-+ kfree(ar->fw); |
1292 |
-+ kfree(ar->fw_patch); |
1293 |
-+ kfree(ar->fw_data); |
1294 |
-+ |
1295 |
- AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n")); |
1296 |
- } |
1297 |
- |
1298 |
-diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c |
1299 |
-index d3a774d..32e3197 100644 |
1300 |
---- a/drivers/staging/ath6kl/os/linux/cfg80211.c |
1301 |
-+++ b/drivers/staging/ath6kl/os/linux/cfg80211.c |
1302 |
-@@ -867,26 +867,31 @@ ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status) |
1303 |
- |
1304 |
- AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status)); |
1305 |
- |
1306 |
-- if(ar->scan_request) |
1307 |
-- { |
1308 |
-- /* Translate data to cfg80211 mgmt format */ |
1309 |
-- if (ar->arWmi) |
1310 |
-- wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); |
1311 |
-+ if (!ar->scan_request) |
1312 |
-+ return; |
1313 |
-+ |
1314 |
-+ if ((status == A_ECANCELED) || (status == A_EBUSY)) { |
1315 |
-+ cfg80211_scan_done(ar->scan_request, true); |
1316 |
-+ goto out; |
1317 |
-+ } |
1318 |
-+ |
1319 |
-+ /* Translate data to cfg80211 mgmt format */ |
1320 |
-+ wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); |
1321 |
- |
1322 |
-- cfg80211_scan_done(ar->scan_request, |
1323 |
-- ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false); |
1324 |
-+ cfg80211_scan_done(ar->scan_request, false); |
1325 |
- |
1326 |
-- if(ar->scan_request->n_ssids && |
1327 |
-- ar->scan_request->ssids[0].ssid_len) { |
1328 |
-+ if(ar->scan_request->n_ssids && |
1329 |
-+ ar->scan_request->ssids[0].ssid_len) { |
1330 |
- u8 i; |
1331 |
- |
1332 |
- for (i = 0; i < ar->scan_request->n_ssids; i++) { |
1333 |
-- wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, |
1334 |
-- 0, NULL); |
1335 |
-+ wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, |
1336 |
-+ 0, NULL); |
1337 |
- } |
1338 |
-- } |
1339 |
-- ar->scan_request = NULL; |
1340 |
- } |
1341 |
-+ |
1342 |
-+out: |
1343 |
-+ ar->scan_request = NULL; |
1344 |
- } |
1345 |
- |
1346 |
- static int |
1347 |
-diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h |
1348 |
-index 22453b0..2911ea0 100644 |
1349 |
---- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h |
1350 |
-+++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h |
1351 |
-@@ -651,6 +651,15 @@ struct ar6_softc { |
1352 |
- void *arApDev; |
1353 |
- #endif |
1354 |
- u8 arAutoAuthStage; |
1355 |
-+ |
1356 |
-+ u8 *fw_otp; |
1357 |
-+ size_t fw_otp_len; |
1358 |
-+ u8 *fw; |
1359 |
-+ size_t fw_len; |
1360 |
-+ u8 *fw_patch; |
1361 |
-+ size_t fw_patch_len; |
1362 |
-+ u8 *fw_data; |
1363 |
-+ size_t fw_data_len; |
1364 |
- }; |
1365 |
- |
1366 |
- #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT |
1367 |
-diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c |
1368 |
-index 6c6236c..aa0d127 100644 |
1369 |
---- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c |
1370 |
-+++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c |
1371 |
-@@ -449,11 +449,6 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, |
1372 |
- wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, |
1373 |
- info->qos ? "true" : "false"); |
1374 |
- } |
1375 |
-- if (changed & BSS_CHANGED_IDLE) { |
1376 |
-- /* Idle changed for this BSS/interface */ |
1377 |
-- wiphy_err(wiphy, "%s: BSS idle: %s (implement)\n", __func__, |
1378 |
-- info->idle ? "true" : "false"); |
1379 |
-- } |
1380 |
- return; |
1381 |
- } |
1382 |
- |
1383 |
-diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c |
1384 |
-index e7e72b8..c20694e 100644 |
1385 |
---- a/drivers/staging/comedi/comedi_fops.c |
1386 |
-+++ b/drivers/staging/comedi/comedi_fops.c |
1387 |
-@@ -383,8 +383,8 @@ static int do_devinfo_ioctl(struct comedi_device *dev, |
1388 |
- /* fill devinfo structure */ |
1389 |
- devinfo.version_code = COMEDI_VERSION_CODE; |
1390 |
- devinfo.n_subdevs = dev->n_subdevices; |
1391 |
-- memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); |
1392 |
-- memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); |
1393 |
-+ strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); |
1394 |
-+ strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); |
1395 |
- |
1396 |
- if (read_subdev) |
1397 |
- devinfo.read_subdevice = read_subdev - dev->subdevices; |
1398 |
-diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c |
1399 |
-index f655e59..d971bab 100644 |
1400 |
---- a/drivers/staging/hv/channel.c |
1401 |
-+++ b/drivers/staging/hv/channel.c |
1402 |
-@@ -212,7 +212,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, |
1403 |
- if (ret != 0) |
1404 |
- goto Cleanup; |
1405 |
- |
1406 |
-- t = wait_for_completion_timeout(&openInfo->waitevent, HZ); |
1407 |
-+ t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ); |
1408 |
- if (t == 0) { |
1409 |
- err = -ETIMEDOUT; |
1410 |
- goto errorout; |
1411 |
-diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c |
1412 |
-index 957d61e..e2e7d05 100644 |
1413 |
---- a/drivers/staging/hv/channel_mgmt.c |
1414 |
-+++ b/drivers/staging/hv/channel_mgmt.c |
1415 |
-@@ -773,7 +773,7 @@ int vmbus_request_offers(void) |
1416 |
- goto cleanup; |
1417 |
- } |
1418 |
- |
1419 |
-- t = wait_for_completion_timeout(&msginfo->waitevent, HZ); |
1420 |
-+ t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); |
1421 |
- if (t == 0) { |
1422 |
- ret = -ETIMEDOUT; |
1423 |
- goto cleanup; |
1424 |
-diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c |
1425 |
-index 37bbf77..91c65ad 100644 |
1426 |
---- a/drivers/staging/hv/connection.c |
1427 |
-+++ b/drivers/staging/hv/connection.c |
1428 |
-@@ -135,7 +135,7 @@ int vmbus_connect(void) |
1429 |
- } |
1430 |
- |
1431 |
- /* Wait for the connection response */ |
1432 |
-- t = wait_for_completion_timeout(&msginfo->waitevent, HZ); |
1433 |
-+ t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); |
1434 |
- if (t == 0) { |
1435 |
- spin_lock_irqsave(&vmbus_connection.channelmsg_lock, |
1436 |
- flags); |
1437 |
-diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c |
1438 |
-index 41cbb26..4742b68 100644 |
1439 |
---- a/drivers/staging/hv/netvsc.c |
1440 |
-+++ b/drivers/staging/hv/netvsc.c |
1441 |
-@@ -270,7 +270,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) |
1442 |
- goto cleanup; |
1443 |
- } |
1444 |
- |
1445 |
-- t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ); |
1446 |
-+ t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ); |
1447 |
- BUG_ON(t == 0); |
1448 |
- |
1449 |
- |
1450 |
-@@ -513,7 +513,7 @@ static int netvsc_connect_vsp(struct hv_device *device) |
1451 |
- if (ret != 0) |
1452 |
- goto cleanup; |
1453 |
- |
1454 |
-- t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ); |
1455 |
-+ t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ); |
1456 |
- |
1457 |
- if (t == 0) { |
1458 |
- ret = -ETIMEDOUT; |
1459 |
-diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c |
1460 |
-index 60ebdb1..b47ebb3 100644 |
1461 |
---- a/drivers/staging/hv/rndis_filter.c |
1462 |
-+++ b/drivers/staging/hv/rndis_filter.c |
1463 |
-@@ -467,7 +467,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, |
1464 |
- if (ret != 0) |
1465 |
- goto Cleanup; |
1466 |
- |
1467 |
-- t = wait_for_completion_timeout(&request->wait_event, HZ); |
1468 |
-+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1469 |
- if (t == 0) { |
1470 |
- ret = -ETIMEDOUT; |
1471 |
- goto Cleanup; |
1472 |
-@@ -543,7 +543,7 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, |
1473 |
- if (ret != 0) |
1474 |
- goto Cleanup; |
1475 |
- |
1476 |
-- t = wait_for_completion_timeout(&request->wait_event, HZ); |
1477 |
-+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1478 |
- |
1479 |
- if (t == 0) { |
1480 |
- ret = -1; |
1481 |
-@@ -600,7 +600,7 @@ static int rndis_filter_init_device(struct rndis_device *dev) |
1482 |
- } |
1483 |
- |
1484 |
- |
1485 |
-- t = wait_for_completion_timeout(&request->wait_event, HZ); |
1486 |
-+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1487 |
- |
1488 |
- if (t == 0) { |
1489 |
- ret = -ETIMEDOUT; |
1490 |
-diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c |
1491 |
-index 06cd327..3029786 100644 |
1492 |
---- a/drivers/staging/hv/storvsc.c |
1493 |
-+++ b/drivers/staging/hv/storvsc.c |
1494 |
-@@ -135,7 +135,7 @@ static int storvsc_channel_init(struct hv_device *device) |
1495 |
- if (ret != 0) |
1496 |
- goto cleanup; |
1497 |
- |
1498 |
-- t = wait_for_completion_timeout(&request->wait_event, HZ); |
1499 |
-+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1500 |
- if (t == 0) { |
1501 |
- ret = -ETIMEDOUT; |
1502 |
- goto cleanup; |
1503 |
-@@ -163,7 +163,7 @@ static int storvsc_channel_init(struct hv_device *device) |
1504 |
- if (ret != 0) |
1505 |
- goto cleanup; |
1506 |
- |
1507 |
-- t = wait_for_completion_timeout(&request->wait_event, HZ); |
1508 |
-+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1509 |
- if (t == 0) { |
1510 |
- ret = -ETIMEDOUT; |
1511 |
- goto cleanup; |
1512 |
-@@ -192,7 +192,7 @@ static int storvsc_channel_init(struct hv_device *device) |
1513 |
- if (ret != 0) |
1514 |
- goto cleanup; |
1515 |
- |
1516 |
-- t = wait_for_completion_timeout(&request->wait_event, HZ); |
1517 |
-+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1518 |
- if (t == 0) { |
1519 |
- ret = -ETIMEDOUT; |
1520 |
- goto cleanup; |
1521 |
-@@ -222,7 +222,7 @@ static int storvsc_channel_init(struct hv_device *device) |
1522 |
- if (ret != 0) |
1523 |
- goto cleanup; |
1524 |
- |
1525 |
-- t = wait_for_completion_timeout(&request->wait_event, HZ); |
1526 |
-+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1527 |
- if (t == 0) { |
1528 |
- ret = -ETIMEDOUT; |
1529 |
- goto cleanup; |
1530 |
-diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c |
1531 |
-index 942cc5f..cb4a25b 100644 |
1532 |
---- a/drivers/staging/hv/storvsc_drv.c |
1533 |
-+++ b/drivers/staging/hv/storvsc_drv.c |
1534 |
-@@ -393,7 +393,7 @@ static int storvsc_host_reset(struct hv_device *device) |
1535 |
- if (ret != 0) |
1536 |
- goto cleanup; |
1537 |
- |
1538 |
-- t = wait_for_completion_timeout(&request->wait_event, HZ); |
1539 |
-+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ); |
1540 |
- if (t == 0) { |
1541 |
- ret = -ETIMEDOUT; |
1542 |
- goto cleanup; |
1543 |
-diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c |
1544 |
-index 58d800f..cd98f89 100644 |
1545 |
---- a/drivers/staging/rtl8192e/r8192E_core.c |
1546 |
-+++ b/drivers/staging/rtl8192e/r8192E_core.c |
1547 |
-@@ -4532,6 +4532,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, |
1548 |
- u8 unit = 0; |
1549 |
- int ret = -ENODEV; |
1550 |
- unsigned long pmem_start, pmem_len, pmem_flags; |
1551 |
-+ u8 revisionid; |
1552 |
- |
1553 |
- RT_TRACE(COMP_INIT,"Configuring chip resources\n"); |
1554 |
- |
1555 |
-@@ -4592,6 +4593,11 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, |
1556 |
- pci_write_config_byte(pdev, 0x41, 0x00); |
1557 |
- |
1558 |
- |
1559 |
-+ pci_read_config_byte(pdev, 0x08, &revisionid); |
1560 |
-+ /* If the revisionid is 0x10, the device uses rtl8192se. */ |
1561 |
-+ if (pdev->device == 0x8192 && revisionid == 0x10) |
1562 |
-+ goto fail1; |
1563 |
-+ |
1564 |
- pci_read_config_byte(pdev, 0x05, &unit); |
1565 |
- pci_write_config_byte(pdev, 0x05, unit & (~0x04)); |
1566 |
- |
1567 |
-diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c |
1568 |
-index a76e8fa..76d7485 100644 |
1569 |
---- a/drivers/staging/usbip/vhci_hcd.c |
1570 |
-+++ b/drivers/staging/usbip/vhci_hcd.c |
1571 |
-@@ -846,9 +846,9 @@ static void vhci_shutdown_connection(struct usbip_device *ud) |
1572 |
- } |
1573 |
- |
1574 |
- /* kill threads related to this sdev, if v.c. exists */ |
1575 |
-- if (vdev->ud.tcp_rx) |
1576 |
-+ if (vdev->ud.tcp_rx && !task_is_dead(vdev->ud.tcp_rx)) |
1577 |
- kthread_stop(vdev->ud.tcp_rx); |
1578 |
-- if (vdev->ud.tcp_tx) |
1579 |
-+ if (vdev->ud.tcp_tx && !task_is_dead(vdev->ud.tcp_tx)) |
1580 |
- kthread_stop(vdev->ud.tcp_tx); |
1581 |
- |
1582 |
- pr_info("stop threads\n"); |
1583 |
-diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c |
1584 |
-index e9cba13..aa84555 100644 |
1585 |
---- a/drivers/tty/hvc/hvc_console.c |
1586 |
-+++ b/drivers/tty/hvc/hvc_console.c |
1587 |
-@@ -163,8 +163,10 @@ static void hvc_console_print(struct console *co, const char *b, |
1588 |
- } else { |
1589 |
- r = cons_ops[index]->put_chars(vtermnos[index], c, i); |
1590 |
- if (r <= 0) { |
1591 |
-- /* throw away chars on error */ |
1592 |
-- i = 0; |
1593 |
-+ /* throw away characters on error |
1594 |
-+ * but spin in case of -EAGAIN */ |
1595 |
-+ if (r != -EAGAIN) |
1596 |
-+ i = 0; |
1597 |
- } else if (r > 0) { |
1598 |
- i -= r; |
1599 |
- if (i > 0) |
1600 |
-@@ -448,7 +450,7 @@ static int hvc_push(struct hvc_struct *hp) |
1601 |
- |
1602 |
- n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); |
1603 |
- if (n <= 0) { |
1604 |
-- if (n == 0) { |
1605 |
-+ if (n == 0 || n == -EAGAIN) { |
1606 |
- hp->do_wakeup = 1; |
1607 |
- return 0; |
1608 |
- } |
1609 |
-diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c |
1610 |
-index 19b4ae0..c0d34ad 100644 |
1611 |
---- a/drivers/tty/n_gsm.c |
1612 |
-+++ b/drivers/tty/n_gsm.c |
1613 |
-@@ -1823,10 +1823,6 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) |
1614 |
- break; |
1615 |
- case GSM_FCS: /* FCS follows the packet */ |
1616 |
- gsm->received_fcs = c; |
1617 |
-- if (c == GSM0_SOF) { |
1618 |
-- gsm->state = GSM_SEARCH; |
1619 |
-- break; |
1620 |
-- } |
1621 |
- gsm_queue(gsm); |
1622 |
- gsm->state = GSM_SSOF; |
1623 |
- break; |
1624 |
-diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c |
1625 |
-index b4129f5..d32b5bb 100644 |
1626 |
---- a/drivers/tty/serial/8250.c |
1627 |
-+++ b/drivers/tty/serial/8250.c |
1628 |
-@@ -1107,7 +1107,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) |
1629 |
- */ |
1630 |
- DEBUG_AUTOCONF("Xscale "); |
1631 |
- up->port.type = PORT_XSCALE; |
1632 |
-- up->capabilities |= UART_CAP_UUE; |
1633 |
-+ up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE; |
1634 |
- return; |
1635 |
- } |
1636 |
- } else { |
1637 |
-diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig |
1638 |
-index 636144c..b3692e6 100644 |
1639 |
---- a/drivers/tty/serial/Kconfig |
1640 |
-+++ b/drivers/tty/serial/Kconfig |
1641 |
-@@ -1419,7 +1419,7 @@ config SERIAL_SC26XX |
1642 |
- |
1643 |
- config SERIAL_SC26XX_CONSOLE |
1644 |
- bool "Console on SC2681/SC2692 serial port" |
1645 |
-- depends on SERIAL_SC26XX |
1646 |
-+ depends on SERIAL_SC26XX=y |
1647 |
- select SERIAL_CORE_CONSOLE |
1648 |
- help |
1649 |
- Support for Console on SC2681/SC2692 serial ports. |
1650 |
-diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c |
1651 |
-index f8030ee..9ff9abc 100644 |
1652 |
---- a/drivers/usb/host/ehci-hcd.c |
1653 |
-+++ b/drivers/usb/host/ehci-hcd.c |
1654 |
-@@ -94,7 +94,8 @@ static const char hcd_name [] = "ehci_hcd"; |
1655 |
- #define EHCI_IAA_MSECS 10 /* arbitrary */ |
1656 |
- #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ |
1657 |
- #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ |
1658 |
--#define EHCI_SHRINK_FRAMES 5 /* async qh unlink delay */ |
1659 |
-+#define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1) |
1660 |
-+ /* 200-ms async qh unlink delay */ |
1661 |
- |
1662 |
- /* Initial IRQ latency: faster than hw default */ |
1663 |
- static int log2_irq_thresh = 0; // 0 to 6 |
1664 |
-@@ -152,10 +153,7 @@ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action) |
1665 |
- break; |
1666 |
- /* case TIMER_ASYNC_SHRINK: */ |
1667 |
- default: |
1668 |
-- /* add a jiffie since we synch against the |
1669 |
-- * 8 KHz uframe counter. |
1670 |
-- */ |
1671 |
-- t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; |
1672 |
-+ t = EHCI_SHRINK_JIFFIES; |
1673 |
- break; |
1674 |
- } |
1675 |
- mod_timer(&ehci->watchdog, t + jiffies); |
1676 |
-diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c |
1677 |
-index ea6184b..88cfb8f 100644 |
1678 |
---- a/drivers/usb/host/ehci-hub.c |
1679 |
-+++ b/drivers/usb/host/ehci-hub.c |
1680 |
-@@ -891,10 +891,11 @@ static int ehci_hub_control ( |
1681 |
- * power switching; they're allowed to just limit the |
1682 |
- * current. khubd will turn the power back on. |
1683 |
- */ |
1684 |
-- if (HCS_PPC (ehci->hcs_params)){ |
1685 |
-+ if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) { |
1686 |
- ehci_writel(ehci, |
1687 |
- temp & ~(PORT_RWC_BITS | PORT_POWER), |
1688 |
- status_reg); |
1689 |
-+ temp = ehci_readl(ehci, status_reg); |
1690 |
- } |
1691 |
- } |
1692 |
- |
1693 |
-diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c |
1694 |
-index 5d6bc62..0917e3a 100644 |
1695 |
---- a/drivers/usb/host/ehci-q.c |
1696 |
-+++ b/drivers/usb/host/ehci-q.c |
1697 |
-@@ -103,7 +103,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) |
1698 |
- if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { |
1699 |
- unsigned is_out, epnum; |
1700 |
- |
1701 |
-- is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); |
1702 |
-+ is_out = qh->is_out; |
1703 |
- epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f; |
1704 |
- if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { |
1705 |
- hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); |
1706 |
-@@ -946,6 +946,7 @@ done: |
1707 |
- hw = qh->hw; |
1708 |
- hw->hw_info1 = cpu_to_hc32(ehci, info1); |
1709 |
- hw->hw_info2 = cpu_to_hc32(ehci, info2); |
1710 |
-+ qh->is_out = !is_input; |
1711 |
- usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); |
1712 |
- qh_refresh (ehci, qh); |
1713 |
- return qh; |
1714 |
-@@ -1231,6 +1232,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
1715 |
- |
1716 |
- prev->hw->hw_next = qh->hw->hw_next; |
1717 |
- prev->qh_next = qh->qh_next; |
1718 |
-+ if (ehci->qh_scan_next == qh) |
1719 |
-+ ehci->qh_scan_next = qh->qh_next.qh; |
1720 |
- wmb (); |
1721 |
- |
1722 |
- /* If the controller isn't running, we don't have to wait for it */ |
1723 |
-@@ -1256,53 +1259,49 @@ static void scan_async (struct ehci_hcd *ehci) |
1724 |
- struct ehci_qh *qh; |
1725 |
- enum ehci_timer_action action = TIMER_IO_WATCHDOG; |
1726 |
- |
1727 |
-- ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); |
1728 |
- timer_action_done (ehci, TIMER_ASYNC_SHRINK); |
1729 |
--rescan: |
1730 |
- stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state); |
1731 |
-- qh = ehci->async->qh_next.qh; |
1732 |
-- if (likely (qh != NULL)) { |
1733 |
-- do { |
1734 |
-- /* clean any finished work for this qh */ |
1735 |
-- if (!list_empty(&qh->qtd_list) && (stopped || |
1736 |
-- qh->stamp != ehci->stamp)) { |
1737 |
-- int temp; |
1738 |
-- |
1739 |
-- /* unlinks could happen here; completion |
1740 |
-- * reporting drops the lock. rescan using |
1741 |
-- * the latest schedule, but don't rescan |
1742 |
-- * qhs we already finished (no looping) |
1743 |
-- * unless the controller is stopped. |
1744 |
-- */ |
1745 |
-- qh = qh_get (qh); |
1746 |
-- qh->stamp = ehci->stamp; |
1747 |
-- temp = qh_completions (ehci, qh); |
1748 |
-- if (qh->needs_rescan) |
1749 |
-- unlink_async(ehci, qh); |
1750 |
-- qh_put (qh); |
1751 |
-- if (temp != 0) { |
1752 |
-- goto rescan; |
1753 |
-- } |
1754 |
-- } |
1755 |
- |
1756 |
-- /* unlink idle entries, reducing DMA usage as well |
1757 |
-- * as HCD schedule-scanning costs. delay for any qh |
1758 |
-- * we just scanned, there's a not-unusual case that it |
1759 |
-- * doesn't stay idle for long. |
1760 |
-- * (plus, avoids some kind of re-activation race.) |
1761 |
-+ ehci->qh_scan_next = ehci->async->qh_next.qh; |
1762 |
-+ while (ehci->qh_scan_next) { |
1763 |
-+ qh = ehci->qh_scan_next; |
1764 |
-+ ehci->qh_scan_next = qh->qh_next.qh; |
1765 |
-+ rescan: |
1766 |
-+ /* clean any finished work for this qh */ |
1767 |
-+ if (!list_empty(&qh->qtd_list)) { |
1768 |
-+ int temp; |
1769 |
-+ |
1770 |
-+ /* |
1771 |
-+ * Unlinks could happen here; completion reporting |
1772 |
-+ * drops the lock. That's why ehci->qh_scan_next |
1773 |
-+ * always holds the next qh to scan; if the next qh |
1774 |
-+ * gets unlinked then ehci->qh_scan_next is adjusted |
1775 |
-+ * in start_unlink_async(). |
1776 |
- */ |
1777 |
-- if (list_empty(&qh->qtd_list) |
1778 |
-- && qh->qh_state == QH_STATE_LINKED) { |
1779 |
-- if (!ehci->reclaim && (stopped || |
1780 |
-- ((ehci->stamp - qh->stamp) & 0x1fff) |
1781 |
-- >= EHCI_SHRINK_FRAMES * 8)) |
1782 |
-- start_unlink_async(ehci, qh); |
1783 |
-- else |
1784 |
-- action = TIMER_ASYNC_SHRINK; |
1785 |
-- } |
1786 |
-+ qh = qh_get(qh); |
1787 |
-+ temp = qh_completions(ehci, qh); |
1788 |
-+ if (qh->needs_rescan) |
1789 |
-+ unlink_async(ehci, qh); |
1790 |
-+ qh->unlink_time = jiffies + EHCI_SHRINK_JIFFIES; |
1791 |
-+ qh_put(qh); |
1792 |
-+ if (temp != 0) |
1793 |
-+ goto rescan; |
1794 |
-+ } |
1795 |
- |
1796 |
-- qh = qh->qh_next.qh; |
1797 |
-- } while (qh); |
1798 |
-+ /* unlink idle entries, reducing DMA usage as well |
1799 |
-+ * as HCD schedule-scanning costs. delay for any qh |
1800 |
-+ * we just scanned, there's a not-unusual case that it |
1801 |
-+ * doesn't stay idle for long. |
1802 |
-+ * (plus, avoids some kind of re-activation race.) |
1803 |
-+ */ |
1804 |
-+ if (list_empty(&qh->qtd_list) |
1805 |
-+ && qh->qh_state == QH_STATE_LINKED) { |
1806 |
-+ if (!ehci->reclaim && (stopped || |
1807 |
-+ time_after_eq(jiffies, qh->unlink_time))) |
1808 |
-+ start_unlink_async(ehci, qh); |
1809 |
-+ else |
1810 |
-+ action = TIMER_ASYNC_SHRINK; |
1811 |
-+ } |
1812 |
- } |
1813 |
- if (action == TIMER_ASYNC_SHRINK) |
1814 |
- timer_action (ehci, TIMER_ASYNC_SHRINK); |
1815 |
-diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h |
1816 |
-index bd6ff48..989e0a8 100644 |
1817 |
---- a/drivers/usb/host/ehci.h |
1818 |
-+++ b/drivers/usb/host/ehci.h |
1819 |
-@@ -75,6 +75,7 @@ struct ehci_hcd { /* one per controller */ |
1820 |
- struct ehci_qh *async; |
1821 |
- struct ehci_qh *dummy; /* For AMD quirk use */ |
1822 |
- struct ehci_qh *reclaim; |
1823 |
-+ struct ehci_qh *qh_scan_next; |
1824 |
- unsigned scanning : 1; |
1825 |
- |
1826 |
- /* periodic schedule support */ |
1827 |
-@@ -117,7 +118,6 @@ struct ehci_hcd { /* one per controller */ |
1828 |
- struct timer_list iaa_watchdog; |
1829 |
- struct timer_list watchdog; |
1830 |
- unsigned long actions; |
1831 |
-- unsigned stamp; |
1832 |
- unsigned periodic_stamp; |
1833 |
- unsigned random_frame; |
1834 |
- unsigned long next_statechange; |
1835 |
-@@ -343,6 +343,7 @@ struct ehci_qh { |
1836 |
- struct ehci_qh *reclaim; /* next to reclaim */ |
1837 |
- |
1838 |
- struct ehci_hcd *ehci; |
1839 |
-+ unsigned long unlink_time; |
1840 |
- |
1841 |
- /* |
1842 |
- * Do NOT use atomic operations for QH refcounting. On some CPUs |
1843 |
-@@ -374,6 +375,7 @@ struct ehci_qh { |
1844 |
- #define NO_FRAME ((unsigned short)~0) /* pick new start */ |
1845 |
- |
1846 |
- struct usb_device *dev; /* access to TT */ |
1847 |
-+ unsigned is_out:1; /* bulk or intr OUT */ |
1848 |
- unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ |
1849 |
- }; |
1850 |
- |
1851 |
-diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c |
1852 |
-index fd93061..04b90ad 100644 |
1853 |
---- a/drivers/usb/host/pci-quirks.c |
1854 |
-+++ b/drivers/usb/host/pci-quirks.c |
1855 |
-@@ -35,6 +35,8 @@ |
1856 |
- #define OHCI_INTRSTATUS 0x0c |
1857 |
- #define OHCI_INTRENABLE 0x10 |
1858 |
- #define OHCI_INTRDISABLE 0x14 |
1859 |
-+#define OHCI_FMINTERVAL 0x34 |
1860 |
-+#define OHCI_HCR (1 << 0) /* host controller reset */ |
1861 |
- #define OHCI_OCR (1 << 3) /* ownership change request */ |
1862 |
- #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ |
1863 |
- #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ |
1864 |
-@@ -497,6 +499,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) |
1865 |
- |
1866 |
- /* reset controller, preserving RWC (and possibly IR) */ |
1867 |
- writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); |
1868 |
-+ readl(base + OHCI_CONTROL); |
1869 |
-+ |
1870 |
-+ /* Some NVIDIA controllers stop working if kept in RESET for too long */ |
1871 |
-+ if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { |
1872 |
-+ u32 fminterval; |
1873 |
-+ int cnt; |
1874 |
-+ |
1875 |
-+ /* drive reset for at least 50 ms (7.1.7.5) */ |
1876 |
-+ msleep(50); |
1877 |
-+ |
1878 |
-+ /* software reset of the controller, preserving HcFmInterval */ |
1879 |
-+ fminterval = readl(base + OHCI_FMINTERVAL); |
1880 |
-+ writel(OHCI_HCR, base + OHCI_CMDSTATUS); |
1881 |
-+ |
1882 |
-+ /* reset requires max 10 us delay */ |
1883 |
-+ for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */ |
1884 |
-+ if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) |
1885 |
-+ break; |
1886 |
-+ udelay(1); |
1887 |
-+ } |
1888 |
-+ writel(fminterval, base + OHCI_FMINTERVAL); |
1889 |
-+ |
1890 |
-+ /* Now we're in the SUSPEND state with all devices reset |
1891 |
-+ * and wakeups and interrupts disabled |
1892 |
-+ */ |
1893 |
-+ } |
1894 |
- |
1895 |
- /* |
1896 |
- * disable interrupts |
1897 |
-diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c |
1898 |
-index c71b037..dce7182 100644 |
1899 |
---- a/drivers/usb/musb/musb_core.c |
1900 |
-+++ b/drivers/usb/musb/musb_core.c |
1901 |
-@@ -2329,6 +2329,7 @@ static void musb_restore_context(struct musb *musb) |
1902 |
- musb->context.index_regs[i].rxhubport); |
1903 |
- } |
1904 |
- } |
1905 |
-+ musb_writeb(musb_base, MUSB_INDEX, musb->context.index); |
1906 |
- } |
1907 |
- |
1908 |
- static int musb_suspend(struct device *dev) |
1909 |
-diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c |
1910 |
-index 30461fc..0c20831 100644 |
1911 |
---- a/drivers/usb/serial/pl2303.c |
1912 |
-+++ b/drivers/usb/serial/pl2303.c |
1913 |
-@@ -91,6 +91,7 @@ static const struct usb_device_id id_table[] = { |
1914 |
- { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, |
1915 |
- { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, |
1916 |
- { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, |
1917 |
-+ { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) }, |
1918 |
- { } /* Terminating entry */ |
1919 |
- }; |
1920 |
- |
1921 |
-diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h |
1922 |
-index 1b025f7..ca0d237 100644 |
1923 |
---- a/drivers/usb/serial/pl2303.h |
1924 |
-+++ b/drivers/usb/serial/pl2303.h |
1925 |
-@@ -144,3 +144,7 @@ |
1926 |
- /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ |
1927 |
- #define ADLINK_VENDOR_ID 0x0b63 |
1928 |
- #define ADLINK_ND6530_PRODUCT_ID 0x6530 |
1929 |
-+ |
1930 |
-+/* WinChipHead USB->RS 232 adapter */ |
1931 |
-+#define WINCHIPHEAD_VENDOR_ID 0x4348 |
1932 |
-+#define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523 |
1933 |
-diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c |
1934 |
-index db84f23..a267dc0 100644 |
1935 |
---- a/drivers/watchdog/shwdt.c |
1936 |
-+++ b/drivers/watchdog/shwdt.c |
1937 |
-@@ -64,7 +64,7 @@ |
1938 |
- * misses its deadline, the kernel timer will allow the WDT to overflow. |
1939 |
- */ |
1940 |
- static int clock_division_ratio = WTCSR_CKS_4096; |
1941 |
--#define next_ping_period(cks) msecs_to_jiffies(cks - 4) |
1942 |
-+#define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) |
1943 |
- |
1944 |
- static const struct watchdog_info sh_wdt_info; |
1945 |
- static struct platform_device *sh_wdt_dev; |
1946 |
-diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c |
1947 |
-index fa8c21d..d8d26f3 100644 |
1948 |
---- a/fs/cifs/dir.c |
1949 |
-+++ b/fs/cifs/dir.c |
1950 |
-@@ -641,7 +641,7 @@ lookup_out: |
1951 |
- static int |
1952 |
- cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) |
1953 |
- { |
1954 |
-- if (nd->flags & LOOKUP_RCU) |
1955 |
-+ if (nd && (nd->flags & LOOKUP_RCU)) |
1956 |
- return -ECHILD; |
1957 |
- |
1958 |
- if (direntry->d_inode) { |
1959 |
-diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c |
1960 |
-index 7349ade..4a4fad7 100644 |
1961 |
---- a/fs/ecryptfs/inode.c |
1962 |
-+++ b/fs/ecryptfs/inode.c |
1963 |
-@@ -69,6 +69,7 @@ static int ecryptfs_inode_set(struct inode *inode, void *opaque) |
1964 |
- inode->i_ino = lower_inode->i_ino; |
1965 |
- inode->i_version++; |
1966 |
- inode->i_mapping->a_ops = &ecryptfs_aops; |
1967 |
-+ inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi; |
1968 |
- |
1969 |
- if (S_ISLNK(inode->i_mode)) |
1970 |
- inode->i_op = &ecryptfs_symlink_iops; |
1971 |
-diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c |
1972 |
-index 27a7fef..89dc18e 100644 |
1973 |
---- a/fs/ecryptfs/keystore.c |
1974 |
-+++ b/fs/ecryptfs/keystore.c |
1975 |
-@@ -1868,11 +1868,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, |
1976 |
- * just one will be sufficient to decrypt to get the FEK. */ |
1977 |
- find_next_matching_auth_tok: |
1978 |
- found_auth_tok = 0; |
1979 |
-- if (auth_tok_key) { |
1980 |
-- up_write(&(auth_tok_key->sem)); |
1981 |
-- key_put(auth_tok_key); |
1982 |
-- auth_tok_key = NULL; |
1983 |
-- } |
1984 |
- list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) { |
1985 |
- candidate_auth_tok = &auth_tok_list_item->auth_tok; |
1986 |
- if (unlikely(ecryptfs_verbosity > 0)) { |
1987 |
-@@ -1909,14 +1904,22 @@ found_matching_auth_tok: |
1988 |
- memcpy(&(candidate_auth_tok->token.private_key), |
1989 |
- &(matching_auth_tok->token.private_key), |
1990 |
- sizeof(struct ecryptfs_private_key)); |
1991 |
-+ up_write(&(auth_tok_key->sem)); |
1992 |
-+ key_put(auth_tok_key); |
1993 |
- rc = decrypt_pki_encrypted_session_key(candidate_auth_tok, |
1994 |
- crypt_stat); |
1995 |
- } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { |
1996 |
- memcpy(&(candidate_auth_tok->token.password), |
1997 |
- &(matching_auth_tok->token.password), |
1998 |
- sizeof(struct ecryptfs_password)); |
1999 |
-+ up_write(&(auth_tok_key->sem)); |
2000 |
-+ key_put(auth_tok_key); |
2001 |
- rc = decrypt_passphrase_encrypted_session_key( |
2002 |
- candidate_auth_tok, crypt_stat); |
2003 |
-+ } else { |
2004 |
-+ up_write(&(auth_tok_key->sem)); |
2005 |
-+ key_put(auth_tok_key); |
2006 |
-+ rc = -EINVAL; |
2007 |
- } |
2008 |
- if (rc) { |
2009 |
- struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp; |
2010 |
-@@ -1956,15 +1959,12 @@ found_matching_auth_tok: |
2011 |
- out_wipe_list: |
2012 |
- wipe_auth_tok_list(&auth_tok_list); |
2013 |
- out: |
2014 |
-- if (auth_tok_key) { |
2015 |
-- up_write(&(auth_tok_key->sem)); |
2016 |
-- key_put(auth_tok_key); |
2017 |
-- } |
2018 |
- return rc; |
2019 |
- } |
2020 |
- |
2021 |
- static int |
2022 |
--pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, |
2023 |
-+pki_encrypt_session_key(struct key *auth_tok_key, |
2024 |
-+ struct ecryptfs_auth_tok *auth_tok, |
2025 |
- struct ecryptfs_crypt_stat *crypt_stat, |
2026 |
- struct ecryptfs_key_record *key_rec) |
2027 |
- { |
2028 |
-@@ -1979,6 +1979,8 @@ pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, |
2029 |
- crypt_stat->cipher, |
2030 |
- crypt_stat->key_size), |
2031 |
- crypt_stat, &payload, &payload_len); |
2032 |
-+ up_write(&(auth_tok_key->sem)); |
2033 |
-+ key_put(auth_tok_key); |
2034 |
- if (rc) { |
2035 |
- ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); |
2036 |
- goto out; |
2037 |
-@@ -2008,6 +2010,8 @@ out: |
2038 |
- * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet |
2039 |
- * @dest: Buffer into which to write the packet |
2040 |
- * @remaining_bytes: Maximum number of bytes that can be writtn |
2041 |
-+ * @auth_tok_key: The authentication token key to unlock and put when done with |
2042 |
-+ * @auth_tok |
2043 |
- * @auth_tok: The authentication token used for generating the tag 1 packet |
2044 |
- * @crypt_stat: The cryptographic context |
2045 |
- * @key_rec: The key record struct for the tag 1 packet |
2046 |
-@@ -2018,7 +2022,7 @@ out: |
2047 |
- */ |
2048 |
- static int |
2049 |
- write_tag_1_packet(char *dest, size_t *remaining_bytes, |
2050 |
-- struct ecryptfs_auth_tok *auth_tok, |
2051 |
-+ struct key *auth_tok_key, struct ecryptfs_auth_tok *auth_tok, |
2052 |
- struct ecryptfs_crypt_stat *crypt_stat, |
2053 |
- struct ecryptfs_key_record *key_rec, size_t *packet_size) |
2054 |
- { |
2055 |
-@@ -2039,12 +2043,15 @@ write_tag_1_packet(char *dest, size_t *remaining_bytes, |
2056 |
- memcpy(key_rec->enc_key, |
2057 |
- auth_tok->session_key.encrypted_key, |
2058 |
- auth_tok->session_key.encrypted_key_size); |
2059 |
-+ up_write(&(auth_tok_key->sem)); |
2060 |
-+ key_put(auth_tok_key); |
2061 |
- goto encrypted_session_key_set; |
2062 |
- } |
2063 |
- if (auth_tok->session_key.encrypted_key_size == 0) |
2064 |
- auth_tok->session_key.encrypted_key_size = |
2065 |
- auth_tok->token.private_key.key_size; |
2066 |
-- rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec); |
2067 |
-+ rc = pki_encrypt_session_key(auth_tok_key, auth_tok, crypt_stat, |
2068 |
-+ key_rec); |
2069 |
- if (rc) { |
2070 |
- printk(KERN_ERR "Failed to encrypt session key via a key " |
2071 |
- "module; rc = [%d]\n", rc); |
2072 |
-@@ -2421,6 +2428,8 @@ ecryptfs_generate_key_packet_set(char *dest_base, |
2073 |
- &max, auth_tok, |
2074 |
- crypt_stat, key_rec, |
2075 |
- &written); |
2076 |
-+ up_write(&(auth_tok_key->sem)); |
2077 |
-+ key_put(auth_tok_key); |
2078 |
- if (rc) { |
2079 |
- ecryptfs_printk(KERN_WARNING, "Error " |
2080 |
- "writing tag 3 packet\n"); |
2081 |
-@@ -2438,8 +2447,8 @@ ecryptfs_generate_key_packet_set(char *dest_base, |
2082 |
- } |
2083 |
- (*len) += written; |
2084 |
- } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { |
2085 |
-- rc = write_tag_1_packet(dest_base + (*len), |
2086 |
-- &max, auth_tok, |
2087 |
-+ rc = write_tag_1_packet(dest_base + (*len), &max, |
2088 |
-+ auth_tok_key, auth_tok, |
2089 |
- crypt_stat, key_rec, &written); |
2090 |
- if (rc) { |
2091 |
- ecryptfs_printk(KERN_WARNING, "Error " |
2092 |
-@@ -2448,14 +2457,13 @@ ecryptfs_generate_key_packet_set(char *dest_base, |
2093 |
- } |
2094 |
- (*len) += written; |
2095 |
- } else { |
2096 |
-+ up_write(&(auth_tok_key->sem)); |
2097 |
-+ key_put(auth_tok_key); |
2098 |
- ecryptfs_printk(KERN_WARNING, "Unsupported " |
2099 |
- "authentication token type\n"); |
2100 |
- rc = -EINVAL; |
2101 |
- goto out_free; |
2102 |
- } |
2103 |
-- up_write(&(auth_tok_key->sem)); |
2104 |
-- key_put(auth_tok_key); |
2105 |
-- auth_tok_key = NULL; |
2106 |
- } |
2107 |
- if (likely(max > 0)) { |
2108 |
- dest_base[(*len)] = 0x00; |
2109 |
-@@ -2468,11 +2476,6 @@ out_free: |
2110 |
- out: |
2111 |
- if (rc) |
2112 |
- (*len) = 0; |
2113 |
-- if (auth_tok_key) { |
2114 |
-- up_write(&(auth_tok_key->sem)); |
2115 |
-- key_put(auth_tok_key); |
2116 |
-- } |
2117 |
-- |
2118 |
- mutex_unlock(&crypt_stat->keysig_list_mutex); |
2119 |
- return rc; |
2120 |
- } |
2121 |
-diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c |
2122 |
-index 32e6cc2..d565759 100644 |
2123 |
---- a/fs/ext3/xattr.c |
2124 |
-+++ b/fs/ext3/xattr.c |
2125 |
-@@ -803,8 +803,16 @@ inserted: |
2126 |
- /* We need to allocate a new block */ |
2127 |
- ext3_fsblk_t goal = ext3_group_first_block_no(sb, |
2128 |
- EXT3_I(inode)->i_block_group); |
2129 |
-- ext3_fsblk_t block = ext3_new_block(handle, inode, |
2130 |
-- goal, &error); |
2131 |
-+ ext3_fsblk_t block; |
2132 |
-+ |
2133 |
-+ /* |
2134 |
-+ * Protect us agaist concurrent allocations to the |
2135 |
-+ * same inode from ext3_..._writepage(). Reservation |
2136 |
-+ * code does not expect racing allocations. |
2137 |
-+ */ |
2138 |
-+ mutex_lock(&EXT3_I(inode)->truncate_mutex); |
2139 |
-+ block = ext3_new_block(handle, inode, goal, &error); |
2140 |
-+ mutex_unlock(&EXT3_I(inode)->truncate_mutex); |
2141 |
- if (error) |
2142 |
- goto cleanup; |
2143 |
- ea_idebug(inode, "creating block %d", block); |
2144 |
-diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h |
2145 |
-index 1921392..354619a 100644 |
2146 |
---- a/fs/ext4/ext4.h |
2147 |
-+++ b/fs/ext4/ext4.h |
2148 |
-@@ -526,6 +526,7 @@ struct ext4_new_group_data { |
2149 |
- #define EXT4_FREE_BLOCKS_METADATA 0x0001 |
2150 |
- #define EXT4_FREE_BLOCKS_FORGET 0x0002 |
2151 |
- #define EXT4_FREE_BLOCKS_VALIDATED 0x0004 |
2152 |
-+#define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE 0x0008 |
2153 |
- |
2154 |
- /* |
2155 |
- * ioctl commands |
2156 |
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c |
2157 |
-index f815cc8..f3aacb3 100644 |
2158 |
---- a/fs/ext4/extents.c |
2159 |
-+++ b/fs/ext4/extents.c |
2160 |
-@@ -3596,17 +3596,18 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, |
2161 |
- } |
2162 |
- |
2163 |
- err = check_eofblocks_fl(handle, inode, map->m_lblk, path, ar.len); |
2164 |
-- if (err) |
2165 |
-- goto out2; |
2166 |
-- |
2167 |
-- err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); |
2168 |
-+ if (!err) |
2169 |
-+ err = ext4_ext_insert_extent(handle, inode, path, |
2170 |
-+ &newex, flags); |
2171 |
- if (err) { |
2172 |
-+ int fb_flags = flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE ? |
2173 |
-+ EXT4_FREE_BLOCKS_NO_QUOT_UPDATE : 0; |
2174 |
- /* free data blocks we just allocated */ |
2175 |
- /* not a good idea to call discard here directly, |
2176 |
- * but otherwise we'd need to call it every free() */ |
2177 |
- ext4_discard_preallocations(inode); |
2178 |
- ext4_free_blocks(handle, inode, NULL, ext4_ext_pblock(&newex), |
2179 |
-- ext4_ext_get_actual_len(&newex), 0); |
2180 |
-+ ext4_ext_get_actual_len(&newex), fb_flags); |
2181 |
- goto out2; |
2182 |
- } |
2183 |
- |
2184 |
-diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c |
2185 |
-index 6ed859d..0f1be7f 100644 |
2186 |
---- a/fs/ext4/mballoc.c |
2187 |
-+++ b/fs/ext4/mballoc.c |
2188 |
-@@ -4637,7 +4637,7 @@ do_more: |
2189 |
- } |
2190 |
- ext4_mark_super_dirty(sb); |
2191 |
- error_return: |
2192 |
-- if (freed) |
2193 |
-+ if (freed && !(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE)) |
2194 |
- dquot_free_block(inode, freed); |
2195 |
- brelse(bitmap_bh); |
2196 |
- ext4_std_error(sb, err); |
2197 |
-diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c |
2198 |
-index 2a77071..fa780e6 100644 |
2199 |
---- a/fs/gfs2/ops_fstype.c |
2200 |
-+++ b/fs/gfs2/ops_fstype.c |
2201 |
-@@ -1018,13 +1018,13 @@ hostdata_error: |
2202 |
- fsname++; |
2203 |
- if (lm->lm_mount == NULL) { |
2204 |
- fs_info(sdp, "Now mounting FS...\n"); |
2205 |
-- complete(&sdp->sd_locking_init); |
2206 |
-+ complete_all(&sdp->sd_locking_init); |
2207 |
- return 0; |
2208 |
- } |
2209 |
- ret = lm->lm_mount(sdp, fsname); |
2210 |
- if (ret == 0) |
2211 |
- fs_info(sdp, "Joined cluster. Now mounting FS...\n"); |
2212 |
-- complete(&sdp->sd_locking_init); |
2213 |
-+ complete_all(&sdp->sd_locking_init); |
2214 |
- return ret; |
2215 |
- } |
2216 |
- |
2217 |
-diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c |
2218 |
-index dd25c2a..321a66b 100644 |
2219 |
---- a/fs/nfs/delegation.c |
2220 |
-+++ b/fs/nfs/delegation.c |
2221 |
-@@ -398,12 +398,11 @@ int nfs_inode_return_delegation(struct inode *inode) |
2222 |
- return err; |
2223 |
- } |
2224 |
- |
2225 |
--static void nfs_mark_return_delegation(struct nfs_delegation *delegation) |
2226 |
-+static void nfs_mark_return_delegation(struct nfs_server *server, |
2227 |
-+ struct nfs_delegation *delegation) |
2228 |
- { |
2229 |
-- struct nfs_client *clp = NFS_SERVER(delegation->inode)->nfs_client; |
2230 |
-- |
2231 |
- set_bit(NFS_DELEGATION_RETURN, &delegation->flags); |
2232 |
-- set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state); |
2233 |
-+ set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state); |
2234 |
- } |
2235 |
- |
2236 |
- /** |
2237 |
-@@ -441,7 +440,7 @@ static void nfs_mark_return_all_delegation_types(struct nfs_server *server, |
2238 |
- if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE)) |
2239 |
- continue; |
2240 |
- if (delegation->type & flags) |
2241 |
-- nfs_mark_return_delegation(delegation); |
2242 |
-+ nfs_mark_return_delegation(server, delegation); |
2243 |
- } |
2244 |
- } |
2245 |
- |
2246 |
-@@ -508,7 +507,7 @@ static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server) |
2247 |
- list_for_each_entry_rcu(delegation, &server->delegations, super_list) { |
2248 |
- if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) |
2249 |
- continue; |
2250 |
-- nfs_mark_return_delegation(delegation); |
2251 |
-+ nfs_mark_return_delegation(server, delegation); |
2252 |
- } |
2253 |
- } |
2254 |
- |
2255 |
-@@ -539,7 +538,8 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp) |
2256 |
- int nfs_async_inode_return_delegation(struct inode *inode, |
2257 |
- const nfs4_stateid *stateid) |
2258 |
- { |
2259 |
-- struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; |
2260 |
-+ struct nfs_server *server = NFS_SERVER(inode); |
2261 |
-+ struct nfs_client *clp = server->nfs_client; |
2262 |
- struct nfs_delegation *delegation; |
2263 |
- |
2264 |
- rcu_read_lock(); |
2265 |
-@@ -549,7 +549,7 @@ int nfs_async_inode_return_delegation(struct inode *inode, |
2266 |
- rcu_read_unlock(); |
2267 |
- return -ENOENT; |
2268 |
- } |
2269 |
-- nfs_mark_return_delegation(delegation); |
2270 |
-+ nfs_mark_return_delegation(server, delegation); |
2271 |
- rcu_read_unlock(); |
2272 |
- |
2273 |
- nfs_delegation_run_state_manager(clp); |
2274 |
-diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c |
2275 |
-index ededdbd..f91c62d 100644 |
2276 |
---- a/fs/nfs/dir.c |
2277 |
-+++ b/fs/nfs/dir.c |
2278 |
-@@ -134,18 +134,19 @@ const struct inode_operations nfs4_dir_inode_operations = { |
2279 |
- |
2280 |
- #endif /* CONFIG_NFS_V4 */ |
2281 |
- |
2282 |
--static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct rpc_cred *cred) |
2283 |
-+static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, struct rpc_cred *cred) |
2284 |
- { |
2285 |
- struct nfs_open_dir_context *ctx; |
2286 |
- ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
2287 |
- if (ctx != NULL) { |
2288 |
- ctx->duped = 0; |
2289 |
-+ ctx->attr_gencount = NFS_I(dir)->attr_gencount; |
2290 |
- ctx->dir_cookie = 0; |
2291 |
- ctx->dup_cookie = 0; |
2292 |
- ctx->cred = get_rpccred(cred); |
2293 |
-- } else |
2294 |
-- ctx = ERR_PTR(-ENOMEM); |
2295 |
-- return ctx; |
2296 |
-+ return ctx; |
2297 |
-+ } |
2298 |
-+ return ERR_PTR(-ENOMEM); |
2299 |
- } |
2300 |
- |
2301 |
- static void put_nfs_open_dir_context(struct nfs_open_dir_context *ctx) |
2302 |
-@@ -173,7 +174,7 @@ nfs_opendir(struct inode *inode, struct file *filp) |
2303 |
- cred = rpc_lookup_cred(); |
2304 |
- if (IS_ERR(cred)) |
2305 |
- return PTR_ERR(cred); |
2306 |
-- ctx = alloc_nfs_open_dir_context(cred); |
2307 |
-+ ctx = alloc_nfs_open_dir_context(inode, cred); |
2308 |
- if (IS_ERR(ctx)) { |
2309 |
- res = PTR_ERR(ctx); |
2310 |
- goto out; |
2311 |
-@@ -323,7 +324,6 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri |
2312 |
- { |
2313 |
- loff_t diff = desc->file->f_pos - desc->current_index; |
2314 |
- unsigned int index; |
2315 |
-- struct nfs_open_dir_context *ctx = desc->file->private_data; |
2316 |
- |
2317 |
- if (diff < 0) |
2318 |
- goto out_eof; |
2319 |
-@@ -336,7 +336,6 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri |
2320 |
- index = (unsigned int)diff; |
2321 |
- *desc->dir_cookie = array->array[index].cookie; |
2322 |
- desc->cache_entry_index = index; |
2323 |
-- ctx->duped = 0; |
2324 |
- return 0; |
2325 |
- out_eof: |
2326 |
- desc->eof = 1; |
2327 |
-@@ -349,14 +348,33 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des |
2328 |
- int i; |
2329 |
- loff_t new_pos; |
2330 |
- int status = -EAGAIN; |
2331 |
-- struct nfs_open_dir_context *ctx = desc->file->private_data; |
2332 |
- |
2333 |
- for (i = 0; i < array->size; i++) { |
2334 |
- if (array->array[i].cookie == *desc->dir_cookie) { |
2335 |
-+ struct nfs_inode *nfsi = NFS_I(desc->file->f_path.dentry->d_inode); |
2336 |
-+ struct nfs_open_dir_context *ctx = desc->file->private_data; |
2337 |
-+ |
2338 |
- new_pos = desc->current_index + i; |
2339 |
-- if (new_pos < desc->file->f_pos) { |
2340 |
-+ if (ctx->attr_gencount != nfsi->attr_gencount |
2341 |
-+ || (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))) { |
2342 |
-+ ctx->duped = 0; |
2343 |
-+ ctx->attr_gencount = nfsi->attr_gencount; |
2344 |
-+ } else if (new_pos < desc->file->f_pos) { |
2345 |
-+ if (ctx->duped > 0 |
2346 |
-+ && ctx->dup_cookie == *desc->dir_cookie) { |
2347 |
-+ if (printk_ratelimit()) { |
2348 |
-+ pr_notice("NFS: directory %s/%s contains a readdir loop." |
2349 |
-+ "Please contact your server vendor. " |
2350 |
-+ "Offending cookie: %llu\n", |
2351 |
-+ desc->file->f_dentry->d_parent->d_name.name, |
2352 |
-+ desc->file->f_dentry->d_name.name, |
2353 |
-+ *desc->dir_cookie); |
2354 |
-+ } |
2355 |
-+ status = -ELOOP; |
2356 |
-+ goto out; |
2357 |
-+ } |
2358 |
- ctx->dup_cookie = *desc->dir_cookie; |
2359 |
-- ctx->duped = 1; |
2360 |
-+ ctx->duped = -1; |
2361 |
- } |
2362 |
- desc->file->f_pos = new_pos; |
2363 |
- desc->cache_entry_index = i; |
2364 |
-@@ -368,6 +386,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des |
2365 |
- if (*desc->dir_cookie == array->last_cookie) |
2366 |
- desc->eof = 1; |
2367 |
- } |
2368 |
-+out: |
2369 |
- return status; |
2370 |
- } |
2371 |
- |
2372 |
-@@ -740,19 +759,6 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, |
2373 |
- struct nfs_cache_array *array = NULL; |
2374 |
- struct nfs_open_dir_context *ctx = file->private_data; |
2375 |
- |
2376 |
-- if (ctx->duped != 0 && ctx->dup_cookie == *desc->dir_cookie) { |
2377 |
-- if (printk_ratelimit()) { |
2378 |
-- pr_notice("NFS: directory %s/%s contains a readdir loop. " |
2379 |
-- "Please contact your server vendor. " |
2380 |
-- "Offending cookie: %llu\n", |
2381 |
-- file->f_dentry->d_parent->d_name.name, |
2382 |
-- file->f_dentry->d_name.name, |
2383 |
-- *desc->dir_cookie); |
2384 |
-- } |
2385 |
-- res = -ELOOP; |
2386 |
-- goto out; |
2387 |
-- } |
2388 |
-- |
2389 |
- array = nfs_readdir_get_array(desc->page); |
2390 |
- if (IS_ERR(array)) { |
2391 |
- res = PTR_ERR(array); |
2392 |
-@@ -774,6 +780,8 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, |
2393 |
- *desc->dir_cookie = array->array[i+1].cookie; |
2394 |
- else |
2395 |
- *desc->dir_cookie = array->last_cookie; |
2396 |
-+ if (ctx->duped != 0) |
2397 |
-+ ctx->duped = 1; |
2398 |
- } |
2399 |
- if (array->eof_index >= 0) |
2400 |
- desc->eof = 1; |
2401 |
-@@ -805,6 +813,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, |
2402 |
- struct page *page = NULL; |
2403 |
- int status; |
2404 |
- struct inode *inode = desc->file->f_path.dentry->d_inode; |
2405 |
-+ struct nfs_open_dir_context *ctx = desc->file->private_data; |
2406 |
- |
2407 |
- dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n", |
2408 |
- (unsigned long long)*desc->dir_cookie); |
2409 |
-@@ -818,6 +827,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, |
2410 |
- desc->page_index = 0; |
2411 |
- desc->last_cookie = *desc->dir_cookie; |
2412 |
- desc->page = page; |
2413 |
-+ ctx->duped = 0; |
2414 |
- |
2415 |
- status = nfs_readdir_xdr_to_array(desc, page, inode); |
2416 |
- if (status < 0) |
2417 |
-diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c |
2418 |
-index f9d03ab..614c4d2 100644 |
2419 |
---- a/fs/nfs/nfs4filelayout.c |
2420 |
-+++ b/fs/nfs/nfs4filelayout.c |
2421 |
-@@ -170,7 +170,7 @@ filelayout_set_layoutcommit(struct nfs_write_data *wdata) |
2422 |
- |
2423 |
- pnfs_set_layoutcommit(wdata); |
2424 |
- dprintk("%s ionde %lu pls_end_pos %lu\n", __func__, wdata->inode->i_ino, |
2425 |
-- (unsigned long) wdata->lseg->pls_end_pos); |
2426 |
-+ (unsigned long) NFS_I(wdata->inode)->layout->plh_lwb); |
2427 |
- } |
2428 |
- |
2429 |
- /* |
2430 |
-diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c |
2431 |
-index 5879b23..92cfd2e 100644 |
2432 |
---- a/fs/nfs/nfs4proc.c |
2433 |
-+++ b/fs/nfs/nfs4proc.c |
2434 |
-@@ -5850,9 +5850,15 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata) |
2435 |
- static void nfs4_layoutcommit_release(void *calldata) |
2436 |
- { |
2437 |
- struct nfs4_layoutcommit_data *data = calldata; |
2438 |
-+ struct pnfs_layout_segment *lseg, *tmp; |
2439 |
- |
2440 |
- /* Matched by references in pnfs_set_layoutcommit */ |
2441 |
-- put_lseg(data->lseg); |
2442 |
-+ list_for_each_entry_safe(lseg, tmp, &data->lseg_list, pls_lc_list) { |
2443 |
-+ list_del_init(&lseg->pls_lc_list); |
2444 |
-+ if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, |
2445 |
-+ &lseg->pls_flags)) |
2446 |
-+ put_lseg(lseg); |
2447 |
-+ } |
2448 |
- put_rpccred(data->cred); |
2449 |
- kfree(data); |
2450 |
- } |
2451 |
-diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c |
2452 |
-index e6e8f3b..fc97fd5 100644 |
2453 |
---- a/fs/nfs/nfs4xdr.c |
2454 |
-+++ b/fs/nfs/nfs4xdr.c |
2455 |
-@@ -1888,7 +1888,7 @@ encode_layoutcommit(struct xdr_stream *xdr, |
2456 |
- *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); |
2457 |
- /* Only whole file layouts */ |
2458 |
- p = xdr_encode_hyper(p, 0); /* offset */ |
2459 |
-- p = xdr_encode_hyper(p, NFS4_MAX_UINT64); /* length */ |
2460 |
-+ p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */ |
2461 |
- *p++ = cpu_to_be32(0); /* reclaim */ |
2462 |
- p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE); |
2463 |
- *p++ = cpu_to_be32(1); /* newoffset = TRUE */ |
2464 |
-diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c |
2465 |
-index 29c0ca7..a726c0a 100644 |
2466 |
---- a/fs/nfs/pnfs.c |
2467 |
-+++ b/fs/nfs/pnfs.c |
2468 |
-@@ -189,6 +189,7 @@ static void |
2469 |
- pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo) |
2470 |
- { |
2471 |
- struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld; |
2472 |
-+ put_rpccred(lo->plh_lc_cred); |
2473 |
- return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo); |
2474 |
- } |
2475 |
- |
2476 |
-@@ -223,6 +224,7 @@ static void |
2477 |
- init_lseg(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg) |
2478 |
- { |
2479 |
- INIT_LIST_HEAD(&lseg->pls_list); |
2480 |
-+ INIT_LIST_HEAD(&lseg->pls_lc_list); |
2481 |
- atomic_set(&lseg->pls_refcount, 1); |
2482 |
- smp_mb(); |
2483 |
- set_bit(NFS_LSEG_VALID, &lseg->pls_flags); |
2484 |
-@@ -805,7 +807,9 @@ out: |
2485 |
- } |
2486 |
- |
2487 |
- static struct pnfs_layout_hdr * |
2488 |
--alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags) |
2489 |
-+alloc_init_layout_hdr(struct inode *ino, |
2490 |
-+ struct nfs_open_context *ctx, |
2491 |
-+ gfp_t gfp_flags) |
2492 |
- { |
2493 |
- struct pnfs_layout_hdr *lo; |
2494 |
- |
2495 |
-@@ -817,11 +821,14 @@ alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags) |
2496 |
- INIT_LIST_HEAD(&lo->plh_segs); |
2497 |
- INIT_LIST_HEAD(&lo->plh_bulk_recall); |
2498 |
- lo->plh_inode = ino; |
2499 |
-+ lo->plh_lc_cred = get_rpccred(ctx->state->owner->so_cred); |
2500 |
- return lo; |
2501 |
- } |
2502 |
- |
2503 |
- static struct pnfs_layout_hdr * |
2504 |
--pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) |
2505 |
-+pnfs_find_alloc_layout(struct inode *ino, |
2506 |
-+ struct nfs_open_context *ctx, |
2507 |
-+ gfp_t gfp_flags) |
2508 |
- { |
2509 |
- struct nfs_inode *nfsi = NFS_I(ino); |
2510 |
- struct pnfs_layout_hdr *new = NULL; |
2511 |
-@@ -836,7 +843,7 @@ pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) |
2512 |
- return nfsi->layout; |
2513 |
- } |
2514 |
- spin_unlock(&ino->i_lock); |
2515 |
-- new = alloc_init_layout_hdr(ino, gfp_flags); |
2516 |
-+ new = alloc_init_layout_hdr(ino, ctx, gfp_flags); |
2517 |
- spin_lock(&ino->i_lock); |
2518 |
- |
2519 |
- if (likely(nfsi->layout == NULL)) /* Won the race? */ |
2520 |
-@@ -928,7 +935,7 @@ pnfs_update_layout(struct inode *ino, |
2521 |
- if (!pnfs_enabled_sb(NFS_SERVER(ino))) |
2522 |
- return NULL; |
2523 |
- spin_lock(&ino->i_lock); |
2524 |
-- lo = pnfs_find_alloc_layout(ino, gfp_flags); |
2525 |
-+ lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); |
2526 |
- if (lo == NULL) { |
2527 |
- dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__); |
2528 |
- goto out_unlock; |
2529 |
-@@ -1195,16 +1202,17 @@ pnfs_try_to_read_data(struct nfs_read_data *rdata, |
2530 |
- } |
2531 |
- |
2532 |
- /* |
2533 |
-- * Currently there is only one (whole file) write lseg. |
2534 |
-+ * There can be multiple RW segments. |
2535 |
- */ |
2536 |
--static struct pnfs_layout_segment *pnfs_list_write_lseg(struct inode *inode) |
2537 |
-+static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp) |
2538 |
- { |
2539 |
-- struct pnfs_layout_segment *lseg, *rv = NULL; |
2540 |
-+ struct pnfs_layout_segment *lseg; |
2541 |
- |
2542 |
-- list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) |
2543 |
-- if (lseg->pls_range.iomode == IOMODE_RW) |
2544 |
-- rv = lseg; |
2545 |
-- return rv; |
2546 |
-+ list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) { |
2547 |
-+ if (lseg->pls_range.iomode == IOMODE_RW && |
2548 |
-+ test_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags)) |
2549 |
-+ list_add(&lseg->pls_lc_list, listp); |
2550 |
-+ } |
2551 |
- } |
2552 |
- |
2553 |
- void |
2554 |
-@@ -1216,17 +1224,19 @@ pnfs_set_layoutcommit(struct nfs_write_data *wdata) |
2555 |
- |
2556 |
- spin_lock(&nfsi->vfs_inode.i_lock); |
2557 |
- if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { |
2558 |
-- /* references matched in nfs4_layoutcommit_release */ |
2559 |
-- get_lseg(wdata->lseg); |
2560 |
-- wdata->lseg->pls_lc_cred = |
2561 |
-- get_rpccred(wdata->args.context->state->owner->so_cred); |
2562 |
- mark_as_dirty = true; |
2563 |
- dprintk("%s: Set layoutcommit for inode %lu ", |
2564 |
- __func__, wdata->inode->i_ino); |
2565 |
- } |
2566 |
-- if (end_pos > wdata->lseg->pls_end_pos) |
2567 |
-- wdata->lseg->pls_end_pos = end_pos; |
2568 |
-+ if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &wdata->lseg->pls_flags)) { |
2569 |
-+ /* references matched in nfs4_layoutcommit_release */ |
2570 |
-+ get_lseg(wdata->lseg); |
2571 |
-+ } |
2572 |
-+ if (end_pos > nfsi->layout->plh_lwb) |
2573 |
-+ nfsi->layout->plh_lwb = end_pos; |
2574 |
- spin_unlock(&nfsi->vfs_inode.i_lock); |
2575 |
-+ dprintk("%s: lseg %p end_pos %llu\n", |
2576 |
-+ __func__, wdata->lseg, nfsi->layout->plh_lwb); |
2577 |
- |
2578 |
- /* if pnfs_layoutcommit_inode() runs between inode locks, the next one |
2579 |
- * will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */ |
2580 |
-@@ -1248,8 +1258,6 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync) |
2581 |
- { |
2582 |
- struct nfs4_layoutcommit_data *data; |
2583 |
- struct nfs_inode *nfsi = NFS_I(inode); |
2584 |
-- struct pnfs_layout_segment *lseg; |
2585 |
-- struct rpc_cred *cred; |
2586 |
- loff_t end_pos; |
2587 |
- int status = 0; |
2588 |
- |
2589 |
-@@ -1266,30 +1274,25 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync) |
2590 |
- goto out; |
2591 |
- } |
2592 |
- |
2593 |
-+ INIT_LIST_HEAD(&data->lseg_list); |
2594 |
- spin_lock(&inode->i_lock); |
2595 |
- if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { |
2596 |
- spin_unlock(&inode->i_lock); |
2597 |
- kfree(data); |
2598 |
- goto out; |
2599 |
- } |
2600 |
-- /* |
2601 |
-- * Currently only one (whole file) write lseg which is referenced |
2602 |
-- * in pnfs_set_layoutcommit and will be found. |
2603 |
-- */ |
2604 |
-- lseg = pnfs_list_write_lseg(inode); |
2605 |
- |
2606 |
-- end_pos = lseg->pls_end_pos; |
2607 |
-- cred = lseg->pls_lc_cred; |
2608 |
-- lseg->pls_end_pos = 0; |
2609 |
-- lseg->pls_lc_cred = NULL; |
2610 |
-+ pnfs_list_write_lseg(inode, &data->lseg_list); |
2611 |
-+ |
2612 |
-+ end_pos = nfsi->layout->plh_lwb; |
2613 |
-+ nfsi->layout->plh_lwb = 0; |
2614 |
- |
2615 |
- memcpy(&data->args.stateid.data, nfsi->layout->plh_stateid.data, |
2616 |
- sizeof(nfsi->layout->plh_stateid.data)); |
2617 |
- spin_unlock(&inode->i_lock); |
2618 |
- |
2619 |
- data->args.inode = inode; |
2620 |
-- data->lseg = lseg; |
2621 |
-- data->cred = cred; |
2622 |
-+ data->cred = get_rpccred(nfsi->layout->plh_lc_cred); |
2623 |
- nfs_fattr_init(&data->fattr); |
2624 |
- data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask; |
2625 |
- data->res.fattr = &data->fattr; |
2626 |
-diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h |
2627 |
-index 96bf4e6..9d147d9 100644 |
2628 |
---- a/fs/nfs/pnfs.h |
2629 |
-+++ b/fs/nfs/pnfs.h |
2630 |
-@@ -36,16 +36,16 @@ |
2631 |
- enum { |
2632 |
- NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */ |
2633 |
- NFS_LSEG_ROC, /* roc bit received from server */ |
2634 |
-+ NFS_LSEG_LAYOUTCOMMIT, /* layoutcommit bit set for layoutcommit */ |
2635 |
- }; |
2636 |
- |
2637 |
- struct pnfs_layout_segment { |
2638 |
- struct list_head pls_list; |
2639 |
-+ struct list_head pls_lc_list; |
2640 |
- struct pnfs_layout_range pls_range; |
2641 |
- atomic_t pls_refcount; |
2642 |
- unsigned long pls_flags; |
2643 |
- struct pnfs_layout_hdr *pls_layout; |
2644 |
-- struct rpc_cred *pls_lc_cred; /* LAYOUTCOMMIT credential */ |
2645 |
-- loff_t pls_end_pos; /* LAYOUTCOMMIT write end */ |
2646 |
- }; |
2647 |
- |
2648 |
- enum pnfs_try_status { |
2649 |
-@@ -124,6 +124,8 @@ struct pnfs_layout_hdr { |
2650 |
- unsigned long plh_block_lgets; /* block LAYOUTGET if >0 */ |
2651 |
- u32 plh_barrier; /* ignore lower seqids */ |
2652 |
- unsigned long plh_flags; |
2653 |
-+ loff_t plh_lwb; /* last write byte for layoutcommit */ |
2654 |
-+ struct rpc_cred *plh_lc_cred; /* layoutcommit cred */ |
2655 |
- struct inode *plh_inode; |
2656 |
- }; |
2657 |
- |
2658 |
-diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c |
2659 |
-index e98f3c2..3b8ad35 100644 |
2660 |
---- a/fs/nfsd/nfs4state.c |
2661 |
-+++ b/fs/nfsd/nfs4state.c |
2662 |
-@@ -381,14 +381,6 @@ static int nfs4_access_to_omode(u32 access) |
2663 |
- BUG(); |
2664 |
- } |
2665 |
- |
2666 |
--static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp) |
2667 |
--{ |
2668 |
-- unsigned int access; |
2669 |
-- |
2670 |
-- set_access(&access, stp->st_access_bmap); |
2671 |
-- return nfs4_access_to_omode(access); |
2672 |
--} |
2673 |
-- |
2674 |
- static void unhash_generic_stateid(struct nfs4_stateid *stp) |
2675 |
- { |
2676 |
- list_del(&stp->st_hash); |
2677 |
-@@ -398,11 +390,14 @@ static void unhash_generic_stateid(struct nfs4_stateid *stp) |
2678 |
- |
2679 |
- static void free_generic_stateid(struct nfs4_stateid *stp) |
2680 |
- { |
2681 |
-- int oflag; |
2682 |
-+ int i; |
2683 |
- |
2684 |
- if (stp->st_access_bmap) { |
2685 |
-- oflag = nfs4_access_bmap_to_omode(stp); |
2686 |
-- nfs4_file_put_access(stp->st_file, oflag); |
2687 |
-+ for (i = 1; i < 4; i++) { |
2688 |
-+ if (test_bit(i, &stp->st_access_bmap)) |
2689 |
-+ nfs4_file_put_access(stp->st_file, |
2690 |
-+ nfs4_access_to_omode(i)); |
2691 |
-+ } |
2692 |
- } |
2693 |
- put_nfs4_file(stp->st_file); |
2694 |
- kmem_cache_free(stateid_slab, stp); |
2695 |
-@@ -2337,15 +2332,6 @@ out: |
2696 |
- return ret; |
2697 |
- } |
2698 |
- |
2699 |
--static inline void |
2700 |
--nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access) |
2701 |
--{ |
2702 |
-- if (share_access & NFS4_SHARE_ACCESS_WRITE) |
2703 |
-- nfs4_file_put_access(fp, O_WRONLY); |
2704 |
-- if (share_access & NFS4_SHARE_ACCESS_READ) |
2705 |
-- nfs4_file_put_access(fp, O_RDONLY); |
2706 |
--} |
2707 |
-- |
2708 |
- static void nfsd_break_one_deleg(struct nfs4_delegation *dp) |
2709 |
- { |
2710 |
- /* We're assuming the state code never drops its reference |
2711 |
-@@ -2556,12 +2542,18 @@ static inline int nfs4_access_to_access(u32 nfs4_access) |
2712 |
- return flags; |
2713 |
- } |
2714 |
- |
2715 |
--static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file |
2716 |
--*fp, struct svc_fh *cur_fh, u32 nfs4_access) |
2717 |
-+static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp, |
2718 |
-+ struct svc_fh *cur_fh, struct nfsd4_open *open) |
2719 |
- { |
2720 |
- __be32 status; |
2721 |
-- int oflag = nfs4_access_to_omode(nfs4_access); |
2722 |
-- int access = nfs4_access_to_access(nfs4_access); |
2723 |
-+ int oflag = nfs4_access_to_omode(open->op_share_access); |
2724 |
-+ int access = nfs4_access_to_access(open->op_share_access); |
2725 |
-+ |
2726 |
-+ /* CLAIM_DELEGATE_CUR is used in response to a broken lease; |
2727 |
-+ * allowing it to break the lease and return EAGAIN leaves the |
2728 |
-+ * client unable to make progress in returning the delegation */ |
2729 |
-+ if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) |
2730 |
-+ access |= NFSD_MAY_NOT_BREAK_LEASE; |
2731 |
- |
2732 |
- if (!fp->fi_fds[oflag]) { |
2733 |
- status = nfsd_open(rqstp, cur_fh, S_IFREG, access, |
2734 |
-@@ -2586,7 +2578,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, |
2735 |
- if (stp == NULL) |
2736 |
- return nfserr_resource; |
2737 |
- |
2738 |
-- status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open->op_share_access); |
2739 |
-+ status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); |
2740 |
- if (status) { |
2741 |
- kmem_cache_free(stateid_slab, stp); |
2742 |
- return status; |
2743 |
-@@ -2619,14 +2611,14 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c |
2744 |
- |
2745 |
- new_access = !test_bit(op_share_access, &stp->st_access_bmap); |
2746 |
- if (new_access) { |
2747 |
-- status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access); |
2748 |
-+ status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); |
2749 |
- if (status) |
2750 |
- return status; |
2751 |
- } |
2752 |
- status = nfsd4_truncate(rqstp, cur_fh, open); |
2753 |
- if (status) { |
2754 |
- if (new_access) { |
2755 |
-- int oflag = nfs4_access_to_omode(new_access); |
2756 |
-+ int oflag = nfs4_access_to_omode(op_share_access); |
2757 |
- nfs4_file_put_access(fp, oflag); |
2758 |
- } |
2759 |
- return status; |
2760 |
-@@ -3384,18 +3376,15 @@ out: |
2761 |
- return status; |
2762 |
- } |
2763 |
- |
2764 |
-- |
2765 |
--/* |
2766 |
-- * unset all bits in union bitmap (bmap) that |
2767 |
-- * do not exist in share (from successful OPEN_DOWNGRADE) |
2768 |
-- */ |
2769 |
--static void |
2770 |
--reset_union_bmap_access(unsigned long access, unsigned long *bmap) |
2771 |
-+static inline void nfs4_file_downgrade(struct nfs4_stateid *stp, unsigned int to_access) |
2772 |
- { |
2773 |
- int i; |
2774 |
-+ |
2775 |
- for (i = 1; i < 4; i++) { |
2776 |
-- if ((i & access) != i) |
2777 |
-- __clear_bit(i, bmap); |
2778 |
-+ if (test_bit(i, &stp->st_access_bmap) && !(i & to_access)) { |
2779 |
-+ nfs4_file_put_access(stp->st_file, i); |
2780 |
-+ __clear_bit(i, &stp->st_access_bmap); |
2781 |
-+ } |
2782 |
- } |
2783 |
- } |
2784 |
- |
2785 |
-@@ -3416,7 +3405,6 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, |
2786 |
- { |
2787 |
- __be32 status; |
2788 |
- struct nfs4_stateid *stp; |
2789 |
-- unsigned int share_access; |
2790 |
- |
2791 |
- dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", |
2792 |
- (int)cstate->current_fh.fh_dentry->d_name.len, |
2793 |
-@@ -3445,10 +3433,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, |
2794 |
- stp->st_deny_bmap, od->od_share_deny); |
2795 |
- goto out; |
2796 |
- } |
2797 |
-- set_access(&share_access, stp->st_access_bmap); |
2798 |
-- nfs4_file_downgrade(stp->st_file, share_access & ~od->od_share_access); |
2799 |
-+ nfs4_file_downgrade(stp, od->od_share_access); |
2800 |
- |
2801 |
-- reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap); |
2802 |
- reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); |
2803 |
- |
2804 |
- update_stateid(&stp->st_stateid); |
2805 |
-diff --git a/fs/proc/base.c b/fs/proc/base.c |
2806 |
-index fc5bc27..5bff4c6 100644 |
2807 |
---- a/fs/proc/base.c |
2808 |
-+++ b/fs/proc/base.c |
2809 |
-@@ -2707,9 +2707,16 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) |
2810 |
- { |
2811 |
- struct task_io_accounting acct = task->ioac; |
2812 |
- unsigned long flags; |
2813 |
-+ int result; |
2814 |
- |
2815 |
-- if (!ptrace_may_access(task, PTRACE_MODE_READ)) |
2816 |
-- return -EACCES; |
2817 |
-+ result = mutex_lock_killable(&task->signal->cred_guard_mutex); |
2818 |
-+ if (result) |
2819 |
-+ return result; |
2820 |
-+ |
2821 |
-+ if (!ptrace_may_access(task, PTRACE_MODE_READ)) { |
2822 |
-+ result = -EACCES; |
2823 |
-+ goto out_unlock; |
2824 |
-+ } |
2825 |
- |
2826 |
- if (whole && lock_task_sighand(task, &flags)) { |
2827 |
- struct task_struct *t = task; |
2828 |
-@@ -2720,7 +2727,7 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) |
2829 |
- |
2830 |
- unlock_task_sighand(task, &flags); |
2831 |
- } |
2832 |
-- return sprintf(buffer, |
2833 |
-+ result = sprintf(buffer, |
2834 |
- "rchar: %llu\n" |
2835 |
- "wchar: %llu\n" |
2836 |
- "syscr: %llu\n" |
2837 |
-@@ -2735,6 +2742,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) |
2838 |
- (unsigned long long)acct.read_bytes, |
2839 |
- (unsigned long long)acct.write_bytes, |
2840 |
- (unsigned long long)acct.cancelled_write_bytes); |
2841 |
-+out_unlock: |
2842 |
-+ mutex_unlock(&task->signal->cred_guard_mutex); |
2843 |
-+ return result; |
2844 |
- } |
2845 |
- |
2846 |
- static int proc_tid_io_accounting(struct task_struct *task, char *buffer) |
2847 |
-diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h |
2848 |
-index 4ff0988..55814aa 100644 |
2849 |
---- a/include/linux/firewire-cdev.h |
2850 |
-+++ b/include/linux/firewire-cdev.h |
2851 |
-@@ -475,6 +475,9 @@ union fw_cdev_event { |
2852 |
- * of the bus. This does not cause a bus reset to happen. |
2853 |
- * @bus_reset_closure: Value of &closure in this and subsequent bus reset events |
2854 |
- * @card: The index of the card this device belongs to |
2855 |
-+ * |
2856 |
-+ * As a side effect, reception of %FW_CDEV_EVENT_BUS_RESET events to be read(2) |
2857 |
-+ * is started by this ioctl. |
2858 |
- */ |
2859 |
- struct fw_cdev_get_info { |
2860 |
- __u32 version; |
2861 |
-diff --git a/include/linux/mm.h b/include/linux/mm.h |
2862 |
-index 9670f71..1036614 100644 |
2863 |
---- a/include/linux/mm.h |
2864 |
-+++ b/include/linux/mm.h |
2865 |
-@@ -985,6 +985,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
2866 |
- int get_user_pages_fast(unsigned long start, int nr_pages, int write, |
2867 |
- struct page **pages); |
2868 |
- struct page *get_dump_page(unsigned long addr); |
2869 |
-+extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, |
2870 |
-+ unsigned long address, unsigned int fault_flags); |
2871 |
- |
2872 |
- extern int try_to_release_page(struct page * page, gfp_t gfp_mask); |
2873 |
- extern void do_invalidatepage(struct page *page, unsigned long offset); |
2874 |
-diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h |
2875 |
-index 9e19477..33b5968 100644 |
2876 |
---- a/include/linux/netdevice.h |
2877 |
-+++ b/include/linux/netdevice.h |
2878 |
-@@ -1688,9 +1688,12 @@ static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen) |
2879 |
- static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen, |
2880 |
- unsigned int offset) |
2881 |
- { |
2882 |
-+ if (!pskb_may_pull(skb, hlen)) |
2883 |
-+ return NULL; |
2884 |
-+ |
2885 |
- NAPI_GRO_CB(skb)->frag0 = NULL; |
2886 |
- NAPI_GRO_CB(skb)->frag0_len = 0; |
2887 |
-- return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; |
2888 |
-+ return skb->data + offset; |
2889 |
- } |
2890 |
- |
2891 |
- static inline void *skb_gro_mac_header(struct sk_buff *skb) |
2892 |
-diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h |
2893 |
-index 1b93b9c..b522370 100644 |
2894 |
---- a/include/linux/nfs_fs.h |
2895 |
-+++ b/include/linux/nfs_fs.h |
2896 |
-@@ -99,9 +99,10 @@ struct nfs_open_context { |
2897 |
- |
2898 |
- struct nfs_open_dir_context { |
2899 |
- struct rpc_cred *cred; |
2900 |
-+ unsigned long attr_gencount; |
2901 |
- __u64 dir_cookie; |
2902 |
- __u64 dup_cookie; |
2903 |
-- int duped; |
2904 |
-+ signed char duped; |
2905 |
- }; |
2906 |
- |
2907 |
- /* |
2908 |
-diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h |
2909 |
-index 00848d8..be2eba7 100644 |
2910 |
---- a/include/linux/nfs_xdr.h |
2911 |
-+++ b/include/linux/nfs_xdr.h |
2912 |
-@@ -262,7 +262,7 @@ struct nfs4_layoutcommit_res { |
2913 |
- struct nfs4_layoutcommit_data { |
2914 |
- struct rpc_task task; |
2915 |
- struct nfs_fattr fattr; |
2916 |
-- struct pnfs_layout_segment *lseg; |
2917 |
-+ struct list_head lseg_list; |
2918 |
- struct rpc_cred *cred; |
2919 |
- struct nfs4_layoutcommit_args args; |
2920 |
- struct nfs4_layoutcommit_res res; |
2921 |
-diff --git a/ipc/sem.c b/ipc/sem.c |
2922 |
-index 34193ed..e68a8f5 100644 |
2923 |
---- a/ipc/sem.c |
2924 |
-+++ b/ipc/sem.c |
2925 |
-@@ -1456,15 +1456,24 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, |
2926 |
- } |
2927 |
- |
2928 |
- sma = sem_lock(ns, semid); |
2929 |
-+ |
2930 |
-+ /* |
2931 |
-+ * Wait until it's guaranteed that no wakeup_sem_queue_do() is ongoing. |
2932 |
-+ */ |
2933 |
-+ error = get_queue_result(&queue); |
2934 |
-+ |
2935 |
-+ /* |
2936 |
-+ * Array removed? If yes, leave without sem_unlock(). |
2937 |
-+ */ |
2938 |
- if (IS_ERR(sma)) { |
2939 |
- error = -EIDRM; |
2940 |
- goto out_free; |
2941 |
- } |
2942 |
- |
2943 |
-- error = get_queue_result(&queue); |
2944 |
- |
2945 |
- /* |
2946 |
-- * If queue.status != -EINTR we are woken up by another process |
2947 |
-+ * If queue.status != -EINTR we are woken up by another process. |
2948 |
-+ * Leave without unlink_queue(), but with sem_unlock(). |
2949 |
- */ |
2950 |
- |
2951 |
- if (error != -EINTR) { |
2952 |
-diff --git a/kernel/events/core.c b/kernel/events/core.c |
2953 |
-index 9efe710..32a6151 100644 |
2954 |
---- a/kernel/events/core.c |
2955 |
-+++ b/kernel/events/core.c |
2956 |
-@@ -5016,11 +5016,8 @@ static int __perf_event_overflow(struct perf_event *event, int nmi, |
2957 |
- if (events && atomic_dec_and_test(&event->event_limit)) { |
2958 |
- ret = 1; |
2959 |
- event->pending_kill = POLL_HUP; |
2960 |
-- if (nmi) { |
2961 |
-- event->pending_disable = 1; |
2962 |
-- irq_work_queue(&event->pending); |
2963 |
-- } else |
2964 |
-- perf_event_disable(event); |
2965 |
-+ event->pending_disable = 1; |
2966 |
-+ irq_work_queue(&event->pending); |
2967 |
- } |
2968 |
- |
2969 |
- if (event->overflow_handler) |
2970 |
-diff --git a/kernel/futex.c b/kernel/futex.c |
2971 |
-index fe28dc2..7a0a4ed 100644 |
2972 |
---- a/kernel/futex.c |
2973 |
-+++ b/kernel/futex.c |
2974 |
-@@ -355,8 +355,8 @@ static int fault_in_user_writeable(u32 __user *uaddr) |
2975 |
- int ret; |
2976 |
- |
2977 |
- down_read(&mm->mmap_sem); |
2978 |
-- ret = get_user_pages(current, mm, (unsigned long)uaddr, |
2979 |
-- 1, 1, 0, NULL, NULL); |
2980 |
-+ ret = fixup_user_fault(current, mm, (unsigned long)uaddr, |
2981 |
-+ FAULT_FLAG_WRITE); |
2982 |
- up_read(&mm->mmap_sem); |
2983 |
- |
2984 |
- return ret < 0 ? ret : 0; |
2985 |
-diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h |
2986 |
-index 229f859..f807407 100644 |
2987 |
---- a/kernel/trace/trace.h |
2988 |
-+++ b/kernel/trace/trace.h |
2989 |
-@@ -677,6 +677,7 @@ struct event_subsystem { |
2990 |
- struct dentry *entry; |
2991 |
- struct event_filter *filter; |
2992 |
- int nr_events; |
2993 |
-+ int ref_count; |
2994 |
- }; |
2995 |
- |
2996 |
- #define FILTER_PRED_INVALID ((unsigned short)-1) |
2997 |
-diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c |
2998 |
-index 686ec39..3e2a7c9 100644 |
2999 |
---- a/kernel/trace/trace_events.c |
3000 |
-+++ b/kernel/trace/trace_events.c |
3001 |
-@@ -244,6 +244,35 @@ static void ftrace_clear_events(void) |
3002 |
- mutex_unlock(&event_mutex); |
3003 |
- } |
3004 |
- |
3005 |
-+static void __put_system(struct event_subsystem *system) |
3006 |
-+{ |
3007 |
-+ struct event_filter *filter = system->filter; |
3008 |
-+ |
3009 |
-+ WARN_ON_ONCE(system->ref_count == 0); |
3010 |
-+ if (--system->ref_count) |
3011 |
-+ return; |
3012 |
-+ |
3013 |
-+ if (filter) { |
3014 |
-+ kfree(filter->filter_string); |
3015 |
-+ kfree(filter); |
3016 |
-+ } |
3017 |
-+ kfree(system->name); |
3018 |
-+ kfree(system); |
3019 |
-+} |
3020 |
-+ |
3021 |
-+static void __get_system(struct event_subsystem *system) |
3022 |
-+{ |
3023 |
-+ WARN_ON_ONCE(system->ref_count == 0); |
3024 |
-+ system->ref_count++; |
3025 |
-+} |
3026 |
-+ |
3027 |
-+static void put_system(struct event_subsystem *system) |
3028 |
-+{ |
3029 |
-+ mutex_lock(&event_mutex); |
3030 |
-+ __put_system(system); |
3031 |
-+ mutex_unlock(&event_mutex); |
3032 |
-+} |
3033 |
-+ |
3034 |
- /* |
3035 |
- * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events. |
3036 |
- */ |
3037 |
-@@ -528,7 +557,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt, |
3038 |
- loff_t *ppos) |
3039 |
- { |
3040 |
- const char set_to_char[4] = { '?', '0', '1', 'X' }; |
3041 |
-- const char *system = filp->private_data; |
3042 |
-+ struct event_subsystem *system = filp->private_data; |
3043 |
- struct ftrace_event_call *call; |
3044 |
- char buf[2]; |
3045 |
- int set = 0; |
3046 |
-@@ -539,7 +568,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt, |
3047 |
- if (!call->name || !call->class || !call->class->reg) |
3048 |
- continue; |
3049 |
- |
3050 |
-- if (system && strcmp(call->class->system, system) != 0) |
3051 |
-+ if (system && strcmp(call->class->system, system->name) != 0) |
3052 |
- continue; |
3053 |
- |
3054 |
- /* |
3055 |
-@@ -569,7 +598,8 @@ static ssize_t |
3056 |
- system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, |
3057 |
- loff_t *ppos) |
3058 |
- { |
3059 |
-- const char *system = filp->private_data; |
3060 |
-+ struct event_subsystem *system = filp->private_data; |
3061 |
-+ const char *name = NULL; |
3062 |
- unsigned long val; |
3063 |
- char buf[64]; |
3064 |
- ssize_t ret; |
3065 |
-@@ -593,7 +623,14 @@ system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, |
3066 |
- if (val != 0 && val != 1) |
3067 |
- return -EINVAL; |
3068 |
- |
3069 |
-- ret = __ftrace_set_clr_event(NULL, system, NULL, val); |
3070 |
-+ /* |
3071 |
-+ * Opening of "enable" adds a ref count to system, |
3072 |
-+ * so the name is safe to use. |
3073 |
-+ */ |
3074 |
-+ if (system) |
3075 |
-+ name = system->name; |
3076 |
-+ |
3077 |
-+ ret = __ftrace_set_clr_event(NULL, name, NULL, val); |
3078 |
- if (ret) |
3079 |
- goto out; |
3080 |
- |
3081 |
-@@ -826,6 +863,52 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, |
3082 |
- return cnt; |
3083 |
- } |
3084 |
- |
3085 |
-+static LIST_HEAD(event_subsystems); |
3086 |
-+ |
3087 |
-+static int subsystem_open(struct inode *inode, struct file *filp) |
3088 |
-+{ |
3089 |
-+ struct event_subsystem *system = NULL; |
3090 |
-+ int ret; |
3091 |
-+ |
3092 |
-+ if (!inode->i_private) |
3093 |
-+ goto skip_search; |
3094 |
-+ |
3095 |
-+ /* Make sure the system still exists */ |
3096 |
-+ mutex_lock(&event_mutex); |
3097 |
-+ list_for_each_entry(system, &event_subsystems, list) { |
3098 |
-+ if (system == inode->i_private) { |
3099 |
-+ /* Don't open systems with no events */ |
3100 |
-+ if (!system->nr_events) { |
3101 |
-+ system = NULL; |
3102 |
-+ break; |
3103 |
-+ } |
3104 |
-+ __get_system(system); |
3105 |
-+ break; |
3106 |
-+ } |
3107 |
-+ } |
3108 |
-+ mutex_unlock(&event_mutex); |
3109 |
-+ |
3110 |
-+ if (system != inode->i_private) |
3111 |
-+ return -ENODEV; |
3112 |
-+ |
3113 |
-+ skip_search: |
3114 |
-+ ret = tracing_open_generic(inode, filp); |
3115 |
-+ if (ret < 0 && system) |
3116 |
-+ put_system(system); |
3117 |
-+ |
3118 |
-+ return ret; |
3119 |
-+} |
3120 |
-+ |
3121 |
-+static int subsystem_release(struct inode *inode, struct file *file) |
3122 |
-+{ |
3123 |
-+ struct event_subsystem *system = inode->i_private; |
3124 |
-+ |
3125 |
-+ if (system) |
3126 |
-+ put_system(system); |
3127 |
-+ |
3128 |
-+ return 0; |
3129 |
-+} |
3130 |
-+ |
3131 |
- static ssize_t |
3132 |
- subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt, |
3133 |
- loff_t *ppos) |
3134 |
-@@ -963,17 +1046,19 @@ static const struct file_operations ftrace_event_filter_fops = { |
3135 |
- }; |
3136 |
- |
3137 |
- static const struct file_operations ftrace_subsystem_filter_fops = { |
3138 |
-- .open = tracing_open_generic, |
3139 |
-+ .open = subsystem_open, |
3140 |
- .read = subsystem_filter_read, |
3141 |
- .write = subsystem_filter_write, |
3142 |
- .llseek = default_llseek, |
3143 |
-+ .release = subsystem_release, |
3144 |
- }; |
3145 |
- |
3146 |
- static const struct file_operations ftrace_system_enable_fops = { |
3147 |
-- .open = tracing_open_generic, |
3148 |
-+ .open = subsystem_open, |
3149 |
- .read = system_enable_read, |
3150 |
- .write = system_enable_write, |
3151 |
- .llseek = default_llseek, |
3152 |
-+ .release = subsystem_release, |
3153 |
- }; |
3154 |
- |
3155 |
- static const struct file_operations ftrace_show_header_fops = { |
3156 |
-@@ -1002,8 +1087,6 @@ static struct dentry *event_trace_events_dir(void) |
3157 |
- return d_events; |
3158 |
- } |
3159 |
- |
3160 |
--static LIST_HEAD(event_subsystems); |
3161 |
-- |
3162 |
- static struct dentry * |
3163 |
- event_subsystem_dir(const char *name, struct dentry *d_events) |
3164 |
- { |
3165 |
-@@ -1013,6 +1096,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events) |
3166 |
- /* First see if we did not already create this dir */ |
3167 |
- list_for_each_entry(system, &event_subsystems, list) { |
3168 |
- if (strcmp(system->name, name) == 0) { |
3169 |
-+ __get_system(system); |
3170 |
- system->nr_events++; |
3171 |
- return system->entry; |
3172 |
- } |
3173 |
-@@ -1035,6 +1119,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events) |
3174 |
- } |
3175 |
- |
3176 |
- system->nr_events = 1; |
3177 |
-+ system->ref_count = 1; |
3178 |
- system->name = kstrdup(name, GFP_KERNEL); |
3179 |
- if (!system->name) { |
3180 |
- debugfs_remove(system->entry); |
3181 |
-@@ -1062,8 +1147,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events) |
3182 |
- "'%s/filter' entry\n", name); |
3183 |
- } |
3184 |
- |
3185 |
-- trace_create_file("enable", 0644, system->entry, |
3186 |
-- (void *)system->name, |
3187 |
-+ trace_create_file("enable", 0644, system->entry, system, |
3188 |
- &ftrace_system_enable_fops); |
3189 |
- |
3190 |
- return system->entry; |
3191 |
-@@ -1184,16 +1268,9 @@ static void remove_subsystem_dir(const char *name) |
3192 |
- list_for_each_entry(system, &event_subsystems, list) { |
3193 |
- if (strcmp(system->name, name) == 0) { |
3194 |
- if (!--system->nr_events) { |
3195 |
-- struct event_filter *filter = system->filter; |
3196 |
-- |
3197 |
- debugfs_remove_recursive(system->entry); |
3198 |
- list_del(&system->list); |
3199 |
-- if (filter) { |
3200 |
-- kfree(filter->filter_string); |
3201 |
-- kfree(filter); |
3202 |
-- } |
3203 |
-- kfree(system->name); |
3204 |
-- kfree(system); |
3205 |
-+ __put_system(system); |
3206 |
- } |
3207 |
- break; |
3208 |
- } |
3209 |
-diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c |
3210 |
-index 8008ddc..256764e 100644 |
3211 |
---- a/kernel/trace/trace_events_filter.c |
3212 |
-+++ b/kernel/trace/trace_events_filter.c |
3213 |
-@@ -1886,6 +1886,12 @@ int apply_subsystem_event_filter(struct event_subsystem *system, |
3214 |
- |
3215 |
- mutex_lock(&event_mutex); |
3216 |
- |
3217 |
-+ /* Make sure the system still has events */ |
3218 |
-+ if (!system->nr_events) { |
3219 |
-+ err = -ENODEV; |
3220 |
-+ goto out_unlock; |
3221 |
-+ } |
3222 |
-+ |
3223 |
- if (!strcmp(strstrip(filter_string), "0")) { |
3224 |
- filter_free_subsystem_preds(system); |
3225 |
- remove_filter_string(system->filter); |
3226 |
-diff --git a/lib/xz/xz_private.h b/lib/xz/xz_private.h |
3227 |
-index a65633e..482b90f 100644 |
3228 |
---- a/lib/xz/xz_private.h |
3229 |
-+++ b/lib/xz/xz_private.h |
3230 |
-@@ -12,7 +12,7 @@ |
3231 |
- |
3232 |
- #ifdef __KERNEL__ |
3233 |
- # include <linux/xz.h> |
3234 |
--# include <asm/byteorder.h> |
3235 |
-+# include <linux/kernel.h> |
3236 |
- # include <asm/unaligned.h> |
3237 |
- /* XZ_PREBOOT may be defined only via decompress_unxz.c. */ |
3238 |
- # ifndef XZ_PREBOOT |
3239 |
-diff --git a/mm/backing-dev.c b/mm/backing-dev.c |
3240 |
-index f032e6e..e56fe35 100644 |
3241 |
---- a/mm/backing-dev.c |
3242 |
-+++ b/mm/backing-dev.c |
3243 |
-@@ -606,6 +606,7 @@ static void bdi_prune_sb(struct backing_dev_info *bdi) |
3244 |
- void bdi_unregister(struct backing_dev_info *bdi) |
3245 |
- { |
3246 |
- if (bdi->dev) { |
3247 |
-+ bdi_set_min_ratio(bdi, 0); |
3248 |
- trace_writeback_bdi_unregister(bdi); |
3249 |
- bdi_prune_sb(bdi); |
3250 |
- del_timer_sync(&bdi->wb.wakeup_timer); |
3251 |
-diff --git a/mm/memcontrol.c b/mm/memcontrol.c |
3252 |
-index e013b8e..59ac5d6 100644 |
3253 |
---- a/mm/memcontrol.c |
3254 |
-+++ b/mm/memcontrol.c |
3255 |
-@@ -1730,7 +1730,7 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, |
3256 |
- excess = res_counter_soft_limit_excess(&root_mem->res) >> PAGE_SHIFT; |
3257 |
- |
3258 |
- /* If memsw_is_minimum==1, swap-out is of-no-use. */ |
3259 |
-- if (!check_soft && root_mem->memsw_is_minimum) |
3260 |
-+ if (!check_soft && !shrink && root_mem->memsw_is_minimum) |
3261 |
- noswap = true; |
3262 |
- |
3263 |
- while (1) { |
3264 |
-diff --git a/mm/memory.c b/mm/memory.c |
3265 |
-index 9b8a01d..d961e19 100644 |
3266 |
---- a/mm/memory.c |
3267 |
-+++ b/mm/memory.c |
3268 |
-@@ -1816,7 +1816,63 @@ next_page: |
3269 |
- } |
3270 |
- EXPORT_SYMBOL(__get_user_pages); |
3271 |
- |
3272 |
--/** |
3273 |
-+/* |
3274 |
-+ * fixup_user_fault() - manually resolve a user page fault |
3275 |
-+ * @tsk: the task_struct to use for page fault accounting, or |
3276 |
-+ * NULL if faults are not to be recorded. |
3277 |
-+ * @mm: mm_struct of target mm |
3278 |
-+ * @address: user address |
3279 |
-+ * @fault_flags:flags to pass down to handle_mm_fault() |
3280 |
-+ * |
3281 |
-+ * This is meant to be called in the specific scenario where for locking reasons |
3282 |
-+ * we try to access user memory in atomic context (within a pagefault_disable() |
3283 |
-+ * section), this returns -EFAULT, and we want to resolve the user fault before |
3284 |
-+ * trying again. |
3285 |
-+ * |
3286 |
-+ * Typically this is meant to be used by the futex code. |
3287 |
-+ * |
3288 |
-+ * The main difference with get_user_pages() is that this function will |
3289 |
-+ * unconditionally call handle_mm_fault() which will in turn perform all the |
3290 |
-+ * necessary SW fixup of the dirty and young bits in the PTE, while |
3291 |
-+ * handle_mm_fault() only guarantees to update these in the struct page. |
3292 |
-+ * |
3293 |
-+ * This is important for some architectures where those bits also gate the |
3294 |
-+ * access permission to the page because they are maintained in software. On |
3295 |
-+ * such architectures, gup() will not be enough to make a subsequent access |
3296 |
-+ * succeed. |
3297 |
-+ * |
3298 |
-+ * This should be called with the mm_sem held for read. |
3299 |
-+ */ |
3300 |
-+int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, |
3301 |
-+ unsigned long address, unsigned int fault_flags) |
3302 |
-+{ |
3303 |
-+ struct vm_area_struct *vma; |
3304 |
-+ int ret; |
3305 |
-+ |
3306 |
-+ vma = find_extend_vma(mm, address); |
3307 |
-+ if (!vma || address < vma->vm_start) |
3308 |
-+ return -EFAULT; |
3309 |
-+ |
3310 |
-+ ret = handle_mm_fault(mm, vma, address, fault_flags); |
3311 |
-+ if (ret & VM_FAULT_ERROR) { |
3312 |
-+ if (ret & VM_FAULT_OOM) |
3313 |
-+ return -ENOMEM; |
3314 |
-+ if (ret & (VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) |
3315 |
-+ return -EHWPOISON; |
3316 |
-+ if (ret & VM_FAULT_SIGBUS) |
3317 |
-+ return -EFAULT; |
3318 |
-+ BUG(); |
3319 |
-+ } |
3320 |
-+ if (tsk) { |
3321 |
-+ if (ret & VM_FAULT_MAJOR) |
3322 |
-+ tsk->maj_flt++; |
3323 |
-+ else |
3324 |
-+ tsk->min_flt++; |
3325 |
-+ } |
3326 |
-+ return 0; |
3327 |
-+} |
3328 |
-+ |
3329 |
-+/* |
3330 |
- * get_user_pages() - pin user pages in memory |
3331 |
- * @tsk: the task_struct to use for page fault accounting, or |
3332 |
- * NULL if faults are not to be recorded. |
3333 |
-diff --git a/mm/oom_kill.c b/mm/oom_kill.c |
3334 |
-index e4b0991..8093fc7 100644 |
3335 |
---- a/mm/oom_kill.c |
3336 |
-+++ b/mm/oom_kill.c |
3337 |
-@@ -303,7 +303,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, |
3338 |
- do_each_thread(g, p) { |
3339 |
- unsigned int points; |
3340 |
- |
3341 |
-- if (!p->mm) |
3342 |
-+ if (p->exit_state) |
3343 |
- continue; |
3344 |
- if (oom_unkillable_task(p, mem, nodemask)) |
3345 |
- continue; |
3346 |
-@@ -319,6 +319,8 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, |
3347 |
- */ |
3348 |
- if (test_tsk_thread_flag(p, TIF_MEMDIE)) |
3349 |
- return ERR_PTR(-1UL); |
3350 |
-+ if (!p->mm) |
3351 |
-+ continue; |
3352 |
- |
3353 |
- if (p->flags & PF_EXITING) { |
3354 |
- /* |
3355 |
-diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h |
3356 |
-index 54578f2..78cc364 100644 |
3357 |
---- a/net/bridge/br_private.h |
3358 |
-+++ b/net/bridge/br_private.h |
3359 |
-@@ -124,6 +124,7 @@ struct net_bridge_port |
3360 |
- bridge_id designated_bridge; |
3361 |
- u32 path_cost; |
3362 |
- u32 designated_cost; |
3363 |
-+ unsigned long designated_age; |
3364 |
- |
3365 |
- struct timer_list forward_delay_timer; |
3366 |
- struct timer_list hold_timer; |
3367 |
-diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c |
3368 |
-index bb4383e..fcff622 100644 |
3369 |
---- a/net/bridge/br_stp.c |
3370 |
-+++ b/net/bridge/br_stp.c |
3371 |
-@@ -164,8 +164,7 @@ void br_transmit_config(struct net_bridge_port *p) |
3372 |
- else { |
3373 |
- struct net_bridge_port *root |
3374 |
- = br_get_port(br, br->root_port); |
3375 |
-- bpdu.message_age = br->max_age |
3376 |
-- - (root->message_age_timer.expires - jiffies) |
3377 |
-+ bpdu.message_age = (jiffies - root->designated_age) |
3378 |
- + MESSAGE_AGE_INCR; |
3379 |
- } |
3380 |
- bpdu.max_age = br->max_age; |
3381 |
-@@ -189,6 +188,7 @@ static inline void br_record_config_information(struct net_bridge_port *p, |
3382 |
- p->designated_cost = bpdu->root_path_cost; |
3383 |
- p->designated_bridge = bpdu->bridge_id; |
3384 |
- p->designated_port = bpdu->port_id; |
3385 |
-+ p->designated_age = jiffies + bpdu->message_age; |
3386 |
- |
3387 |
- mod_timer(&p->message_age_timer, jiffies |
3388 |
- + (p->br->max_age - bpdu->message_age)); |
3389 |
-diff --git a/net/core/ethtool.c b/net/core/ethtool.c |
3390 |
-index fd14116..4fb7704 100644 |
3391 |
---- a/net/core/ethtool.c |
3392 |
-+++ b/net/core/ethtool.c |
3393 |
-@@ -1227,7 +1227,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) |
3394 |
- regs.len = reglen; |
3395 |
- |
3396 |
- regbuf = vzalloc(reglen); |
3397 |
-- if (!regbuf) |
3398 |
-+ if (reglen && !regbuf) |
3399 |
- return -ENOMEM; |
3400 |
- |
3401 |
- ops->get_regs(dev, ®s, regbuf); |
3402 |
-@@ -1236,7 +1236,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) |
3403 |
- if (copy_to_user(useraddr, ®s, sizeof(regs))) |
3404 |
- goto out; |
3405 |
- useraddr += offsetof(struct ethtool_regs, data); |
3406 |
-- if (copy_to_user(useraddr, regbuf, regs.len)) |
3407 |
-+ if (regbuf && copy_to_user(useraddr, regbuf, regs.len)) |
3408 |
- goto out; |
3409 |
- ret = 0; |
3410 |
- |
3411 |
-diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c |
3412 |
-index d595265..7a334fd 100644 |
3413 |
---- a/net/mac80211/mlme.c |
3414 |
-+++ b/net/mac80211/mlme.c |
3415 |
-@@ -2200,6 +2200,9 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) |
3416 |
- { |
3417 |
- struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3418 |
- |
3419 |
-+ if (!ifmgd->associated) |
3420 |
-+ return; |
3421 |
-+ |
3422 |
- if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) |
3423 |
- add_timer(&ifmgd->timer); |
3424 |
- if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) |
3425 |
-diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c |
3426 |
-index ab86b79..bd31208 100644 |
3427 |
---- a/net/sunrpc/svc_xprt.c |
3428 |
-+++ b/net/sunrpc/svc_xprt.c |
3429 |
-@@ -902,12 +902,13 @@ void svc_delete_xprt(struct svc_xprt *xprt) |
3430 |
- if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) |
3431 |
- list_del_init(&xprt->xpt_list); |
3432 |
- /* |
3433 |
-- * We used to delete the transport from whichever list |
3434 |
-- * it's sk_xprt.xpt_ready node was on, but we don't actually |
3435 |
-- * need to. This is because the only time we're called |
3436 |
-- * while still attached to a queue, the queue itself |
3437 |
-- * is about to be destroyed (in svc_destroy). |
3438 |
-+ * The only time we're called while xpt_ready is still on a list |
3439 |
-+ * is while the list itself is about to be destroyed (in |
3440 |
-+ * svc_destroy). BUT svc_xprt_enqueue could still be attempting |
3441 |
-+ * to add new entries to the sp_sockets list, so we can't leave |
3442 |
-+ * a freed xprt on it. |
3443 |
- */ |
3444 |
-+ list_del_init(&xprt->xpt_ready); |
3445 |
- if (test_bit(XPT_TEMP, &xprt->xpt_flags)) |
3446 |
- serv->sv_tmpcnt--; |
3447 |
- spin_unlock_bh(&serv->sv_lock); |
3448 |
-diff --git a/net/wireless/reg.c b/net/wireless/reg.c |
3449 |
-index 1ad0f39..4453eb7 100644 |
3450 |
---- a/net/wireless/reg.c |
3451 |
-+++ b/net/wireless/reg.c |
3452 |
-@@ -1125,12 +1125,13 @@ void wiphy_update_regulatory(struct wiphy *wiphy, |
3453 |
- enum ieee80211_band band; |
3454 |
- |
3455 |
- if (ignore_reg_update(wiphy, initiator)) |
3456 |
-- goto out; |
3457 |
-+ return; |
3458 |
-+ |
3459 |
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
3460 |
- if (wiphy->bands[band]) |
3461 |
- handle_band(wiphy, band, initiator); |
3462 |
- } |
3463 |
--out: |
3464 |
-+ |
3465 |
- reg_process_beacons(wiphy); |
3466 |
- reg_process_ht_flags(wiphy); |
3467 |
- if (wiphy->reg_notifier) |
3468 |
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c |
3469 |
-index c825c6e..78adc43 100644 |
3470 |
---- a/security/apparmor/domain.c |
3471 |
-+++ b/security/apparmor/domain.c |
3472 |
-@@ -73,7 +73,6 @@ static int may_change_ptraced_domain(struct task_struct *task, |
3473 |
- cred = get_task_cred(tracer); |
3474 |
- tracerp = aa_cred_profile(cred); |
3475 |
- } |
3476 |
-- rcu_read_unlock(); |
3477 |
- |
3478 |
- /* not ptraced */ |
3479 |
- if (!tracer || unconfined(tracerp)) |
3480 |
-@@ -82,6 +81,7 @@ static int may_change_ptraced_domain(struct task_struct *task, |
3481 |
- error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH); |
3482 |
- |
3483 |
- out: |
3484 |
-+ rcu_read_unlock(); |
3485 |
- if (cred) |
3486 |
- put_cred(cred); |
3487 |
- |
3488 |
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c |
3489 |
-index 3d2fd14..3783202 100644 |
3490 |
---- a/security/apparmor/lsm.c |
3491 |
-+++ b/security/apparmor/lsm.c |
3492 |
-@@ -127,7 +127,7 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective, |
3493 |
- *inheritable = cred->cap_inheritable; |
3494 |
- *permitted = cred->cap_permitted; |
3495 |
- |
3496 |
-- if (!unconfined(profile)) { |
3497 |
-+ if (!unconfined(profile) && !COMPLAIN_MODE(profile)) { |
3498 |
- *effective = cap_intersect(*effective, profile->caps.allow); |
3499 |
- *permitted = cap_intersect(*permitted, profile->caps.allow); |
3500 |
- } |
3501 |
-diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c |
3502 |
-index 5fb2e28..91cdf94 100644 |
3503 |
---- a/sound/core/pcm_compat.c |
3504 |
-+++ b/sound/core/pcm_compat.c |
3505 |
-@@ -342,7 +342,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, |
3506 |
- kfree(bufs); |
3507 |
- return -EFAULT; |
3508 |
- } |
3509 |
-- bufs[ch] = compat_ptr(ptr); |
3510 |
-+ bufs[i] = compat_ptr(ptr); |
3511 |
- bufptr++; |
3512 |
- } |
3513 |
- if (dir == SNDRV_PCM_STREAM_PLAYBACK) |
3514 |
-diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
3515 |
-index b48fb43..524ff26 100644 |
3516 |
---- a/sound/pci/hda/patch_realtek.c |
3517 |
-+++ b/sound/pci/hda/patch_realtek.c |
3518 |
-@@ -1578,13 +1578,15 @@ static void alc_init_auto_hp(struct hda_codec *codec) |
3519 |
- if (present == 3) |
3520 |
- spec->automute_hp_lo = 1; /* both HP and LO automute */ |
3521 |
- |
3522 |
-- if (!cfg->speaker_pins[0]) { |
3523 |
-+ if (!cfg->speaker_pins[0] && |
3524 |
-+ cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { |
3525 |
- memcpy(cfg->speaker_pins, cfg->line_out_pins, |
3526 |
- sizeof(cfg->speaker_pins)); |
3527 |
- cfg->speaker_outs = cfg->line_outs; |
3528 |
- } |
3529 |
- |
3530 |
-- if (!cfg->hp_pins[0]) { |
3531 |
-+ if (!cfg->hp_pins[0] && |
3532 |
-+ cfg->line_out_type == AUTO_PIN_HP_OUT) { |
3533 |
- memcpy(cfg->hp_pins, cfg->line_out_pins, |
3534 |
- sizeof(cfg->hp_pins)); |
3535 |
- cfg->hp_outs = cfg->line_outs; |
3536 |
-@@ -1603,6 +1605,7 @@ static void alc_init_auto_hp(struct hda_codec *codec) |
3537 |
- spec->automute_mode = ALC_AUTOMUTE_PIN; |
3538 |
- } |
3539 |
- if (spec->automute && cfg->line_out_pins[0] && |
3540 |
-+ cfg->speaker_pins[0] && |
3541 |
- cfg->line_out_pins[0] != cfg->hp_pins[0] && |
3542 |
- cfg->line_out_pins[0] != cfg->speaker_pins[0]) { |
3543 |
- for (i = 0; i < cfg->line_outs; i++) { |
3544 |
-diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c |
3545 |
-index 54cad38..32d096c 100644 |
3546 |
---- a/sound/pci/oxygen/xonar_pcm179x.c |
3547 |
-+++ b/sound/pci/oxygen/xonar_pcm179x.c |
3548 |
-@@ -327,8 +327,10 @@ static void pcm1796_init(struct oxygen *chip) |
3549 |
- { |
3550 |
- struct xonar_pcm179x *data = chip->model_data; |
3551 |
- |
3552 |
-- data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE | |
3553 |
-+ data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = |
3554 |
- PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; |
3555 |
-+ if (!data->broken_i2c) |
3556 |
-+ data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE; |
3557 |
- data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = |
3558 |
- PCM1796_FLT_SHARP | PCM1796_ATS_1; |
3559 |
- data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = |
3560 |
-@@ -1123,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, |
3561 |
- chip->model.control_filter = xonar_st_h6_control_filter; |
3562 |
- chip->model.dac_channels_pcm = 8; |
3563 |
- chip->model.dac_channels_mixer = 8; |
3564 |
-+ chip->model.dac_volume_min = 255; |
3565 |
- chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); |
3566 |
- break; |
3567 |
- } |
3568 |
-diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c |
3569 |
-index 9259f1f..1f11525 100644 |
3570 |
---- a/sound/soc/davinci/davinci-vcif.c |
3571 |
-+++ b/sound/soc/davinci/davinci-vcif.c |
3572 |
-@@ -62,9 +62,9 @@ static void davinci_vcif_start(struct snd_pcm_substream *substream) |
3573 |
- w = readl(davinci_vc->base + DAVINCI_VC_CTRL); |
3574 |
- |
3575 |
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
3576 |
-- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1); |
3577 |
-+ MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0); |
3578 |
- else |
3579 |
-- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1); |
3580 |
-+ MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0); |
3581 |
- |
3582 |
- writel(w, davinci_vc->base + DAVINCI_VC_CTRL); |
3583 |
- } |
3584 |
-@@ -80,9 +80,9 @@ static void davinci_vcif_stop(struct snd_pcm_substream *substream) |
3585 |
- /* Reset transmitter/receiver and sample rate/frame sync generators */ |
3586 |
- w = readl(davinci_vc->base + DAVINCI_VC_CTRL); |
3587 |
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
3588 |
-- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0); |
3589 |
-+ MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1); |
3590 |
- else |
3591 |
-- MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0); |
3592 |
-+ MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1); |
3593 |
- |
3594 |
- writel(w, davinci_vc->base + DAVINCI_VC_CTRL); |
3595 |
- } |
3596 |
-@@ -159,6 +159,7 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd, |
3597 |
- case SNDRV_PCM_TRIGGER_RESUME: |
3598 |
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
3599 |
- davinci_vcif_start(substream); |
3600 |
-+ break; |
3601 |
- case SNDRV_PCM_TRIGGER_STOP: |
3602 |
- case SNDRV_PCM_TRIGGER_SUSPEND: |
3603 |
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
3604 |
-diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c |
3605 |
-index b194be0..59abd84 100644 |
3606 |
---- a/sound/soc/soc-core.c |
3607 |
-+++ b/sound/soc/soc-core.c |
3608 |
-@@ -1124,6 +1124,7 @@ int snd_soc_suspend(struct device *dev) |
3609 |
- case SND_SOC_BIAS_OFF: |
3610 |
- codec->driver->suspend(codec, PMSG_SUSPEND); |
3611 |
- codec->suspended = 1; |
3612 |
-+ codec->cache_sync = 1; |
3613 |
- break; |
3614 |
- default: |
3615 |
- dev_dbg(codec->dev, "CODEC is on over suspend\n"); |
3616 |
-diff --git a/tools/perf/Makefile b/tools/perf/Makefile |
3617 |
-index 940257b..c168366 100644 |
3618 |
---- a/tools/perf/Makefile |
3619 |
-+++ b/tools/perf/Makefile |
3620 |
-@@ -52,7 +52,10 @@ ifeq ($(ARCH),i386) |
3621 |
- endif |
3622 |
- ifeq ($(ARCH),x86_64) |
3623 |
- ARCH := x86 |
3624 |
-- IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) |
3625 |
-+ IS_X86_64 := 0 |
3626 |
-+ ifeq (, $(findstring m32,$(EXTRA_CFLAGS))) |
3627 |
-+ IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) |
3628 |
-+ endif |
3629 |
- ifeq (${IS_X86_64}, 1) |
3630 |
- RAW_ARCH := x86_64 |
3631 |
- ARCH_CFLAGS := -DARCH_X86_64 |
3632 |
-diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c |
3633 |
-index afb0849..cb2959a 100644 |
3634 |
---- a/tools/perf/util/header.c |
3635 |
-+++ b/tools/perf/util/header.c |
3636 |
-@@ -877,9 +877,12 @@ int perf_session__read_header(struct perf_session *session, int fd) |
3637 |
- struct perf_evsel *evsel; |
3638 |
- off_t tmp; |
3639 |
- |
3640 |
-- if (perf_header__getbuffer64(header, fd, &f_attr, sizeof(f_attr))) |
3641 |
-+ if (readn(fd, &f_attr, sizeof(f_attr)) <= 0) |
3642 |
- goto out_errno; |
3643 |
- |
3644 |
-+ if (header->needs_swap) |
3645 |
-+ perf_event__attr_swap(&f_attr.attr); |
3646 |
-+ |
3647 |
- tmp = lseek(fd, 0, SEEK_CUR); |
3648 |
- evsel = perf_evsel__new(&f_attr.attr, i); |
3649 |
- |
3650 |
-diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c |
3651 |
-index f5a8fbd..2dbf0ab 100644 |
3652 |
---- a/tools/perf/util/session.c |
3653 |
-+++ b/tools/perf/util/session.c |
3654 |
-@@ -407,20 +407,26 @@ static void perf_event__read_swap(union perf_event *event) |
3655 |
- event->read.id = bswap_64(event->read.id); |
3656 |
- } |
3657 |
- |
3658 |
--static void perf_event__attr_swap(union perf_event *event) |
3659 |
-+/* exported for swapping attributes in file header */ |
3660 |
-+void perf_event__attr_swap(struct perf_event_attr *attr) |
3661 |
-+{ |
3662 |
-+ attr->type = bswap_32(attr->type); |
3663 |
-+ attr->size = bswap_32(attr->size); |
3664 |
-+ attr->config = bswap_64(attr->config); |
3665 |
-+ attr->sample_period = bswap_64(attr->sample_period); |
3666 |
-+ attr->sample_type = bswap_64(attr->sample_type); |
3667 |
-+ attr->read_format = bswap_64(attr->read_format); |
3668 |
-+ attr->wakeup_events = bswap_32(attr->wakeup_events); |
3669 |
-+ attr->bp_type = bswap_32(attr->bp_type); |
3670 |
-+ attr->bp_addr = bswap_64(attr->bp_addr); |
3671 |
-+ attr->bp_len = bswap_64(attr->bp_len); |
3672 |
-+} |
3673 |
-+ |
3674 |
-+static void perf_event__hdr_attr_swap(union perf_event *event) |
3675 |
- { |
3676 |
- size_t size; |
3677 |
- |
3678 |
-- event->attr.attr.type = bswap_32(event->attr.attr.type); |
3679 |
-- event->attr.attr.size = bswap_32(event->attr.attr.size); |
3680 |
-- event->attr.attr.config = bswap_64(event->attr.attr.config); |
3681 |
-- event->attr.attr.sample_period = bswap_64(event->attr.attr.sample_period); |
3682 |
-- event->attr.attr.sample_type = bswap_64(event->attr.attr.sample_type); |
3683 |
-- event->attr.attr.read_format = bswap_64(event->attr.attr.read_format); |
3684 |
-- event->attr.attr.wakeup_events = bswap_32(event->attr.attr.wakeup_events); |
3685 |
-- event->attr.attr.bp_type = bswap_32(event->attr.attr.bp_type); |
3686 |
-- event->attr.attr.bp_addr = bswap_64(event->attr.attr.bp_addr); |
3687 |
-- event->attr.attr.bp_len = bswap_64(event->attr.attr.bp_len); |
3688 |
-+ perf_event__attr_swap(&event->attr.attr); |
3689 |
- |
3690 |
- size = event->header.size; |
3691 |
- size -= (void *)&event->attr.id - (void *)event; |
3692 |
-@@ -448,7 +454,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { |
3693 |
- [PERF_RECORD_LOST] = perf_event__all64_swap, |
3694 |
- [PERF_RECORD_READ] = perf_event__read_swap, |
3695 |
- [PERF_RECORD_SAMPLE] = perf_event__all64_swap, |
3696 |
-- [PERF_RECORD_HEADER_ATTR] = perf_event__attr_swap, |
3697 |
-+ [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap, |
3698 |
- [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap, |
3699 |
- [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap, |
3700 |
- [PERF_RECORD_HEADER_BUILD_ID] = NULL, |
3701 |
-diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h |
3702 |
-index 66d4e14..b84c003 100644 |
3703 |
---- a/tools/perf/util/session.h |
3704 |
-+++ b/tools/perf/util/session.h |
3705 |
-@@ -112,6 +112,7 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps, |
3706 |
- u64 addr); |
3707 |
- |
3708 |
- void mem_bswap_64(void *src, int byte_size); |
3709 |
-+void perf_event__attr_swap(struct perf_event_attr *attr); |
3710 |
- |
3711 |
- int perf_session__create_kernel_maps(struct perf_session *self); |
3712 |
- |
3713 |
|
3714 |
Deleted: genpatches-2.6/trunk/3.1/1001_linux-3.0.2.patch |
3715 |
=================================================================== |
3716 |
--- genpatches-2.6/trunk/3.1/1001_linux-3.0.2.patch 2011-08-29 15:02:13 UTC (rev 1967) |
3717 |
+++ genpatches-2.6/trunk/3.1/1001_linux-3.0.2.patch 2011-08-29 15:03:18 UTC (rev 1968) |
3718 |
@@ -1,6203 +0,0 @@ |
3719 |
-diff --git a/Makefile b/Makefile |
3720 |
-index f124b18..794fa28 100644 |
3721 |
---- a/Makefile |
3722 |
-+++ b/Makefile |
3723 |
-@@ -1,6 +1,6 @@ |
3724 |
- VERSION = 3 |
3725 |
- PATCHLEVEL = 0 |
3726 |
--SUBLEVEL = 1 |
3727 |
-+SUBLEVEL = 2 |
3728 |
- EXTRAVERSION = |
3729 |
- NAME = Sneaky Weasel |
3730 |
- |
3731 |
-diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c |
3732 |
-index 85026537..466af40 100644 |
3733 |
---- a/arch/cris/arch-v10/drivers/sync_serial.c |
3734 |
-+++ b/arch/cris/arch-v10/drivers/sync_serial.c |
3735 |
-@@ -158,7 +158,7 @@ static int sync_serial_open(struct inode *inode, struct file *file); |
3736 |
- static int sync_serial_release(struct inode *inode, struct file *file); |
3737 |
- static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); |
3738 |
- |
3739 |
--static int sync_serial_ioctl(struct file *file, |
3740 |
-+static long sync_serial_ioctl(struct file *file, |
3741 |
- unsigned int cmd, unsigned long arg); |
3742 |
- static ssize_t sync_serial_write(struct file *file, const char *buf, |
3743 |
- size_t count, loff_t *ppos); |
3744 |
-@@ -625,11 +625,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) |
3745 |
- *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; |
3746 |
- DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); |
3747 |
- } |
3748 |
-- ret = 0; |
3749 |
-+ err = 0; |
3750 |
- |
3751 |
- out: |
3752 |
- mutex_unlock(&sync_serial_mutex); |
3753 |
-- return ret; |
3754 |
-+ return err; |
3755 |
- } |
3756 |
- |
3757 |
- static int sync_serial_release(struct inode *inode, struct file *file) |
3758 |
-diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c |
3759 |
-index 907cfb5..ba0e596 100644 |
3760 |
---- a/arch/cris/arch-v10/kernel/irq.c |
3761 |
-+++ b/arch/cris/arch-v10/kernel/irq.c |
3762 |
-@@ -20,6 +20,9 @@ |
3763 |
- #define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); |
3764 |
- #define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); |
3765 |
- |
3766 |
-+extern void kgdb_init(void); |
3767 |
-+extern void breakpoint(void); |
3768 |
-+ |
3769 |
- /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is |
3770 |
- * global just so that the kernel gdb can use it. |
3771 |
- */ |
3772 |
-diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h |
3773 |
-index 29b74a1..332f19c 100644 |
3774 |
---- a/arch/cris/include/asm/thread_info.h |
3775 |
-+++ b/arch/cris/include/asm/thread_info.h |
3776 |
-@@ -11,8 +11,6 @@ |
3777 |
- |
3778 |
- #ifdef __KERNEL__ |
3779 |
- |
3780 |
--#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR |
3781 |
-- |
3782 |
- #ifndef __ASSEMBLY__ |
3783 |
- #include <asm/types.h> |
3784 |
- #include <asm/processor.h> |
3785 |
-@@ -67,8 +65,10 @@ struct thread_info { |
3786 |
- |
3787 |
- #define init_thread_info (init_thread_union.thread_info) |
3788 |
- |
3789 |
-+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR |
3790 |
- /* thread information allocation */ |
3791 |
--#define alloc_thread_info(tsk, node) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) |
3792 |
-+#define alloc_thread_info_node(tsk, node) \ |
3793 |
-+ ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1)) |
3794 |
- #define free_thread_info(ti) free_pages((unsigned long) (ti), 1) |
3795 |
- |
3796 |
- #endif /* !__ASSEMBLY__ */ |
3797 |
-diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h |
3798 |
-index f819559..26fd114 100644 |
3799 |
---- a/arch/parisc/include/asm/atomic.h |
3800 |
-+++ b/arch/parisc/include/asm/atomic.h |
3801 |
-@@ -259,10 +259,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) |
3802 |
- |
3803 |
- #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) |
3804 |
- |
3805 |
--static __inline__ int |
3806 |
-+static __inline__ s64 |
3807 |
- __atomic64_add_return(s64 i, atomic64_t *v) |
3808 |
- { |
3809 |
-- int ret; |
3810 |
-+ s64 ret; |
3811 |
- unsigned long flags; |
3812 |
- _atomic_spin_lock_irqsave(v, flags); |
3813 |
- |
3814 |
-diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h |
3815 |
-index 67a33cc..2388bdb 100644 |
3816 |
---- a/arch/parisc/include/asm/futex.h |
3817 |
-+++ b/arch/parisc/include/asm/futex.h |
3818 |
-@@ -5,11 +5,14 @@ |
3819 |
- |
3820 |
- #include <linux/futex.h> |
3821 |
- #include <linux/uaccess.h> |
3822 |
-+#include <asm/atomic.h> |
3823 |
- #include <asm/errno.h> |
3824 |
- |
3825 |
- static inline int |
3826 |
- futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
3827 |
- { |
3828 |
-+ unsigned long int flags; |
3829 |
-+ u32 val; |
3830 |
- int op = (encoded_op >> 28) & 7; |
3831 |
- int cmp = (encoded_op >> 24) & 15; |
3832 |
- int oparg = (encoded_op << 8) >> 20; |
3833 |
-@@ -18,21 +21,58 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
3834 |
- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) |
3835 |
- oparg = 1 << oparg; |
3836 |
- |
3837 |
-- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) |
3838 |
-+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) |
3839 |
- return -EFAULT; |
3840 |
- |
3841 |
- pagefault_disable(); |
3842 |
- |
3843 |
-+ _atomic_spin_lock_irqsave(uaddr, flags); |
3844 |
-+ |
3845 |
- switch (op) { |
3846 |
- case FUTEX_OP_SET: |
3847 |
-+ /* *(int *)UADDR2 = OPARG; */ |
3848 |
-+ ret = get_user(oldval, uaddr); |
3849 |
-+ if (!ret) |
3850 |
-+ ret = put_user(oparg, uaddr); |
3851 |
-+ break; |
3852 |
- case FUTEX_OP_ADD: |
3853 |
-+ /* *(int *)UADDR2 += OPARG; */ |
3854 |
-+ ret = get_user(oldval, uaddr); |
3855 |
-+ if (!ret) { |
3856 |
-+ val = oldval + oparg; |
3857 |
-+ ret = put_user(val, uaddr); |
3858 |
-+ } |
3859 |
-+ break; |
3860 |
- case FUTEX_OP_OR: |
3861 |
-+ /* *(int *)UADDR2 |= OPARG; */ |
3862 |
-+ ret = get_user(oldval, uaddr); |
3863 |
-+ if (!ret) { |
3864 |
-+ val = oldval | oparg; |
3865 |
-+ ret = put_user(val, uaddr); |
3866 |
-+ } |
3867 |
-+ break; |
3868 |
- case FUTEX_OP_ANDN: |
3869 |
-+ /* *(int *)UADDR2 &= ~OPARG; */ |
3870 |
-+ ret = get_user(oldval, uaddr); |
3871 |
-+ if (!ret) { |
3872 |
-+ val = oldval & ~oparg; |
3873 |
-+ ret = put_user(val, uaddr); |
3874 |
-+ } |
3875 |
-+ break; |
3876 |
- case FUTEX_OP_XOR: |
3877 |
-+ /* *(int *)UADDR2 ^= OPARG; */ |
3878 |
-+ ret = get_user(oldval, uaddr); |
3879 |
-+ if (!ret) { |
3880 |
-+ val = oldval ^ oparg; |
3881 |
-+ ret = put_user(val, uaddr); |
3882 |
-+ } |
3883 |
-+ break; |
3884 |
- default: |
3885 |
- ret = -ENOSYS; |
3886 |
- } |
3887 |
- |
3888 |
-+ _atomic_spin_unlock_irqrestore(uaddr, flags); |
3889 |
-+ |
3890 |
- pagefault_enable(); |
3891 |
- |
3892 |
- if (!ret) { |
3893 |
-@@ -54,7 +94,9 @@ static inline int |
3894 |
- futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
3895 |
- u32 oldval, u32 newval) |
3896 |
- { |
3897 |
-+ int ret; |
3898 |
- u32 val; |
3899 |
-+ unsigned long flags; |
3900 |
- |
3901 |
- /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is |
3902 |
- * our gateway page, and causes no end of trouble... |
3903 |
-@@ -65,12 +107,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
3904 |
- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) |
3905 |
- return -EFAULT; |
3906 |
- |
3907 |
-- if (get_user(val, uaddr)) |
3908 |
-- return -EFAULT; |
3909 |
-- if (val == oldval && put_user(newval, uaddr)) |
3910 |
-- return -EFAULT; |
3911 |
-+ /* HPPA has no cmpxchg in hardware and therefore the |
3912 |
-+ * best we can do here is use an array of locks. The |
3913 |
-+ * lock selected is based on a hash of the userspace |
3914 |
-+ * address. This should scale to a couple of CPUs. |
3915 |
-+ */ |
3916 |
-+ |
3917 |
-+ _atomic_spin_lock_irqsave(uaddr, flags); |
3918 |
-+ |
3919 |
-+ ret = get_user(val, uaddr); |
3920 |
-+ |
3921 |
-+ if (!ret && val == oldval) |
3922 |
-+ ret = put_user(newval, uaddr); |
3923 |
-+ |
3924 |
- *uval = val; |
3925 |
-- return 0; |
3926 |
-+ |
3927 |
-+ _atomic_spin_unlock_irqrestore(uaddr, flags); |
3928 |
-+ |
3929 |
-+ return ret; |
3930 |
- } |
3931 |
- |
3932 |
- #endif /*__KERNEL__*/ |
3933 |
-diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h |
3934 |
-index 3392de3..d61de64 100644 |
3935 |
---- a/arch/parisc/include/asm/unistd.h |
3936 |
-+++ b/arch/parisc/include/asm/unistd.h |
3937 |
-@@ -821,8 +821,9 @@ |
3938 |
- #define __NR_open_by_handle_at (__NR_Linux + 326) |
3939 |
- #define __NR_syncfs (__NR_Linux + 327) |
3940 |
- #define __NR_setns (__NR_Linux + 328) |
3941 |
-+#define __NR_sendmmsg (__NR_Linux + 329) |
3942 |
- |
3943 |
--#define __NR_Linux_syscalls (__NR_setns + 1) |
3944 |
-+#define __NR_Linux_syscalls (__NR_sendmmsg + 1) |
3945 |
- |
3946 |
- |
3947 |
- #define __IGNORE_select /* newselect */ |
3948 |
-diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S |
3949 |
-index 34a4f5a..e66366f 100644 |
3950 |
---- a/arch/parisc/kernel/syscall_table.S |
3951 |
-+++ b/arch/parisc/kernel/syscall_table.S |
3952 |
-@@ -427,6 +427,7 @@ |
3953 |
- ENTRY_COMP(open_by_handle_at) |
3954 |
- ENTRY_SAME(syncfs) |
3955 |
- ENTRY_SAME(setns) |
3956 |
-+ ENTRY_COMP(sendmmsg) |
3957 |
- |
3958 |
- /* Nothing yet */ |
3959 |
- |
3960 |
-diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c |
3961 |
-index c016033..3b22142 100644 |
3962 |
---- a/arch/powerpc/kernel/prom_init.c |
3963 |
-+++ b/arch/powerpc/kernel/prom_init.c |
3964 |
-@@ -1020,7 +1020,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) |
3965 |
- } |
3966 |
- if (addr == 0) |
3967 |
- return 0; |
3968 |
-- RELOC(alloc_bottom) = addr; |
3969 |
-+ RELOC(alloc_bottom) = addr + size; |
3970 |
- |
3971 |
- prom_debug(" -> %x\n", addr); |
3972 |
- prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); |
3973 |
-@@ -1834,7 +1834,7 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, |
3974 |
- chunk = alloc_up(room, 0); |
3975 |
- if (chunk == 0) |
3976 |
- prom_panic("No memory for flatten_device_tree (claim failed)"); |
3977 |
-- *mem_end = RELOC(alloc_top); |
3978 |
-+ *mem_end = chunk + room; |
3979 |
- } |
3980 |
- |
3981 |
- ret = (void *)*mem_start; |
3982 |
-@@ -2053,7 +2053,7 @@ static void __init flatten_device_tree(void) |
3983 |
- mem_start = (unsigned long)alloc_up(room, PAGE_SIZE); |
3984 |
- if (mem_start == 0) |
3985 |
- prom_panic("Can't allocate initial device-tree chunk\n"); |
3986 |
-- mem_end = RELOC(alloc_top); |
3987 |
-+ mem_end = mem_start + room; |
3988 |
- |
3989 |
- /* Get root of tree */ |
3990 |
- root = call_prom("peer", 1, 1, (phandle)0); |
3991 |
-diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c |
3992 |
-index e919007..0e86563 100644 |
3993 |
---- a/arch/powerpc/platforms/pseries/dtl.c |
3994 |
-+++ b/arch/powerpc/platforms/pseries/dtl.c |
3995 |
-@@ -181,7 +181,7 @@ static void dtl_stop(struct dtl *dtl) |
3996 |
- |
3997 |
- lppaca_of(dtl->cpu).dtl_enable_mask = 0x0; |
3998 |
- |
3999 |
-- unregister_dtl(hwcpu, __pa(dtl->buf)); |
4000 |
-+ unregister_dtl(hwcpu); |
4001 |
- } |
4002 |
- |
4003 |
- static u64 dtl_current_index(struct dtl *dtl) |
4004 |
-diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c |
4005 |
-index 54cf3a4..1118cb7 100644 |
4006 |
---- a/arch/powerpc/platforms/pseries/kexec.c |
4007 |
-+++ b/arch/powerpc/platforms/pseries/kexec.c |
4008 |
-@@ -26,6 +26,17 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) |
4009 |
- /* Don't risk a hypervisor call if we're crashing */ |
4010 |
- if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { |
4011 |
- unsigned long addr; |
4012 |
-+ int ret; |
4013 |
-+ |
4014 |
-+ if (get_lppaca()->dtl_enable_mask) { |
4015 |
-+ ret = unregister_dtl(hard_smp_processor_id()); |
4016 |
-+ if (ret) { |
4017 |
-+ pr_err("WARNING: DTL deregistration for cpu " |
4018 |
-+ "%d (hw %d) failed with %d\n", |
4019 |
-+ smp_processor_id(), |
4020 |
-+ hard_smp_processor_id(), ret); |
4021 |
-+ } |
4022 |
-+ } |
4023 |
- |
4024 |
- addr = __pa(get_slb_shadow()); |
4025 |
- if (unregister_slb_shadow(hard_smp_processor_id(), addr)) |
4026 |
-diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c |
4027 |
-index 39e6e0a..ed96b37 100644 |
4028 |
---- a/arch/powerpc/platforms/pseries/lpar.c |
4029 |
-+++ b/arch/powerpc/platforms/pseries/lpar.c |
4030 |
-@@ -395,7 +395,7 @@ static void pSeries_lpar_hptab_clear(void) |
4031 |
- unsigned long ptel; |
4032 |
- } ptes[4]; |
4033 |
- long lpar_rc; |
4034 |
-- int i, j; |
4035 |
-+ unsigned long i, j; |
4036 |
- |
4037 |
- /* Read in batches of 4, |
4038 |
- * invalidate only valid entries not in the VRMA |
4039 |
-diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h |
4040 |
-index 4bf2120..a6921ae 100644 |
4041 |
---- a/arch/powerpc/platforms/pseries/plpar_wrappers.h |
4042 |
-+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h |
4043 |
-@@ -73,9 +73,9 @@ static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) |
4044 |
- return vpa_call(0x3, cpu, vpa); |
4045 |
- } |
4046 |
- |
4047 |
--static inline long unregister_dtl(unsigned long cpu, unsigned long vpa) |
4048 |
-+static inline long unregister_dtl(unsigned long cpu) |
4049 |
- { |
4050 |
-- return vpa_call(0x6, cpu, vpa); |
4051 |
-+ return vpa_call(0x6, cpu, 0); |
4052 |
- } |
4053 |
- |
4054 |
- static inline long register_dtl(unsigned long cpu, unsigned long vpa) |
4055 |
-diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h |
4056 |
-index 38e9aa1..3fc595a 100644 |
4057 |
---- a/arch/sparc/include/asm/bitops_64.h |
4058 |
-+++ b/arch/sparc/include/asm/bitops_64.h |
4059 |
-@@ -26,61 +26,28 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr); |
4060 |
- #define smp_mb__before_clear_bit() barrier() |
4061 |
- #define smp_mb__after_clear_bit() barrier() |
4062 |
- |
4063 |
--#include <asm-generic/bitops/ffz.h> |
4064 |
--#include <asm-generic/bitops/__ffs.h> |
4065 |
- #include <asm-generic/bitops/fls.h> |
4066 |
- #include <asm-generic/bitops/__fls.h> |
4067 |
- #include <asm-generic/bitops/fls64.h> |
4068 |
- |
4069 |
- #ifdef __KERNEL__ |
4070 |
- |
4071 |
-+extern int ffs(int x); |
4072 |
-+extern unsigned long __ffs(unsigned long); |
4073 |
-+ |
4074 |
-+#include <asm-generic/bitops/ffz.h> |
4075 |
- #include <asm-generic/bitops/sched.h> |
4076 |
--#include <asm-generic/bitops/ffs.h> |
4077 |
- |
4078 |
- /* |
4079 |
- * hweightN: returns the hamming weight (i.e. the number |
4080 |
- * of bits set) of a N-bit word |
4081 |
- */ |
4082 |
- |
4083 |
--#ifdef ULTRA_HAS_POPULATION_COUNT |
4084 |
-- |
4085 |
--static inline unsigned int __arch_hweight64(unsigned long w) |
4086 |
--{ |
4087 |
-- unsigned int res; |
4088 |
-- |
4089 |
-- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); |
4090 |
-- return res; |
4091 |
--} |
4092 |
-- |
4093 |
--static inline unsigned int __arch_hweight32(unsigned int w) |
4094 |
--{ |
4095 |
-- unsigned int res; |
4096 |
-- |
4097 |
-- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff)); |
4098 |
-- return res; |
4099 |
--} |
4100 |
-+extern unsigned long __arch_hweight64(__u64 w); |
4101 |
-+extern unsigned int __arch_hweight32(unsigned int w); |
4102 |
-+extern unsigned int __arch_hweight16(unsigned int w); |
4103 |
-+extern unsigned int __arch_hweight8(unsigned int w); |
4104 |
- |
4105 |
--static inline unsigned int __arch_hweight16(unsigned int w) |
4106 |
--{ |
4107 |
-- unsigned int res; |
4108 |
-- |
4109 |
-- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff)); |
4110 |
-- return res; |
4111 |
--} |
4112 |
-- |
4113 |
--static inline unsigned int __arch_hweight8(unsigned int w) |
4114 |
--{ |
4115 |
-- unsigned int res; |
4116 |
-- |
4117 |
-- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff)); |
4118 |
-- return res; |
4119 |
--} |
4120 |
-- |
4121 |
--#else |
4122 |
-- |
4123 |
--#include <asm-generic/bitops/arch_hweight.h> |
4124 |
-- |
4125 |
--#endif |
4126 |
- #include <asm-generic/bitops/const_hweight.h> |
4127 |
- #include <asm-generic/bitops/lock.h> |
4128 |
- #endif /* __KERNEL__ */ |
4129 |
-diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h |
4130 |
-index e678803..7df8b7f 100644 |
4131 |
---- a/arch/sparc/include/asm/elf_64.h |
4132 |
-+++ b/arch/sparc/include/asm/elf_64.h |
4133 |
-@@ -59,15 +59,33 @@ |
4134 |
- #define R_SPARC_6 45 |
4135 |
- |
4136 |
- /* Bits present in AT_HWCAP, primarily for Sparc32. */ |
4137 |
-- |
4138 |
--#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ |
4139 |
--#define HWCAP_SPARC_STBAR 2 |
4140 |
--#define HWCAP_SPARC_SWAP 4 |
4141 |
--#define HWCAP_SPARC_MULDIV 8 |
4142 |
--#define HWCAP_SPARC_V9 16 |
4143 |
--#define HWCAP_SPARC_ULTRA3 32 |
4144 |
--#define HWCAP_SPARC_BLKINIT 64 |
4145 |
--#define HWCAP_SPARC_N2 128 |
4146 |
-+#define HWCAP_SPARC_FLUSH 0x00000001 |
4147 |
-+#define HWCAP_SPARC_STBAR 0x00000002 |
4148 |
-+#define HWCAP_SPARC_SWAP 0x00000004 |
4149 |
-+#define HWCAP_SPARC_MULDIV 0x00000008 |
4150 |
-+#define HWCAP_SPARC_V9 0x00000010 |
4151 |
-+#define HWCAP_SPARC_ULTRA3 0x00000020 |
4152 |
-+#define HWCAP_SPARC_BLKINIT 0x00000040 |
4153 |
-+#define HWCAP_SPARC_N2 0x00000080 |
4154 |
-+ |
4155 |
-+/* Solaris compatible AT_HWCAP bits. */ |
4156 |
-+#define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */ |
4157 |
-+#define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */ |
4158 |
-+#define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */ |
4159 |
-+#define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */ |
4160 |
-+#define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */ |
4161 |
-+#define AV_SPARC_VIS 0x00002000 /* VIS insns available */ |
4162 |
-+#define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */ |
4163 |
-+#define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */ |
4164 |
-+#define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */ |
4165 |
-+#define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */ |
4166 |
-+#define AV_SPARC_HPC 0x00040000 /* HPC insns available */ |
4167 |
-+#define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */ |
4168 |
-+#define AV_SPARC_TRANS 0x00100000 /* transaction insns available */ |
4169 |
-+#define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */ |
4170 |
-+#define AV_SPARC_IMA 0x00400000 /* integer multiply-add */ |
4171 |
-+#define AV_SPARC_ASI_CACHE_SPARING \ |
4172 |
-+ 0x00800000 /* cache sparing ASIs available */ |
4173 |
- |
4174 |
- #define CORE_DUMP_USE_REGSET |
4175 |
- |
4176 |
-@@ -162,31 +180,8 @@ typedef struct { |
4177 |
- #define ELF_ET_DYN_BASE 0x0000010000000000UL |
4178 |
- #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL |
4179 |
- |
4180 |
-- |
4181 |
--/* This yields a mask that user programs can use to figure out what |
4182 |
-- instruction set this cpu supports. */ |
4183 |
-- |
4184 |
--/* On Ultra, we support all of the v8 capabilities. */ |
4185 |
--static inline unsigned int sparc64_elf_hwcap(void) |
4186 |
--{ |
4187 |
-- unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | |
4188 |
-- HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | |
4189 |
-- HWCAP_SPARC_V9); |
4190 |
-- |
4191 |
-- if (tlb_type == cheetah || tlb_type == cheetah_plus) |
4192 |
-- cap |= HWCAP_SPARC_ULTRA3; |
4193 |
-- else if (tlb_type == hypervisor) { |
4194 |
-- if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || |
4195 |
-- sun4v_chip_type == SUN4V_CHIP_NIAGARA2) |
4196 |
-- cap |= HWCAP_SPARC_BLKINIT; |
4197 |
-- if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2) |
4198 |
-- cap |= HWCAP_SPARC_N2; |
4199 |
-- } |
4200 |
-- |
4201 |
-- return cap; |
4202 |
--} |
4203 |
-- |
4204 |
--#define ELF_HWCAP sparc64_elf_hwcap(); |
4205 |
-+extern unsigned long sparc64_elf_hwcap; |
4206 |
-+#define ELF_HWCAP sparc64_elf_hwcap |
4207 |
- |
4208 |
- /* This yields a string that ld.so will use to load implementation |
4209 |
- specific libraries for optimization. This is more specific in |
4210 |
-diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h |
4211 |
-index 7568640..015a761 100644 |
4212 |
---- a/arch/sparc/include/asm/hypervisor.h |
4213 |
-+++ b/arch/sparc/include/asm/hypervisor.h |
4214 |
-@@ -2927,6 +2927,13 @@ extern unsigned long sun4v_ncs_request(unsigned long request, |
4215 |
- #define HV_FAST_FIRE_GET_PERFREG 0x120 |
4216 |
- #define HV_FAST_FIRE_SET_PERFREG 0x121 |
4217 |
- |
4218 |
-+#define HV_FAST_REBOOT_DATA_SET 0x172 |
4219 |
-+ |
4220 |
-+#ifndef __ASSEMBLY__ |
4221 |
-+extern unsigned long sun4v_reboot_data_set(unsigned long ra, |
4222 |
-+ unsigned long len); |
4223 |
-+#endif |
4224 |
-+ |
4225 |
- /* Function numbers for HV_CORE_TRAP. */ |
4226 |
- #define HV_CORE_SET_VER 0x00 |
4227 |
- #define HV_CORE_PUTCHAR 0x01 |
4228 |
-@@ -2940,16 +2947,23 @@ extern unsigned long sun4v_ncs_request(unsigned long request, |
4229 |
- #define HV_GRP_CORE 0x0001 |
4230 |
- #define HV_GRP_INTR 0x0002 |
4231 |
- #define HV_GRP_SOFT_STATE 0x0003 |
4232 |
-+#define HV_GRP_TM 0x0080 |
4233 |
- #define HV_GRP_PCI 0x0100 |
4234 |
- #define HV_GRP_LDOM 0x0101 |
4235 |
- #define HV_GRP_SVC_CHAN 0x0102 |
4236 |
- #define HV_GRP_NCS 0x0103 |
4237 |
- #define HV_GRP_RNG 0x0104 |
4238 |
-+#define HV_GRP_PBOOT 0x0105 |
4239 |
-+#define HV_GRP_TPM 0x0107 |
4240 |
-+#define HV_GRP_SDIO 0x0108 |
4241 |
-+#define HV_GRP_SDIO_ERR 0x0109 |
4242 |
-+#define HV_GRP_REBOOT_DATA 0x0110 |
4243 |
- #define HV_GRP_NIAG_PERF 0x0200 |
4244 |
- #define HV_GRP_FIRE_PERF 0x0201 |
4245 |
- #define HV_GRP_N2_CPU 0x0202 |
4246 |
- #define HV_GRP_NIU 0x0204 |
4247 |
- #define HV_GRP_VF_CPU 0x0205 |
4248 |
-+#define HV_GRP_KT_CPU 0x0209 |
4249 |
- #define HV_GRP_DIAG 0x0300 |
4250 |
- |
4251 |
- #ifndef __ASSEMBLY__ |
4252 |
-diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h |
4253 |
-index f0d0c40..55a17c6 100644 |
4254 |
---- a/arch/sparc/include/asm/spitfire.h |
4255 |
-+++ b/arch/sparc/include/asm/spitfire.h |
4256 |
-@@ -42,6 +42,7 @@ |
4257 |
- #define SUN4V_CHIP_INVALID 0x00 |
4258 |
- #define SUN4V_CHIP_NIAGARA1 0x01 |
4259 |
- #define SUN4V_CHIP_NIAGARA2 0x02 |
4260 |
-+#define SUN4V_CHIP_NIAGARA3 0x03 |
4261 |
- #define SUN4V_CHIP_UNKNOWN 0xff |
4262 |
- |
4263 |
- #ifndef __ASSEMBLY__ |
4264 |
-diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h |
4265 |
-index 83c571d..1a8afd1 100644 |
4266 |
---- a/arch/sparc/include/asm/tsb.h |
4267 |
-+++ b/arch/sparc/include/asm/tsb.h |
4268 |
-@@ -133,29 +133,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; |
4269 |
- sub TSB, 0x8, TSB; \ |
4270 |
- TSB_STORE(TSB, TAG); |
4271 |
- |
4272 |
--#define KTSB_LOAD_QUAD(TSB, REG) \ |
4273 |
-- ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; |
4274 |
-- |
4275 |
--#define KTSB_STORE(ADDR, VAL) \ |
4276 |
-- stxa VAL, [ADDR] ASI_N; |
4277 |
-- |
4278 |
--#define KTSB_LOCK_TAG(TSB, REG1, REG2) \ |
4279 |
--99: lduwa [TSB] ASI_N, REG1; \ |
4280 |
-- sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ |
4281 |
-- andcc REG1, REG2, %g0; \ |
4282 |
-- bne,pn %icc, 99b; \ |
4283 |
-- nop; \ |
4284 |
-- casa [TSB] ASI_N, REG1, REG2;\ |
4285 |
-- cmp REG1, REG2; \ |
4286 |
-- bne,pn %icc, 99b; \ |
4287 |
-- nop; \ |
4288 |
-- |
4289 |
--#define KTSB_WRITE(TSB, TTE, TAG) \ |
4290 |
-- add TSB, 0x8, TSB; \ |
4291 |
-- stxa TTE, [TSB] ASI_N; \ |
4292 |
-- sub TSB, 0x8, TSB; \ |
4293 |
-- stxa TAG, [TSB] ASI_N; |
4294 |
-- |
4295 |
- /* Do a kernel page table walk. Leaves physical PTE pointer in |
4296 |
- * REG1. Jumps to FAIL_LABEL on early page table walk termination. |
4297 |
- * VADDR will not be clobbered, but REG2 will. |
4298 |
-@@ -239,6 +216,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; |
4299 |
- (KERNEL_TSB_SIZE_BYTES / 16) |
4300 |
- #define KERNEL_TSB4M_NENTRIES 4096 |
4301 |
- |
4302 |
-+#define KTSB_PHYS_SHIFT 15 |
4303 |
-+ |
4304 |
- /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL |
4305 |
- * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries |
4306 |
- * and the found TTE will be left in REG1. REG3 and REG4 must |
4307 |
-@@ -247,13 +226,22 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; |
4308 |
- * VADDR and TAG will be preserved and not clobbered by this macro. |
4309 |
- */ |
4310 |
- #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ |
4311 |
-- sethi %hi(swapper_tsb), REG1; \ |
4312 |
-+661: sethi %hi(swapper_tsb), REG1; \ |
4313 |
- or REG1, %lo(swapper_tsb), REG1; \ |
4314 |
-+ .section .swapper_tsb_phys_patch, "ax"; \ |
4315 |
-+ .word 661b; \ |
4316 |
-+ .previous; \ |
4317 |
-+661: nop; \ |
4318 |
-+ .section .tsb_ldquad_phys_patch, "ax"; \ |
4319 |
-+ .word 661b; \ |
4320 |
-+ sllx REG1, KTSB_PHYS_SHIFT, REG1; \ |
4321 |
-+ sllx REG1, KTSB_PHYS_SHIFT, REG1; \ |
4322 |
-+ .previous; \ |
4323 |
- srlx VADDR, PAGE_SHIFT, REG2; \ |
4324 |
- and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ |
4325 |
- sllx REG2, 4, REG2; \ |
4326 |
- add REG1, REG2, REG2; \ |
4327 |
-- KTSB_LOAD_QUAD(REG2, REG3); \ |
4328 |
-+ TSB_LOAD_QUAD(REG2, REG3); \ |
4329 |
- cmp REG3, TAG; \ |
4330 |
- be,a,pt %xcc, OK_LABEL; \ |
4331 |
- mov REG4, REG1; |
4332 |
-@@ -263,12 +251,21 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; |
4333 |
- * we can make use of that for the index computation. |
4334 |
- */ |
4335 |
- #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ |
4336 |
-- sethi %hi(swapper_4m_tsb), REG1; \ |
4337 |
-+661: sethi %hi(swapper_4m_tsb), REG1; \ |
4338 |
- or REG1, %lo(swapper_4m_tsb), REG1; \ |
4339 |
-+ .section .swapper_4m_tsb_phys_patch, "ax"; \ |
4340 |
-+ .word 661b; \ |
4341 |
-+ .previous; \ |
4342 |
-+661: nop; \ |
4343 |
-+ .section .tsb_ldquad_phys_patch, "ax"; \ |
4344 |
-+ .word 661b; \ |
4345 |
-+ sllx REG1, KTSB_PHYS_SHIFT, REG1; \ |
4346 |
-+ sllx REG1, KTSB_PHYS_SHIFT, REG1; \ |
4347 |
-+ .previous; \ |
4348 |
- and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ |
4349 |
- sllx REG2, 4, REG2; \ |
4350 |
- add REG1, REG2, REG2; \ |
4351 |
-- KTSB_LOAD_QUAD(REG2, REG3); \ |
4352 |
-+ TSB_LOAD_QUAD(REG2, REG3); \ |
4353 |
- cmp REG3, TAG; \ |
4354 |
- be,a,pt %xcc, OK_LABEL; \ |
4355 |
- mov REG4, REG1; |
4356 |
-diff --git a/arch/sparc/include/asm/xor_64.h b/arch/sparc/include/asm/xor_64.h |
4357 |
-index bee4bf4..9ed6ff6 100644 |
4358 |
---- a/arch/sparc/include/asm/xor_64.h |
4359 |
-+++ b/arch/sparc/include/asm/xor_64.h |
4360 |
-@@ -65,6 +65,7 @@ static struct xor_block_template xor_block_niagara = { |
4361 |
- #define XOR_SELECT_TEMPLATE(FASTEST) \ |
4362 |
- ((tlb_type == hypervisor && \ |
4363 |
- (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \ |
4364 |
-- sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \ |
4365 |
-+ sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || \ |
4366 |
-+ sun4v_chip_type == SUN4V_CHIP_NIAGARA3)) ? \ |
4367 |
- &xor_block_niagara : \ |
4368 |
- &xor_block_VIS) |
4369 |
-diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c |
4370 |
-index 138dbbc..9810fd8 100644 |
4371 |
---- a/arch/sparc/kernel/cpu.c |
4372 |
-+++ b/arch/sparc/kernel/cpu.c |
4373 |
-@@ -396,6 +396,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) |
4374 |
- , cpu_data(0).clock_tick |
4375 |
- #endif |
4376 |
- ); |
4377 |
-+ cpucap_info(m); |
4378 |
- #ifdef CONFIG_SMP |
4379 |
- smp_bogo(m); |
4380 |
- #endif |
4381 |
-@@ -474,11 +475,18 @@ static void __init sun4v_cpu_probe(void) |
4382 |
- sparc_pmu_type = "niagara2"; |
4383 |
- break; |
4384 |
- |
4385 |
-+ case SUN4V_CHIP_NIAGARA3: |
4386 |
-+ sparc_cpu_type = "UltraSparc T3 (Niagara3)"; |
4387 |
-+ sparc_fpu_type = "UltraSparc T3 integrated FPU"; |
4388 |
-+ sparc_pmu_type = "niagara3"; |
4389 |
-+ break; |
4390 |
-+ |
4391 |
- default: |
4392 |
- printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", |
4393 |
- prom_cpu_compatible); |
4394 |
- sparc_cpu_type = "Unknown SUN4V CPU"; |
4395 |
- sparc_fpu_type = "Unknown SUN4V FPU"; |
4396 |
-+ sparc_pmu_type = "Unknown SUN4V PMU"; |
4397 |
- break; |
4398 |
- } |
4399 |
- } |
4400 |
-diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c |
4401 |
-index d91fd78..4197e8d 100644 |
4402 |
---- a/arch/sparc/kernel/cpumap.c |
4403 |
-+++ b/arch/sparc/kernel/cpumap.c |
4404 |
-@@ -324,6 +324,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) |
4405 |
- switch (sun4v_chip_type) { |
4406 |
- case SUN4V_CHIP_NIAGARA1: |
4407 |
- case SUN4V_CHIP_NIAGARA2: |
4408 |
-+ case SUN4V_CHIP_NIAGARA3: |
4409 |
- rover_inc_table = niagara_iterate_method; |
4410 |
- break; |
4411 |
- default: |
4412 |
-diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c |
4413 |
-index dd1342c..7429b47 100644 |
4414 |
---- a/arch/sparc/kernel/ds.c |
4415 |
-+++ b/arch/sparc/kernel/ds.c |
4416 |
-@@ -15,12 +15,15 @@ |
4417 |
- #include <linux/reboot.h> |
4418 |
- #include <linux/cpu.h> |
4419 |
- |
4420 |
-+#include <asm/hypervisor.h> |
4421 |
- #include <asm/ldc.h> |
4422 |
- #include <asm/vio.h> |
4423 |
- #include <asm/mdesc.h> |
4424 |
- #include <asm/head.h> |
4425 |
- #include <asm/irq.h> |
4426 |
- |
4427 |
-+#include "kernel.h" |
4428 |
-+ |
4429 |
- #define DRV_MODULE_NAME "ds" |
4430 |
- #define PFX DRV_MODULE_NAME ": " |
4431 |
- #define DRV_MODULE_VERSION "1.0" |
4432 |
-@@ -828,18 +831,32 @@ void ldom_set_var(const char *var, const char *value) |
4433 |
- } |
4434 |
- } |
4435 |
- |
4436 |
-+static char full_boot_str[256] __attribute__((aligned(32))); |
4437 |
-+static int reboot_data_supported; |
4438 |
-+ |
4439 |
- void ldom_reboot(const char *boot_command) |
4440 |
- { |
4441 |
- /* Don't bother with any of this if the boot_command |
4442 |
- * is empty. |
4443 |
- */ |
4444 |
- if (boot_command && strlen(boot_command)) { |
4445 |
-- char full_boot_str[256]; |
4446 |
-+ unsigned long len; |
4447 |
- |
4448 |
- strcpy(full_boot_str, "boot "); |
4449 |
- strcpy(full_boot_str + strlen("boot "), boot_command); |
4450 |
-+ len = strlen(full_boot_str); |
4451 |
- |
4452 |
-- ldom_set_var("reboot-command", full_boot_str); |
4453 |
-+ if (reboot_data_supported) { |
4454 |
-+ unsigned long ra = kimage_addr_to_ra(full_boot_str); |
4455 |
-+ unsigned long hv_ret; |
4456 |
-+ |
4457 |
-+ hv_ret = sun4v_reboot_data_set(ra, len); |
4458 |
-+ if (hv_ret != HV_EOK) |
4459 |
-+ pr_err("SUN4V: Unable to set reboot data " |
4460 |
-+ "hv_ret=%lu\n", hv_ret); |
4461 |
-+ } else { |
4462 |
-+ ldom_set_var("reboot-command", full_boot_str); |
4463 |
-+ } |
4464 |
- } |
4465 |
- sun4v_mach_sir(); |
4466 |
- } |
4467 |
-@@ -1237,6 +1254,16 @@ static struct vio_driver ds_driver = { |
4468 |
- |
4469 |
- static int __init ds_init(void) |
4470 |
- { |
4471 |
-+ unsigned long hv_ret, major, minor; |
4472 |
-+ |
4473 |
-+ if (tlb_type == hypervisor) { |
4474 |
-+ hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor); |
4475 |
-+ if (hv_ret == HV_EOK) { |
4476 |
-+ pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n", |
4477 |
-+ major, minor); |
4478 |
-+ reboot_data_supported = 1; |
4479 |
-+ } |
4480 |
-+ } |
4481 |
- kthread_run(ds_thread, NULL, "kldomd"); |
4482 |
- |
4483 |
- return vio_register_driver(&ds_driver); |
4484 |
-diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h |
4485 |
-index d1f1361..e27f8ea 100644 |
4486 |
---- a/arch/sparc/kernel/entry.h |
4487 |
-+++ b/arch/sparc/kernel/entry.h |
4488 |
-@@ -42,6 +42,20 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, |
4489 |
- extern void fpload(unsigned long *fpregs, unsigned long *fsr); |
4490 |
- |
4491 |
- #else /* CONFIG_SPARC32 */ |
4492 |
-+struct popc_3insn_patch_entry { |
4493 |
-+ unsigned int addr; |
4494 |
-+ unsigned int insns[3]; |
4495 |
-+}; |
4496 |
-+extern struct popc_3insn_patch_entry __popc_3insn_patch, |
4497 |
-+ __popc_3insn_patch_end; |
4498 |
-+ |
4499 |
-+struct popc_6insn_patch_entry { |
4500 |
-+ unsigned int addr; |
4501 |
-+ unsigned int insns[6]; |
4502 |
-+}; |
4503 |
-+extern struct popc_6insn_patch_entry __popc_6insn_patch, |
4504 |
-+ __popc_6insn_patch_end; |
4505 |
-+ |
4506 |
- extern void __init per_cpu_patch(void); |
4507 |
- extern void __init sun4v_patch(void); |
4508 |
- extern void __init boot_cpu_id_too_large(int cpu); |
4509 |
-diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S |
4510 |
-index aa594c7..0cbab31 100644 |
4511 |
---- a/arch/sparc/kernel/head_64.S |
4512 |
-+++ b/arch/sparc/kernel/head_64.S |
4513 |
-@@ -132,6 +132,8 @@ prom_sun4v_name: |
4514 |
- .asciz "sun4v" |
4515 |
- prom_niagara_prefix: |
4516 |
- .asciz "SUNW,UltraSPARC-T" |
4517 |
-+prom_sparc_prefix: |
4518 |
-+ .asciz "SPARC-T" |
4519 |
- .align 4 |
4520 |
- prom_root_compatible: |
4521 |
- .skip 64 |
4522 |
-@@ -382,6 +384,22 @@ sun4v_chip_type: |
4523 |
- 90: ldub [%g7], %g2 |
4524 |
- ldub [%g1], %g4 |
4525 |
- cmp %g2, %g4 |
4526 |
-+ bne,pn %icc, 89f |
4527 |
-+ add %g7, 1, %g7 |
4528 |
-+ subcc %g3, 1, %g3 |
4529 |
-+ bne,pt %xcc, 90b |
4530 |
-+ add %g1, 1, %g1 |
4531 |
-+ ba,pt %xcc, 91f |
4532 |
-+ nop |
4533 |
-+ |
4534 |
-+89: sethi %hi(prom_cpu_compatible), %g1 |
4535 |
-+ or %g1, %lo(prom_cpu_compatible), %g1 |
4536 |
-+ sethi %hi(prom_sparc_prefix), %g7 |
4537 |
-+ or %g7, %lo(prom_sparc_prefix), %g7 |
4538 |
-+ mov 7, %g3 |
4539 |
-+90: ldub [%g7], %g2 |
4540 |
-+ ldub [%g1], %g4 |
4541 |
-+ cmp %g2, %g4 |
4542 |
- bne,pn %icc, 4f |
4543 |
- add %g7, 1, %g7 |
4544 |
- subcc %g3, 1, %g3 |
4545 |
-@@ -390,6 +408,15 @@ sun4v_chip_type: |
4546 |
- |
4547 |
- sethi %hi(prom_cpu_compatible), %g1 |
4548 |
- or %g1, %lo(prom_cpu_compatible), %g1 |
4549 |
-+ ldub [%g1 + 7], %g2 |
4550 |
-+ cmp %g2, '3' |
4551 |
-+ be,pt %xcc, 5f |
4552 |
-+ mov SUN4V_CHIP_NIAGARA3, %g4 |
4553 |
-+ ba,pt %xcc, 4f |
4554 |
-+ nop |
4555 |
-+ |
4556 |
-+91: sethi %hi(prom_cpu_compatible), %g1 |
4557 |
-+ or %g1, %lo(prom_cpu_compatible), %g1 |
4558 |
- ldub [%g1 + 17], %g2 |
4559 |
- cmp %g2, '1' |
4560 |
- be,pt %xcc, 5f |
4561 |
-@@ -397,6 +424,7 @@ sun4v_chip_type: |
4562 |
- cmp %g2, '2' |
4563 |
- be,pt %xcc, 5f |
4564 |
- mov SUN4V_CHIP_NIAGARA2, %g4 |
4565 |
-+ |
4566 |
- 4: |
4567 |
- mov SUN4V_CHIP_UNKNOWN, %g4 |
4568 |
- 5: sethi %hi(sun4v_chip_type), %g2 |
4569 |
-@@ -514,6 +542,9 @@ niagara_tlb_fixup: |
4570 |
- cmp %g1, SUN4V_CHIP_NIAGARA2 |
4571 |
- be,pt %xcc, niagara2_patch |
4572 |
- nop |
4573 |
-+ cmp %g1, SUN4V_CHIP_NIAGARA3 |
4574 |
-+ be,pt %xcc, niagara2_patch |
4575 |
-+ nop |
4576 |
- |
4577 |
- call generic_patch_copyops |
4578 |
- nop |
4579 |
-@@ -528,7 +559,7 @@ niagara2_patch: |
4580 |
- nop |
4581 |
- call niagara_patch_bzero |
4582 |
- nop |
4583 |
-- call niagara2_patch_pageops |
4584 |
-+ call niagara_patch_pageops |
4585 |
- nop |
4586 |
- |
4587 |
- ba,a,pt %xcc, 80f |
4588 |
-diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c |
4589 |
-index 7c60afb..c2d055d 100644 |
4590 |
---- a/arch/sparc/kernel/hvapi.c |
4591 |
-+++ b/arch/sparc/kernel/hvapi.c |
4592 |
-@@ -28,16 +28,23 @@ static struct api_info api_table[] = { |
4593 |
- { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, |
4594 |
- { .group = HV_GRP_INTR, }, |
4595 |
- { .group = HV_GRP_SOFT_STATE, }, |
4596 |
-+ { .group = HV_GRP_TM, }, |
4597 |
- { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, |
4598 |
- { .group = HV_GRP_LDOM, }, |
4599 |
- { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, |
4600 |
- { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, |
4601 |
- { .group = HV_GRP_RNG, }, |
4602 |
-+ { .group = HV_GRP_PBOOT, }, |
4603 |
-+ { .group = HV_GRP_TPM, }, |
4604 |
-+ { .group = HV_GRP_SDIO, }, |
4605 |
-+ { .group = HV_GRP_SDIO_ERR, }, |
4606 |
-+ { .group = HV_GRP_REBOOT_DATA, }, |
4607 |
- { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, |
4608 |
- { .group = HV_GRP_FIRE_PERF, }, |
4609 |
- { .group = HV_GRP_N2_CPU, }, |
4610 |
- { .group = HV_GRP_NIU, }, |
4611 |
- { .group = HV_GRP_VF_CPU, }, |
4612 |
-+ { .group = HV_GRP_KT_CPU, }, |
4613 |
- { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API }, |
4614 |
- }; |
4615 |
- |
4616 |
-diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S |
4617 |
-index 8a5f35f..58d60de 100644 |
4618 |
---- a/arch/sparc/kernel/hvcalls.S |
4619 |
-+++ b/arch/sparc/kernel/hvcalls.S |
4620 |
-@@ -798,3 +798,10 @@ ENTRY(sun4v_niagara2_setperf) |
4621 |
- retl |
4622 |
- nop |
4623 |
- ENDPROC(sun4v_niagara2_setperf) |
4624 |
-+ |
4625 |
-+ENTRY(sun4v_reboot_data_set) |
4626 |
-+ mov HV_FAST_REBOOT_DATA_SET, %o5 |
4627 |
-+ ta HV_FAST_TRAP |
4628 |
-+ retl |
4629 |
-+ nop |
4630 |
-+ENDPROC(sun4v_reboot_data_set) |
4631 |
-diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h |
4632 |
-index 6f6544c..fd6c36b 100644 |
4633 |
---- a/arch/sparc/kernel/kernel.h |
4634 |
-+++ b/arch/sparc/kernel/kernel.h |
4635 |
-@@ -4,12 +4,27 @@ |
4636 |
- #include <linux/interrupt.h> |
4637 |
- |
4638 |
- #include <asm/traps.h> |
4639 |
-+#include <asm/head.h> |
4640 |
-+#include <asm/io.h> |
4641 |
- |
4642 |
- /* cpu.c */ |
4643 |
- extern const char *sparc_pmu_type; |
4644 |
- extern unsigned int fsr_storage; |
4645 |
- extern int ncpus_probed; |
4646 |
- |
4647 |
-+#ifdef CONFIG_SPARC64 |
4648 |
-+/* setup_64.c */ |
4649 |
-+struct seq_file; |
4650 |
-+extern void cpucap_info(struct seq_file *); |
4651 |
-+ |
4652 |
-+static inline unsigned long kimage_addr_to_ra(const char *p) |
4653 |
-+{ |
4654 |
-+ unsigned long val = (unsigned long) p; |
4655 |
-+ |
4656 |
-+ return kern_base + (val - KERNBASE); |
4657 |
-+} |
4658 |
-+#endif |
4659 |
-+ |
4660 |
- #ifdef CONFIG_SPARC32 |
4661 |
- /* cpu.c */ |
4662 |
- extern void cpu_probe(void); |
4663 |
-diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S |
4664 |
-index 1d36147..79f3103 100644 |
4665 |
---- a/arch/sparc/kernel/ktlb.S |
4666 |
-+++ b/arch/sparc/kernel/ktlb.S |
4667 |
-@@ -47,16 +47,16 @@ kvmap_itlb_tsb_miss: |
4668 |
- kvmap_itlb_vmalloc_addr: |
4669 |
- KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath) |
4670 |
- |
4671 |
-- KTSB_LOCK_TAG(%g1, %g2, %g7) |
4672 |
-+ TSB_LOCK_TAG(%g1, %g2, %g7) |
4673 |
- |
4674 |
- /* Load and check PTE. */ |
4675 |
- ldxa [%g5] ASI_PHYS_USE_EC, %g5 |
4676 |
- mov 1, %g7 |
4677 |
- sllx %g7, TSB_TAG_INVALID_BIT, %g7 |
4678 |
- brgez,a,pn %g5, kvmap_itlb_longpath |
4679 |
-- KTSB_STORE(%g1, %g7) |
4680 |
-+ TSB_STORE(%g1, %g7) |
4681 |
- |
4682 |
-- KTSB_WRITE(%g1, %g5, %g6) |
4683 |
-+ TSB_WRITE(%g1, %g5, %g6) |
4684 |
- |
4685 |
- /* fallthrough to TLB load */ |
4686 |
- |
4687 |
-@@ -102,9 +102,9 @@ kvmap_itlb_longpath: |
4688 |
- kvmap_itlb_obp: |
4689 |
- OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath) |
4690 |
- |
4691 |
-- KTSB_LOCK_TAG(%g1, %g2, %g7) |
4692 |
-+ TSB_LOCK_TAG(%g1, %g2, %g7) |
4693 |
- |
4694 |
-- KTSB_WRITE(%g1, %g5, %g6) |
4695 |
-+ TSB_WRITE(%g1, %g5, %g6) |
4696 |
- |
4697 |
- ba,pt %xcc, kvmap_itlb_load |
4698 |
- nop |
4699 |
-@@ -112,17 +112,17 @@ kvmap_itlb_obp: |
4700 |
- kvmap_dtlb_obp: |
4701 |
- OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath) |
4702 |
- |
4703 |
-- KTSB_LOCK_TAG(%g1, %g2, %g7) |
4704 |
-+ TSB_LOCK_TAG(%g1, %g2, %g7) |
4705 |
- |
4706 |
-- KTSB_WRITE(%g1, %g5, %g6) |
4707 |
-+ TSB_WRITE(%g1, %g5, %g6) |
4708 |
- |
4709 |
- ba,pt %xcc, kvmap_dtlb_load |
4710 |
- nop |
4711 |
- |
4712 |
- .align 32 |
4713 |
- kvmap_dtlb_tsb4m_load: |
4714 |
-- KTSB_LOCK_TAG(%g1, %g2, %g7) |
4715 |
-- KTSB_WRITE(%g1, %g5, %g6) |
4716 |
-+ TSB_LOCK_TAG(%g1, %g2, %g7) |
4717 |
-+ TSB_WRITE(%g1, %g5, %g6) |
4718 |
- ba,pt %xcc, kvmap_dtlb_load |
4719 |
- nop |
4720 |
- |
4721 |
-@@ -222,16 +222,16 @@ kvmap_linear_patch: |
4722 |
- kvmap_dtlb_vmalloc_addr: |
4723 |
- KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath) |
4724 |
- |
4725 |
-- KTSB_LOCK_TAG(%g1, %g2, %g7) |
4726 |
-+ TSB_LOCK_TAG(%g1, %g2, %g7) |
4727 |
- |
4728 |
- /* Load and check PTE. */ |
4729 |
- ldxa [%g5] ASI_PHYS_USE_EC, %g5 |
4730 |
- mov 1, %g7 |
4731 |
- sllx %g7, TSB_TAG_INVALID_BIT, %g7 |
4732 |
- brgez,a,pn %g5, kvmap_dtlb_longpath |
4733 |
-- KTSB_STORE(%g1, %g7) |
4734 |
-+ TSB_STORE(%g1, %g7) |
4735 |
- |
4736 |
-- KTSB_WRITE(%g1, %g5, %g6) |
4737 |
-+ TSB_WRITE(%g1, %g5, %g6) |
4738 |
- |
4739 |
- /* fallthrough to TLB load */ |
4740 |
- |
4741 |
-diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c |
4742 |
-index 42f28c7..acaebb6 100644 |
4743 |
---- a/arch/sparc/kernel/mdesc.c |
4744 |
-+++ b/arch/sparc/kernel/mdesc.c |
4745 |
-@@ -508,6 +508,8 @@ const char *mdesc_node_name(struct mdesc_handle *hp, u64 node) |
4746 |
- } |
4747 |
- EXPORT_SYMBOL(mdesc_node_name); |
4748 |
- |
4749 |
-+static u64 max_cpus = 64; |
4750 |
-+ |
4751 |
- static void __init report_platform_properties(void) |
4752 |
- { |
4753 |
- struct mdesc_handle *hp = mdesc_grab(); |
4754 |
-@@ -543,8 +545,10 @@ static void __init report_platform_properties(void) |
4755 |
- if (v) |
4756 |
- printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v); |
4757 |
- v = mdesc_get_property(hp, pn, "max-cpus", NULL); |
4758 |
-- if (v) |
4759 |
-- printk("PLATFORM: max-cpus [%llu]\n", *v); |
4760 |
-+ if (v) { |
4761 |
-+ max_cpus = *v; |
4762 |
-+ printk("PLATFORM: max-cpus [%llu]\n", max_cpus); |
4763 |
-+ } |
4764 |
- |
4765 |
- #ifdef CONFIG_SMP |
4766 |
- { |
4767 |
-@@ -715,7 +719,7 @@ static void __cpuinit set_proc_ids(struct mdesc_handle *hp) |
4768 |
- } |
4769 |
- |
4770 |
- static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, |
4771 |
-- unsigned char def) |
4772 |
-+ unsigned long def, unsigned long max) |
4773 |
- { |
4774 |
- u64 val; |
4775 |
- |
4776 |
-@@ -726,6 +730,9 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, |
4777 |
- if (!val || val >= 64) |
4778 |
- goto use_default; |
4779 |
- |
4780 |
-+ if (val > max) |
4781 |
-+ val = max; |
4782 |
-+ |
4783 |
- *mask = ((1U << val) * 64U) - 1U; |
4784 |
- return; |
4785 |
- |
4786 |
-@@ -736,19 +743,28 @@ use_default: |
4787 |
- static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, |
4788 |
- struct trap_per_cpu *tb) |
4789 |
- { |
4790 |
-+ static int printed; |
4791 |
- const u64 *val; |
4792 |
- |
4793 |
- val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); |
4794 |
-- get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); |
4795 |
-+ get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2)); |
4796 |
- |
4797 |
- val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); |
4798 |
-- get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); |
4799 |
-+ get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8); |
4800 |
- |
4801 |
- val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); |
4802 |
-- get_one_mondo_bits(val, &tb->resum_qmask, 6); |
4803 |
-+ get_one_mondo_bits(val, &tb->resum_qmask, 6, 7); |
4804 |
- |
4805 |
- val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); |
4806 |
-- get_one_mondo_bits(val, &tb->nonresum_qmask, 2); |
4807 |
-+ get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2); |
4808 |
-+ if (!printed++) { |
4809 |
-+ pr_info("SUN4V: Mondo queue sizes " |
4810 |
-+ "[cpu(%u) dev(%u) r(%u) nr(%u)]\n", |
4811 |
-+ tb->cpu_mondo_qmask + 1, |
4812 |
-+ tb->dev_mondo_qmask + 1, |
4813 |
-+ tb->resum_qmask + 1, |
4814 |
-+ tb->nonresum_qmask + 1); |
4815 |
-+ } |
4816 |
- } |
4817 |
- |
4818 |
- static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) |
4819 |
-diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c |
4820 |
-index 8ac23e6..343b0f9 100644 |
4821 |
---- a/arch/sparc/kernel/pcr.c |
4822 |
-+++ b/arch/sparc/kernel/pcr.c |
4823 |
-@@ -80,8 +80,11 @@ static void n2_pcr_write(u64 val) |
4824 |
- { |
4825 |
- unsigned long ret; |
4826 |
- |
4827 |
-- ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); |
4828 |
-- if (ret != HV_EOK) |
4829 |
-+ if (val & PCR_N2_HTRACE) { |
4830 |
-+ ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); |
4831 |
-+ if (ret != HV_EOK) |
4832 |
-+ write_pcr(val); |
4833 |
-+ } else |
4834 |
- write_pcr(val); |
4835 |
- } |
4836 |
- |
4837 |
-@@ -106,6 +109,10 @@ static int __init register_perf_hsvc(void) |
4838 |
- perf_hsvc_group = HV_GRP_N2_CPU; |
4839 |
- break; |
4840 |
- |
4841 |
-+ case SUN4V_CHIP_NIAGARA3: |
4842 |
-+ perf_hsvc_group = HV_GRP_KT_CPU; |
4843 |
-+ break; |
4844 |
-+ |
4845 |
- default: |
4846 |
- return -ENODEV; |
4847 |
- } |
4848 |
-diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c |
4849 |
-index 2cb0e1c..6860d40 100644 |
4850 |
---- a/arch/sparc/kernel/perf_event.c |
4851 |
-+++ b/arch/sparc/kernel/perf_event.c |
4852 |
-@@ -1301,7 +1301,8 @@ static bool __init supported_pmu(void) |
4853 |
- sparc_pmu = &niagara1_pmu; |
4854 |
- return true; |
4855 |
- } |
4856 |
-- if (!strcmp(sparc_pmu_type, "niagara2")) { |
4857 |
-+ if (!strcmp(sparc_pmu_type, "niagara2") || |
4858 |
-+ !strcmp(sparc_pmu_type, "niagara3")) { |
4859 |
- sparc_pmu = &niagara2_pmu; |
4860 |
- return true; |
4861 |
- } |
4862 |
-diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c |
4863 |
-index c4dd099..3e9daea 100644 |
4864 |
---- a/arch/sparc/kernel/setup_64.c |
4865 |
-+++ b/arch/sparc/kernel/setup_64.c |
4866 |
-@@ -29,6 +29,7 @@ |
4867 |
- #include <linux/interrupt.h> |
4868 |
- #include <linux/cpu.h> |
4869 |
- #include <linux/initrd.h> |
4870 |
-+#include <linux/module.h> |
4871 |
- |
4872 |
- #include <asm/system.h> |
4873 |
- #include <asm/io.h> |
4874 |
-@@ -46,6 +47,8 @@ |
4875 |
- #include <asm/mmu.h> |
4876 |
- #include <asm/ns87303.h> |
4877 |
- #include <asm/btext.h> |
4878 |
-+#include <asm/elf.h> |
4879 |
-+#include <asm/mdesc.h> |
4880 |
- |
4881 |
- #ifdef CONFIG_IP_PNP |
4882 |
- #include <net/ipconfig.h> |
4883 |
-@@ -269,6 +272,40 @@ void __init sun4v_patch(void) |
4884 |
- sun4v_hvapi_init(); |
4885 |
- } |
4886 |
- |
4887 |
-+static void __init popc_patch(void) |
4888 |
-+{ |
4889 |
-+ struct popc_3insn_patch_entry *p3; |
4890 |
-+ struct popc_6insn_patch_entry *p6; |
4891 |
-+ |
4892 |
-+ p3 = &__popc_3insn_patch; |
4893 |
-+ while (p3 < &__popc_3insn_patch_end) { |
4894 |
-+ unsigned long i, addr = p3->addr; |
4895 |
-+ |
4896 |
-+ for (i = 0; i < 3; i++) { |
4897 |
-+ *(unsigned int *) (addr + (i * 4)) = p3->insns[i]; |
4898 |
-+ wmb(); |
4899 |
-+ __asm__ __volatile__("flush %0" |
4900 |
-+ : : "r" (addr + (i * 4))); |
4901 |
-+ } |
4902 |
-+ |
4903 |
-+ p3++; |
4904 |
-+ } |
4905 |
-+ |
4906 |
-+ p6 = &__popc_6insn_patch; |
4907 |
-+ while (p6 < &__popc_6insn_patch_end) { |
4908 |
-+ unsigned long i, addr = p6->addr; |
4909 |
-+ |
4910 |
-+ for (i = 0; i < 6; i++) { |
4911 |
-+ *(unsigned int *) (addr + (i * 4)) = p6->insns[i]; |
4912 |
-+ wmb(); |
4913 |
-+ __asm__ __volatile__("flush %0" |
4914 |
-+ : : "r" (addr + (i * 4))); |
4915 |
-+ } |
4916 |
-+ |
4917 |
-+ p6++; |
4918 |
-+ } |
4919 |
-+} |
4920 |
-+ |
4921 |
- #ifdef CONFIG_SMP |
4922 |
- void __init boot_cpu_id_too_large(int cpu) |
4923 |
- { |
4924 |
-@@ -278,6 +315,154 @@ void __init boot_cpu_id_too_large(int cpu) |
4925 |
- } |
4926 |
- #endif |
4927 |
- |
4928 |
-+/* On Ultra, we support all of the v8 capabilities. */ |
4929 |
-+unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | |
4930 |
-+ HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | |
4931 |
-+ HWCAP_SPARC_V9); |
4932 |
-+EXPORT_SYMBOL(sparc64_elf_hwcap); |
4933 |
-+ |
4934 |
-+static const char *hwcaps[] = { |
4935 |
-+ "flush", "stbar", "swap", "muldiv", "v9", |
4936 |
-+ "ultra3", "blkinit", "n2", |
4937 |
-+ |
4938 |
-+ /* These strings are as they appear in the machine description |
4939 |
-+ * 'hwcap-list' property for cpu nodes. |
4940 |
-+ */ |
4941 |
-+ "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", |
4942 |
-+ "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau", |
4943 |
-+ "ima", "cspare", |
4944 |
-+}; |
4945 |
-+ |
4946 |
-+void cpucap_info(struct seq_file *m) |
4947 |
-+{ |
4948 |
-+ unsigned long caps = sparc64_elf_hwcap; |
4949 |
-+ int i, printed = 0; |
4950 |
-+ |
4951 |
-+ seq_puts(m, "cpucaps\t\t: "); |
4952 |
-+ for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { |
4953 |
-+ unsigned long bit = 1UL << i; |
4954 |
-+ if (caps & bit) { |
4955 |
-+ seq_printf(m, "%s%s", |
4956 |
-+ printed ? "," : "", hwcaps[i]); |
4957 |
-+ printed++; |
4958 |
-+ } |
4959 |
-+ } |
4960 |
-+ seq_putc(m, '\n'); |
4961 |
-+} |
4962 |
-+ |
4963 |
-+static void __init report_hwcaps(unsigned long caps) |
4964 |
-+{ |
4965 |
-+ int i, printed = 0; |
4966 |
-+ |
4967 |
-+ printk(KERN_INFO "CPU CAPS: ["); |
4968 |
-+ for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { |
4969 |
-+ unsigned long bit = 1UL << i; |
4970 |
-+ if (caps & bit) { |
4971 |
-+ printk(KERN_CONT "%s%s", |
4972 |
-+ printed ? "," : "", hwcaps[i]); |
4973 |
-+ if (++printed == 8) { |
4974 |
-+ printk(KERN_CONT "]\n"); |
4975 |
-+ printk(KERN_INFO "CPU CAPS: ["); |
4976 |
-+ printed = 0; |
4977 |
-+ } |
4978 |
-+ } |
4979 |
-+ } |
4980 |
-+ printk(KERN_CONT "]\n"); |
4981 |
-+} |
4982 |
-+ |
4983 |
-+static unsigned long __init mdesc_cpu_hwcap_list(void) |
4984 |
-+{ |
4985 |
-+ struct mdesc_handle *hp; |
4986 |
-+ unsigned long caps = 0; |
4987 |
-+ const char *prop; |
4988 |
-+ int len; |
4989 |
-+ u64 pn; |
4990 |
-+ |
4991 |
-+ hp = mdesc_grab(); |
4992 |
-+ if (!hp) |
4993 |
-+ return 0; |
4994 |
-+ |
4995 |
-+ pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu"); |
4996 |
-+ if (pn == MDESC_NODE_NULL) |
4997 |
-+ goto out; |
4998 |
-+ |
4999 |
-+ prop = mdesc_get_property(hp, pn, "hwcap-list", &len); |
5000 |
-+ if (!prop) |
5001 |
-+ goto out; |
5002 |
-+ |
5003 |
-+ while (len) { |
5004 |
-+ int i, plen; |
5005 |
-+ |
5006 |
-+ for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { |
5007 |
-+ unsigned long bit = 1UL << i; |
5008 |
-+ |
5009 |
-+ if (!strcmp(prop, hwcaps[i])) { |
5010 |
-+ caps |= bit; |
5011 |
-+ break; |
5012 |
-+ } |
5013 |
-+ } |
5014 |
-+ |
5015 |
-+ plen = strlen(prop) + 1; |
5016 |
-+ prop += plen; |
5017 |
-+ len -= plen; |
5018 |
-+ } |
5019 |
-+ |
5020 |
-+out: |
5021 |
-+ mdesc_release(hp); |
5022 |
-+ return caps; |
5023 |
-+} |
5024 |
-+ |
5025 |
-+/* This yields a mask that user programs can use to figure out what |
5026 |
-+ * instruction set this cpu supports. |
5027 |
-+ */ |
5028 |
-+static void __init init_sparc64_elf_hwcap(void) |
5029 |
-+{ |
5030 |
-+ unsigned long cap = sparc64_elf_hwcap; |
5031 |
-+ unsigned long mdesc_caps; |
5032 |
-+ |
5033 |
-+ if (tlb_type == cheetah || tlb_type == cheetah_plus) |
5034 |
-+ cap |= HWCAP_SPARC_ULTRA3; |
5035 |
-+ else if (tlb_type == hypervisor) { |
5036 |
-+ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || |
5037 |
-+ sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
5038 |
-+ sun4v_chip_type == SUN4V_CHIP_NIAGARA3) |
5039 |
-+ cap |= HWCAP_SPARC_BLKINIT; |
5040 |
-+ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
5041 |
-+ sun4v_chip_type == SUN4V_CHIP_NIAGARA3) |
5042 |
-+ cap |= HWCAP_SPARC_N2; |
5043 |
-+ } |
5044 |
-+ |
5045 |
-+ cap |= (AV_SPARC_MUL32 | AV_SPARC_DIV32 | AV_SPARC_V8PLUS); |
5046 |
-+ |
5047 |
-+ mdesc_caps = mdesc_cpu_hwcap_list(); |
5048 |
-+ if (!mdesc_caps) { |
5049 |
-+ if (tlb_type == spitfire) |
5050 |
-+ cap |= AV_SPARC_VIS; |
5051 |
-+ if (tlb_type == cheetah || tlb_type == cheetah_plus) |
5052 |
-+ cap |= AV_SPARC_VIS | AV_SPARC_VIS2; |
5053 |
-+ if (tlb_type == cheetah_plus) |
5054 |
-+ cap |= AV_SPARC_POPC; |
5055 |
-+ if (tlb_type == hypervisor) { |
5056 |
-+ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1) |
5057 |
-+ cap |= AV_SPARC_ASI_BLK_INIT; |
5058 |
-+ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || |
5059 |
-+ sun4v_chip_type == SUN4V_CHIP_NIAGARA3) |
5060 |
-+ cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | |
5061 |
-+ AV_SPARC_ASI_BLK_INIT | |
5062 |
-+ AV_SPARC_POPC); |
5063 |
-+ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3) |
5064 |
-+ cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | |
5065 |
-+ AV_SPARC_FMAF); |
5066 |
-+ } |
5067 |
-+ } |
5068 |
-+ sparc64_elf_hwcap = cap | mdesc_caps; |
5069 |
-+ |
5070 |
-+ report_hwcaps(sparc64_elf_hwcap); |
5071 |
-+ |
5072 |
-+ if (sparc64_elf_hwcap & AV_SPARC_POPC) |
5073 |
-+ popc_patch(); |
5074 |
-+} |
5075 |
-+ |
5076 |
- void __init setup_arch(char **cmdline_p) |
5077 |
- { |
5078 |
- /* Initialize PROM console and command line. */ |
5079 |
-@@ -337,6 +522,7 @@ void __init setup_arch(char **cmdline_p) |
5080 |
- init_cur_cpu_trap(current_thread_info()); |
5081 |
- |
5082 |
- paging_init(); |
5083 |
-+ init_sparc64_elf_hwcap(); |
5084 |
- } |
5085 |
- |
5086 |
- extern int stop_a_enabled; |
5087 |
-diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c |
5088 |
-index 372ad59..83b47ab 100644 |
5089 |
---- a/arch/sparc/kernel/sparc_ksyms_64.c |
5090 |
-+++ b/arch/sparc/kernel/sparc_ksyms_64.c |
5091 |
-@@ -8,6 +8,7 @@ |
5092 |
- #include <linux/module.h> |
5093 |
- #include <linux/pci.h> |
5094 |
- #include <linux/init.h> |
5095 |
-+#include <linux/bitops.h> |
5096 |
- |
5097 |
- #include <asm/system.h> |
5098 |
- #include <asm/cpudata.h> |
5099 |
-@@ -38,5 +39,15 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); |
5100 |
- EXPORT_SYMBOL(sun4v_niagara2_getperf); |
5101 |
- EXPORT_SYMBOL(sun4v_niagara2_setperf); |
5102 |
- |
5103 |
-+/* from hweight.S */ |
5104 |
-+EXPORT_SYMBOL(__arch_hweight8); |
5105 |
-+EXPORT_SYMBOL(__arch_hweight16); |
5106 |
-+EXPORT_SYMBOL(__arch_hweight32); |
5107 |
-+EXPORT_SYMBOL(__arch_hweight64); |
5108 |
-+ |
5109 |
-+/* from ffs_ffz.S */ |
5110 |
-+EXPORT_SYMBOL(ffs); |
5111 |
-+EXPORT_SYMBOL(__ffs); |
5112 |
-+ |
5113 |
- /* Exporting a symbol from /init/main.c */ |
5114 |
- EXPORT_SYMBOL(saved_command_line); |
5115 |
-diff --git a/arch/sparc/kernel/sstate.c b/arch/sparc/kernel/sstate.c |
5116 |
-index 8cdbe59..c59af54 100644 |
5117 |
---- a/arch/sparc/kernel/sstate.c |
5118 |
-+++ b/arch/sparc/kernel/sstate.c |
5119 |
-@@ -14,14 +14,9 @@ |
5120 |
- #include <asm/head.h> |
5121 |
- #include <asm/io.h> |
5122 |
- |
5123 |
--static int hv_supports_soft_state; |
5124 |
-- |
5125 |
--static unsigned long kimage_addr_to_ra(const char *p) |
5126 |
--{ |
5127 |
-- unsigned long val = (unsigned long) p; |
5128 |
-+#include "kernel.h" |
5129 |
- |
5130 |
-- return kern_base + (val - KERNBASE); |
5131 |
--} |
5132 |
-+static int hv_supports_soft_state; |
5133 |
- |
5134 |
- static void do_set_sstate(unsigned long state, const char *msg) |
5135 |
- { |
5136 |
-diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c |
5137 |
-index b2b019e..9043106 100644 |
5138 |
---- a/arch/sparc/kernel/unaligned_64.c |
5139 |
-+++ b/arch/sparc/kernel/unaligned_64.c |
5140 |
-@@ -22,6 +22,7 @@ |
5141 |
- #include <linux/bitops.h> |
5142 |
- #include <linux/perf_event.h> |
5143 |
- #include <linux/ratelimit.h> |
5144 |
-+#include <linux/bitops.h> |
5145 |
- #include <asm/fpumacro.h> |
5146 |
- |
5147 |
- enum direction { |
5148 |
-@@ -373,16 +374,11 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) |
5149 |
- } |
5150 |
- } |
5151 |
- |
5152 |
--static char popc_helper[] = { |
5153 |
--0, 1, 1, 2, 1, 2, 2, 3, |
5154 |
--1, 2, 2, 3, 2, 3, 3, 4, |
5155 |
--}; |
5156 |
-- |
5157 |
- int handle_popc(u32 insn, struct pt_regs *regs) |
5158 |
- { |
5159 |
-- u64 value; |
5160 |
-- int ret, i, rd = ((insn >> 25) & 0x1f); |
5161 |
- int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; |
5162 |
-+ int ret, rd = ((insn >> 25) & 0x1f); |
5163 |
-+ u64 value; |
5164 |
- |
5165 |
- perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); |
5166 |
- if (insn & 0x2000) { |
5167 |
-@@ -392,10 +388,7 @@ int handle_popc(u32 insn, struct pt_regs *regs) |
5168 |
- maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); |
5169 |
- value = fetch_reg(insn & 0x1f, regs); |
5170 |
- } |
5171 |
-- for (ret = 0, i = 0; i < 16; i++) { |
5172 |
-- ret += popc_helper[value & 0xf]; |
5173 |
-- value >>= 4; |
5174 |
-- } |
5175 |
-+ ret = hweight64(value); |
5176 |
- if (rd < 16) { |
5177 |
- if (rd) |
5178 |
- regs->u_regs[rd] = ret; |
5179 |
-diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S |
5180 |
-index c022075..0e16056 100644 |
5181 |
---- a/arch/sparc/kernel/vmlinux.lds.S |
5182 |
-+++ b/arch/sparc/kernel/vmlinux.lds.S |
5183 |
-@@ -107,7 +107,26 @@ SECTIONS |
5184 |
- *(.sun4v_2insn_patch) |
5185 |
- __sun4v_2insn_patch_end = .; |
5186 |
- } |
5187 |
-- |
5188 |
-+ .swapper_tsb_phys_patch : { |
5189 |
-+ __swapper_tsb_phys_patch = .; |
5190 |
-+ *(.swapper_tsb_phys_patch) |
5191 |
-+ __swapper_tsb_phys_patch_end = .; |
5192 |
-+ } |
5193 |
-+ .swapper_4m_tsb_phys_patch : { |
5194 |
-+ __swapper_4m_tsb_phys_patch = .; |
5195 |
-+ *(.swapper_4m_tsb_phys_patch) |
5196 |
-+ __swapper_4m_tsb_phys_patch_end = .; |
5197 |
-+ } |
5198 |
-+ .popc_3insn_patch : { |
5199 |
-+ __popc_3insn_patch = .; |
5200 |
-+ *(.popc_3insn_patch) |
5201 |
-+ __popc_3insn_patch_end = .; |
5202 |
-+ } |
5203 |
-+ .popc_6insn_patch : { |
5204 |
-+ __popc_6insn_patch = .; |
5205 |
-+ *(.popc_6insn_patch) |
5206 |
-+ __popc_6insn_patch_end = .; |
5207 |
-+ } |
5208 |
- PERCPU_SECTION(SMP_CACHE_BYTES) |
5209 |
- |
5210 |
- . = ALIGN(PAGE_SIZE); |
5211 |
-diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile |
5212 |
-index 7f01b8f..a3fc437 100644 |
5213 |
---- a/arch/sparc/lib/Makefile |
5214 |
-+++ b/arch/sparc/lib/Makefile |
5215 |
-@@ -31,13 +31,13 @@ lib-$(CONFIG_SPARC64) += NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o |
5216 |
- lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o |
5217 |
- |
5218 |
- lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o |
5219 |
--lib-$(CONFIG_SPARC64) += NG2patch.o NG2page.o |
5220 |
-+lib-$(CONFIG_SPARC64) += NG2patch.o |
5221 |
- |
5222 |
- lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o |
5223 |
- lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o |
5224 |
- |
5225 |
- lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o |
5226 |
--lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o |
5227 |
-+lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o |
5228 |
- |
5229 |
- obj-y += iomap.o |
5230 |
- obj-$(CONFIG_SPARC32) += atomic32.o |
5231 |
-diff --git a/arch/sparc/lib/NG2page.S b/arch/sparc/lib/NG2page.S |
5232 |
-deleted file mode 100644 |
5233 |
-index 73b6b7c..0000000 |
5234 |
---- a/arch/sparc/lib/NG2page.S |
5235 |
-+++ /dev/null |
5236 |
-@@ -1,61 +0,0 @@ |
5237 |
--/* NG2page.S: Niagara-2 optimized clear and copy page. |
5238 |
-- * |
5239 |
-- * Copyright (C) 2007 (davem@×××××××××.net) |
5240 |
-- */ |
5241 |
-- |
5242 |
--#include <asm/asi.h> |
5243 |
--#include <asm/page.h> |
5244 |
--#include <asm/visasm.h> |
5245 |
-- |
5246 |
-- .text |
5247 |
-- .align 32 |
5248 |
-- |
5249 |
-- /* This is heavily simplified from the sun4u variants |
5250 |
-- * because Niagara-2 does not have any D-cache aliasing issues. |
5251 |
-- */ |
5252 |
--NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ |
5253 |
-- prefetch [%o1 + 0x00], #one_read |
5254 |
-- prefetch [%o1 + 0x40], #one_read |
5255 |
-- VISEntryHalf |
5256 |
-- set PAGE_SIZE, %g7 |
5257 |
-- sub %o0, %o1, %g3 |
5258 |
--1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
5259 |
-- subcc %g7, 64, %g7 |
5260 |
-- ldda [%o1] ASI_BLK_P, %f0 |
5261 |
-- stda %f0, [%o1 + %g3] ASI_BLK_P |
5262 |
-- add %o1, 64, %o1 |
5263 |
-- bne,pt %xcc, 1b |
5264 |
-- prefetch [%o1 + 0x40], #one_read |
5265 |
-- membar #Sync |
5266 |
-- VISExitHalf |
5267 |
-- retl |
5268 |
-- nop |
5269 |
-- |
5270 |
--#define BRANCH_ALWAYS 0x10680000 |
5271 |
--#define NOP 0x01000000 |
5272 |
--#define NG_DO_PATCH(OLD, NEW) \ |
5273 |
-- sethi %hi(NEW), %g1; \ |
5274 |
-- or %g1, %lo(NEW), %g1; \ |
5275 |
-- sethi %hi(OLD), %g2; \ |
5276 |
-- or %g2, %lo(OLD), %g2; \ |
5277 |
-- sub %g1, %g2, %g1; \ |
5278 |
-- sethi %hi(BRANCH_ALWAYS), %g3; \ |
5279 |
-- sll %g1, 11, %g1; \ |
5280 |
-- srl %g1, 11 + 2, %g1; \ |
5281 |
-- or %g3, %lo(BRANCH_ALWAYS), %g3; \ |
5282 |
-- or %g3, %g1, %g3; \ |
5283 |
-- stw %g3, [%g2]; \ |
5284 |
-- sethi %hi(NOP), %g3; \ |
5285 |
-- or %g3, %lo(NOP), %g3; \ |
5286 |
-- stw %g3, [%g2 + 0x4]; \ |
5287 |
-- flush %g2; |
5288 |
-- |
5289 |
-- .globl niagara2_patch_pageops |
5290 |
-- .type niagara2_patch_pageops,#function |
5291 |
--niagara2_patch_pageops: |
5292 |
-- NG_DO_PATCH(copy_user_page, NG2copy_user_page) |
5293 |
-- NG_DO_PATCH(_clear_page, NGclear_page) |
5294 |
-- NG_DO_PATCH(clear_user_page, NGclear_user_page) |
5295 |
-- retl |
5296 |
-- nop |
5297 |
-- .size niagara2_patch_pageops,.-niagara2_patch_pageops |
5298 |
-diff --git a/arch/sparc/lib/NGpage.S b/arch/sparc/lib/NGpage.S |
5299 |
-index 428920d..b9e790b 100644 |
5300 |
---- a/arch/sparc/lib/NGpage.S |
5301 |
-+++ b/arch/sparc/lib/NGpage.S |
5302 |
-@@ -16,55 +16,91 @@ |
5303 |
- */ |
5304 |
- |
5305 |
- NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ |
5306 |
-- prefetch [%o1 + 0x00], #one_read |
5307 |
-- mov 8, %g1 |
5308 |
-- mov 16, %g2 |
5309 |
-- mov 24, %g3 |
5310 |
-+ save %sp, -192, %sp |
5311 |
-+ rd %asi, %g3 |
5312 |
-+ wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi |
5313 |
- set PAGE_SIZE, %g7 |
5314 |
-+ prefetch [%i1 + 0x00], #one_read |
5315 |
-+ prefetch [%i1 + 0x40], #one_read |
5316 |
- |
5317 |
--1: ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 |
5318 |
-- ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 |
5319 |
-- prefetch [%o1 + 0x40], #one_read |
5320 |
-- add %o1, 32, %o1 |
5321 |
-- stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P |
5322 |
-- stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P |
5323 |
-- ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 |
5324 |
-- stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P |
5325 |
-- stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
5326 |
-- ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 |
5327 |
-- add %o1, 32, %o1 |
5328 |
-- add %o0, 32, %o0 |
5329 |
-- stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P |
5330 |
-- stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P |
5331 |
-- stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P |
5332 |
-- stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
5333 |
-- subcc %g7, 64, %g7 |
5334 |
-+1: prefetch [%i1 + 0x80], #one_read |
5335 |
-+ prefetch [%i1 + 0xc0], #one_read |
5336 |
-+ ldda [%i1 + 0x00] %asi, %o2 |
5337 |
-+ ldda [%i1 + 0x10] %asi, %o4 |
5338 |
-+ ldda [%i1 + 0x20] %asi, %l2 |
5339 |
-+ ldda [%i1 + 0x30] %asi, %l4 |
5340 |
-+ stxa %o2, [%i0 + 0x00] %asi |
5341 |
-+ stxa %o3, [%i0 + 0x08] %asi |
5342 |
-+ stxa %o4, [%i0 + 0x10] %asi |
5343 |
-+ stxa %o5, [%i0 + 0x18] %asi |
5344 |
-+ stxa %l2, [%i0 + 0x20] %asi |
5345 |
-+ stxa %l3, [%i0 + 0x28] %asi |
5346 |
-+ stxa %l4, [%i0 + 0x30] %asi |
5347 |
-+ stxa %l5, [%i0 + 0x38] %asi |
5348 |
-+ ldda [%i1 + 0x40] %asi, %o2 |
5349 |
-+ ldda [%i1 + 0x50] %asi, %o4 |
5350 |
-+ ldda [%i1 + 0x60] %asi, %l2 |
5351 |
-+ ldda [%i1 + 0x70] %asi, %l4 |
5352 |
-+ stxa %o2, [%i0 + 0x40] %asi |
5353 |
-+ stxa %o3, [%i0 + 0x48] %asi |
5354 |
-+ stxa %o4, [%i0 + 0x50] %asi |
5355 |
-+ stxa %o5, [%i0 + 0x58] %asi |
5356 |
-+ stxa %l2, [%i0 + 0x60] %asi |
5357 |
-+ stxa %l3, [%i0 + 0x68] %asi |
5358 |
-+ stxa %l4, [%i0 + 0x70] %asi |
5359 |
-+ stxa %l5, [%i0 + 0x78] %asi |
5360 |
-+ add %i1, 128, %i1 |
5361 |
-+ subcc %g7, 128, %g7 |
5362 |
- bne,pt %xcc, 1b |
5363 |
-- add %o0, 32, %o0 |
5364 |
-+ add %i0, 128, %i0 |
5365 |
-+ wr %g3, 0x0, %asi |
5366 |
- membar #Sync |
5367 |
-- retl |
5368 |
-- nop |
5369 |
-+ ret |
5370 |
-+ restore |
5371 |
- |
5372 |
-- .globl NGclear_page, NGclear_user_page |
5373 |
-+ .align 32 |
5374 |
- NGclear_page: /* %o0=dest */ |
5375 |
- NGclear_user_page: /* %o0=dest, %o1=vaddr */ |
5376 |
-- mov 8, %g1 |
5377 |
-- mov 16, %g2 |
5378 |
-- mov 24, %g3 |
5379 |
-+ rd %asi, %g3 |
5380 |
-+ wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi |
5381 |
- set PAGE_SIZE, %g7 |
5382 |
- |
5383 |
--1: stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P |
5384 |
-- stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P |
5385 |
-- stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P |
5386 |
-- stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
5387 |
-- add %o0, 32, %o0 |
5388 |
-- stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P |
5389 |
-- stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P |
5390 |
-- stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P |
5391 |
-- stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P |
5392 |
-- subcc %g7, 64, %g7 |
5393 |
-+1: stxa %g0, [%o0 + 0x00] %asi |
5394 |
-+ stxa %g0, [%o0 + 0x08] %asi |
5395 |
-+ stxa %g0, [%o0 + 0x10] %asi |
5396 |
-+ stxa %g0, [%o0 + 0x18] %asi |
5397 |
-+ stxa %g0, [%o0 + 0x20] %asi |
5398 |
-+ stxa %g0, [%o0 + 0x28] %asi |
5399 |
-+ stxa %g0, [%o0 + 0x30] %asi |
5400 |
-+ stxa %g0, [%o0 + 0x38] %asi |
5401 |
-+ stxa %g0, [%o0 + 0x40] %asi |
5402 |
-+ stxa %g0, [%o0 + 0x48] %asi |
5403 |
-+ stxa %g0, [%o0 + 0x50] %asi |
5404 |
-+ stxa %g0, [%o0 + 0x58] %asi |
5405 |
-+ stxa %g0, [%o0 + 0x60] %asi |
5406 |
-+ stxa %g0, [%o0 + 0x68] %asi |
5407 |
-+ stxa %g0, [%o0 + 0x70] %asi |
5408 |
-+ stxa %g0, [%o0 + 0x78] %asi |
5409 |
-+ stxa %g0, [%o0 + 0x80] %asi |
5410 |
-+ stxa %g0, [%o0 + 0x88] %asi |
5411 |
-+ stxa %g0, [%o0 + 0x90] %asi |
5412 |
-+ stxa %g0, [%o0 + 0x98] %asi |
5413 |
-+ stxa %g0, [%o0 + 0xa0] %asi |
5414 |
-+ stxa %g0, [%o0 + 0xa8] %asi |
5415 |
-+ stxa %g0, [%o0 + 0xb0] %asi |
5416 |
-+ stxa %g0, [%o0 + 0xb8] %asi |
5417 |
-+ stxa %g0, [%o0 + 0xc0] %asi |
5418 |
-+ stxa %g0, [%o0 + 0xc8] %asi |
5419 |
-+ stxa %g0, [%o0 + 0xd0] %asi |
5420 |
-+ stxa %g0, [%o0 + 0xd8] %asi |
5421 |
-+ stxa %g0, [%o0 + 0xe0] %asi |
5422 |
-+ stxa %g0, [%o0 + 0xe8] %asi |
5423 |
-+ stxa %g0, [%o0 + 0xf0] %asi |
5424 |
-+ stxa %g0, [%o0 + 0xf8] %asi |
5425 |
-+ subcc %g7, 256, %g7 |
5426 |
- bne,pt %xcc, 1b |
5427 |
-- add %o0, 32, %o0 |
5428 |
-+ add %o0, 256, %o0 |
5429 |
-+ wr %g3, 0x0, %asi |
5430 |
- membar #Sync |
5431 |
- retl |
5432 |
- nop |
5433 |
-diff --git a/arch/sparc/lib/ffs.S b/arch/sparc/lib/ffs.S |
5434 |
-new file mode 100644 |
5435 |
-index 0000000..b39389f |
5436 |
---- /dev/null |
5437 |
-+++ b/arch/sparc/lib/ffs.S |
5438 |
-@@ -0,0 +1,84 @@ |
5439 |
-+#include <linux/linkage.h> |
5440 |
-+ |
5441 |
-+ .register %g2,#scratch |
5442 |
-+ |
5443 |
-+ .text |
5444 |
-+ .align 32 |
5445 |
-+ |
5446 |
-+ENTRY(ffs) |
5447 |
-+ brnz,pt %o0, 1f |
5448 |
-+ mov 1, %o1 |
5449 |
-+ retl |
5450 |
-+ clr %o0 |
5451 |
-+ nop |
5452 |
-+ nop |
5453 |
-+ENTRY(__ffs) |
5454 |
-+ sllx %o0, 32, %g1 /* 1 */ |
5455 |
-+ srlx %o0, 32, %g2 |
5456 |
-+ |
5457 |
-+ clr %o1 /* 2 */ |
5458 |
-+ movrz %g1, %g2, %o0 |
5459 |
-+ |
5460 |
-+ movrz %g1, 32, %o1 /* 3 */ |
5461 |
-+1: clr %o2 |
5462 |
-+ |
5463 |
-+ sllx %o0, (64 - 16), %g1 /* 4 */ |
5464 |
-+ srlx %o0, 16, %g2 |
5465 |
-+ |
5466 |
-+ movrz %g1, %g2, %o0 /* 5 */ |
5467 |
-+ clr %o3 |
5468 |
-+ |
5469 |
-+ movrz %g1, 16, %o2 /* 6 */ |
5470 |
-+ clr %o4 |
5471 |
-+ |
5472 |
-+ and %o0, 0xff, %g1 /* 7 */ |
5473 |
-+ srlx %o0, 8, %g2 |
5474 |
-+ |
5475 |
-+ movrz %g1, %g2, %o0 /* 8 */ |
5476 |
-+ clr %o5 |
5477 |
-+ |
5478 |
-+ movrz %g1, 8, %o3 /* 9 */ |
5479 |
-+ add %o2, %o1, %o2 |
5480 |
-+ |
5481 |
-+ and %o0, 0xf, %g1 /* 10 */ |
5482 |
-+ srlx %o0, 4, %g2 |
5483 |
-+ |
5484 |
-+ movrz %g1, %g2, %o0 /* 11 */ |
5485 |
-+ add %o2, %o3, %o2 |
5486 |
-+ |
5487 |
-+ movrz %g1, 4, %o4 /* 12 */ |
5488 |
-+ |
5489 |
-+ and %o0, 0x3, %g1 /* 13 */ |
5490 |
-+ srlx %o0, 2, %g2 |
5491 |
-+ |
5492 |
-+ movrz %g1, %g2, %o0 /* 14 */ |
5493 |
-+ add %o2, %o4, %o2 |
5494 |
-+ |
5495 |
-+ movrz %g1, 2, %o5 /* 15 */ |
5496 |
-+ |
5497 |
-+ and %o0, 0x1, %g1 /* 16 */ |
5498 |
-+ |
5499 |
-+ add %o2, %o5, %o2 /* 17 */ |
5500 |
-+ xor %g1, 0x1, %g1 |
5501 |
-+ |
5502 |
-+ retl /* 18 */ |
5503 |
-+ add %o2, %g1, %o0 |
5504 |
-+ENDPROC(ffs) |
5505 |
-+ENDPROC(__ffs) |
5506 |
-+ |
5507 |
-+ .section .popc_6insn_patch, "ax" |
5508 |
-+ .word ffs |
5509 |
-+ brz,pn %o0, 98f |
5510 |
-+ neg %o0, %g1 |
5511 |
-+ xnor %o0, %g1, %o1 |
5512 |
-+ popc %o1, %o0 |
5513 |
-+98: retl |
5514 |
-+ nop |
5515 |
-+ .word __ffs |
5516 |
-+ neg %o0, %g1 |
5517 |
-+ xnor %o0, %g1, %o1 |
5518 |
-+ popc %o1, %o0 |
5519 |
-+ retl |
5520 |
-+ sub %o0, 1, %o0 |
5521 |
-+ nop |
5522 |
-+ .previous |
5523 |
-diff --git a/arch/sparc/lib/hweight.S b/arch/sparc/lib/hweight.S |
5524 |
-new file mode 100644 |
5525 |
-index 0000000..95414e0 |
5526 |
---- /dev/null |
5527 |
-+++ b/arch/sparc/lib/hweight.S |
5528 |
-@@ -0,0 +1,51 @@ |
5529 |
-+#include <linux/linkage.h> |
5530 |
-+ |
5531 |
-+ .text |
5532 |
-+ .align 32 |
5533 |
-+ENTRY(__arch_hweight8) |
5534 |
-+ ba,pt %xcc, __sw_hweight8 |
5535 |
-+ nop |
5536 |
-+ nop |
5537 |
-+ENDPROC(__arch_hweight8) |
5538 |
-+ .section .popc_3insn_patch, "ax" |
5539 |
-+ .word __arch_hweight8 |
5540 |
-+ sllx %o0, 64-8, %g1 |
5541 |
-+ retl |
5542 |
-+ popc %g1, %o0 |
5543 |
-+ .previous |
5544 |
-+ |
5545 |
-+ENTRY(__arch_hweight16) |
5546 |
-+ ba,pt %xcc, __sw_hweight16 |
5547 |
-+ nop |
5548 |
-+ nop |
5549 |
-+ENDPROC(__arch_hweight16) |
5550 |
-+ .section .popc_3insn_patch, "ax" |
5551 |
-+ .word __arch_hweight16 |
5552 |
-+ sllx %o0, 64-16, %g1 |
5553 |
-+ retl |
5554 |
-+ popc %g1, %o0 |
5555 |
-+ .previous |
5556 |
-+ |
5557 |
-+ENTRY(__arch_hweight32) |
5558 |
-+ ba,pt %xcc, __sw_hweight32 |
5559 |
-+ nop |
5560 |
-+ nop |
5561 |
-+ENDPROC(__arch_hweight32) |
5562 |
-+ .section .popc_3insn_patch, "ax" |
5563 |
-+ .word __arch_hweight32 |
5564 |
-+ sllx %o0, 64-32, %g1 |
5565 |
-+ retl |
5566 |
-+ popc %g1, %o0 |
5567 |
-+ .previous |
5568 |
-+ |
5569 |
-+ENTRY(__arch_hweight64) |
5570 |
-+ ba,pt %xcc, __sw_hweight64 |
5571 |
-+ nop |
5572 |
-+ nop |
5573 |
-+ENDPROC(__arch_hweight64) |
5574 |
-+ .section .popc_3insn_patch, "ax" |
5575 |
-+ .word __arch_hweight64 |
5576 |
-+ retl |
5577 |
-+ popc %o0, %o0 |
5578 |
-+ nop |
5579 |
-+ .previous |
5580 |
-diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c |
5581 |
-index 3fd8e18..581531d 100644 |
5582 |
---- a/arch/sparc/mm/init_64.c |
5583 |
-+++ b/arch/sparc/mm/init_64.c |
5584 |
-@@ -1597,6 +1597,44 @@ static void __init tsb_phys_patch(void) |
5585 |
- static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; |
5586 |
- extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; |
5587 |
- |
5588 |
-+static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) |
5589 |
-+{ |
5590 |
-+ pa >>= KTSB_PHYS_SHIFT; |
5591 |
-+ |
5592 |
-+ while (start < end) { |
5593 |
-+ unsigned int *ia = (unsigned int *)(unsigned long)*start; |
5594 |
-+ |
5595 |
-+ ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); |
5596 |
-+ __asm__ __volatile__("flush %0" : : "r" (ia)); |
5597 |
-+ |
5598 |
-+ ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); |
5599 |
-+ __asm__ __volatile__("flush %0" : : "r" (ia + 1)); |
5600 |
-+ |
5601 |
-+ start++; |
5602 |
-+ } |
5603 |
-+} |
5604 |
-+ |
5605 |
-+static void ktsb_phys_patch(void) |
5606 |
-+{ |
5607 |
-+ extern unsigned int __swapper_tsb_phys_patch; |
5608 |
-+ extern unsigned int __swapper_tsb_phys_patch_end; |
5609 |
-+ unsigned long ktsb_pa; |
5610 |
-+ |
5611 |
-+ ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE); |
5612 |
-+ patch_one_ktsb_phys(&__swapper_tsb_phys_patch, |
5613 |
-+ &__swapper_tsb_phys_patch_end, ktsb_pa); |
5614 |
-+#ifndef CONFIG_DEBUG_PAGEALLOC |
5615 |
-+ { |
5616 |
-+ extern unsigned int __swapper_4m_tsb_phys_patch; |
5617 |
-+ extern unsigned int __swapper_4m_tsb_phys_patch_end; |
5618 |
-+ ktsb_pa = (kern_base + |
5619 |
-+ ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); |
5620 |
-+ patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch, |
5621 |
-+ &__swapper_4m_tsb_phys_patch_end, ktsb_pa); |
5622 |
-+ } |
5623 |
-+#endif |
5624 |
-+} |
5625 |
-+ |
5626 |
- static void __init sun4v_ktsb_init(void) |
5627 |
- { |
5628 |
- unsigned long ktsb_pa; |
5629 |
-@@ -1716,8 +1754,10 @@ void __init paging_init(void) |
5630 |
- sun4u_pgprot_init(); |
5631 |
- |
5632 |
- if (tlb_type == cheetah_plus || |
5633 |
-- tlb_type == hypervisor) |
5634 |
-+ tlb_type == hypervisor) { |
5635 |
- tsb_phys_patch(); |
5636 |
-+ ktsb_phys_patch(); |
5637 |
-+ } |
5638 |
- |
5639 |
- if (tlb_type == hypervisor) { |
5640 |
- sun4v_patch_tlb_handlers(); |
5641 |
-diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile |
5642 |
-index 17c565d..a6575b9 100644 |
5643 |
---- a/arch/x86/xen/Makefile |
5644 |
-+++ b/arch/x86/xen/Makefile |
5645 |
-@@ -18,5 +18,5 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ |
5646 |
- obj-$(CONFIG_SMP) += smp.o |
5647 |
- obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o |
5648 |
- obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o |
5649 |
-- |
5650 |
-+obj-$(CONFIG_XEN_DOM0) += vga.o |
5651 |
- obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o |
5652 |
-diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c |
5653 |
-index 5525163..5325742 100644 |
5654 |
---- a/arch/x86/xen/enlighten.c |
5655 |
-+++ b/arch/x86/xen/enlighten.c |
5656 |
-@@ -1248,6 +1248,14 @@ asmlinkage void __init xen_start_kernel(void) |
5657 |
- if (pci_xen) |
5658 |
- x86_init.pci.arch_init = pci_xen_init; |
5659 |
- } else { |
5660 |
-+ const struct dom0_vga_console_info *info = |
5661 |
-+ (void *)((char *)xen_start_info + |
5662 |
-+ xen_start_info->console.dom0.info_off); |
5663 |
-+ |
5664 |
-+ xen_init_vga(info, xen_start_info->console.dom0.info_size); |
5665 |
-+ xen_start_info->console.domU.mfn = 0; |
5666 |
-+ xen_start_info->console.domU.evtchn = 0; |
5667 |
-+ |
5668 |
- /* Make sure ACS will be enabled */ |
5669 |
- pci_request_acs(); |
5670 |
- } |
5671 |
-diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c |
5672 |
-new file mode 100644 |
5673 |
-index 0000000..1cd7f4d |
5674 |
---- /dev/null |
5675 |
-+++ b/arch/x86/xen/vga.c |
5676 |
-@@ -0,0 +1,67 @@ |
5677 |
-+#include <linux/screen_info.h> |
5678 |
-+#include <linux/init.h> |
5679 |
-+ |
5680 |
-+#include <asm/bootparam.h> |
5681 |
-+#include <asm/setup.h> |
5682 |
-+ |
5683 |
-+#include <xen/interface/xen.h> |
5684 |
-+ |
5685 |
-+#include "xen-ops.h" |
5686 |
-+ |
5687 |
-+void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size) |
5688 |
-+{ |
5689 |
-+ struct screen_info *screen_info = &boot_params.screen_info; |
5690 |
-+ |
5691 |
-+ /* This is drawn from a dump from vgacon:startup in |
5692 |
-+ * standard Linux. */ |
5693 |
-+ screen_info->orig_video_mode = 3; |
5694 |
-+ screen_info->orig_video_isVGA = 1; |
5695 |
-+ screen_info->orig_video_lines = 25; |
5696 |
-+ screen_info->orig_video_cols = 80; |
5697 |
-+ screen_info->orig_video_ega_bx = 3; |
5698 |
-+ screen_info->orig_video_points = 16; |
5699 |
-+ screen_info->orig_y = screen_info->orig_video_lines - 1; |
5700 |
-+ |
5701 |
-+ switch (info->video_type) { |
5702 |
-+ case XEN_VGATYPE_TEXT_MODE_3: |
5703 |
-+ if (size < offsetof(struct dom0_vga_console_info, u.text_mode_3) |
5704 |
-+ + sizeof(info->u.text_mode_3)) |
5705 |
-+ break; |
5706 |
-+ screen_info->orig_video_lines = info->u.text_mode_3.rows; |
5707 |
-+ screen_info->orig_video_cols = info->u.text_mode_3.columns; |
5708 |
-+ screen_info->orig_x = info->u.text_mode_3.cursor_x; |
5709 |
-+ screen_info->orig_y = info->u.text_mode_3.cursor_y; |
5710 |
-+ screen_info->orig_video_points = |
5711 |
-+ info->u.text_mode_3.font_height; |
5712 |
-+ break; |
5713 |
-+ |
5714 |
-+ case XEN_VGATYPE_VESA_LFB: |
5715 |
-+ if (size < offsetof(struct dom0_vga_console_info, |
5716 |
-+ u.vesa_lfb.gbl_caps)) |
5717 |
-+ break; |
5718 |
-+ screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB; |
5719 |
-+ screen_info->lfb_width = info->u.vesa_lfb.width; |
5720 |
-+ screen_info->lfb_height = info->u.vesa_lfb.height; |
5721 |
-+ screen_info->lfb_depth = info->u.vesa_lfb.bits_per_pixel; |
5722 |
-+ screen_info->lfb_base = info->u.vesa_lfb.lfb_base; |
5723 |
-+ screen_info->lfb_size = info->u.vesa_lfb.lfb_size; |
5724 |
-+ screen_info->lfb_linelength = info->u.vesa_lfb.bytes_per_line; |
5725 |
-+ screen_info->red_size = info->u.vesa_lfb.red_size; |
5726 |
-+ screen_info->red_pos = info->u.vesa_lfb.red_pos; |
5727 |
-+ screen_info->green_size = info->u.vesa_lfb.green_size; |
5728 |
-+ screen_info->green_pos = info->u.vesa_lfb.green_pos; |
5729 |
-+ screen_info->blue_size = info->u.vesa_lfb.blue_size; |
5730 |
-+ screen_info->blue_pos = info->u.vesa_lfb.blue_pos; |
5731 |
-+ screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size; |
5732 |
-+ screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos; |
5733 |
-+ if (size >= offsetof(struct dom0_vga_console_info, |
5734 |
-+ u.vesa_lfb.gbl_caps) |
5735 |
-+ + sizeof(info->u.vesa_lfb.gbl_caps)) |
5736 |
-+ screen_info->capabilities = info->u.vesa_lfb.gbl_caps; |
5737 |
-+ if (size >= offsetof(struct dom0_vga_console_info, |
5738 |
-+ u.vesa_lfb.mode_attrs) |
5739 |
-+ + sizeof(info->u.vesa_lfb.mode_attrs)) |
5740 |
-+ screen_info->vesa_attributes = info->u.vesa_lfb.mode_attrs; |
5741 |
-+ break; |
5742 |
-+ } |
5743 |
-+} |
5744 |
-diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h |
5745 |
-index 97dfdc8..b095739 100644 |
5746 |
---- a/arch/x86/xen/xen-ops.h |
5747 |
-+++ b/arch/x86/xen/xen-ops.h |
5748 |
-@@ -88,6 +88,17 @@ static inline void xen_uninit_lock_cpu(int cpu) |
5749 |
- } |
5750 |
- #endif |
5751 |
- |
5752 |
-+struct dom0_vga_console_info; |
5753 |
-+ |
5754 |
-+#ifdef CONFIG_XEN_DOM0 |
5755 |
-+void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size); |
5756 |
-+#else |
5757 |
-+static inline void __init xen_init_vga(const struct dom0_vga_console_info *info, |
5758 |
-+ size_t size) |
5759 |
-+{ |
5760 |
-+} |
5761 |
-+#endif |
5762 |
-+ |
5763 |
- /* Declare an asm function, along with symbols needed to make it |
5764 |
- inlineable */ |
5765 |
- #define DECL_ASM(ret, name, ...) \ |
5766 |
-diff --git a/crypto/md5.c b/crypto/md5.c |
5767 |
-index 30efc7d..7febeaa 100644 |
5768 |
---- a/crypto/md5.c |
5769 |
-+++ b/crypto/md5.c |
5770 |
-@@ -21,99 +21,9 @@ |
5771 |
- #include <linux/module.h> |
5772 |
- #include <linux/string.h> |
5773 |
- #include <linux/types.h> |
5774 |
-+#include <linux/cryptohash.h> |
5775 |
- #include <asm/byteorder.h> |
5776 |
- |
5777 |
--#define F1(x, y, z) (z ^ (x & (y ^ z))) |
5778 |
--#define F2(x, y, z) F1(z, x, y) |
5779 |
--#define F3(x, y, z) (x ^ y ^ z) |
5780 |
--#define F4(x, y, z) (y ^ (x | ~z)) |
5781 |
-- |
5782 |
--#define MD5STEP(f, w, x, y, z, in, s) \ |
5783 |
-- (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) |
5784 |
-- |
5785 |
--static void md5_transform(u32 *hash, u32 const *in) |
5786 |
--{ |
5787 |
-- u32 a, b, c, d; |
5788 |
-- |
5789 |
-- a = hash[0]; |
5790 |
-- b = hash[1]; |
5791 |
-- c = hash[2]; |
5792 |
-- d = hash[3]; |
5793 |
-- |
5794 |
-- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); |
5795 |
-- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); |
5796 |
-- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); |
5797 |
-- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); |
5798 |
-- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); |
5799 |
-- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); |
5800 |
-- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); |
5801 |
-- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); |
5802 |
-- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); |
5803 |
-- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); |
5804 |
-- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); |
5805 |
-- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); |
5806 |
-- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); |
5807 |
-- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); |
5808 |
-- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); |
5809 |
-- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); |
5810 |
-- |
5811 |
-- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); |
5812 |
-- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); |
5813 |
-- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); |
5814 |
-- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); |
5815 |
-- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); |
5816 |
-- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); |
5817 |
-- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); |
5818 |
-- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); |
5819 |
-- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); |
5820 |
-- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); |
5821 |
-- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); |
5822 |
-- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); |
5823 |
-- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); |
5824 |
-- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); |
5825 |
-- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); |
5826 |
-- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); |
5827 |
-- |
5828 |
-- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); |
5829 |
-- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); |
5830 |
-- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); |
5831 |
-- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); |
5832 |
-- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); |
5833 |
-- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); |
5834 |
-- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); |
5835 |
-- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); |
5836 |
-- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); |
5837 |
-- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); |
5838 |
-- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); |
5839 |
-- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); |
5840 |
-- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); |
5841 |
-- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); |
5842 |
-- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); |
5843 |
-- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); |
5844 |
-- |
5845 |
-- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); |
5846 |
-- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); |
5847 |
-- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); |
5848 |
-- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); |
5849 |
-- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); |
5850 |
-- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); |
5851 |
-- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); |
5852 |
-- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); |
5853 |
-- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); |
5854 |
-- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); |
5855 |
-- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); |
5856 |
-- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); |
5857 |
-- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); |
5858 |
-- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); |
5859 |
-- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); |
5860 |
-- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); |
5861 |
-- |
5862 |
-- hash[0] += a; |
5863 |
-- hash[1] += b; |
5864 |
-- hash[2] += c; |
5865 |
-- hash[3] += d; |
5866 |
--} |
5867 |
-- |
5868 |
- /* XXX: this stuff can be optimized */ |
5869 |
- static inline void le32_to_cpu_array(u32 *buf, unsigned int words) |
5870 |
- { |
5871 |
-diff --git a/drivers/char/random.c b/drivers/char/random.c |
5872 |
-index d4ddeba..c35a785 100644 |
5873 |
---- a/drivers/char/random.c |
5874 |
-+++ b/drivers/char/random.c |
5875 |
-@@ -1300,330 +1300,14 @@ ctl_table random_table[] = { |
5876 |
- }; |
5877 |
- #endif /* CONFIG_SYSCTL */ |
5878 |
- |
5879 |
--/******************************************************************** |
5880 |
-- * |
5881 |
-- * Random functions for networking |
5882 |
-- * |
5883 |
-- ********************************************************************/ |
5884 |
-- |
5885 |
--/* |
5886 |
-- * TCP initial sequence number picking. This uses the random number |
5887 |
-- * generator to pick an initial secret value. This value is hashed |
5888 |
-- * along with the TCP endpoint information to provide a unique |
5889 |
-- * starting point for each pair of TCP endpoints. This defeats |
5890 |
-- * attacks which rely on guessing the initial TCP sequence number. |
5891 |
-- * This algorithm was suggested by Steve Bellovin. |
5892 |
-- * |
5893 |
-- * Using a very strong hash was taking an appreciable amount of the total |
5894 |
-- * TCP connection establishment time, so this is a weaker hash, |
5895 |
-- * compensated for by changing the secret periodically. |
5896 |
-- */ |
5897 |
-- |
5898 |
--/* F, G and H are basic MD4 functions: selection, majority, parity */ |
5899 |
--#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) |
5900 |
--#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z))) |
5901 |
--#define H(x, y, z) ((x) ^ (y) ^ (z)) |
5902 |
-- |
5903 |
--/* |
5904 |
-- * The generic round function. The application is so specific that |
5905 |
-- * we don't bother protecting all the arguments with parens, as is generally |
5906 |
-- * good macro practice, in favor of extra legibility. |
5907 |
-- * Rotation is separate from addition to prevent recomputation |
5908 |
-- */ |
5909 |
--#define ROUND(f, a, b, c, d, x, s) \ |
5910 |
-- (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s))) |
5911 |
--#define K1 0 |
5912 |
--#define K2 013240474631UL |
5913 |
--#define K3 015666365641UL |
5914 |
-+static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; |
5915 |
- |
5916 |
--#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
5917 |
-- |
5918 |
--static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12]) |
5919 |
-+static int __init random_int_secret_init(void) |
5920 |
- { |
5921 |
-- __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; |
5922 |
-- |
5923 |
-- /* Round 1 */ |
5924 |
-- ROUND(F, a, b, c, d, in[ 0] + K1, 3); |
5925 |
-- ROUND(F, d, a, b, c, in[ 1] + K1, 7); |
5926 |
-- ROUND(F, c, d, a, b, in[ 2] + K1, 11); |
5927 |
-- ROUND(F, b, c, d, a, in[ 3] + K1, 19); |
5928 |
-- ROUND(F, a, b, c, d, in[ 4] + K1, 3); |
5929 |
-- ROUND(F, d, a, b, c, in[ 5] + K1, 7); |
5930 |
-- ROUND(F, c, d, a, b, in[ 6] + K1, 11); |
5931 |
-- ROUND(F, b, c, d, a, in[ 7] + K1, 19); |
5932 |
-- ROUND(F, a, b, c, d, in[ 8] + K1, 3); |
5933 |
-- ROUND(F, d, a, b, c, in[ 9] + K1, 7); |
5934 |
-- ROUND(F, c, d, a, b, in[10] + K1, 11); |
5935 |
-- ROUND(F, b, c, d, a, in[11] + K1, 19); |
5936 |
-- |
5937 |
-- /* Round 2 */ |
5938 |
-- ROUND(G, a, b, c, d, in[ 1] + K2, 3); |
5939 |
-- ROUND(G, d, a, b, c, in[ 3] + K2, 5); |
5940 |
-- ROUND(G, c, d, a, b, in[ 5] + K2, 9); |
5941 |
-- ROUND(G, b, c, d, a, in[ 7] + K2, 13); |
5942 |
-- ROUND(G, a, b, c, d, in[ 9] + K2, 3); |
5943 |
-- ROUND(G, d, a, b, c, in[11] + K2, 5); |
5944 |
-- ROUND(G, c, d, a, b, in[ 0] + K2, 9); |
5945 |
-- ROUND(G, b, c, d, a, in[ 2] + K2, 13); |
5946 |
-- ROUND(G, a, b, c, d, in[ 4] + K2, 3); |
5947 |
-- ROUND(G, d, a, b, c, in[ 6] + K2, 5); |
5948 |
-- ROUND(G, c, d, a, b, in[ 8] + K2, 9); |
5949 |
-- ROUND(G, b, c, d, a, in[10] + K2, 13); |
5950 |
-- |
5951 |
-- /* Round 3 */ |
5952 |
-- ROUND(H, a, b, c, d, in[ 3] + K3, 3); |
5953 |
-- ROUND(H, d, a, b, c, in[ 7] + K3, 9); |
5954 |
-- ROUND(H, c, d, a, b, in[11] + K3, 11); |
5955 |
-- ROUND(H, b, c, d, a, in[ 2] + K3, 15); |
5956 |
-- ROUND(H, a, b, c, d, in[ 6] + K3, 3); |
5957 |
-- ROUND(H, d, a, b, c, in[10] + K3, 9); |
5958 |
-- ROUND(H, c, d, a, b, in[ 1] + K3, 11); |
5959 |
-- ROUND(H, b, c, d, a, in[ 5] + K3, 15); |
5960 |
-- ROUND(H, a, b, c, d, in[ 9] + K3, 3); |
5961 |
-- ROUND(H, d, a, b, c, in[ 0] + K3, 9); |
5962 |
-- ROUND(H, c, d, a, b, in[ 4] + K3, 11); |
5963 |
-- ROUND(H, b, c, d, a, in[ 8] + K3, 15); |
5964 |
-- |
5965 |
-- return buf[1] + b; /* "most hashed" word */ |
5966 |
-- /* Alternative: return sum of all words? */ |
5967 |
--} |
5968 |
--#endif |
5969 |
-- |
5970 |
--#undef ROUND |
5971 |
--#undef F |
5972 |
--#undef G |
5973 |
--#undef H |
5974 |
--#undef K1 |
5975 |
--#undef K2 |
5976 |
--#undef K3 |
5977 |
-- |
5978 |
--/* This should not be decreased so low that ISNs wrap too fast. */ |
5979 |
--#define REKEY_INTERVAL (300 * HZ) |
5980 |
--/* |
5981 |
-- * Bit layout of the tcp sequence numbers (before adding current time): |
5982 |
-- * bit 24-31: increased after every key exchange |
5983 |
-- * bit 0-23: hash(source,dest) |
5984 |
-- * |
5985 |
-- * The implementation is similar to the algorithm described |
5986 |
-- * in the Appendix of RFC 1185, except that |
5987 |
-- * - it uses a 1 MHz clock instead of a 250 kHz clock |
5988 |
-- * - it performs a rekey every 5 minutes, which is equivalent |
5989 |
-- * to a (source,dest) tulple dependent forward jump of the |
5990 |
-- * clock by 0..2^(HASH_BITS+1) |
5991 |
-- * |
5992 |
-- * Thus the average ISN wraparound time is 68 minutes instead of |
5993 |
-- * 4.55 hours. |
5994 |
-- * |
5995 |
-- * SMP cleanup and lock avoidance with poor man's RCU. |
5996 |
-- * Manfred Spraul <manfred@××××××××××××.com> |
5997 |
-- * |
5998 |
-- */ |
5999 |
--#define COUNT_BITS 8 |
6000 |
--#define COUNT_MASK ((1 << COUNT_BITS) - 1) |
6001 |
--#define HASH_BITS 24 |
6002 |
--#define HASH_MASK ((1 << HASH_BITS) - 1) |
6003 |
-- |
6004 |
--static struct keydata { |
6005 |
-- __u32 count; /* already shifted to the final position */ |
6006 |
-- __u32 secret[12]; |
6007 |
--} ____cacheline_aligned ip_keydata[2]; |
6008 |
-- |
6009 |
--static unsigned int ip_cnt; |
6010 |
-- |
6011 |
--static void rekey_seq_generator(struct work_struct *work); |
6012 |
-- |
6013 |
--static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator); |
6014 |
-- |
6015 |
--/* |
6016 |
-- * Lock avoidance: |
6017 |
-- * The ISN generation runs lockless - it's just a hash over random data. |
6018 |
-- * State changes happen every 5 minutes when the random key is replaced. |
6019 |
-- * Synchronization is performed by having two copies of the hash function |
6020 |
-- * state and rekey_seq_generator always updates the inactive copy. |
6021 |
-- * The copy is then activated by updating ip_cnt. |
6022 |
-- * The implementation breaks down if someone blocks the thread |
6023 |
-- * that processes SYN requests for more than 5 minutes. Should never |
6024 |
-- * happen, and even if that happens only a not perfectly compliant |
6025 |
-- * ISN is generated, nothing fatal. |
6026 |
-- */ |
6027 |
--static void rekey_seq_generator(struct work_struct *work) |
6028 |
--{ |
6029 |
-- struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)]; |
6030 |
-- |
6031 |
-- get_random_bytes(keyptr->secret, sizeof(keyptr->secret)); |
6032 |
-- keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS; |
6033 |
-- smp_wmb(); |
6034 |
-- ip_cnt++; |
6035 |
-- schedule_delayed_work(&rekey_work, |
6036 |
-- round_jiffies_relative(REKEY_INTERVAL)); |
6037 |
--} |
6038 |
-- |
6039 |
--static inline struct keydata *get_keyptr(void) |
6040 |
--{ |
6041 |
-- struct keydata *keyptr = &ip_keydata[ip_cnt & 1]; |
6042 |
-- |
6043 |
-- smp_rmb(); |
6044 |
-- |
6045 |
-- return keyptr; |
6046 |
--} |
6047 |
-- |
6048 |
--static __init int seqgen_init(void) |
6049 |
--{ |
6050 |
-- rekey_seq_generator(NULL); |
6051 |
-+ get_random_bytes(random_int_secret, sizeof(random_int_secret)); |
6052 |
- return 0; |
6053 |
- } |
6054 |
--late_initcall(seqgen_init); |
6055 |
-- |
6056 |
--#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
6057 |
--__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
6058 |
-- __be16 sport, __be16 dport) |
6059 |
--{ |
6060 |
-- __u32 seq; |
6061 |
-- __u32 hash[12]; |
6062 |
-- struct keydata *keyptr = get_keyptr(); |
6063 |
-- |
6064 |
-- /* The procedure is the same as for IPv4, but addresses are longer. |
6065 |
-- * Thus we must use twothirdsMD4Transform. |
6066 |
-- */ |
6067 |
-- |
6068 |
-- memcpy(hash, saddr, 16); |
6069 |
-- hash[4] = ((__force u16)sport << 16) + (__force u16)dport; |
6070 |
-- memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); |
6071 |
-- |
6072 |
-- seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK; |
6073 |
-- seq += keyptr->count; |
6074 |
-- |
6075 |
-- seq += ktime_to_ns(ktime_get_real()); |
6076 |
-- |
6077 |
-- return seq; |
6078 |
--} |
6079 |
--EXPORT_SYMBOL(secure_tcpv6_sequence_number); |
6080 |
--#endif |
6081 |
-- |
6082 |
--/* The code below is shamelessly stolen from secure_tcp_sequence_number(). |
6083 |
-- * All blames to Andrey V. Savochkin <saw@×××.ru>. |
6084 |
-- */ |
6085 |
--__u32 secure_ip_id(__be32 daddr) |
6086 |
--{ |
6087 |
-- struct keydata *keyptr; |
6088 |
-- __u32 hash[4]; |
6089 |
-- |
6090 |
-- keyptr = get_keyptr(); |
6091 |
-- |
6092 |
-- /* |
6093 |
-- * Pick a unique starting offset for each IP destination. |
6094 |
-- * The dest ip address is placed in the starting vector, |
6095 |
-- * which is then hashed with random data. |
6096 |
-- */ |
6097 |
-- hash[0] = (__force __u32)daddr; |
6098 |
-- hash[1] = keyptr->secret[9]; |
6099 |
-- hash[2] = keyptr->secret[10]; |
6100 |
-- hash[3] = keyptr->secret[11]; |
6101 |
-- |
6102 |
-- return half_md4_transform(hash, keyptr->secret); |
6103 |
--} |
6104 |
-- |
6105 |
--#ifdef CONFIG_INET |
6106 |
-- |
6107 |
--__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, |
6108 |
-- __be16 sport, __be16 dport) |
6109 |
--{ |
6110 |
-- __u32 seq; |
6111 |
-- __u32 hash[4]; |
6112 |
-- struct keydata *keyptr = get_keyptr(); |
6113 |
-- |
6114 |
-- /* |
6115 |
-- * Pick a unique starting offset for each TCP connection endpoints |
6116 |
-- * (saddr, daddr, sport, dport). |
6117 |
-- * Note that the words are placed into the starting vector, which is |
6118 |
-- * then mixed with a partial MD4 over random data. |
6119 |
-- */ |
6120 |
-- hash[0] = (__force u32)saddr; |
6121 |
-- hash[1] = (__force u32)daddr; |
6122 |
-- hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
6123 |
-- hash[3] = keyptr->secret[11]; |
6124 |
-- |
6125 |
-- seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK; |
6126 |
-- seq += keyptr->count; |
6127 |
-- /* |
6128 |
-- * As close as possible to RFC 793, which |
6129 |
-- * suggests using a 250 kHz clock. |
6130 |
-- * Further reading shows this assumes 2 Mb/s networks. |
6131 |
-- * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. |
6132 |
-- * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but |
6133 |
-- * we also need to limit the resolution so that the u32 seq |
6134 |
-- * overlaps less than one time per MSL (2 minutes). |
6135 |
-- * Choosing a clock of 64 ns period is OK. (period of 274 s) |
6136 |
-- */ |
6137 |
-- seq += ktime_to_ns(ktime_get_real()) >> 6; |
6138 |
-- |
6139 |
-- return seq; |
6140 |
--} |
6141 |
-- |
6142 |
--/* Generate secure starting point for ephemeral IPV4 transport port search */ |
6143 |
--u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) |
6144 |
--{ |
6145 |
-- struct keydata *keyptr = get_keyptr(); |
6146 |
-- u32 hash[4]; |
6147 |
-- |
6148 |
-- /* |
6149 |
-- * Pick a unique starting offset for each ephemeral port search |
6150 |
-- * (saddr, daddr, dport) and 48bits of random data. |
6151 |
-- */ |
6152 |
-- hash[0] = (__force u32)saddr; |
6153 |
-- hash[1] = (__force u32)daddr; |
6154 |
-- hash[2] = (__force u32)dport ^ keyptr->secret[10]; |
6155 |
-- hash[3] = keyptr->secret[11]; |
6156 |
-- |
6157 |
-- return half_md4_transform(hash, keyptr->secret); |
6158 |
--} |
6159 |
--EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); |
6160 |
-- |
6161 |
--#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
6162 |
--u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
6163 |
-- __be16 dport) |
6164 |
--{ |
6165 |
-- struct keydata *keyptr = get_keyptr(); |
6166 |
-- u32 hash[12]; |
6167 |
-- |
6168 |
-- memcpy(hash, saddr, 16); |
6169 |
-- hash[4] = (__force u32)dport; |
6170 |
-- memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); |
6171 |
-- |
6172 |
-- return twothirdsMD4Transform((const __u32 *)daddr, hash); |
6173 |
--} |
6174 |
--#endif |
6175 |
-- |
6176 |
--#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) |
6177 |
--/* Similar to secure_tcp_sequence_number but generate a 48 bit value |
6178 |
-- * bit's 32-47 increase every key exchange |
6179 |
-- * 0-31 hash(source, dest) |
6180 |
-- */ |
6181 |
--u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, |
6182 |
-- __be16 sport, __be16 dport) |
6183 |
--{ |
6184 |
-- u64 seq; |
6185 |
-- __u32 hash[4]; |
6186 |
-- struct keydata *keyptr = get_keyptr(); |
6187 |
-- |
6188 |
-- hash[0] = (__force u32)saddr; |
6189 |
-- hash[1] = (__force u32)daddr; |
6190 |
-- hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
6191 |
-- hash[3] = keyptr->secret[11]; |
6192 |
-- |
6193 |
-- seq = half_md4_transform(hash, keyptr->secret); |
6194 |
-- seq |= ((u64)keyptr->count) << (32 - HASH_BITS); |
6195 |
-- |
6196 |
-- seq += ktime_to_ns(ktime_get_real()); |
6197 |
-- seq &= (1ull << 48) - 1; |
6198 |
-- |
6199 |
-- return seq; |
6200 |
--} |
6201 |
--EXPORT_SYMBOL(secure_dccp_sequence_number); |
6202 |
--#endif |
6203 |
-- |
6204 |
--#endif /* CONFIG_INET */ |
6205 |
-- |
6206 |
-+late_initcall(random_int_secret_init); |
6207 |
- |
6208 |
- /* |
6209 |
- * Get a random word for internal kernel use only. Similar to urandom but |
6210 |
-@@ -1631,17 +1315,15 @@ EXPORT_SYMBOL(secure_dccp_sequence_number); |
6211 |
- * value is not cryptographically secure but for several uses the cost of |
6212 |
- * depleting entropy is too high |
6213 |
- */ |
6214 |
--DEFINE_PER_CPU(__u32 [4], get_random_int_hash); |
6215 |
-+DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); |
6216 |
- unsigned int get_random_int(void) |
6217 |
- { |
6218 |
-- struct keydata *keyptr; |
6219 |
- __u32 *hash = get_cpu_var(get_random_int_hash); |
6220 |
-- int ret; |
6221 |
-+ unsigned int ret; |
6222 |
- |
6223 |
-- keyptr = get_keyptr(); |
6224 |
- hash[0] += current->pid + jiffies + get_cycles(); |
6225 |
-- |
6226 |
-- ret = half_md4_transform(hash, keyptr->secret); |
6227 |
-+ md5_transform(hash, random_int_secret); |
6228 |
-+ ret = hash[0]; |
6229 |
- put_cpu_var(get_random_int_hash); |
6230 |
- |
6231 |
- return ret; |
6232 |
-diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c |
6233 |
-index 0929219..1bbb85b 100644 |
6234 |
---- a/drivers/gpu/drm/drm_edid.c |
6235 |
-+++ b/drivers/gpu/drm/drm_edid.c |
6236 |
-@@ -127,6 +127,23 @@ static const u8 edid_header[] = { |
6237 |
- 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 |
6238 |
- }; |
6239 |
- |
6240 |
-+ /* |
6241 |
-+ * Sanity check the header of the base EDID block. Return 8 if the header |
6242 |
-+ * is perfect, down to 0 if it's totally wrong. |
6243 |
-+ */ |
6244 |
-+int drm_edid_header_is_valid(const u8 *raw_edid) |
6245 |
-+{ |
6246 |
-+ int i, score = 0; |
6247 |
-+ |
6248 |
-+ for (i = 0; i < sizeof(edid_header); i++) |
6249 |
-+ if (raw_edid[i] == edid_header[i]) |
6250 |
-+ score++; |
6251 |
-+ |
6252 |
-+ return score; |
6253 |
-+} |
6254 |
-+EXPORT_SYMBOL(drm_edid_header_is_valid); |
6255 |
-+ |
6256 |
-+ |
6257 |
- /* |
6258 |
- * Sanity check the EDID block (base or extension). Return 0 if the block |
6259 |
- * doesn't check out, or 1 if it's valid. |
6260 |
-@@ -139,12 +156,7 @@ drm_edid_block_valid(u8 *raw_edid) |
6261 |
- struct edid *edid = (struct edid *)raw_edid; |
6262 |
- |
6263 |
- if (raw_edid[0] == 0x00) { |
6264 |
-- int score = 0; |
6265 |
-- |
6266 |
-- for (i = 0; i < sizeof(edid_header); i++) |
6267 |
-- if (raw_edid[i] == edid_header[i]) |
6268 |
-- score++; |
6269 |
-- |
6270 |
-+ int score = drm_edid_header_is_valid(raw_edid); |
6271 |
- if (score == 8) ; |
6272 |
- else if (score >= 6) { |
6273 |
- DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); |
6274 |
-diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c |
6275 |
-index 296fbd6..7eef6e1 100644 |
6276 |
---- a/drivers/gpu/drm/i915/i915_dma.c |
6277 |
-+++ b/drivers/gpu/drm/i915/i915_dma.c |
6278 |
-@@ -61,7 +61,6 @@ static void i915_write_hws_pga(struct drm_device *dev) |
6279 |
- static int i915_init_phys_hws(struct drm_device *dev) |
6280 |
- { |
6281 |
- drm_i915_private_t *dev_priv = dev->dev_private; |
6282 |
-- struct intel_ring_buffer *ring = LP_RING(dev_priv); |
6283 |
- |
6284 |
- /* Program Hardware Status Page */ |
6285 |
- dev_priv->status_page_dmah = |
6286 |
-@@ -71,10 +70,9 @@ static int i915_init_phys_hws(struct drm_device *dev) |
6287 |
- DRM_ERROR("Can not allocate hardware status page\n"); |
6288 |
- return -ENOMEM; |
6289 |
- } |
6290 |
-- ring->status_page.page_addr = |
6291 |
-- (void __force __iomem *)dev_priv->status_page_dmah->vaddr; |
6292 |
- |
6293 |
-- memset_io(ring->status_page.page_addr, 0, PAGE_SIZE); |
6294 |
-+ memset_io((void __force __iomem *)dev_priv->status_page_dmah->vaddr, |
6295 |
-+ 0, PAGE_SIZE); |
6296 |
- |
6297 |
- i915_write_hws_pga(dev); |
6298 |
- |
6299 |
-diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c |
6300 |
-index 3b03f85..9b1d669 100644 |
6301 |
---- a/drivers/gpu/drm/i915/i915_irq.c |
6302 |
-+++ b/drivers/gpu/drm/i915/i915_irq.c |
6303 |
-@@ -306,12 +306,15 @@ static void i915_hotplug_work_func(struct work_struct *work) |
6304 |
- struct drm_mode_config *mode_config = &dev->mode_config; |
6305 |
- struct intel_encoder *encoder; |
6306 |
- |
6307 |
-+ mutex_lock(&mode_config->mutex); |
6308 |
- DRM_DEBUG_KMS("running encoder hotplug functions\n"); |
6309 |
- |
6310 |
- list_for_each_entry(encoder, &mode_config->encoder_list, base.head) |
6311 |
- if (encoder->hot_plug) |
6312 |
- encoder->hot_plug(encoder); |
6313 |
- |
6314 |
-+ mutex_unlock(&mode_config->mutex); |
6315 |
-+ |
6316 |
- /* Just fire off a uevent and let userspace tell us what to do */ |
6317 |
- drm_helper_hpd_irq_event(dev); |
6318 |
- } |
6319 |
-diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c |
6320 |
-index 0f1c799..5609c06 100644 |
6321 |
---- a/drivers/gpu/drm/i915/intel_display.c |
6322 |
-+++ b/drivers/gpu/drm/i915/intel_display.c |
6323 |
-@@ -2699,14 +2699,18 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) |
6324 |
- I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size); |
6325 |
- } |
6326 |
- |
6327 |
-+ /* |
6328 |
-+ * On ILK+ LUT must be loaded before the pipe is running but with |
6329 |
-+ * clocks enabled |
6330 |
-+ */ |
6331 |
-+ intel_crtc_load_lut(crtc); |
6332 |
-+ |
6333 |
- intel_enable_pipe(dev_priv, pipe, is_pch_port); |
6334 |
- intel_enable_plane(dev_priv, plane, pipe); |
6335 |
- |
6336 |
- if (is_pch_port) |
6337 |
- ironlake_pch_enable(crtc); |
6338 |
- |
6339 |
-- intel_crtc_load_lut(crtc); |
6340 |
-- |
6341 |
- mutex_lock(&dev->struct_mutex); |
6342 |
- intel_update_fbc(dev); |
6343 |
- mutex_unlock(&dev->struct_mutex); |
6344 |
-diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c |
6345 |
-index a06ff07..05f500c 100644 |
6346 |
---- a/drivers/gpu/drm/i915/intel_panel.c |
6347 |
-+++ b/drivers/gpu/drm/i915/intel_panel.c |
6348 |
-@@ -83,11 +83,15 @@ intel_pch_panel_fitting(struct drm_device *dev, |
6349 |
- u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; |
6350 |
- if (scaled_width > scaled_height) { /* pillar */ |
6351 |
- width = scaled_height / mode->vdisplay; |
6352 |
-+ if (width & 1) |
6353 |
-+ width++; |
6354 |
- x = (adjusted_mode->hdisplay - width + 1) / 2; |
6355 |
- y = 0; |
6356 |
- height = adjusted_mode->vdisplay; |
6357 |
- } else if (scaled_width < scaled_height) { /* letter */ |
6358 |
- height = scaled_width / mode->hdisplay; |
6359 |
-+ if (height & 1) |
6360 |
-+ height++; |
6361 |
- y = (adjusted_mode->vdisplay - height + 1) / 2; |
6362 |
- x = 0; |
6363 |
- width = adjusted_mode->hdisplay; |
6364 |
-diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c |
6365 |
-index 95c4b14..1f61fc7 100644 |
6366 |
---- a/drivers/gpu/drm/i915/intel_ringbuffer.c |
6367 |
-+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c |
6368 |
-@@ -1319,6 +1319,9 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) |
6369 |
- ring->get_seqno = pc_render_get_seqno; |
6370 |
- } |
6371 |
- |
6372 |
-+ if (!I915_NEED_GFX_HWS(dev)) |
6373 |
-+ ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; |
6374 |
-+ |
6375 |
- ring->dev = dev; |
6376 |
- INIT_LIST_HEAD(&ring->active_list); |
6377 |
- INIT_LIST_HEAD(&ring->request_list); |
6378 |
-diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c |
6379 |
-index 9792d4f..6d6b5f1 100644 |
6380 |
---- a/drivers/gpu/drm/radeon/radeon_connectors.c |
6381 |
-+++ b/drivers/gpu/drm/radeon/radeon_connectors.c |
6382 |
-@@ -430,6 +430,45 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr |
6383 |
- return 0; |
6384 |
- } |
6385 |
- |
6386 |
-+/* |
6387 |
-+ * Some integrated ATI Radeon chipset implementations (e. g. |
6388 |
-+ * Asus M2A-VM HDMI) may indicate the availability of a DDC, |
6389 |
-+ * even when there's no monitor connected. For these connectors |
6390 |
-+ * following DDC probe extension will be applied: check also for the |
6391 |
-+ * availability of EDID with at least a correct EDID header. Only then, |
6392 |
-+ * DDC is assumed to be available. This prevents drm_get_edid() and |
6393 |
-+ * drm_edid_block_valid() from periodically dumping data and kernel |
6394 |
-+ * errors into the logs and onto the terminal. |
6395 |
-+ */ |
6396 |
-+static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, |
6397 |
-+ uint32_t supported_device, |
6398 |
-+ int connector_type) |
6399 |
-+{ |
6400 |
-+ /* Asus M2A-VM HDMI board sends data to i2c bus even, |
6401 |
-+ * if HDMI add-on card is not plugged in or HDMI is disabled in |
6402 |
-+ * BIOS. Valid DDC can only be assumed, if also a valid EDID header |
6403 |
-+ * can be retrieved via i2c bus during DDC probe */ |
6404 |
-+ if ((dev->pdev->device == 0x791e) && |
6405 |
-+ (dev->pdev->subsystem_vendor == 0x1043) && |
6406 |
-+ (dev->pdev->subsystem_device == 0x826d)) { |
6407 |
-+ if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && |
6408 |
-+ (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
6409 |
-+ return true; |
6410 |
-+ } |
6411 |
-+ /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus |
6412 |
-+ * for a DVI connector that is not implemented */ |
6413 |
-+ if ((dev->pdev->device == 0x796e) && |
6414 |
-+ (dev->pdev->subsystem_vendor == 0x1019) && |
6415 |
-+ (dev->pdev->subsystem_device == 0x2615)) { |
6416 |
-+ if ((connector_type == DRM_MODE_CONNECTOR_DVID) && |
6417 |
-+ (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
6418 |
-+ return true; |
6419 |
-+ } |
6420 |
-+ |
6421 |
-+ /* Default: no EDID header probe required for DDC probing */ |
6422 |
-+ return false; |
6423 |
-+} |
6424 |
-+ |
6425 |
- static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, |
6426 |
- struct drm_connector *connector) |
6427 |
- { |
6428 |
-@@ -661,7 +700,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) |
6429 |
- ret = connector_status_disconnected; |
6430 |
- |
6431 |
- if (radeon_connector->ddc_bus) |
6432 |
-- dret = radeon_ddc_probe(radeon_connector); |
6433 |
-+ dret = radeon_ddc_probe(radeon_connector, |
6434 |
-+ radeon_connector->requires_extended_probe); |
6435 |
- if (dret) { |
6436 |
- if (radeon_connector->edid) { |
6437 |
- kfree(radeon_connector->edid); |
6438 |
-@@ -833,7 +873,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) |
6439 |
- bool dret = false; |
6440 |
- |
6441 |
- if (radeon_connector->ddc_bus) |
6442 |
-- dret = radeon_ddc_probe(radeon_connector); |
6443 |
-+ dret = radeon_ddc_probe(radeon_connector, |
6444 |
-+ radeon_connector->requires_extended_probe); |
6445 |
- if (dret) { |
6446 |
- if (radeon_connector->edid) { |
6447 |
- kfree(radeon_connector->edid); |
6448 |
-@@ -1251,7 +1292,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) |
6449 |
- if (radeon_dp_getdpcd(radeon_connector)) |
6450 |
- ret = connector_status_connected; |
6451 |
- } else { |
6452 |
-- if (radeon_ddc_probe(radeon_connector)) |
6453 |
-+ if (radeon_ddc_probe(radeon_connector, |
6454 |
-+ radeon_connector->requires_extended_probe)) |
6455 |
- ret = connector_status_connected; |
6456 |
- } |
6457 |
- } |
6458 |
-@@ -1406,6 +1448,9 @@ radeon_add_atom_connector(struct drm_device *dev, |
6459 |
- radeon_connector->shared_ddc = shared_ddc; |
6460 |
- radeon_connector->connector_object_id = connector_object_id; |
6461 |
- radeon_connector->hpd = *hpd; |
6462 |
-+ radeon_connector->requires_extended_probe = |
6463 |
-+ radeon_connector_needs_extended_probe(rdev, supported_device, |
6464 |
-+ connector_type); |
6465 |
- radeon_connector->router = *router; |
6466 |
- if (router->ddc_valid || router->cd_valid) { |
6467 |
- radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); |
6468 |
-@@ -1752,6 +1797,9 @@ radeon_add_legacy_connector(struct drm_device *dev, |
6469 |
- radeon_connector->devices = supported_device; |
6470 |
- radeon_connector->connector_object_id = connector_object_id; |
6471 |
- radeon_connector->hpd = *hpd; |
6472 |
-+ radeon_connector->requires_extended_probe = |
6473 |
-+ radeon_connector_needs_extended_probe(rdev, supported_device, |
6474 |
-+ connector_type); |
6475 |
- switch (connector_type) { |
6476 |
- case DRM_MODE_CONNECTOR_VGA: |
6477 |
- drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
6478 |
-diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c |
6479 |
-index 7cfaa7e..440e6ec 100644 |
6480 |
---- a/drivers/gpu/drm/radeon/radeon_device.c |
6481 |
-+++ b/drivers/gpu/drm/radeon/radeon_device.c |
6482 |
-@@ -704,8 +704,9 @@ int radeon_device_init(struct radeon_device *rdev, |
6483 |
- rdev->gpu_lockup = false; |
6484 |
- rdev->accel_working = false; |
6485 |
- |
6486 |
-- DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n", |
6487 |
-- radeon_family_name[rdev->family], pdev->vendor, pdev->device); |
6488 |
-+ DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", |
6489 |
-+ radeon_family_name[rdev->family], pdev->vendor, pdev->device, |
6490 |
-+ pdev->subsystem_vendor, pdev->subsystem_device); |
6491 |
- |
6492 |
- /* mutex initialization are all done here so we |
6493 |
- * can recall function without having locking issues */ |
6494 |
-diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c |
6495 |
-index 292f73f..ed085ce 100644 |
6496 |
---- a/drivers/gpu/drm/radeon/radeon_display.c |
6497 |
-+++ b/drivers/gpu/drm/radeon/radeon_display.c |
6498 |
-@@ -777,8 +777,17 @@ static int radeon_ddc_dump(struct drm_connector *connector) |
6499 |
- if (!radeon_connector->ddc_bus) |
6500 |
- return -1; |
6501 |
- edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); |
6502 |
-+ /* Log EDID retrieval status here. In particular with regard to |
6503 |
-+ * connectors with requires_extended_probe flag set, that will prevent |
6504 |
-+ * function radeon_dvi_detect() to fetch EDID on this connector, |
6505 |
-+ * as long as there is no valid EDID header found */ |
6506 |
- if (edid) { |
6507 |
-+ DRM_INFO("Radeon display connector %s: Found valid EDID", |
6508 |
-+ drm_get_connector_name(connector)); |
6509 |
- kfree(edid); |
6510 |
-+ } else { |
6511 |
-+ DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID", |
6512 |
-+ drm_get_connector_name(connector)); |
6513 |
- } |
6514 |
- return ret; |
6515 |
- } |
6516 |
-diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c |
6517 |
-index 781196d..6c111c1 100644 |
6518 |
---- a/drivers/gpu/drm/radeon/radeon_i2c.c |
6519 |
-+++ b/drivers/gpu/drm/radeon/radeon_i2c.c |
6520 |
-@@ -32,17 +32,17 @@ |
6521 |
- * radeon_ddc_probe |
6522 |
- * |
6523 |
- */ |
6524 |
--bool radeon_ddc_probe(struct radeon_connector *radeon_connector) |
6525 |
-+bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) |
6526 |
- { |
6527 |
-- u8 out_buf[] = { 0x0, 0x0}; |
6528 |
-- u8 buf[2]; |
6529 |
-+ u8 out = 0x0; |
6530 |
-+ u8 buf[8]; |
6531 |
- int ret; |
6532 |
- struct i2c_msg msgs[] = { |
6533 |
- { |
6534 |
- .addr = 0x50, |
6535 |
- .flags = 0, |
6536 |
- .len = 1, |
6537 |
-- .buf = out_buf, |
6538 |
-+ .buf = &out, |
6539 |
- }, |
6540 |
- { |
6541 |
- .addr = 0x50, |
6542 |
-@@ -52,15 +52,31 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) |
6543 |
- } |
6544 |
- }; |
6545 |
- |
6546 |
-+ /* Read 8 bytes from i2c for extended probe of EDID header */ |
6547 |
-+ if (requires_extended_probe) |
6548 |
-+ msgs[1].len = 8; |
6549 |
-+ |
6550 |
- /* on hw with routers, select right port */ |
6551 |
- if (radeon_connector->router.ddc_valid) |
6552 |
- radeon_router_select_ddc_port(radeon_connector); |
6553 |
- |
6554 |
- ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); |
6555 |
-- if (ret == 2) |
6556 |
-- return true; |
6557 |
-- |
6558 |
-- return false; |
6559 |
-+ if (ret != 2) |
6560 |
-+ /* Couldn't find an accessible DDC on this connector */ |
6561 |
-+ return false; |
6562 |
-+ if (requires_extended_probe) { |
6563 |
-+ /* Probe also for valid EDID header |
6564 |
-+ * EDID header starts with: |
6565 |
-+ * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. |
6566 |
-+ * Only the first 6 bytes must be valid as |
6567 |
-+ * drm_edid_block_valid() can fix the last 2 bytes */ |
6568 |
-+ if (drm_edid_header_is_valid(buf) < 6) { |
6569 |
-+ /* Couldn't find an accessible EDID on this |
6570 |
-+ * connector */ |
6571 |
-+ return false; |
6572 |
-+ } |
6573 |
-+ } |
6574 |
-+ return true; |
6575 |
- } |
6576 |
- |
6577 |
- /* bit banging i2c */ |
6578 |
-diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h |
6579 |
-index 6df4e3c..d09031c 100644 |
6580 |
---- a/drivers/gpu/drm/radeon/radeon_mode.h |
6581 |
-+++ b/drivers/gpu/drm/radeon/radeon_mode.h |
6582 |
-@@ -438,6 +438,9 @@ struct radeon_connector { |
6583 |
- struct radeon_i2c_chan *ddc_bus; |
6584 |
- /* some systems have an hdmi and vga port with a shared ddc line */ |
6585 |
- bool shared_ddc; |
6586 |
-+ /* for some Radeon chip families we apply an additional EDID header |
6587 |
-+ check as part of the DDC probe */ |
6588 |
-+ bool requires_extended_probe; |
6589 |
- bool use_digital; |
6590 |
- /* we need to mind the EDID between detect |
6591 |
- and get modes due to analog/digital/tvencoder */ |
6592 |
-@@ -514,7 +517,8 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, |
6593 |
- u8 val); |
6594 |
- extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); |
6595 |
- extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); |
6596 |
--extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); |
6597 |
-+extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, |
6598 |
-+ bool requires_extended_probe); |
6599 |
- extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); |
6600 |
- |
6601 |
- extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); |
6602 |
-diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c |
6603 |
-index 9798811..b145b5a 100644 |
6604 |
---- a/drivers/isdn/i4l/isdn_net.c |
6605 |
-+++ b/drivers/isdn/i4l/isdn_net.c |
6606 |
-@@ -2531,6 +2531,9 @@ static void _isdn_setup(struct net_device *dev) |
6607 |
- |
6608 |
- /* Setup the generic properties */ |
6609 |
- dev->flags = IFF_NOARP|IFF_POINTOPOINT; |
6610 |
-+ |
6611 |
-+ /* isdn prepends a header in the tx path, can't share skbs */ |
6612 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
6613 |
- dev->header_ops = NULL; |
6614 |
- dev->netdev_ops = &isdn_netdev_ops; |
6615 |
- |
6616 |
-diff --git a/drivers/net/Makefile b/drivers/net/Makefile |
6617 |
-index 776a478..d5ce011 100644 |
6618 |
---- a/drivers/net/Makefile |
6619 |
-+++ b/drivers/net/Makefile |
6620 |
-@@ -283,6 +283,7 @@ obj-$(CONFIG_USB_HSO) += usb/ |
6621 |
- obj-$(CONFIG_USB_USBNET) += usb/ |
6622 |
- obj-$(CONFIG_USB_ZD1201) += usb/ |
6623 |
- obj-$(CONFIG_USB_IPHETH) += usb/ |
6624 |
-+obj-$(CONFIG_USB_CDC_PHONET) += usb/ |
6625 |
- |
6626 |
- obj-$(CONFIG_WLAN) += wireless/ |
6627 |
- obj-$(CONFIG_NET_TULIP) += tulip/ |
6628 |
-diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c |
6629 |
-index 63c22b0..9ea2f21 100644 |
6630 |
---- a/drivers/net/bonding/bond_main.c |
6631 |
-+++ b/drivers/net/bonding/bond_main.c |
6632 |
-@@ -1625,8 +1625,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) |
6633 |
- |
6634 |
- if (slave_dev->type != ARPHRD_ETHER) |
6635 |
- bond_setup_by_slave(bond_dev, slave_dev); |
6636 |
-- else |
6637 |
-+ else { |
6638 |
- ether_setup(bond_dev); |
6639 |
-+ bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
6640 |
-+ } |
6641 |
- |
6642 |
- netdev_bonding_change(bond_dev, |
6643 |
- NETDEV_POST_TYPE_CHANGE); |
6644 |
-@@ -4398,7 +4400,7 @@ static void bond_setup(struct net_device *bond_dev) |
6645 |
- bond_dev->tx_queue_len = 0; |
6646 |
- bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; |
6647 |
- bond_dev->priv_flags |= IFF_BONDING; |
6648 |
-- bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
6649 |
-+ bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
6650 |
- |
6651 |
- /* At first, we block adding VLANs. That's the only way to |
6652 |
- * prevent problems that occur when adding VLANs over an |
6653 |
-diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c |
6654 |
-index 88fcb25..0624610 100644 |
6655 |
---- a/drivers/net/bonding/bond_sysfs.c |
6656 |
-+++ b/drivers/net/bonding/bond_sysfs.c |
6657 |
-@@ -992,6 +992,7 @@ static ssize_t bonding_store_primary(struct device *d, |
6658 |
- int i; |
6659 |
- struct slave *slave; |
6660 |
- struct bonding *bond = to_bond(d); |
6661 |
-+ char ifname[IFNAMSIZ]; |
6662 |
- |
6663 |
- if (!rtnl_trylock()) |
6664 |
- return restart_syscall(); |
6665 |
-@@ -1002,32 +1003,33 @@ static ssize_t bonding_store_primary(struct device *d, |
6666 |
- if (!USES_PRIMARY(bond->params.mode)) { |
6667 |
- pr_info("%s: Unable to set primary slave; %s is in mode %d\n", |
6668 |
- bond->dev->name, bond->dev->name, bond->params.mode); |
6669 |
-- } else { |
6670 |
-- bond_for_each_slave(bond, slave, i) { |
6671 |
-- if (strnicmp |
6672 |
-- (slave->dev->name, buf, |
6673 |
-- strlen(slave->dev->name)) == 0) { |
6674 |
-- pr_info("%s: Setting %s as primary slave.\n", |
6675 |
-- bond->dev->name, slave->dev->name); |
6676 |
-- bond->primary_slave = slave; |
6677 |
-- strcpy(bond->params.primary, slave->dev->name); |
6678 |
-- bond_select_active_slave(bond); |
6679 |
-- goto out; |
6680 |
-- } |
6681 |
-- } |
6682 |
-+ goto out; |
6683 |
-+ } |
6684 |
- |
6685 |
-- /* if we got here, then we didn't match the name of any slave */ |
6686 |
-+ sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ |
6687 |
- |
6688 |
-- if (strlen(buf) == 0 || buf[0] == '\n') { |
6689 |
-- pr_info("%s: Setting primary slave to None.\n", |
6690 |
-- bond->dev->name); |
6691 |
-- bond->primary_slave = NULL; |
6692 |
-- bond_select_active_slave(bond); |
6693 |
-- } else { |
6694 |
-- pr_info("%s: Unable to set %.*s as primary slave as it is not a slave.\n", |
6695 |
-- bond->dev->name, (int)strlen(buf) - 1, buf); |
6696 |
-+ /* check to see if we are clearing primary */ |
6697 |
-+ if (!strlen(ifname) || buf[0] == '\n') { |
6698 |
-+ pr_info("%s: Setting primary slave to None.\n", |
6699 |
-+ bond->dev->name); |
6700 |
-+ bond->primary_slave = NULL; |
6701 |
-+ bond_select_active_slave(bond); |
6702 |
-+ goto out; |
6703 |
-+ } |
6704 |
-+ |
6705 |
-+ bond_for_each_slave(bond, slave, i) { |
6706 |
-+ if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { |
6707 |
-+ pr_info("%s: Setting %s as primary slave.\n", |
6708 |
-+ bond->dev->name, slave->dev->name); |
6709 |
-+ bond->primary_slave = slave; |
6710 |
-+ strcpy(bond->params.primary, slave->dev->name); |
6711 |
-+ bond_select_active_slave(bond); |
6712 |
-+ goto out; |
6713 |
- } |
6714 |
- } |
6715 |
-+ |
6716 |
-+ pr_info("%s: Unable to set %.*s as primary slave.\n", |
6717 |
-+ bond->dev->name, (int)strlen(buf) - 1, buf); |
6718 |
- out: |
6719 |
- write_unlock_bh(&bond->curr_slave_lock); |
6720 |
- read_unlock(&bond->lock); |
6721 |
-@@ -1162,6 +1164,7 @@ static ssize_t bonding_store_active_slave(struct device *d, |
6722 |
- struct slave *old_active = NULL; |
6723 |
- struct slave *new_active = NULL; |
6724 |
- struct bonding *bond = to_bond(d); |
6725 |
-+ char ifname[IFNAMSIZ]; |
6726 |
- |
6727 |
- if (!rtnl_trylock()) |
6728 |
- return restart_syscall(); |
6729 |
-@@ -1170,56 +1173,62 @@ static ssize_t bonding_store_active_slave(struct device *d, |
6730 |
- read_lock(&bond->lock); |
6731 |
- write_lock_bh(&bond->curr_slave_lock); |
6732 |
- |
6733 |
-- if (!USES_PRIMARY(bond->params.mode)) |
6734 |
-+ if (!USES_PRIMARY(bond->params.mode)) { |
6735 |
- pr_info("%s: Unable to change active slave; %s is in mode %d\n", |
6736 |
- bond->dev->name, bond->dev->name, bond->params.mode); |
6737 |
-- else { |
6738 |
-- bond_for_each_slave(bond, slave, i) { |
6739 |
-- if (strnicmp |
6740 |
-- (slave->dev->name, buf, |
6741 |
-- strlen(slave->dev->name)) == 0) { |
6742 |
-- old_active = bond->curr_active_slave; |
6743 |
-- new_active = slave; |
6744 |
-- if (new_active == old_active) { |
6745 |
-- /* do nothing */ |
6746 |
-- pr_info("%s: %s is already the current active slave.\n", |
6747 |
-+ goto out; |
6748 |
-+ } |
6749 |
-+ |
6750 |
-+ sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ |
6751 |
-+ |
6752 |
-+ /* check to see if we are clearing active */ |
6753 |
-+ if (!strlen(ifname) || buf[0] == '\n') { |
6754 |
-+ pr_info("%s: Clearing current active slave.\n", |
6755 |
-+ bond->dev->name); |
6756 |
-+ bond->curr_active_slave = NULL; |
6757 |
-+ bond_select_active_slave(bond); |
6758 |
-+ goto out; |
6759 |
-+ } |
6760 |
-+ |
6761 |
-+ bond_for_each_slave(bond, slave, i) { |
6762 |
-+ if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { |
6763 |
-+ old_active = bond->curr_active_slave; |
6764 |
-+ new_active = slave; |
6765 |
-+ if (new_active == old_active) { |
6766 |
-+ /* do nothing */ |
6767 |
-+ pr_info("%s: %s is already the current" |
6768 |
-+ " active slave.\n", |
6769 |
-+ bond->dev->name, |
6770 |
-+ slave->dev->name); |
6771 |
-+ goto out; |
6772 |
-+ } |
6773 |
-+ else { |
6774 |
-+ if ((new_active) && |
6775 |
-+ (old_active) && |
6776 |
-+ (new_active->link == BOND_LINK_UP) && |
6777 |
-+ IS_UP(new_active->dev)) { |
6778 |
-+ pr_info("%s: Setting %s as active" |
6779 |
-+ " slave.\n", |
6780 |
- bond->dev->name, |
6781 |
- slave->dev->name); |
6782 |
-- goto out; |
6783 |
-+ bond_change_active_slave(bond, |
6784 |
-+ new_active); |
6785 |
- } |
6786 |
- else { |
6787 |
-- if ((new_active) && |
6788 |
-- (old_active) && |
6789 |
-- (new_active->link == BOND_LINK_UP) && |
6790 |
-- IS_UP(new_active->dev)) { |
6791 |
-- pr_info("%s: Setting %s as active slave.\n", |
6792 |
-- bond->dev->name, |
6793 |
-- slave->dev->name); |
6794 |
-- bond_change_active_slave(bond, new_active); |
6795 |
-- } |
6796 |
-- else { |
6797 |
-- pr_info("%s: Could not set %s as active slave; either %s is down or the link is down.\n", |
6798 |
-- bond->dev->name, |
6799 |
-- slave->dev->name, |
6800 |
-- slave->dev->name); |
6801 |
-- } |
6802 |
-- goto out; |
6803 |
-+ pr_info("%s: Could not set %s as" |
6804 |
-+ " active slave; either %s is" |
6805 |
-+ " down or the link is down.\n", |
6806 |
-+ bond->dev->name, |
6807 |
-+ slave->dev->name, |
6808 |
-+ slave->dev->name); |
6809 |
- } |
6810 |
-+ goto out; |
6811 |
- } |
6812 |
- } |
6813 |
-- |
6814 |
-- /* if we got here, then we didn't match the name of any slave */ |
6815 |
-- |
6816 |
-- if (strlen(buf) == 0 || buf[0] == '\n') { |
6817 |
-- pr_info("%s: Setting active slave to None.\n", |
6818 |
-- bond->dev->name); |
6819 |
-- bond->primary_slave = NULL; |
6820 |
-- bond_select_active_slave(bond); |
6821 |
-- } else { |
6822 |
-- pr_info("%s: Unable to set %.*s as active slave as it is not a slave.\n", |
6823 |
-- bond->dev->name, (int)strlen(buf) - 1, buf); |
6824 |
-- } |
6825 |
- } |
6826 |
-+ |
6827 |
-+ pr_info("%s: Unable to set %.*s as active slave.\n", |
6828 |
-+ bond->dev->name, (int)strlen(buf) - 1, buf); |
6829 |
- out: |
6830 |
- write_unlock_bh(&bond->curr_slave_lock); |
6831 |
- read_unlock(&bond->lock); |
6832 |
-diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c |
6833 |
-index dd8ab05..8d28602 100644 |
6834 |
---- a/drivers/net/e1000e/lib.c |
6835 |
-+++ b/drivers/net/e1000e/lib.c |
6836 |
-@@ -190,7 +190,8 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) |
6837 |
- /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ |
6838 |
- if (!((nvm_data & NVM_COMPAT_LOM) || |
6839 |
- (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || |
6840 |
-- (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD))) |
6841 |
-+ (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) || |
6842 |
-+ (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES))) |
6843 |
- goto out; |
6844 |
- |
6845 |
- ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, |
6846 |
-diff --git a/drivers/net/gianfar_ptp.c b/drivers/net/gianfar_ptp.c |
6847 |
-index d8e1753..c413479 100644 |
6848 |
---- a/drivers/net/gianfar_ptp.c |
6849 |
-+++ b/drivers/net/gianfar_ptp.c |
6850 |
-@@ -193,14 +193,9 @@ static void set_alarm(struct etsects *etsects) |
6851 |
- /* Caller must hold etsects->lock. */ |
6852 |
- static void set_fipers(struct etsects *etsects) |
6853 |
- { |
6854 |
-- u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl); |
6855 |
-- |
6856 |
-- gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl & (~TE)); |
6857 |
-- gfar_write(&etsects->regs->tmr_prsc, etsects->tmr_prsc); |
6858 |
-+ set_alarm(etsects); |
6859 |
- gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); |
6860 |
- gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); |
6861 |
-- set_alarm(etsects); |
6862 |
-- gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|TE); |
6863 |
- } |
6864 |
- |
6865 |
- /* |
6866 |
-@@ -511,7 +506,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) |
6867 |
- gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); |
6868 |
- gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); |
6869 |
- set_alarm(etsects); |
6870 |
-- gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE); |
6871 |
-+ gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE|FRD); |
6872 |
- |
6873 |
- spin_unlock_irqrestore(&etsects->lock, flags); |
6874 |
- |
6875 |
-diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c |
6876 |
-index 4fecaed..2b98461 100644 |
6877 |
---- a/drivers/net/ifb.c |
6878 |
-+++ b/drivers/net/ifb.c |
6879 |
-@@ -145,7 +145,7 @@ static void ifb_setup(struct net_device *dev) |
6880 |
- |
6881 |
- dev->flags |= IFF_NOARP; |
6882 |
- dev->flags &= ~IFF_MULTICAST; |
6883 |
-- dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
6884 |
-+ dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
6885 |
- random_ether_addr(dev->dev_addr); |
6886 |
- } |
6887 |
- |
6888 |
-diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c |
6889 |
-index d6aeaa5..2f3c48d 100644 |
6890 |
---- a/drivers/net/macvlan.c |
6891 |
-+++ b/drivers/net/macvlan.c |
6892 |
-@@ -547,7 +547,7 @@ void macvlan_common_setup(struct net_device *dev) |
6893 |
- { |
6894 |
- ether_setup(dev); |
6895 |
- |
6896 |
-- dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
6897 |
-+ dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
6898 |
- dev->netdev_ops = &macvlan_netdev_ops; |
6899 |
- dev->destructor = free_netdev; |
6900 |
- dev->header_ops = &macvlan_hard_header_ops, |
6901 |
-diff --git a/drivers/net/niu.c b/drivers/net/niu.c |
6902 |
-index cc25bff..2f8c351 100644 |
6903 |
---- a/drivers/net/niu.c |
6904 |
-+++ b/drivers/net/niu.c |
6905 |
-@@ -9196,7 +9196,7 @@ static int __devinit niu_ldg_init(struct niu *np) |
6906 |
- |
6907 |
- first_chan = 0; |
6908 |
- for (i = 0; i < port; i++) |
6909 |
-- first_chan += parent->rxchan_per_port[port]; |
6910 |
-+ first_chan += parent->rxchan_per_port[i]; |
6911 |
- num_chan = parent->rxchan_per_port[port]; |
6912 |
- |
6913 |
- for (i = first_chan; i < (first_chan + num_chan); i++) { |
6914 |
-@@ -9212,7 +9212,7 @@ static int __devinit niu_ldg_init(struct niu *np) |
6915 |
- |
6916 |
- first_chan = 0; |
6917 |
- for (i = 0; i < port; i++) |
6918 |
-- first_chan += parent->txchan_per_port[port]; |
6919 |
-+ first_chan += parent->txchan_per_port[i]; |
6920 |
- num_chan = parent->txchan_per_port[port]; |
6921 |
- for (i = first_chan; i < (first_chan + num_chan); i++) { |
6922 |
- err = niu_ldg_assign_ldn(np, parent, |
6923 |
-diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c |
6924 |
-index 2cd8dc5..cb6e0b4 100644 |
6925 |
---- a/drivers/net/phy/dp83640.c |
6926 |
-+++ b/drivers/net/phy/dp83640.c |
6927 |
-@@ -34,8 +34,7 @@ |
6928 |
- #define PAGESEL 0x13 |
6929 |
- #define LAYER4 0x02 |
6930 |
- #define LAYER2 0x01 |
6931 |
--#define MAX_RXTS 4 |
6932 |
--#define MAX_TXTS 4 |
6933 |
-+#define MAX_RXTS 64 |
6934 |
- #define N_EXT_TS 1 |
6935 |
- #define PSF_PTPVER 2 |
6936 |
- #define PSF_EVNT 0x4000 |
6937 |
-@@ -218,7 +217,7 @@ static void phy2rxts(struct phy_rxts *p, struct rxts *rxts) |
6938 |
- rxts->seqid = p->seqid; |
6939 |
- rxts->msgtype = (p->msgtype >> 12) & 0xf; |
6940 |
- rxts->hash = p->msgtype & 0x0fff; |
6941 |
-- rxts->tmo = jiffies + HZ; |
6942 |
-+ rxts->tmo = jiffies + 2; |
6943 |
- } |
6944 |
- |
6945 |
- static u64 phy2txts(struct phy_txts *p) |
6946 |
-diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c |
6947 |
-index 5990621..5f838ef 100644 |
6948 |
---- a/drivers/net/r8169.c |
6949 |
-+++ b/drivers/net/r8169.c |
6950 |
-@@ -236,6 +236,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { |
6951 |
- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, |
6952 |
- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, |
6953 |
- { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, |
6954 |
-+ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, |
6955 |
- { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, |
6956 |
- { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, |
6957 |
- { PCI_VENDOR_ID_LINKSYS, 0x1032, |
6958 |
-diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c |
6959 |
-index b436e00..f6d26ab 100644 |
6960 |
---- a/drivers/net/sis190.c |
6961 |
-+++ b/drivers/net/sis190.c |
6962 |
-@@ -1824,6 +1824,16 @@ static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
6963 |
- generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); |
6964 |
- } |
6965 |
- |
6966 |
-+static int sis190_mac_addr(struct net_device *dev, void *p) |
6967 |
-+{ |
6968 |
-+ int rc; |
6969 |
-+ |
6970 |
-+ rc = eth_mac_addr(dev, p); |
6971 |
-+ if (!rc) |
6972 |
-+ sis190_init_rxfilter(dev); |
6973 |
-+ return rc; |
6974 |
-+} |
6975 |
-+ |
6976 |
- static const struct net_device_ops sis190_netdev_ops = { |
6977 |
- .ndo_open = sis190_open, |
6978 |
- .ndo_stop = sis190_close, |
6979 |
-@@ -1832,7 +1842,7 @@ static const struct net_device_ops sis190_netdev_ops = { |
6980 |
- .ndo_tx_timeout = sis190_tx_timeout, |
6981 |
- .ndo_set_multicast_list = sis190_set_rx_mode, |
6982 |
- .ndo_change_mtu = eth_change_mtu, |
6983 |
-- .ndo_set_mac_address = eth_mac_addr, |
6984 |
-+ .ndo_set_mac_address = sis190_mac_addr, |
6985 |
- .ndo_validate_addr = eth_validate_addr, |
6986 |
- #ifdef CONFIG_NET_POLL_CONTROLLER |
6987 |
- .ndo_poll_controller = sis190_netpoll, |
6988 |
-diff --git a/drivers/net/tun.c b/drivers/net/tun.c |
6989 |
-index 5235f48..fb50e5a 100644 |
6990 |
---- a/drivers/net/tun.c |
6991 |
-+++ b/drivers/net/tun.c |
6992 |
-@@ -528,6 +528,7 @@ static void tun_net_init(struct net_device *dev) |
6993 |
- dev->netdev_ops = &tap_netdev_ops; |
6994 |
- /* Ethernet TAP Device */ |
6995 |
- ether_setup(dev); |
6996 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
6997 |
- |
6998 |
- random_ether_addr(dev->dev_addr); |
6999 |
- |
7000 |
-diff --git a/drivers/net/veth.c b/drivers/net/veth.c |
7001 |
-index 8461576..4bf7c6d 100644 |
7002 |
---- a/drivers/net/veth.c |
7003 |
-+++ b/drivers/net/veth.c |
7004 |
-@@ -262,6 +262,8 @@ static void veth_setup(struct net_device *dev) |
7005 |
- { |
7006 |
- ether_setup(dev); |
7007 |
- |
7008 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
7009 |
-+ |
7010 |
- dev->netdev_ops = &veth_netdev_ops; |
7011 |
- dev->ethtool_ops = &veth_ethtool_ops; |
7012 |
- dev->features |= NETIF_F_LLTX; |
7013 |
-diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c |
7014 |
-index fc433f2..13f9997 100644 |
7015 |
---- a/drivers/net/wan/hdlc_fr.c |
7016 |
-+++ b/drivers/net/wan/hdlc_fr.c |
7017 |
-@@ -1083,9 +1083,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) |
7018 |
- |
7019 |
- used = pvc_is_used(pvc); |
7020 |
- |
7021 |
-- if (type == ARPHRD_ETHER) |
7022 |
-+ if (type == ARPHRD_ETHER) { |
7023 |
- dev = alloc_netdev(0, "pvceth%d", ether_setup); |
7024 |
-- else |
7025 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
7026 |
-+ } else |
7027 |
- dev = alloc_netdev(0, "pvc%d", pvc_setup); |
7028 |
- |
7029 |
- if (!dev) { |
7030 |
-diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c |
7031 |
-index 55cf71f..e1b3e3c 100644 |
7032 |
---- a/drivers/net/wireless/airo.c |
7033 |
-+++ b/drivers/net/wireless/airo.c |
7034 |
-@@ -2823,6 +2823,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, |
7035 |
- dev->wireless_data = &ai->wireless_data; |
7036 |
- dev->irq = irq; |
7037 |
- dev->base_addr = port; |
7038 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
7039 |
- |
7040 |
- SET_NETDEV_DEV(dev, dmdev); |
7041 |
- |
7042 |
-diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c |
7043 |
-index f344cc2..c32f9d1 100644 |
7044 |
---- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c |
7045 |
-+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c |
7046 |
-@@ -309,11 +309,7 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, |
7047 |
- u8 i; |
7048 |
- u32 val; |
7049 |
- |
7050 |
-- if (ah->is_pciexpress != true) |
7051 |
-- return; |
7052 |
-- |
7053 |
-- /* Do not touch SerDes registers */ |
7054 |
-- if (ah->config.pcie_powersave_enable == 2) |
7055 |
-+ if (ah->is_pciexpress != true || ah->aspm_enabled != true) |
7056 |
- return; |
7057 |
- |
7058 |
- /* Nothing to do on restore for 11N */ |
7059 |
-diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |
7060 |
-index ff8150e..7e07f0f 100644 |
7061 |
---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |
7062 |
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |
7063 |
-@@ -306,7 +306,7 @@ static const struct ar9300_eeprom ar9300_default = { |
7064 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7065 |
- { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
7066 |
- |
7067 |
-- { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
7068 |
-+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, |
7069 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7070 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7071 |
- |
7072 |
-@@ -883,7 +883,7 @@ static const struct ar9300_eeprom ar9300_x113 = { |
7073 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7074 |
- { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
7075 |
- |
7076 |
-- { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
7077 |
-+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, |
7078 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7079 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7080 |
- |
7081 |
-@@ -2039,7 +2039,7 @@ static const struct ar9300_eeprom ar9300_x112 = { |
7082 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7083 |
- { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
7084 |
- |
7085 |
-- { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
7086 |
-+ { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, |
7087 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7088 |
- { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
7089 |
- |
7090 |
-diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c |
7091 |
-index 392bf0f..7e02fb4 100644 |
7092 |
---- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c |
7093 |
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c |
7094 |
-@@ -351,11 +351,7 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, |
7095 |
- int restore, |
7096 |
- int power_off) |
7097 |
- { |
7098 |
-- if (ah->is_pciexpress != true) |
7099 |
-- return; |
7100 |
-- |
7101 |
-- /* Do not touch SerDes registers */ |
7102 |
-- if (ah->config.pcie_powersave_enable == 2) |
7103 |
-+ if (ah->is_pciexpress != true || ah->aspm_enabled != true) |
7104 |
- return; |
7105 |
- |
7106 |
- /* Nothing to do on restore for 11N */ |
7107 |
-diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h |
7108 |
-index 443090d..efdbe98 100644 |
7109 |
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h |
7110 |
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h |
7111 |
-@@ -848,7 +848,7 @@ |
7112 |
- #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) |
7113 |
- #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) |
7114 |
- #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) |
7115 |
--#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2)) |
7116 |
-+#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2)) |
7117 |
- |
7118 |
- /* |
7119 |
- * Channel 2 Register Map |
7120 |
-diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c |
7121 |
-index 1be7c8b..03900ca 100644 |
7122 |
---- a/drivers/net/wireless/ath/ath9k/hw.c |
7123 |
-+++ b/drivers/net/wireless/ath/ath9k/hw.c |
7124 |
-@@ -299,6 +299,14 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) |
7125 |
- REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
7126 |
- } |
7127 |
- |
7128 |
-+static void ath9k_hw_aspm_init(struct ath_hw *ah) |
7129 |
-+{ |
7130 |
-+ struct ath_common *common = ath9k_hw_common(ah); |
7131 |
-+ |
7132 |
-+ if (common->bus_ops->aspm_init) |
7133 |
-+ common->bus_ops->aspm_init(common); |
7134 |
-+} |
7135 |
-+ |
7136 |
- /* This should work for all families including legacy */ |
7137 |
- static bool ath9k_hw_chip_test(struct ath_hw *ah) |
7138 |
- { |
7139 |
-@@ -359,7 +367,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) |
7140 |
- ah->config.additional_swba_backoff = 0; |
7141 |
- ah->config.ack_6mb = 0x0; |
7142 |
- ah->config.cwm_ignore_extcca = 0; |
7143 |
-- ah->config.pcie_powersave_enable = 0; |
7144 |
- ah->config.pcie_clock_req = 0; |
7145 |
- ah->config.pcie_waen = 0; |
7146 |
- ah->config.analog_shiftreg = 1; |
7147 |
-@@ -577,7 +584,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) |
7148 |
- |
7149 |
- |
7150 |
- if (ah->is_pciexpress) |
7151 |
-- ath9k_hw_configpcipowersave(ah, 0, 0); |
7152 |
-+ ath9k_hw_aspm_init(ah); |
7153 |
- else |
7154 |
- ath9k_hw_disablepcie(ah); |
7155 |
- |
7156 |
-diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h |
7157 |
-index 4b157c5..939cc9d 100644 |
7158 |
---- a/drivers/net/wireless/ath/ath9k/hw.h |
7159 |
-+++ b/drivers/net/wireless/ath/ath9k/hw.h |
7160 |
-@@ -215,7 +215,6 @@ struct ath9k_ops_config { |
7161 |
- int additional_swba_backoff; |
7162 |
- int ack_6mb; |
7163 |
- u32 cwm_ignore_extcca; |
7164 |
-- u8 pcie_powersave_enable; |
7165 |
- bool pcieSerDesWrite; |
7166 |
- u8 pcie_clock_req; |
7167 |
- u32 pcie_waen; |
7168 |
-@@ -671,6 +670,7 @@ struct ath_hw { |
7169 |
- |
7170 |
- bool sw_mgmt_crypto; |
7171 |
- bool is_pciexpress; |
7172 |
-+ bool aspm_enabled; |
7173 |
- bool is_monitoring; |
7174 |
- bool need_an_top2_fixup; |
7175 |
- u16 tx_trig_level; |
7176 |
-@@ -870,6 +870,7 @@ struct ath_bus_ops { |
7177 |
- bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); |
7178 |
- void (*bt_coex_prep)(struct ath_common *common); |
7179 |
- void (*extn_synch_en)(struct ath_common *common); |
7180 |
-+ void (*aspm_init)(struct ath_common *common); |
7181 |
- }; |
7182 |
- |
7183 |
- static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) |
7184 |
-diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c |
7185 |
-index 45c585a..5a9fd21 100644 |
7186 |
---- a/drivers/net/wireless/ath/ath9k/init.c |
7187 |
-+++ b/drivers/net/wireless/ath/ath9k/init.c |
7188 |
-@@ -665,8 +665,10 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) |
7189 |
- static void ath9k_init_txpower_limits(struct ath_softc *sc) |
7190 |
- { |
7191 |
- struct ath_hw *ah = sc->sc_ah; |
7192 |
-+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
7193 |
- struct ath9k_channel *curchan = ah->curchan; |
7194 |
- |
7195 |
-+ ah->txchainmask = common->tx_chainmask; |
7196 |
- if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) |
7197 |
- ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); |
7198 |
- if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) |
7199 |
-diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c |
7200 |
-index 3bad0b2..be4ea13 100644 |
7201 |
---- a/drivers/net/wireless/ath/ath9k/pci.c |
7202 |
-+++ b/drivers/net/wireless/ath/ath9k/pci.c |
7203 |
-@@ -16,6 +16,7 @@ |
7204 |
- |
7205 |
- #include <linux/nl80211.h> |
7206 |
- #include <linux/pci.h> |
7207 |
-+#include <linux/pci-aspm.h> |
7208 |
- #include <linux/ath9k_platform.h> |
7209 |
- #include "ath9k.h" |
7210 |
- |
7211 |
-@@ -115,12 +116,38 @@ static void ath_pci_extn_synch_enable(struct ath_common *common) |
7212 |
- pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); |
7213 |
- } |
7214 |
- |
7215 |
-+static void ath_pci_aspm_init(struct ath_common *common) |
7216 |
-+{ |
7217 |
-+ struct ath_softc *sc = (struct ath_softc *) common->priv; |
7218 |
-+ struct ath_hw *ah = sc->sc_ah; |
7219 |
-+ struct pci_dev *pdev = to_pci_dev(sc->dev); |
7220 |
-+ struct pci_dev *parent; |
7221 |
-+ int pos; |
7222 |
-+ u8 aspm; |
7223 |
-+ |
7224 |
-+ if (!pci_is_pcie(pdev)) |
7225 |
-+ return; |
7226 |
-+ |
7227 |
-+ parent = pdev->bus->self; |
7228 |
-+ if (WARN_ON(!parent)) |
7229 |
-+ return; |
7230 |
-+ |
7231 |
-+ pos = pci_pcie_cap(parent); |
7232 |
-+ pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); |
7233 |
-+ if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { |
7234 |
-+ ah->aspm_enabled = true; |
7235 |
-+ /* Initialize PCIe PM and SERDES registers. */ |
7236 |
-+ ath9k_hw_configpcipowersave(ah, 0, 0); |
7237 |
-+ } |
7238 |
-+} |
7239 |
-+ |
7240 |
- static const struct ath_bus_ops ath_pci_bus_ops = { |
7241 |
- .ath_bus_type = ATH_PCI, |
7242 |
- .read_cachesize = ath_pci_read_cachesize, |
7243 |
- .eeprom_read = ath_pci_eeprom_read, |
7244 |
- .bt_coex_prep = ath_pci_bt_coex_prep, |
7245 |
- .extn_synch_en = ath_pci_extn_synch_enable, |
7246 |
-+ .aspm_init = ath_pci_aspm_init, |
7247 |
- }; |
7248 |
- |
7249 |
- static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
7250 |
-diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c |
7251 |
-index d508482..89a116f 100644 |
7252 |
---- a/drivers/net/wireless/hostap/hostap_main.c |
7253 |
-+++ b/drivers/net/wireless/hostap/hostap_main.c |
7254 |
-@@ -855,6 +855,7 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local, |
7255 |
- |
7256 |
- iface = netdev_priv(dev); |
7257 |
- ether_setup(dev); |
7258 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
7259 |
- |
7260 |
- /* kernel callbacks */ |
7261 |
- if (iface) { |
7262 |
-diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c |
7263 |
-index d096dc2..dcc1552 100644 |
7264 |
---- a/drivers/net/wireless/iwlegacy/iwl-3945.c |
7265 |
-+++ b/drivers/net/wireless/iwlegacy/iwl-3945.c |
7266 |
-@@ -1747,7 +1747,11 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) |
7267 |
- } |
7268 |
- |
7269 |
- memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); |
7270 |
-- |
7271 |
-+ /* |
7272 |
-+ * We do not commit tx power settings while channel changing, |
7273 |
-+ * do it now if tx power changed. |
7274 |
-+ */ |
7275 |
-+ iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); |
7276 |
- return 0; |
7277 |
- } |
7278 |
- |
7279 |
-diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c |
7280 |
-index facc94e..0a1babb 100644 |
7281 |
---- a/drivers/net/wireless/iwlegacy/iwl-4965.c |
7282 |
-+++ b/drivers/net/wireless/iwlegacy/iwl-4965.c |
7283 |
-@@ -1237,7 +1237,12 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c |
7284 |
- |
7285 |
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); |
7286 |
- iwl_legacy_print_rx_config_cmd(priv, ctx); |
7287 |
-- goto set_tx_power; |
7288 |
-+ /* |
7289 |
-+ * We do not commit tx power settings while channel changing, |
7290 |
-+ * do it now if tx power changed. |
7291 |
-+ */ |
7292 |
-+ iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); |
7293 |
-+ return 0; |
7294 |
- } |
7295 |
- |
7296 |
- /* If we are currently associated and the new config requires |
7297 |
-@@ -1317,7 +1322,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c |
7298 |
- |
7299 |
- iwl4965_init_sensitivity(priv); |
7300 |
- |
7301 |
--set_tx_power: |
7302 |
- /* If we issue a new RXON command which required a tune then we must |
7303 |
- * send a new TXPOWER command or we won't be able to Tx any frames */ |
7304 |
- ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); |
7305 |
-diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c |
7306 |
-index e816c27..f1c3f49 100644 |
7307 |
---- a/drivers/net/wireless/iwlwifi/iwl-5000.c |
7308 |
-+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c |
7309 |
-@@ -421,6 +421,7 @@ static struct iwl_base_params iwl5000_base_params = { |
7310 |
- .chain_noise_scale = 1000, |
7311 |
- .wd_timeout = IWL_LONG_WD_TIMEOUT, |
7312 |
- .max_event_log_size = 512, |
7313 |
-+ .no_idle_support = true, |
7314 |
- }; |
7315 |
- static struct iwl_ht_params iwl5000_ht_params = { |
7316 |
- .ht_greenfield_support = true, |
7317 |
-diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h |
7318 |
-index a54d416..b76996a 100644 |
7319 |
---- a/drivers/net/wireless/iwlwifi/iwl-core.h |
7320 |
-+++ b/drivers/net/wireless/iwlwifi/iwl-core.h |
7321 |
-@@ -195,6 +195,7 @@ struct iwl_mod_params { |
7322 |
- * @temperature_kelvin: temperature report by uCode in kelvin |
7323 |
- * @max_event_log_size: size of event log buffer size for ucode event logging |
7324 |
- * @shadow_reg_enable: HW shadhow register bit |
7325 |
-+ * @no_idle_support: do not support idle mode |
7326 |
- */ |
7327 |
- struct iwl_base_params { |
7328 |
- int eeprom_size; |
7329 |
-@@ -216,6 +217,7 @@ struct iwl_base_params { |
7330 |
- bool temperature_kelvin; |
7331 |
- u32 max_event_log_size; |
7332 |
- const bool shadow_reg_enable; |
7333 |
-+ const bool no_idle_support; |
7334 |
- }; |
7335 |
- /* |
7336 |
- * @advanced_bt_coexist: support advanced bt coexist |
7337 |
-diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c |
7338 |
-index 595c930..4a05a6a 100644 |
7339 |
---- a/drivers/net/wireless/iwlwifi/iwl-power.c |
7340 |
-+++ b/drivers/net/wireless/iwlwifi/iwl-power.c |
7341 |
-@@ -355,7 +355,8 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, |
7342 |
- |
7343 |
- dtimper = priv->hw->conf.ps_dtim_period ?: 1; |
7344 |
- |
7345 |
-- if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
7346 |
-+ if (!priv->cfg->base_params->no_idle_support && |
7347 |
-+ priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
7348 |
- iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); |
7349 |
- else if (iwl_tt_is_low_power_state(priv)) { |
7350 |
- /* in thermal throttling low power state */ |
7351 |
-diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c |
7352 |
-index 2a6aa85..5a45228 100644 |
7353 |
---- a/drivers/net/wireless/rt2x00/rt2800lib.c |
7354 |
-+++ b/drivers/net/wireless/rt2x00/rt2800lib.c |
7355 |
-@@ -784,8 +784,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) |
7356 |
- /* |
7357 |
- * Add space for the TXWI in front of the skb. |
7358 |
- */ |
7359 |
-- skb_push(entry->skb, TXWI_DESC_SIZE); |
7360 |
-- memset(entry->skb, 0, TXWI_DESC_SIZE); |
7361 |
-+ memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE); |
7362 |
- |
7363 |
- /* |
7364 |
- * Register descriptor details in skb frame descriptor. |
7365 |
-diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c |
7366 |
-index 93bec14..a76fdbe 100644 |
7367 |
---- a/drivers/net/wireless/rt2x00/rt2x00mac.c |
7368 |
-+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c |
7369 |
-@@ -113,7 +113,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
7370 |
- * due to possible race conditions in mac80211. |
7371 |
- */ |
7372 |
- if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
7373 |
-- goto exit_fail; |
7374 |
-+ goto exit_free_skb; |
7375 |
- |
7376 |
- /* |
7377 |
- * Use the ATIM queue if appropriate and present. |
7378 |
-@@ -127,7 +127,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
7379 |
- ERROR(rt2x00dev, |
7380 |
- "Attempt to send packet over invalid queue %d.\n" |
7381 |
- "Please file bug report to %s.\n", qid, DRV_PROJECT); |
7382 |
-- goto exit_fail; |
7383 |
-+ goto exit_free_skb; |
7384 |
- } |
7385 |
- |
7386 |
- /* |
7387 |
-@@ -159,6 +159,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
7388 |
- |
7389 |
- exit_fail: |
7390 |
- rt2x00queue_pause_queue(queue); |
7391 |
-+ exit_free_skb: |
7392 |
- dev_kfree_skb_any(skb); |
7393 |
- } |
7394 |
- EXPORT_SYMBOL_GPL(rt2x00mac_tx); |
7395 |
-diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c |
7396 |
-index 254b64b..c872a23 100644 |
7397 |
---- a/drivers/net/wireless/rtlwifi/pci.c |
7398 |
-+++ b/drivers/net/wireless/rtlwifi/pci.c |
7399 |
-@@ -1709,15 +1709,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, |
7400 |
- pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); |
7401 |
- pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); |
7402 |
- |
7403 |
-- /*find bridge info */ |
7404 |
-- pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; |
7405 |
-- for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { |
7406 |
-- if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { |
7407 |
-- pcipriv->ndis_adapter.pcibridge_vendor = tmp; |
7408 |
-- RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
7409 |
-- ("Pci Bridge Vendor is found index: %d\n", |
7410 |
-- tmp)); |
7411 |
-- break; |
7412 |
-+ if (bridge_pdev) { |
7413 |
-+ /*find bridge info if available */ |
7414 |
-+ pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; |
7415 |
-+ for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { |
7416 |
-+ if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { |
7417 |
-+ pcipriv->ndis_adapter.pcibridge_vendor = tmp; |
7418 |
-+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
7419 |
-+ ("Pci Bridge Vendor is found index:" |
7420 |
-+ " %d\n", tmp)); |
7421 |
-+ break; |
7422 |
-+ } |
7423 |
- } |
7424 |
- } |
7425 |
- |
7426 |
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c |
7427 |
-index 3c7857c..e1678b9 100644 |
7428 |
---- a/drivers/platform/x86/asus-wmi.c |
7429 |
-+++ b/drivers/platform/x86/asus-wmi.c |
7430 |
-@@ -797,8 +797,8 @@ exit: |
7431 |
- * Hwmon device |
7432 |
- */ |
7433 |
- static ssize_t asus_hwmon_pwm1(struct device *dev, |
7434 |
-- struct device_attribute *attr, |
7435 |
-- char *buf) |
7436 |
-+ struct device_attribute *attr, |
7437 |
-+ char *buf) |
7438 |
- { |
7439 |
- struct asus_wmi *asus = dev_get_drvdata(dev); |
7440 |
- u32 value; |
7441 |
-@@ -809,7 +809,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev, |
7442 |
- if (err < 0) |
7443 |
- return err; |
7444 |
- |
7445 |
-- value |= 0xFF; |
7446 |
-+ value &= 0xFF; |
7447 |
- |
7448 |
- if (value == 1) /* Low Speed */ |
7449 |
- value = 85; |
7450 |
-@@ -869,7 +869,7 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, |
7451 |
- * - reverved bits are non-zero |
7452 |
- * - sfun and presence bit are not set |
7453 |
- */ |
7454 |
-- if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 |
7455 |
-+ if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 |
7456 |
- || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) |
7457 |
- ok = false; |
7458 |
- } |
7459 |
-@@ -904,6 +904,7 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus) |
7460 |
- pr_err("Could not register asus hwmon device\n"); |
7461 |
- return PTR_ERR(hwmon); |
7462 |
- } |
7463 |
-+ dev_set_drvdata(hwmon, asus); |
7464 |
- asus->hwmon_device = hwmon; |
7465 |
- result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); |
7466 |
- if (result) |
7467 |
-@@ -1164,14 +1165,18 @@ ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); |
7468 |
- static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, |
7469 |
- const char *buf, size_t count) |
7470 |
- { |
7471 |
-- int value; |
7472 |
-+ int value, rv; |
7473 |
- |
7474 |
- if (!count || sscanf(buf, "%i", &value) != 1) |
7475 |
- return -EINVAL; |
7476 |
- if (value < 0 || value > 2) |
7477 |
- return -EINVAL; |
7478 |
- |
7479 |
-- return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); |
7480 |
-+ rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); |
7481 |
-+ if (rv < 0) |
7482 |
-+ return rv; |
7483 |
-+ |
7484 |
-+ return count; |
7485 |
- } |
7486 |
- |
7487 |
- static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); |
7488 |
-diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c |
7489 |
-index efa0255..1da606c 100644 |
7490 |
---- a/drivers/scsi/mpt2sas/mpt2sas_base.c |
7491 |
-+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c |
7492 |
-@@ -94,7 +94,7 @@ module_param(diag_buffer_enable, int, 0); |
7493 |
- MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " |
7494 |
- "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); |
7495 |
- |
7496 |
--int mpt2sas_fwfault_debug; |
7497 |
-+static int mpt2sas_fwfault_debug; |
7498 |
- MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " |
7499 |
- "and halt firmware - (default=0)"); |
7500 |
- |
7501 |
-@@ -857,7 +857,7 @@ _base_interrupt(int irq, void *bus_id) |
7502 |
- completed_cmds = 0; |
7503 |
- cb_idx = 0xFF; |
7504 |
- do { |
7505 |
-- rd.word = rpf->Words; |
7506 |
-+ rd.word = le64_to_cpu(rpf->Words); |
7507 |
- if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) |
7508 |
- goto out; |
7509 |
- reply = 0; |
7510 |
-@@ -906,7 +906,7 @@ _base_interrupt(int irq, void *bus_id) |
7511 |
- |
7512 |
- next: |
7513 |
- |
7514 |
-- rpf->Words = ULLONG_MAX; |
7515 |
-+ rpf->Words = cpu_to_le64(ULLONG_MAX); |
7516 |
- ioc->reply_post_host_index = (ioc->reply_post_host_index == |
7517 |
- (ioc->reply_post_queue_depth - 1)) ? 0 : |
7518 |
- ioc->reply_post_host_index + 1; |
7519 |
-@@ -1817,7 +1817,9 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) |
7520 |
- char desc[16]; |
7521 |
- u8 revision; |
7522 |
- u32 iounit_pg1_flags; |
7523 |
-+ u32 bios_version; |
7524 |
- |
7525 |
-+ bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); |
7526 |
- pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); |
7527 |
- strncpy(desc, ioc->manu_pg0.ChipName, 16); |
7528 |
- printk(MPT2SAS_INFO_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), " |
7529 |
-@@ -1828,10 +1830,10 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) |
7530 |
- (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, |
7531 |
- ioc->facts.FWVersion.Word & 0x000000FF, |
7532 |
- revision, |
7533 |
-- (ioc->bios_pg3.BiosVersion & 0xFF000000) >> 24, |
7534 |
-- (ioc->bios_pg3.BiosVersion & 0x00FF0000) >> 16, |
7535 |
-- (ioc->bios_pg3.BiosVersion & 0x0000FF00) >> 8, |
7536 |
-- ioc->bios_pg3.BiosVersion & 0x000000FF); |
7537 |
-+ (bios_version & 0xFF000000) >> 24, |
7538 |
-+ (bios_version & 0x00FF0000) >> 16, |
7539 |
-+ (bios_version & 0x0000FF00) >> 8, |
7540 |
-+ bios_version & 0x000000FF); |
7541 |
- |
7542 |
- _base_display_dell_branding(ioc); |
7543 |
- _base_display_intel_branding(ioc); |
7544 |
-@@ -2150,7 +2152,7 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) |
7545 |
- static int |
7546 |
- _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
7547 |
- { |
7548 |
-- Mpi2IOCFactsReply_t *facts; |
7549 |
-+ struct mpt2sas_facts *facts; |
7550 |
- u32 queue_size, queue_diff; |
7551 |
- u16 max_sge_elements; |
7552 |
- u16 num_of_reply_frames; |
7553 |
-@@ -2783,7 +2785,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, |
7554 |
- int i; |
7555 |
- u8 failed; |
7556 |
- u16 dummy; |
7557 |
-- u32 *mfp; |
7558 |
-+ __le32 *mfp; |
7559 |
- |
7560 |
- /* make sure doorbell is not in use */ |
7561 |
- if ((readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { |
7562 |
-@@ -2871,7 +2873,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes, |
7563 |
- writel(0, &ioc->chip->HostInterruptStatus); |
7564 |
- |
7565 |
- if (ioc->logging_level & MPT_DEBUG_INIT) { |
7566 |
-- mfp = (u32 *)reply; |
7567 |
-+ mfp = (__le32 *)reply; |
7568 |
- printk(KERN_INFO "\toffset:data\n"); |
7569 |
- for (i = 0; i < reply_bytes/4; i++) |
7570 |
- printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, |
7571 |
-@@ -3097,7 +3099,8 @@ static int |
7572 |
- _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag) |
7573 |
- { |
7574 |
- Mpi2PortFactsRequest_t mpi_request; |
7575 |
-- Mpi2PortFactsReply_t mpi_reply, *pfacts; |
7576 |
-+ Mpi2PortFactsReply_t mpi_reply; |
7577 |
-+ struct mpt2sas_port_facts *pfacts; |
7578 |
- int mpi_reply_sz, mpi_request_sz, r; |
7579 |
- |
7580 |
- dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
7581 |
-@@ -3139,7 +3142,8 @@ static int |
7582 |
- _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
7583 |
- { |
7584 |
- Mpi2IOCFactsRequest_t mpi_request; |
7585 |
-- Mpi2IOCFactsReply_t mpi_reply, *facts; |
7586 |
-+ Mpi2IOCFactsReply_t mpi_reply; |
7587 |
-+ struct mpt2sas_facts *facts; |
7588 |
- int mpi_reply_sz, mpi_request_sz, r; |
7589 |
- |
7590 |
- dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
7591 |
-@@ -3225,17 +3229,6 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
7592 |
- mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION); |
7593 |
- mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); |
7594 |
- |
7595 |
-- /* In MPI Revision I (0xA), the SystemReplyFrameSize(offset 0x18) was |
7596 |
-- * removed and made reserved. For those with older firmware will need |
7597 |
-- * this fix. It was decided that the Reply and Request frame sizes are |
7598 |
-- * the same. |
7599 |
-- */ |
7600 |
-- if ((ioc->facts.HeaderVersion >> 8) < 0xA) { |
7601 |
-- mpi_request.Reserved7 = cpu_to_le16(ioc->reply_sz); |
7602 |
--/* mpi_request.SystemReplyFrameSize = |
7603 |
-- * cpu_to_le16(ioc->reply_sz); |
7604 |
-- */ |
7605 |
-- } |
7606 |
- |
7607 |
- mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4); |
7608 |
- mpi_request.ReplyDescriptorPostQueueDepth = |
7609 |
-@@ -3243,25 +3236,17 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
7610 |
- mpi_request.ReplyFreeQueueDepth = |
7611 |
- cpu_to_le16(ioc->reply_free_queue_depth); |
7612 |
- |
7613 |
--#if BITS_PER_LONG > 32 |
7614 |
- mpi_request.SenseBufferAddressHigh = |
7615 |
-- cpu_to_le32(ioc->sense_dma >> 32); |
7616 |
-+ cpu_to_le32((u64)ioc->sense_dma >> 32); |
7617 |
- mpi_request.SystemReplyAddressHigh = |
7618 |
-- cpu_to_le32(ioc->reply_dma >> 32); |
7619 |
-+ cpu_to_le32((u64)ioc->reply_dma >> 32); |
7620 |
- mpi_request.SystemRequestFrameBaseAddress = |
7621 |
-- cpu_to_le64(ioc->request_dma); |
7622 |
-+ cpu_to_le64((u64)ioc->request_dma); |
7623 |
- mpi_request.ReplyFreeQueueAddress = |
7624 |
-- cpu_to_le64(ioc->reply_free_dma); |
7625 |
-+ cpu_to_le64((u64)ioc->reply_free_dma); |
7626 |
- mpi_request.ReplyDescriptorPostQueueAddress = |
7627 |
-- cpu_to_le64(ioc->reply_post_free_dma); |
7628 |
--#else |
7629 |
-- mpi_request.SystemRequestFrameBaseAddress = |
7630 |
-- cpu_to_le32(ioc->request_dma); |
7631 |
-- mpi_request.ReplyFreeQueueAddress = |
7632 |
-- cpu_to_le32(ioc->reply_free_dma); |
7633 |
-- mpi_request.ReplyDescriptorPostQueueAddress = |
7634 |
-- cpu_to_le32(ioc->reply_post_free_dma); |
7635 |
--#endif |
7636 |
-+ cpu_to_le64((u64)ioc->reply_post_free_dma); |
7637 |
-+ |
7638 |
- |
7639 |
- /* This time stamp specifies number of milliseconds |
7640 |
- * since epoch ~ midnight January 1, 1970. |
7641 |
-@@ -3271,10 +3256,10 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
7642 |
- (current_time.tv_usec / 1000)); |
7643 |
- |
7644 |
- if (ioc->logging_level & MPT_DEBUG_INIT) { |
7645 |
-- u32 *mfp; |
7646 |
-+ __le32 *mfp; |
7647 |
- int i; |
7648 |
- |
7649 |
-- mfp = (u32 *)&mpi_request; |
7650 |
-+ mfp = (__le32 *)&mpi_request; |
7651 |
- printk(KERN_INFO "\toffset:data\n"); |
7652 |
- for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) |
7653 |
- printk(KERN_INFO "\t[0x%02x]:%08x\n", i*4, |
7654 |
-@@ -3759,7 +3744,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
7655 |
- |
7656 |
- /* initialize Reply Post Free Queue */ |
7657 |
- for (i = 0; i < ioc->reply_post_queue_depth; i++) |
7658 |
-- ioc->reply_post_free[i].Words = ULLONG_MAX; |
7659 |
-+ ioc->reply_post_free[i].Words = cpu_to_le64(ULLONG_MAX); |
7660 |
- |
7661 |
- r = _base_send_ioc_init(ioc, sleep_flag); |
7662 |
- if (r) |
7663 |
-diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h |
7664 |
-index dcc289c..451dc1c 100644 |
7665 |
---- a/drivers/scsi/mpt2sas/mpt2sas_base.h |
7666 |
-+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h |
7667 |
-@@ -541,6 +541,53 @@ struct _tr_list { |
7668 |
- |
7669 |
- typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); |
7670 |
- |
7671 |
-+/* IOC Facts and Port Facts converted from little endian to cpu */ |
7672 |
-+union mpi2_version_union { |
7673 |
-+ MPI2_VERSION_STRUCT Struct; |
7674 |
-+ u32 Word; |
7675 |
-+}; |
7676 |
-+ |
7677 |
-+struct mpt2sas_facts { |
7678 |
-+ u16 MsgVersion; |
7679 |
-+ u16 HeaderVersion; |
7680 |
-+ u8 IOCNumber; |
7681 |
-+ u8 VP_ID; |
7682 |
-+ u8 VF_ID; |
7683 |
-+ u16 IOCExceptions; |
7684 |
-+ u16 IOCStatus; |
7685 |
-+ u32 IOCLogInfo; |
7686 |
-+ u8 MaxChainDepth; |
7687 |
-+ u8 WhoInit; |
7688 |
-+ u8 NumberOfPorts; |
7689 |
-+ u8 MaxMSIxVectors; |
7690 |
-+ u16 RequestCredit; |
7691 |
-+ u16 ProductID; |
7692 |
-+ u32 IOCCapabilities; |
7693 |
-+ union mpi2_version_union FWVersion; |
7694 |
-+ u16 IOCRequestFrameSize; |
7695 |
-+ u16 Reserved3; |
7696 |
-+ u16 MaxInitiators; |
7697 |
-+ u16 MaxTargets; |
7698 |
-+ u16 MaxSasExpanders; |
7699 |
-+ u16 MaxEnclosures; |
7700 |
-+ u16 ProtocolFlags; |
7701 |
-+ u16 HighPriorityCredit; |
7702 |
-+ u16 MaxReplyDescriptorPostQueueDepth; |
7703 |
-+ u8 ReplyFrameSize; |
7704 |
-+ u8 MaxVolumes; |
7705 |
-+ u16 MaxDevHandle; |
7706 |
-+ u16 MaxPersistentEntries; |
7707 |
-+ u16 MinDevHandle; |
7708 |
-+}; |
7709 |
-+ |
7710 |
-+struct mpt2sas_port_facts { |
7711 |
-+ u8 PortNumber; |
7712 |
-+ u8 VP_ID; |
7713 |
-+ u8 VF_ID; |
7714 |
-+ u8 PortType; |
7715 |
-+ u16 MaxPostedCmdBuffers; |
7716 |
-+}; |
7717 |
-+ |
7718 |
- /** |
7719 |
- * struct MPT2SAS_ADAPTER - per adapter struct |
7720 |
- * @list: ioc_list |
7721 |
-@@ -749,8 +796,8 @@ struct MPT2SAS_ADAPTER { |
7722 |
- u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; |
7723 |
- |
7724 |
- /* static config pages */ |
7725 |
-- Mpi2IOCFactsReply_t facts; |
7726 |
-- Mpi2PortFactsReply_t *pfacts; |
7727 |
-+ struct mpt2sas_facts facts; |
7728 |
-+ struct mpt2sas_port_facts *pfacts; |
7729 |
- Mpi2ManufacturingPage0_t manu_pg0; |
7730 |
- Mpi2BiosPage2_t bios_pg2; |
7731 |
- Mpi2BiosPage3_t bios_pg3; |
7732 |
-@@ -840,7 +887,7 @@ struct MPT2SAS_ADAPTER { |
7733 |
- |
7734 |
- /* reply free queue */ |
7735 |
- u16 reply_free_queue_depth; |
7736 |
-- u32 *reply_free; |
7737 |
-+ __le32 *reply_free; |
7738 |
- dma_addr_t reply_free_dma; |
7739 |
- struct dma_pool *reply_free_dma_pool; |
7740 |
- u32 reply_free_host_index; |
7741 |
-diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c |
7742 |
-index 437c2d9..d1c3bba 100644 |
7743 |
---- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c |
7744 |
-+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c |
7745 |
-@@ -2706,13 +2706,13 @@ static DEVICE_ATTR(ioc_reset_count, S_IRUGO, |
7746 |
- _ctl_ioc_reset_count_show, NULL); |
7747 |
- |
7748 |
- struct DIAG_BUFFER_START { |
7749 |
-- u32 Size; |
7750 |
-- u32 DiagVersion; |
7751 |
-+ __le32 Size; |
7752 |
-+ __le32 DiagVersion; |
7753 |
- u8 BufferType; |
7754 |
- u8 Reserved[3]; |
7755 |
-- u32 Reserved1; |
7756 |
-- u32 Reserved2; |
7757 |
-- u32 Reserved3; |
7758 |
-+ __le32 Reserved1; |
7759 |
-+ __le32 Reserved2; |
7760 |
-+ __le32 Reserved3; |
7761 |
- }; |
7762 |
- /** |
7763 |
- * _ctl_host_trace_buffer_size_show - host buffer size (trace only) |
7764 |
-diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h |
7765 |
-index 3dcddfe..9731f8e 100644 |
7766 |
---- a/drivers/scsi/mpt2sas/mpt2sas_debug.h |
7767 |
-+++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h |
7768 |
-@@ -164,7 +164,7 @@ static inline void |
7769 |
- _debug_dump_mf(void *mpi_request, int sz) |
7770 |
- { |
7771 |
- int i; |
7772 |
-- u32 *mfp = (u32 *)mpi_request; |
7773 |
-+ __le32 *mfp = (__le32 *)mpi_request; |
7774 |
- |
7775 |
- printk(KERN_INFO "mf:\n\t"); |
7776 |
- for (i = 0; i < sz; i++) { |
7777 |
-diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c |
7778 |
-index a7dbc68..e327a3c 100644 |
7779 |
---- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c |
7780 |
-+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c |
7781 |
-@@ -1956,7 +1956,7 @@ _scsih_slave_configure(struct scsi_device *sdev) |
7782 |
- case MPI2_RAID_VOL_TYPE_RAID1E: |
7783 |
- qdepth = MPT2SAS_RAID_QUEUE_DEPTH; |
7784 |
- if (ioc->manu_pg10.OEMIdentifier && |
7785 |
-- (ioc->manu_pg10.GenericFlags0 & |
7786 |
-+ (le32_to_cpu(ioc->manu_pg10.GenericFlags0) & |
7787 |
- MFG10_GF0_R10_DISPLAY) && |
7788 |
- !(raid_device->num_pds % 2)) |
7789 |
- r_level = "RAID10"; |
7790 |
-@@ -4598,7 +4598,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle) |
7791 |
- Mpi2SasEnclosurePage0_t enclosure_pg0; |
7792 |
- u32 ioc_status; |
7793 |
- u16 parent_handle; |
7794 |
-- __le64 sas_address, sas_address_parent = 0; |
7795 |
-+ u64 sas_address, sas_address_parent = 0; |
7796 |
- int i; |
7797 |
- unsigned long flags; |
7798 |
- struct _sas_port *mpt2sas_port = NULL; |
7799 |
-@@ -5404,7 +5404,7 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, |
7800 |
- { |
7801 |
- struct MPT2SAS_TARGET *target_priv_data; |
7802 |
- struct _sas_device *sas_device; |
7803 |
-- __le64 sas_address; |
7804 |
-+ u64 sas_address; |
7805 |
- unsigned long flags; |
7806 |
- Mpi2EventDataSasDeviceStatusChange_t *event_data = |
7807 |
- fw_event->event_data; |
7808 |
-@@ -6566,7 +6566,7 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc) |
7809 |
- Mpi2ExpanderPage0_t expander_pg0; |
7810 |
- Mpi2ConfigReply_t mpi_reply; |
7811 |
- u16 ioc_status; |
7812 |
-- __le64 sas_address; |
7813 |
-+ u64 sas_address; |
7814 |
- u16 handle; |
7815 |
- |
7816 |
- printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); |
7817 |
-@@ -7505,7 +7505,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) |
7818 |
- { |
7819 |
- struct Scsi_Host *shost = pci_get_drvdata(pdev); |
7820 |
- struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); |
7821 |
-- u32 device_state; |
7822 |
-+ pci_power_t device_state; |
7823 |
- |
7824 |
- mpt2sas_base_stop_watchdog(ioc); |
7825 |
- scsi_block_requests(shost); |
7826 |
-@@ -7532,7 +7532,7 @@ _scsih_resume(struct pci_dev *pdev) |
7827 |
- { |
7828 |
- struct Scsi_Host *shost = pci_get_drvdata(pdev); |
7829 |
- struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); |
7830 |
-- u32 device_state = pdev->current_state; |
7831 |
-+ pci_power_t device_state = pdev->current_state; |
7832 |
- int r; |
7833 |
- |
7834 |
- printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, previous " |
7835 |
-diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c |
7836 |
-index cb1cdec..15c7980 100644 |
7837 |
---- a/drivers/scsi/mpt2sas/mpt2sas_transport.c |
7838 |
-+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c |
7839 |
-@@ -299,7 +299,6 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, |
7840 |
- void *data_out = NULL; |
7841 |
- dma_addr_t data_out_dma; |
7842 |
- u32 sz; |
7843 |
-- u64 *sas_address_le; |
7844 |
- u16 wait_state_count; |
7845 |
- |
7846 |
- if (ioc->shost_recovery || ioc->pci_error_recovery) { |
7847 |
-@@ -372,8 +371,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, |
7848 |
- mpi_request->PhysicalPort = 0xFF; |
7849 |
- mpi_request->VF_ID = 0; /* TODO */ |
7850 |
- mpi_request->VP_ID = 0; |
7851 |
-- sas_address_le = (u64 *)&mpi_request->SASAddress; |
7852 |
-- *sas_address_le = cpu_to_le64(sas_address); |
7853 |
-+ mpi_request->SASAddress = cpu_to_le64(sas_address); |
7854 |
- mpi_request->RequestDataLength = |
7855 |
- cpu_to_le16(sizeof(struct rep_manu_request)); |
7856 |
- psge = &mpi_request->SGL; |
7857 |
-@@ -1049,14 +1047,14 @@ struct phy_error_log_reply{ |
7858 |
- u8 function; /* 0x11 */ |
7859 |
- u8 function_result; |
7860 |
- u8 response_length; |
7861 |
-- u16 expander_change_count; |
7862 |
-+ __be16 expander_change_count; |
7863 |
- u8 reserved_1[3]; |
7864 |
- u8 phy_identifier; |
7865 |
- u8 reserved_2[2]; |
7866 |
-- u32 invalid_dword; |
7867 |
-- u32 running_disparity_error; |
7868 |
-- u32 loss_of_dword_sync; |
7869 |
-- u32 phy_reset_problem; |
7870 |
-+ __be32 invalid_dword; |
7871 |
-+ __be32 running_disparity_error; |
7872 |
-+ __be32 loss_of_dword_sync; |
7873 |
-+ __be32 phy_reset_problem; |
7874 |
- }; |
7875 |
- |
7876 |
- /** |
7877 |
-@@ -1085,7 +1083,6 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, |
7878 |
- void *data_out = NULL; |
7879 |
- dma_addr_t data_out_dma; |
7880 |
- u32 sz; |
7881 |
-- u64 *sas_address_le; |
7882 |
- u16 wait_state_count; |
7883 |
- |
7884 |
- if (ioc->shost_recovery || ioc->pci_error_recovery) { |
7885 |
-@@ -1160,8 +1157,7 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, |
7886 |
- mpi_request->PhysicalPort = 0xFF; |
7887 |
- mpi_request->VF_ID = 0; /* TODO */ |
7888 |
- mpi_request->VP_ID = 0; |
7889 |
-- sas_address_le = (u64 *)&mpi_request->SASAddress; |
7890 |
-- *sas_address_le = cpu_to_le64(phy->identify.sas_address); |
7891 |
-+ mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); |
7892 |
- mpi_request->RequestDataLength = |
7893 |
- cpu_to_le16(sizeof(struct phy_error_log_request)); |
7894 |
- psge = &mpi_request->SGL; |
7895 |
-@@ -1406,7 +1402,6 @@ _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, |
7896 |
- void *data_out = NULL; |
7897 |
- dma_addr_t data_out_dma; |
7898 |
- u32 sz; |
7899 |
-- u64 *sas_address_le; |
7900 |
- u16 wait_state_count; |
7901 |
- |
7902 |
- if (ioc->shost_recovery) { |
7903 |
-@@ -1486,8 +1481,7 @@ _transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, |
7904 |
- mpi_request->PhysicalPort = 0xFF; |
7905 |
- mpi_request->VF_ID = 0; /* TODO */ |
7906 |
- mpi_request->VP_ID = 0; |
7907 |
-- sas_address_le = (u64 *)&mpi_request->SASAddress; |
7908 |
-- *sas_address_le = cpu_to_le64(phy->identify.sas_address); |
7909 |
-+ mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); |
7910 |
- mpi_request->RequestDataLength = |
7911 |
- cpu_to_le16(sizeof(struct phy_error_log_request)); |
7912 |
- psge = &mpi_request->SGL; |
7913 |
-@@ -1914,7 +1908,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, |
7914 |
- mpi_request->PhysicalPort = 0xFF; |
7915 |
- mpi_request->VF_ID = 0; /* TODO */ |
7916 |
- mpi_request->VP_ID = 0; |
7917 |
-- *((u64 *)&mpi_request->SASAddress) = (rphy) ? |
7918 |
-+ mpi_request->SASAddress = (rphy) ? |
7919 |
- cpu_to_le64(rphy->identify.sas_address) : |
7920 |
- cpu_to_le64(ioc->sas_hba.sas_address); |
7921 |
- mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); |
7922 |
-diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
7923 |
-index aa97efc..62487a7 100644 |
7924 |
---- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
7925 |
-+++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c |
7926 |
-@@ -6198,6 +6198,7 @@ int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname) |
7927 |
- |
7928 |
- ether_setup(dev); |
7929 |
- init_netdev(dev, ap_ifname); |
7930 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
7931 |
- |
7932 |
- if (register_netdev(dev)) { |
7933 |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n")); |
7934 |
-diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c |
7935 |
-index bc4b12c..fc7e57b 100644 |
7936 |
---- a/fs/cifs/cifsfs.c |
7937 |
-+++ b/fs/cifs/cifsfs.c |
7938 |
-@@ -581,6 +581,10 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) |
7939 |
- mutex_unlock(&dir->i_mutex); |
7940 |
- dput(dentry); |
7941 |
- dentry = child; |
7942 |
-+ if (!dentry->d_inode) { |
7943 |
-+ dput(dentry); |
7944 |
-+ dentry = ERR_PTR(-ENOENT); |
7945 |
-+ } |
7946 |
- } while (!IS_ERR(dentry)); |
7947 |
- _FreeXid(xid); |
7948 |
- kfree(full_path); |
7949 |
-diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c |
7950 |
-index 9b018c8..a7b2dcd 100644 |
7951 |
---- a/fs/cifs/inode.c |
7952 |
-+++ b/fs/cifs/inode.c |
7953 |
-@@ -764,20 +764,10 @@ char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, |
7954 |
- if (full_path == NULL) |
7955 |
- return full_path; |
7956 |
- |
7957 |
-- if (dfsplen) { |
7958 |
-+ if (dfsplen) |
7959 |
- strncpy(full_path, tcon->treeName, dfsplen); |
7960 |
-- /* switch slash direction in prepath depending on whether |
7961 |
-- * windows or posix style path names |
7962 |
-- */ |
7963 |
-- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { |
7964 |
-- int i; |
7965 |
-- for (i = 0; i < dfsplen; i++) { |
7966 |
-- if (full_path[i] == '\\') |
7967 |
-- full_path[i] = '/'; |
7968 |
-- } |
7969 |
-- } |
7970 |
-- } |
7971 |
- strncpy(full_path + dfsplen, vol->prepath, pplen); |
7972 |
-+ convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
7973 |
- full_path[dfsplen + pplen] = 0; /* add trailing null */ |
7974 |
- return full_path; |
7975 |
- } |
7976 |
-diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c |
7977 |
-index 147aa22..c1b9c4b 100644 |
7978 |
---- a/fs/cifs/transport.c |
7979 |
-+++ b/fs/cifs/transport.c |
7980 |
-@@ -362,6 +362,8 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, |
7981 |
- mid = AllocMidQEntry(hdr, server); |
7982 |
- if (mid == NULL) { |
7983 |
- mutex_unlock(&server->srv_mutex); |
7984 |
-+ atomic_dec(&server->inFlight); |
7985 |
-+ wake_up(&server->request_q); |
7986 |
- return -ENOMEM; |
7987 |
- } |
7988 |
- |
7989 |
-diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c |
7990 |
-index 9f1bb74..b4a6bef 100644 |
7991 |
---- a/fs/ecryptfs/main.c |
7992 |
-+++ b/fs/ecryptfs/main.c |
7993 |
-@@ -175,6 +175,7 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, |
7994 |
- ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, |
7995 |
- ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, |
7996 |
- ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, |
7997 |
-+ ecryptfs_opt_check_dev_ruid, |
7998 |
- ecryptfs_opt_err }; |
7999 |
- |
8000 |
- static const match_table_t tokens = { |
8001 |
-@@ -191,6 +192,7 @@ static const match_table_t tokens = { |
8002 |
- {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, |
8003 |
- {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, |
8004 |
- {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, |
8005 |
-+ {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"}, |
8006 |
- {ecryptfs_opt_err, NULL} |
8007 |
- }; |
8008 |
- |
8009 |
-@@ -236,6 +238,7 @@ static void ecryptfs_init_mount_crypt_stat( |
8010 |
- * ecryptfs_parse_options |
8011 |
- * @sb: The ecryptfs super block |
8012 |
- * @options: The options passed to the kernel |
8013 |
-+ * @check_ruid: set to 1 if device uid should be checked against the ruid |
8014 |
- * |
8015 |
- * Parse mount options: |
8016 |
- * debug=N - ecryptfs_verbosity level for debug output |
8017 |
-@@ -251,7 +254,8 @@ static void ecryptfs_init_mount_crypt_stat( |
8018 |
- * |
8019 |
- * Returns zero on success; non-zero on error |
8020 |
- */ |
8021 |
--static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
8022 |
-+static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, |
8023 |
-+ uid_t *check_ruid) |
8024 |
- { |
8025 |
- char *p; |
8026 |
- int rc = 0; |
8027 |
-@@ -276,6 +280,8 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
8028 |
- char *cipher_key_bytes_src; |
8029 |
- char *fn_cipher_key_bytes_src; |
8030 |
- |
8031 |
-+ *check_ruid = 0; |
8032 |
-+ |
8033 |
- if (!options) { |
8034 |
- rc = -EINVAL; |
8035 |
- goto out; |
8036 |
-@@ -380,6 +386,9 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
8037 |
- mount_crypt_stat->flags |= |
8038 |
- ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; |
8039 |
- break; |
8040 |
-+ case ecryptfs_opt_check_dev_ruid: |
8041 |
-+ *check_ruid = 1; |
8042 |
-+ break; |
8043 |
- case ecryptfs_opt_err: |
8044 |
- default: |
8045 |
- printk(KERN_WARNING |
8046 |
-@@ -475,6 +484,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags |
8047 |
- const char *err = "Getting sb failed"; |
8048 |
- struct inode *inode; |
8049 |
- struct path path; |
8050 |
-+ uid_t check_ruid; |
8051 |
- int rc; |
8052 |
- |
8053 |
- sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
8054 |
-@@ -483,7 +493,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags |
8055 |
- goto out; |
8056 |
- } |
8057 |
- |
8058 |
-- rc = ecryptfs_parse_options(sbi, raw_data); |
8059 |
-+ rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); |
8060 |
- if (rc) { |
8061 |
- err = "Error parsing options"; |
8062 |
- goto out; |
8063 |
-@@ -521,6 +531,15 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags |
8064 |
- "known incompatibilities\n"); |
8065 |
- goto out_free; |
8066 |
- } |
8067 |
-+ |
8068 |
-+ if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) { |
8069 |
-+ rc = -EPERM; |
8070 |
-+ printk(KERN_ERR "Mount of device (uid: %d) not owned by " |
8071 |
-+ "requested user (uid: %d)\n", |
8072 |
-+ path.dentry->d_inode->i_uid, current_uid()); |
8073 |
-+ goto out_free; |
8074 |
-+ } |
8075 |
-+ |
8076 |
- ecryptfs_set_superblock_lower(s, path.dentry->d_sb); |
8077 |
- s->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
8078 |
- s->s_blocksize = path.dentry->d_sb->s_blocksize; |
8079 |
-diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c |
8080 |
-index 85d4309..3745f7c 100644 |
8081 |
---- a/fs/ecryptfs/read_write.c |
8082 |
-+++ b/fs/ecryptfs/read_write.c |
8083 |
-@@ -39,15 +39,16 @@ |
8084 |
- int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, |
8085 |
- loff_t offset, size_t size) |
8086 |
- { |
8087 |
-- struct ecryptfs_inode_info *inode_info; |
8088 |
-+ struct file *lower_file; |
8089 |
- mm_segment_t fs_save; |
8090 |
- ssize_t rc; |
8091 |
- |
8092 |
-- inode_info = ecryptfs_inode_to_private(ecryptfs_inode); |
8093 |
-- BUG_ON(!inode_info->lower_file); |
8094 |
-+ lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
8095 |
-+ if (!lower_file) |
8096 |
-+ return -EIO; |
8097 |
- fs_save = get_fs(); |
8098 |
- set_fs(get_ds()); |
8099 |
-- rc = vfs_write(inode_info->lower_file, data, size, &offset); |
8100 |
-+ rc = vfs_write(lower_file, data, size, &offset); |
8101 |
- set_fs(fs_save); |
8102 |
- mark_inode_dirty_sync(ecryptfs_inode); |
8103 |
- return rc; |
8104 |
-@@ -225,15 +226,16 @@ out: |
8105 |
- int ecryptfs_read_lower(char *data, loff_t offset, size_t size, |
8106 |
- struct inode *ecryptfs_inode) |
8107 |
- { |
8108 |
-- struct ecryptfs_inode_info *inode_info = |
8109 |
-- ecryptfs_inode_to_private(ecryptfs_inode); |
8110 |
-+ struct file *lower_file; |
8111 |
- mm_segment_t fs_save; |
8112 |
- ssize_t rc; |
8113 |
- |
8114 |
-- BUG_ON(!inode_info->lower_file); |
8115 |
-+ lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; |
8116 |
-+ if (!lower_file) |
8117 |
-+ return -EIO; |
8118 |
- fs_save = get_fs(); |
8119 |
- set_fs(get_ds()); |
8120 |
-- rc = vfs_read(inode_info->lower_file, data, size, &offset); |
8121 |
-+ rc = vfs_read(lower_file, data, size, &offset); |
8122 |
- set_fs(fs_save); |
8123 |
- return rc; |
8124 |
- } |
8125 |
-diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c |
8126 |
-index 34b6d9b..e5a7111 100644 |
8127 |
---- a/fs/ext3/namei.c |
8128 |
-+++ b/fs/ext3/namei.c |
8129 |
-@@ -2210,9 +2210,11 @@ static int ext3_symlink (struct inode * dir, |
8130 |
- /* |
8131 |
- * For non-fast symlinks, we just allocate inode and put it on |
8132 |
- * orphan list in the first transaction => we need bitmap, |
8133 |
-- * group descriptor, sb, inode block, quota blocks. |
8134 |
-+ * group descriptor, sb, inode block, quota blocks, and |
8135 |
-+ * possibly selinux xattr blocks. |
8136 |
- */ |
8137 |
-- credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); |
8138 |
-+ credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + |
8139 |
-+ EXT3_XATTR_TRANS_BLOCKS; |
8140 |
- } else { |
8141 |
- /* |
8142 |
- * Fast symlink. We have to add entry to directory |
8143 |
-diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c |
8144 |
-index b754b77..458a394 100644 |
8145 |
---- a/fs/ext4/namei.c |
8146 |
-+++ b/fs/ext4/namei.c |
8147 |
-@@ -2264,9 +2264,11 @@ static int ext4_symlink(struct inode *dir, |
8148 |
- /* |
8149 |
- * For non-fast symlinks, we just allocate inode and put it on |
8150 |
- * orphan list in the first transaction => we need bitmap, |
8151 |
-- * group descriptor, sb, inode block, quota blocks. |
8152 |
-+ * group descriptor, sb, inode block, quota blocks, and |
8153 |
-+ * possibly selinux xattr blocks. |
8154 |
- */ |
8155 |
-- credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); |
8156 |
-+ credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + |
8157 |
-+ EXT4_XATTR_TRANS_BLOCKS; |
8158 |
- } else { |
8159 |
- /* |
8160 |
- * Fast symlink. We have to add entry to directory |
8161 |
-diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h |
8162 |
-index 33d12f8..0ec3687 100644 |
8163 |
---- a/include/drm/drm_crtc.h |
8164 |
-+++ b/include/drm/drm_crtc.h |
8165 |
-@@ -802,6 +802,7 @@ extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev, |
8166 |
- extern int drm_add_modes_noedid(struct drm_connector *connector, |
8167 |
- int hdisplay, int vdisplay); |
8168 |
- |
8169 |
-+extern int drm_edid_header_is_valid(const u8 *raw_edid); |
8170 |
- extern bool drm_edid_is_valid(struct edid *edid); |
8171 |
- struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, |
8172 |
- int hsize, int vsize, int fresh); |
8173 |
-diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h |
8174 |
-index c4d6dbf..28c0d11 100644 |
8175 |
---- a/include/drm/i915_drm.h |
8176 |
-+++ b/include/drm/i915_drm.h |
8177 |
-@@ -237,7 +237,7 @@ typedef struct _drm_i915_sarea { |
8178 |
- #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) |
8179 |
- #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) |
8180 |
- #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) |
8181 |
--#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image) |
8182 |
-+#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image) |
8183 |
- #define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) |
8184 |
- |
8185 |
- /* Allow drivers to submit batchbuffers directly to hardware, relying |
8186 |
-diff --git a/include/linux/cryptohash.h b/include/linux/cryptohash.h |
8187 |
-index ec78a4b..d2984fb 100644 |
8188 |
---- a/include/linux/cryptohash.h |
8189 |
-+++ b/include/linux/cryptohash.h |
8190 |
-@@ -8,6 +8,11 @@ |
8191 |
- void sha_init(__u32 *buf); |
8192 |
- void sha_transform(__u32 *digest, const char *data, __u32 *W); |
8193 |
- |
8194 |
-+#define MD5_DIGEST_WORDS 4 |
8195 |
-+#define MD5_MESSAGE_BYTES 64 |
8196 |
-+ |
8197 |
-+void md5_transform(__u32 *hash, __u32 const *in); |
8198 |
-+ |
8199 |
- __u32 half_md4_transform(__u32 buf[4], __u32 const in[8]); |
8200 |
- |
8201 |
- #endif |
8202 |
-diff --git a/include/linux/if.h b/include/linux/if.h |
8203 |
-index 3bc63e6..03489ca 100644 |
8204 |
---- a/include/linux/if.h |
8205 |
-+++ b/include/linux/if.h |
8206 |
-@@ -76,6 +76,8 @@ |
8207 |
- #define IFF_BRIDGE_PORT 0x4000 /* device used as bridge port */ |
8208 |
- #define IFF_OVS_DATAPATH 0x8000 /* device used as Open vSwitch |
8209 |
- * datapath port */ |
8210 |
-+#define IFF_TX_SKB_SHARING 0x10000 /* The interface supports sharing |
8211 |
-+ * skbs on transmit */ |
8212 |
- |
8213 |
- #define IF_GET_IFACE 0x0001 /* for querying only */ |
8214 |
- #define IF_GET_PROTO 0x0002 |
8215 |
-diff --git a/include/linux/mm.h b/include/linux/mm.h |
8216 |
-index 1036614..ec6e33d 100644 |
8217 |
---- a/include/linux/mm.h |
8218 |
-+++ b/include/linux/mm.h |
8219 |
-@@ -959,6 +959,8 @@ int invalidate_inode_page(struct page *page); |
8220 |
- #ifdef CONFIG_MMU |
8221 |
- extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, |
8222 |
- unsigned long address, unsigned int flags); |
8223 |
-+extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, |
8224 |
-+ unsigned long address, unsigned int fault_flags); |
8225 |
- #else |
8226 |
- static inline int handle_mm_fault(struct mm_struct *mm, |
8227 |
- struct vm_area_struct *vma, unsigned long address, |
8228 |
-@@ -968,6 +970,14 @@ static inline int handle_mm_fault(struct mm_struct *mm, |
8229 |
- BUG(); |
8230 |
- return VM_FAULT_SIGBUS; |
8231 |
- } |
8232 |
-+static inline int fixup_user_fault(struct task_struct *tsk, |
8233 |
-+ struct mm_struct *mm, unsigned long address, |
8234 |
-+ unsigned int fault_flags) |
8235 |
-+{ |
8236 |
-+ /* should never happen if there's no MMU */ |
8237 |
-+ BUG(); |
8238 |
-+ return -EFAULT; |
8239 |
-+} |
8240 |
- #endif |
8241 |
- |
8242 |
- extern int make_pages_present(unsigned long addr, unsigned long end); |
8243 |
-@@ -985,8 +995,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
8244 |
- int get_user_pages_fast(unsigned long start, int nr_pages, int write, |
8245 |
- struct page **pages); |
8246 |
- struct page *get_dump_page(unsigned long addr); |
8247 |
--extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, |
8248 |
-- unsigned long address, unsigned int fault_flags); |
8249 |
- |
8250 |
- extern int try_to_release_page(struct page * page, gfp_t gfp_mask); |
8251 |
- extern void do_invalidatepage(struct page *page, unsigned long offset); |
8252 |
-diff --git a/include/linux/random.h b/include/linux/random.h |
8253 |
-index fb7ab9d..d13059f 100644 |
8254 |
---- a/include/linux/random.h |
8255 |
-+++ b/include/linux/random.h |
8256 |
-@@ -57,17 +57,6 @@ extern void add_interrupt_randomness(int irq); |
8257 |
- extern void get_random_bytes(void *buf, int nbytes); |
8258 |
- void generate_random_uuid(unsigned char uuid_out[16]); |
8259 |
- |
8260 |
--extern __u32 secure_ip_id(__be32 daddr); |
8261 |
--extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); |
8262 |
--extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
8263 |
-- __be16 dport); |
8264 |
--extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, |
8265 |
-- __be16 sport, __be16 dport); |
8266 |
--extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
8267 |
-- __be16 sport, __be16 dport); |
8268 |
--extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, |
8269 |
-- __be16 sport, __be16 dport); |
8270 |
-- |
8271 |
- #ifndef MODULE |
8272 |
- extern const struct file_operations random_fops, urandom_fops; |
8273 |
- #endif |
8274 |
-diff --git a/include/net/ipv6.h b/include/net/ipv6.h |
8275 |
-index c033ed0..3b5ac1f 100644 |
8276 |
---- a/include/net/ipv6.h |
8277 |
-+++ b/include/net/ipv6.h |
8278 |
-@@ -463,17 +463,7 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add |
8279 |
- return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); |
8280 |
- } |
8281 |
- |
8282 |
--static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr) |
8283 |
--{ |
8284 |
-- static u32 ipv6_fragmentation_id = 1; |
8285 |
-- static DEFINE_SPINLOCK(ip6_id_lock); |
8286 |
-- |
8287 |
-- spin_lock_bh(&ip6_id_lock); |
8288 |
-- fhdr->identification = htonl(ipv6_fragmentation_id); |
8289 |
-- if (++ipv6_fragmentation_id == 0) |
8290 |
-- ipv6_fragmentation_id = 1; |
8291 |
-- spin_unlock_bh(&ip6_id_lock); |
8292 |
--} |
8293 |
-+extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); |
8294 |
- |
8295 |
- /* |
8296 |
- * Prototypes exported by ipv6 |
8297 |
-diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h |
8298 |
-new file mode 100644 |
8299 |
-index 0000000..d97f689 |
8300 |
---- /dev/null |
8301 |
-+++ b/include/net/secure_seq.h |
8302 |
-@@ -0,0 +1,20 @@ |
8303 |
-+#ifndef _NET_SECURE_SEQ |
8304 |
-+#define _NET_SECURE_SEQ |
8305 |
-+ |
8306 |
-+#include <linux/types.h> |
8307 |
-+ |
8308 |
-+extern __u32 secure_ip_id(__be32 daddr); |
8309 |
-+extern __u32 secure_ipv6_id(const __be32 daddr[4]); |
8310 |
-+extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); |
8311 |
-+extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
8312 |
-+ __be16 dport); |
8313 |
-+extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, |
8314 |
-+ __be16 sport, __be16 dport); |
8315 |
-+extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
8316 |
-+ __be16 sport, __be16 dport); |
8317 |
-+extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, |
8318 |
-+ __be16 sport, __be16 dport); |
8319 |
-+extern u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
8320 |
-+ __be16 sport, __be16 dport); |
8321 |
-+ |
8322 |
-+#endif /* _NET_SECURE_SEQ */ |
8323 |
-diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h |
8324 |
-index 5271a74..45ce307 100644 |
8325 |
---- a/include/net/transp_v6.h |
8326 |
-+++ b/include/net/transp_v6.h |
8327 |
-@@ -14,6 +14,8 @@ extern struct proto tcpv6_prot; |
8328 |
- |
8329 |
- struct flowi6; |
8330 |
- |
8331 |
-+extern void initialize_hashidentrnd(void); |
8332 |
-+ |
8333 |
- /* extension headers */ |
8334 |
- extern int ipv6_exthdrs_init(void); |
8335 |
- extern void ipv6_exthdrs_exit(void); |
8336 |
-diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h |
8337 |
-index 70213b4..6acd9ce 100644 |
8338 |
---- a/include/xen/interface/xen.h |
8339 |
-+++ b/include/xen/interface/xen.h |
8340 |
-@@ -450,6 +450,45 @@ struct start_info { |
8341 |
- int8_t cmd_line[MAX_GUEST_CMDLINE]; |
8342 |
- }; |
8343 |
- |
8344 |
-+struct dom0_vga_console_info { |
8345 |
-+ uint8_t video_type; |
8346 |
-+#define XEN_VGATYPE_TEXT_MODE_3 0x03 |
8347 |
-+#define XEN_VGATYPE_VESA_LFB 0x23 |
8348 |
-+ |
8349 |
-+ union { |
8350 |
-+ struct { |
8351 |
-+ /* Font height, in pixels. */ |
8352 |
-+ uint16_t font_height; |
8353 |
-+ /* Cursor location (column, row). */ |
8354 |
-+ uint16_t cursor_x, cursor_y; |
8355 |
-+ /* Number of rows and columns (dimensions in characters). */ |
8356 |
-+ uint16_t rows, columns; |
8357 |
-+ } text_mode_3; |
8358 |
-+ |
8359 |
-+ struct { |
8360 |
-+ /* Width and height, in pixels. */ |
8361 |
-+ uint16_t width, height; |
8362 |
-+ /* Bytes per scan line. */ |
8363 |
-+ uint16_t bytes_per_line; |
8364 |
-+ /* Bits per pixel. */ |
8365 |
-+ uint16_t bits_per_pixel; |
8366 |
-+ /* LFB physical address, and size (in units of 64kB). */ |
8367 |
-+ uint32_t lfb_base; |
8368 |
-+ uint32_t lfb_size; |
8369 |
-+ /* RGB mask offsets and sizes, as defined by VBE 1.2+ */ |
8370 |
-+ uint8_t red_pos, red_size; |
8371 |
-+ uint8_t green_pos, green_size; |
8372 |
-+ uint8_t blue_pos, blue_size; |
8373 |
-+ uint8_t rsvd_pos, rsvd_size; |
8374 |
-+ |
8375 |
-+ /* VESA capabilities (offset 0xa, VESA command 0x4f00). */ |
8376 |
-+ uint32_t gbl_caps; |
8377 |
-+ /* Mode attributes (offset 0x0, VESA command 0x4f01). */ |
8378 |
-+ uint16_t mode_attrs; |
8379 |
-+ } vesa_lfb; |
8380 |
-+ } u; |
8381 |
-+}; |
8382 |
-+ |
8383 |
- /* These flags are passed in the 'flags' field of start_info_t. */ |
8384 |
- #define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */ |
8385 |
- #define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ |
8386 |
-diff --git a/kernel/futex.c b/kernel/futex.c |
8387 |
-index 7a0a4ed..8b6da25 100644 |
8388 |
---- a/kernel/futex.c |
8389 |
-+++ b/kernel/futex.c |
8390 |
-@@ -218,6 +218,8 @@ static void drop_futex_key_refs(union futex_key *key) |
8391 |
- * @uaddr: virtual address of the futex |
8392 |
- * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED |
8393 |
- * @key: address where result is stored. |
8394 |
-+ * @rw: mapping needs to be read/write (values: VERIFY_READ, |
8395 |
-+ * VERIFY_WRITE) |
8396 |
- * |
8397 |
- * Returns a negative error code or 0 |
8398 |
- * The key words are stored in *key on success. |
8399 |
-@@ -229,12 +231,12 @@ static void drop_futex_key_refs(union futex_key *key) |
8400 |
- * lock_page() might sleep, the caller should not hold a spinlock. |
8401 |
- */ |
8402 |
- static int |
8403 |
--get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) |
8404 |
-+get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) |
8405 |
- { |
8406 |
- unsigned long address = (unsigned long)uaddr; |
8407 |
- struct mm_struct *mm = current->mm; |
8408 |
- struct page *page, *page_head; |
8409 |
-- int err; |
8410 |
-+ int err, ro = 0; |
8411 |
- |
8412 |
- /* |
8413 |
- * The futex address must be "naturally" aligned. |
8414 |
-@@ -262,8 +264,18 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) |
8415 |
- |
8416 |
- again: |
8417 |
- err = get_user_pages_fast(address, 1, 1, &page); |
8418 |
-+ /* |
8419 |
-+ * If write access is not required (eg. FUTEX_WAIT), try |
8420 |
-+ * and get read-only access. |
8421 |
-+ */ |
8422 |
-+ if (err == -EFAULT && rw == VERIFY_READ) { |
8423 |
-+ err = get_user_pages_fast(address, 1, 0, &page); |
8424 |
-+ ro = 1; |
8425 |
-+ } |
8426 |
- if (err < 0) |
8427 |
- return err; |
8428 |
-+ else |
8429 |
-+ err = 0; |
8430 |
- |
8431 |
- #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
8432 |
- page_head = page; |
8433 |
-@@ -305,6 +317,13 @@ again: |
8434 |
- if (!page_head->mapping) { |
8435 |
- unlock_page(page_head); |
8436 |
- put_page(page_head); |
8437 |
-+ /* |
8438 |
-+ * ZERO_PAGE pages don't have a mapping. Avoid a busy loop |
8439 |
-+ * trying to find one. RW mapping would have COW'd (and thus |
8440 |
-+ * have a mapping) so this page is RO and won't ever change. |
8441 |
-+ */ |
8442 |
-+ if ((page_head == ZERO_PAGE(address))) |
8443 |
-+ return -EFAULT; |
8444 |
- goto again; |
8445 |
- } |
8446 |
- |
8447 |
-@@ -316,6 +335,15 @@ again: |
8448 |
- * the object not the particular process. |
8449 |
- */ |
8450 |
- if (PageAnon(page_head)) { |
8451 |
-+ /* |
8452 |
-+ * A RO anonymous page will never change and thus doesn't make |
8453 |
-+ * sense for futex operations. |
8454 |
-+ */ |
8455 |
-+ if (ro) { |
8456 |
-+ err = -EFAULT; |
8457 |
-+ goto out; |
8458 |
-+ } |
8459 |
-+ |
8460 |
- key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ |
8461 |
- key->private.mm = mm; |
8462 |
- key->private.address = address; |
8463 |
-@@ -327,9 +355,10 @@ again: |
8464 |
- |
8465 |
- get_futex_key_refs(key); |
8466 |
- |
8467 |
-+out: |
8468 |
- unlock_page(page_head); |
8469 |
- put_page(page_head); |
8470 |
-- return 0; |
8471 |
-+ return err; |
8472 |
- } |
8473 |
- |
8474 |
- static inline void put_futex_key(union futex_key *key) |
8475 |
-@@ -940,7 +969,7 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) |
8476 |
- if (!bitset) |
8477 |
- return -EINVAL; |
8478 |
- |
8479 |
-- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); |
8480 |
-+ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_READ); |
8481 |
- if (unlikely(ret != 0)) |
8482 |
- goto out; |
8483 |
- |
8484 |
-@@ -986,10 +1015,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, |
8485 |
- int ret, op_ret; |
8486 |
- |
8487 |
- retry: |
8488 |
-- ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); |
8489 |
-+ ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ); |
8490 |
- if (unlikely(ret != 0)) |
8491 |
- goto out; |
8492 |
-- ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
8493 |
-+ ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); |
8494 |
- if (unlikely(ret != 0)) |
8495 |
- goto out_put_key1; |
8496 |
- |
8497 |
-@@ -1243,10 +1272,11 @@ retry: |
8498 |
- pi_state = NULL; |
8499 |
- } |
8500 |
- |
8501 |
-- ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); |
8502 |
-+ ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ); |
8503 |
- if (unlikely(ret != 0)) |
8504 |
- goto out; |
8505 |
-- ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
8506 |
-+ ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, |
8507 |
-+ requeue_pi ? VERIFY_WRITE : VERIFY_READ); |
8508 |
- if (unlikely(ret != 0)) |
8509 |
- goto out_put_key1; |
8510 |
- |
8511 |
-@@ -1790,7 +1820,7 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, |
8512 |
- * while the syscall executes. |
8513 |
- */ |
8514 |
- retry: |
8515 |
-- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); |
8516 |
-+ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key, VERIFY_READ); |
8517 |
- if (unlikely(ret != 0)) |
8518 |
- return ret; |
8519 |
- |
8520 |
-@@ -1941,7 +1971,7 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, int detect, |
8521 |
- } |
8522 |
- |
8523 |
- retry: |
8524 |
-- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key); |
8525 |
-+ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key, VERIFY_WRITE); |
8526 |
- if (unlikely(ret != 0)) |
8527 |
- goto out; |
8528 |
- |
8529 |
-@@ -2060,7 +2090,7 @@ retry: |
8530 |
- if ((uval & FUTEX_TID_MASK) != vpid) |
8531 |
- return -EPERM; |
8532 |
- |
8533 |
-- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); |
8534 |
-+ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_WRITE); |
8535 |
- if (unlikely(ret != 0)) |
8536 |
- goto out; |
8537 |
- |
8538 |
-@@ -2249,7 +2279,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, |
8539 |
- debug_rt_mutex_init_waiter(&rt_waiter); |
8540 |
- rt_waiter.task = NULL; |
8541 |
- |
8542 |
-- ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
8543 |
-+ ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); |
8544 |
- if (unlikely(ret != 0)) |
8545 |
- goto out; |
8546 |
- |
8547 |
-diff --git a/lib/Makefile b/lib/Makefile |
8548 |
-index 6b597fd..578414a 100644 |
8549 |
---- a/lib/Makefile |
8550 |
-+++ b/lib/Makefile |
8551 |
-@@ -10,7 +10,7 @@ endif |
8552 |
- lib-y := ctype.o string.o vsprintf.o cmdline.o \ |
8553 |
- rbtree.o radix-tree.o dump_stack.o timerqueue.o\ |
8554 |
- idr.o int_sqrt.o extable.o prio_tree.o \ |
8555 |
-- sha1.o irq_regs.o reciprocal_div.o argv_split.o \ |
8556 |
-+ sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ |
8557 |
- proportions.o prio_heap.o ratelimit.o show_mem.o \ |
8558 |
- is_single_threaded.o plist.o decompress.o find_next_bit.o |
8559 |
- |
8560 |
-diff --git a/lib/md5.c b/lib/md5.c |
8561 |
-new file mode 100644 |
8562 |
-index 0000000..c777180 |
8563 |
---- /dev/null |
8564 |
-+++ b/lib/md5.c |
8565 |
-@@ -0,0 +1,95 @@ |
8566 |
-+#include <linux/kernel.h> |
8567 |
-+#include <linux/module.h> |
8568 |
-+#include <linux/cryptohash.h> |
8569 |
-+ |
8570 |
-+#define F1(x, y, z) (z ^ (x & (y ^ z))) |
8571 |
-+#define F2(x, y, z) F1(z, x, y) |
8572 |
-+#define F3(x, y, z) (x ^ y ^ z) |
8573 |
-+#define F4(x, y, z) (y ^ (x | ~z)) |
8574 |
-+ |
8575 |
-+#define MD5STEP(f, w, x, y, z, in, s) \ |
8576 |
-+ (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) |
8577 |
-+ |
8578 |
-+void md5_transform(__u32 *hash, __u32 const *in) |
8579 |
-+{ |
8580 |
-+ u32 a, b, c, d; |
8581 |
-+ |
8582 |
-+ a = hash[0]; |
8583 |
-+ b = hash[1]; |
8584 |
-+ c = hash[2]; |
8585 |
-+ d = hash[3]; |
8586 |
-+ |
8587 |
-+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); |
8588 |
-+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); |
8589 |
-+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); |
8590 |
-+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); |
8591 |
-+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); |
8592 |
-+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); |
8593 |
-+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); |
8594 |
-+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); |
8595 |
-+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); |
8596 |
-+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); |
8597 |
-+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); |
8598 |
-+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); |
8599 |
-+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); |
8600 |
-+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); |
8601 |
-+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); |
8602 |
-+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); |
8603 |
-+ |
8604 |
-+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); |
8605 |
-+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); |
8606 |
-+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); |
8607 |
-+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); |
8608 |
-+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); |
8609 |
-+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); |
8610 |
-+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); |
8611 |
-+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); |
8612 |
-+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); |
8613 |
-+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); |
8614 |
-+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); |
8615 |
-+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); |
8616 |
-+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); |
8617 |
-+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); |
8618 |
-+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); |
8619 |
-+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); |
8620 |
-+ |
8621 |
-+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); |
8622 |
-+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); |
8623 |
-+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); |
8624 |
-+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); |
8625 |
-+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); |
8626 |
-+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); |
8627 |
-+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); |
8628 |
-+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); |
8629 |
-+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); |
8630 |
-+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); |
8631 |
-+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); |
8632 |
-+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); |
8633 |
-+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); |
8634 |
-+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); |
8635 |
-+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); |
8636 |
-+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); |
8637 |
-+ |
8638 |
-+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); |
8639 |
-+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); |
8640 |
-+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); |
8641 |
-+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); |
8642 |
-+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); |
8643 |
-+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); |
8644 |
-+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); |
8645 |
-+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); |
8646 |
-+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); |
8647 |
-+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); |
8648 |
-+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); |
8649 |
-+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); |
8650 |
-+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); |
8651 |
-+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); |
8652 |
-+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); |
8653 |
-+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); |
8654 |
-+ |
8655 |
-+ hash[0] += a; |
8656 |
-+ hash[1] += b; |
8657 |
-+ hash[2] += c; |
8658 |
-+ hash[3] += d; |
8659 |
-+} |
8660 |
-+EXPORT_SYMBOL(md5_transform); |
8661 |
-diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c |
8662 |
-index 6e82148..5b4f51d 100644 |
8663 |
---- a/net/8021q/vlan_dev.c |
8664 |
-+++ b/net/8021q/vlan_dev.c |
8665 |
-@@ -694,7 +694,7 @@ void vlan_setup(struct net_device *dev) |
8666 |
- ether_setup(dev); |
8667 |
- |
8668 |
- dev->priv_flags |= IFF_802_1Q_VLAN; |
8669 |
-- dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; |
8670 |
-+ dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
8671 |
- dev->tx_queue_len = 0; |
8672 |
- |
8673 |
- dev->netdev_ops = &vlan_netdev_ops; |
8674 |
-diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c |
8675 |
-index 8c100c9..d4f5dff 100644 |
8676 |
---- a/net/bluetooth/bnep/netdev.c |
8677 |
-+++ b/net/bluetooth/bnep/netdev.c |
8678 |
-@@ -231,6 +231,7 @@ void bnep_net_setup(struct net_device *dev) |
8679 |
- dev->addr_len = ETH_ALEN; |
8680 |
- |
8681 |
- ether_setup(dev); |
8682 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
8683 |
- dev->netdev_ops = &bnep_netdev_ops; |
8684 |
- |
8685 |
- dev->watchdog_timeo = HZ * 2; |
8686 |
-diff --git a/net/core/Makefile b/net/core/Makefile |
8687 |
-index 8a04dd2..0d357b1 100644 |
8688 |
---- a/net/core/Makefile |
8689 |
-+++ b/net/core/Makefile |
8690 |
-@@ -3,7 +3,7 @@ |
8691 |
- # |
8692 |
- |
8693 |
- obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ |
8694 |
-- gen_stats.o gen_estimator.o net_namespace.o |
8695 |
-+ gen_stats.o gen_estimator.o net_namespace.o secure_seq.o |
8696 |
- |
8697 |
- obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
8698 |
- |
8699 |
-diff --git a/net/core/link_watch.c b/net/core/link_watch.c |
8700 |
-index a7b3421..357bd4e 100644 |
8701 |
---- a/net/core/link_watch.c |
8702 |
-+++ b/net/core/link_watch.c |
8703 |
-@@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent) |
8704 |
- return; |
8705 |
- |
8706 |
- /* It's already running which is good enough. */ |
8707 |
-- if (!cancel_delayed_work(&linkwatch_work)) |
8708 |
-+ if (!__cancel_delayed_work(&linkwatch_work)) |
8709 |
- return; |
8710 |
- |
8711 |
- /* Otherwise we reschedule it again for immediate execution. */ |
8712 |
-diff --git a/net/core/pktgen.c b/net/core/pktgen.c |
8713 |
-index f76079c..e35a6fb 100644 |
8714 |
---- a/net/core/pktgen.c |
8715 |
-+++ b/net/core/pktgen.c |
8716 |
-@@ -1070,7 +1070,9 @@ static ssize_t pktgen_if_write(struct file *file, |
8717 |
- len = num_arg(&user_buffer[i], 10, &value); |
8718 |
- if (len < 0) |
8719 |
- return len; |
8720 |
-- |
8721 |
-+ if ((value > 0) && |
8722 |
-+ (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) |
8723 |
-+ return -ENOTSUPP; |
8724 |
- i += len; |
8725 |
- pkt_dev->clone_skb = value; |
8726 |
- |
8727 |
-@@ -3555,7 +3557,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) |
8728 |
- pkt_dev->min_pkt_size = ETH_ZLEN; |
8729 |
- pkt_dev->max_pkt_size = ETH_ZLEN; |
8730 |
- pkt_dev->nfrags = 0; |
8731 |
-- pkt_dev->clone_skb = pg_clone_skb_d; |
8732 |
- pkt_dev->delay = pg_delay_d; |
8733 |
- pkt_dev->count = pg_count_d; |
8734 |
- pkt_dev->sofar = 0; |
8735 |
-@@ -3563,7 +3564,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) |
8736 |
- pkt_dev->udp_src_max = 9; |
8737 |
- pkt_dev->udp_dst_min = 9; |
8738 |
- pkt_dev->udp_dst_max = 9; |
8739 |
-- |
8740 |
- pkt_dev->vlan_p = 0; |
8741 |
- pkt_dev->vlan_cfi = 0; |
8742 |
- pkt_dev->vlan_id = 0xffff; |
8743 |
-@@ -3575,6 +3575,8 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) |
8744 |
- err = pktgen_setup_dev(pkt_dev, ifname); |
8745 |
- if (err) |
8746 |
- goto out1; |
8747 |
-+ if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING) |
8748 |
-+ pkt_dev->clone_skb = pg_clone_skb_d; |
8749 |
- |
8750 |
- pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, |
8751 |
- &pktgen_if_fops, pkt_dev); |
8752 |
-diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c |
8753 |
-new file mode 100644 |
8754 |
-index 0000000..45329d7 |
8755 |
---- /dev/null |
8756 |
-+++ b/net/core/secure_seq.c |
8757 |
-@@ -0,0 +1,184 @@ |
8758 |
-+#include <linux/kernel.h> |
8759 |
-+#include <linux/init.h> |
8760 |
-+#include <linux/cryptohash.h> |
8761 |
-+#include <linux/module.h> |
8762 |
-+#include <linux/cache.h> |
8763 |
-+#include <linux/random.h> |
8764 |
-+#include <linux/hrtimer.h> |
8765 |
-+#include <linux/ktime.h> |
8766 |
-+#include <linux/string.h> |
8767 |
-+ |
8768 |
-+#include <net/secure_seq.h> |
8769 |
-+ |
8770 |
-+static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; |
8771 |
-+ |
8772 |
-+static int __init net_secret_init(void) |
8773 |
-+{ |
8774 |
-+ get_random_bytes(net_secret, sizeof(net_secret)); |
8775 |
-+ return 0; |
8776 |
-+} |
8777 |
-+late_initcall(net_secret_init); |
8778 |
-+ |
8779 |
-+static u32 seq_scale(u32 seq) |
8780 |
-+{ |
8781 |
-+ /* |
8782 |
-+ * As close as possible to RFC 793, which |
8783 |
-+ * suggests using a 250 kHz clock. |
8784 |
-+ * Further reading shows this assumes 2 Mb/s networks. |
8785 |
-+ * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. |
8786 |
-+ * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but |
8787 |
-+ * we also need to limit the resolution so that the u32 seq |
8788 |
-+ * overlaps less than one time per MSL (2 minutes). |
8789 |
-+ * Choosing a clock of 64 ns period is OK. (period of 274 s) |
8790 |
-+ */ |
8791 |
-+ return seq + (ktime_to_ns(ktime_get_real()) >> 6); |
8792 |
-+} |
8793 |
-+ |
8794 |
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
8795 |
-+__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
8796 |
-+ __be16 sport, __be16 dport) |
8797 |
-+{ |
8798 |
-+ u32 secret[MD5_MESSAGE_BYTES / 4]; |
8799 |
-+ u32 hash[MD5_DIGEST_WORDS]; |
8800 |
-+ u32 i; |
8801 |
-+ |
8802 |
-+ memcpy(hash, saddr, 16); |
8803 |
-+ for (i = 0; i < 4; i++) |
8804 |
-+ secret[i] = net_secret[i] + daddr[i]; |
8805 |
-+ secret[4] = net_secret[4] + |
8806 |
-+ (((__force u16)sport << 16) + (__force u16)dport); |
8807 |
-+ for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) |
8808 |
-+ secret[i] = net_secret[i]; |
8809 |
-+ |
8810 |
-+ md5_transform(hash, secret); |
8811 |
-+ |
8812 |
-+ return seq_scale(hash[0]); |
8813 |
-+} |
8814 |
-+EXPORT_SYMBOL(secure_tcpv6_sequence_number); |
8815 |
-+ |
8816 |
-+u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
8817 |
-+ __be16 dport) |
8818 |
-+{ |
8819 |
-+ u32 secret[MD5_MESSAGE_BYTES / 4]; |
8820 |
-+ u32 hash[MD5_DIGEST_WORDS]; |
8821 |
-+ u32 i; |
8822 |
-+ |
8823 |
-+ memcpy(hash, saddr, 16); |
8824 |
-+ for (i = 0; i < 4; i++) |
8825 |
-+ secret[i] = net_secret[i] + (__force u32) daddr[i]; |
8826 |
-+ secret[4] = net_secret[4] + (__force u32)dport; |
8827 |
-+ for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) |
8828 |
-+ secret[i] = net_secret[i]; |
8829 |
-+ |
8830 |
-+ md5_transform(hash, secret); |
8831 |
-+ |
8832 |
-+ return hash[0]; |
8833 |
-+} |
8834 |
-+#endif |
8835 |
-+ |
8836 |
-+#ifdef CONFIG_INET |
8837 |
-+__u32 secure_ip_id(__be32 daddr) |
8838 |
-+{ |
8839 |
-+ u32 hash[MD5_DIGEST_WORDS]; |
8840 |
-+ |
8841 |
-+ hash[0] = (__force __u32) daddr; |
8842 |
-+ hash[1] = net_secret[13]; |
8843 |
-+ hash[2] = net_secret[14]; |
8844 |
-+ hash[3] = net_secret[15]; |
8845 |
-+ |
8846 |
-+ md5_transform(hash, net_secret); |
8847 |
-+ |
8848 |
-+ return hash[0]; |
8849 |
-+} |
8850 |
-+ |
8851 |
-+__u32 secure_ipv6_id(const __be32 daddr[4]) |
8852 |
-+{ |
8853 |
-+ __u32 hash[4]; |
8854 |
-+ |
8855 |
-+ memcpy(hash, daddr, 16); |
8856 |
-+ md5_transform(hash, net_secret); |
8857 |
-+ |
8858 |
-+ return hash[0]; |
8859 |
-+} |
8860 |
-+ |
8861 |
-+__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, |
8862 |
-+ __be16 sport, __be16 dport) |
8863 |
-+{ |
8864 |
-+ u32 hash[MD5_DIGEST_WORDS]; |
8865 |
-+ |
8866 |
-+ hash[0] = (__force u32)saddr; |
8867 |
-+ hash[1] = (__force u32)daddr; |
8868 |
-+ hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
8869 |
-+ hash[3] = net_secret[15]; |
8870 |
-+ |
8871 |
-+ md5_transform(hash, net_secret); |
8872 |
-+ |
8873 |
-+ return seq_scale(hash[0]); |
8874 |
-+} |
8875 |
-+ |
8876 |
-+u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) |
8877 |
-+{ |
8878 |
-+ u32 hash[MD5_DIGEST_WORDS]; |
8879 |
-+ |
8880 |
-+ hash[0] = (__force u32)saddr; |
8881 |
-+ hash[1] = (__force u32)daddr; |
8882 |
-+ hash[2] = (__force u32)dport ^ net_secret[14]; |
8883 |
-+ hash[3] = net_secret[15]; |
8884 |
-+ |
8885 |
-+ md5_transform(hash, net_secret); |
8886 |
-+ |
8887 |
-+ return hash[0]; |
8888 |
-+} |
8889 |
-+EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); |
8890 |
-+#endif |
8891 |
-+ |
8892 |
-+#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) |
8893 |
-+u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, |
8894 |
-+ __be16 sport, __be16 dport) |
8895 |
-+{ |
8896 |
-+ u32 hash[MD5_DIGEST_WORDS]; |
8897 |
-+ u64 seq; |
8898 |
-+ |
8899 |
-+ hash[0] = (__force u32)saddr; |
8900 |
-+ hash[1] = (__force u32)daddr; |
8901 |
-+ hash[2] = ((__force u16)sport << 16) + (__force u16)dport; |
8902 |
-+ hash[3] = net_secret[15]; |
8903 |
-+ |
8904 |
-+ md5_transform(hash, net_secret); |
8905 |
-+ |
8906 |
-+ seq = hash[0] | (((u64)hash[1]) << 32); |
8907 |
-+ seq += ktime_to_ns(ktime_get_real()); |
8908 |
-+ seq &= (1ull << 48) - 1; |
8909 |
-+ |
8910 |
-+ return seq; |
8911 |
-+} |
8912 |
-+EXPORT_SYMBOL(secure_dccp_sequence_number); |
8913 |
-+ |
8914 |
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
8915 |
-+u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
8916 |
-+ __be16 sport, __be16 dport) |
8917 |
-+{ |
8918 |
-+ u32 secret[MD5_MESSAGE_BYTES / 4]; |
8919 |
-+ u32 hash[MD5_DIGEST_WORDS]; |
8920 |
-+ u64 seq; |
8921 |
-+ u32 i; |
8922 |
-+ |
8923 |
-+ memcpy(hash, saddr, 16); |
8924 |
-+ for (i = 0; i < 4; i++) |
8925 |
-+ secret[i] = net_secret[i] + daddr[i]; |
8926 |
-+ secret[4] = net_secret[4] + |
8927 |
-+ (((__force u16)sport << 16) + (__force u16)dport); |
8928 |
-+ for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) |
8929 |
-+ secret[i] = net_secret[i]; |
8930 |
-+ |
8931 |
-+ md5_transform(hash, secret); |
8932 |
-+ |
8933 |
-+ seq = hash[0] | (((u64)hash[1]) << 32); |
8934 |
-+ seq += ktime_to_ns(ktime_get_real()); |
8935 |
-+ seq &= (1ull << 48) - 1; |
8936 |
-+ |
8937 |
-+ return seq; |
8938 |
-+} |
8939 |
-+EXPORT_SYMBOL(secure_dccpv6_sequence_number); |
8940 |
-+#endif |
8941 |
-+#endif |
8942 |
-diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c |
8943 |
-index 8c36adf..332639b 100644 |
8944 |
---- a/net/dccp/ipv4.c |
8945 |
-+++ b/net/dccp/ipv4.c |
8946 |
-@@ -26,6 +26,7 @@ |
8947 |
- #include <net/timewait_sock.h> |
8948 |
- #include <net/tcp_states.h> |
8949 |
- #include <net/xfrm.h> |
8950 |
-+#include <net/secure_seq.h> |
8951 |
- |
8952 |
- #include "ackvec.h" |
8953 |
- #include "ccid.h" |
8954 |
-diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c |
8955 |
-index 8dc4348..b74f761 100644 |
8956 |
---- a/net/dccp/ipv6.c |
8957 |
-+++ b/net/dccp/ipv6.c |
8958 |
-@@ -29,6 +29,7 @@ |
8959 |
- #include <net/transp_v6.h> |
8960 |
- #include <net/ip6_checksum.h> |
8961 |
- #include <net/xfrm.h> |
8962 |
-+#include <net/secure_seq.h> |
8963 |
- |
8964 |
- #include "dccp.h" |
8965 |
- #include "ipv6.h" |
8966 |
-@@ -69,13 +70,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) |
8967 |
- dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); |
8968 |
- } |
8969 |
- |
8970 |
--static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, |
8971 |
-- __be16 sport, __be16 dport ) |
8972 |
--{ |
8973 |
-- return secure_tcpv6_sequence_number(saddr, daddr, sport, dport); |
8974 |
--} |
8975 |
-- |
8976 |
--static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb) |
8977 |
-+static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) |
8978 |
- { |
8979 |
- return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, |
8980 |
- ipv6_hdr(skb)->saddr.s6_addr32, |
8981 |
-diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c |
8982 |
-index 44d2b42..2780e9b 100644 |
8983 |
---- a/net/ethernet/eth.c |
8984 |
-+++ b/net/ethernet/eth.c |
8985 |
-@@ -340,6 +340,7 @@ void ether_setup(struct net_device *dev) |
8986 |
- dev->addr_len = ETH_ALEN; |
8987 |
- dev->tx_queue_len = 1000; /* Ethernet wants good queues */ |
8988 |
- dev->flags = IFF_BROADCAST|IFF_MULTICAST; |
8989 |
-+ dev->priv_flags = IFF_TX_SKB_SHARING; |
8990 |
- |
8991 |
- memset(dev->broadcast, 0xFF, ETH_ALEN); |
8992 |
- |
8993 |
-diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c |
8994 |
-index 0d4a184..4155abc 100644 |
8995 |
---- a/net/ipv4/devinet.c |
8996 |
-+++ b/net/ipv4/devinet.c |
8997 |
-@@ -1134,15 +1134,15 @@ static void inetdev_send_gratuitous_arp(struct net_device *dev, |
8998 |
- struct in_device *in_dev) |
8999 |
- |
9000 |
- { |
9001 |
-- struct in_ifaddr *ifa = in_dev->ifa_list; |
9002 |
-- |
9003 |
-- if (!ifa) |
9004 |
-- return; |
9005 |
-+ struct in_ifaddr *ifa; |
9006 |
- |
9007 |
-- arp_send(ARPOP_REQUEST, ETH_P_ARP, |
9008 |
-- ifa->ifa_local, dev, |
9009 |
-- ifa->ifa_local, NULL, |
9010 |
-- dev->dev_addr, NULL); |
9011 |
-+ for (ifa = in_dev->ifa_list; ifa; |
9012 |
-+ ifa = ifa->ifa_next) { |
9013 |
-+ arp_send(ARPOP_REQUEST, ETH_P_ARP, |
9014 |
-+ ifa->ifa_local, dev, |
9015 |
-+ ifa->ifa_local, NULL, |
9016 |
-+ dev->dev_addr, NULL); |
9017 |
-+ } |
9018 |
- } |
9019 |
- |
9020 |
- /* Called only under RTNL semaphore */ |
9021 |
-diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c |
9022 |
-index c6933f2..3e3f75d 100644 |
9023 |
---- a/net/ipv4/gre.c |
9024 |
-+++ b/net/ipv4/gre.c |
9025 |
-@@ -15,6 +15,7 @@ |
9026 |
- #include <linux/kmod.h> |
9027 |
- #include <linux/skbuff.h> |
9028 |
- #include <linux/in.h> |
9029 |
-+#include <linux/ip.h> |
9030 |
- #include <linux/netdevice.h> |
9031 |
- #include <linux/version.h> |
9032 |
- #include <linux/spinlock.h> |
9033 |
-@@ -97,27 +98,17 @@ drop: |
9034 |
- static void gre_err(struct sk_buff *skb, u32 info) |
9035 |
- { |
9036 |
- const struct gre_protocol *proto; |
9037 |
-- u8 ver; |
9038 |
-- |
9039 |
-- if (!pskb_may_pull(skb, 12)) |
9040 |
-- goto drop; |
9041 |
-+ const struct iphdr *iph = (const struct iphdr *)skb->data; |
9042 |
-+ u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f; |
9043 |
- |
9044 |
-- ver = skb->data[1]&0x7f; |
9045 |
- if (ver >= GREPROTO_MAX) |
9046 |
-- goto drop; |
9047 |
-+ return; |
9048 |
- |
9049 |
- rcu_read_lock(); |
9050 |
- proto = rcu_dereference(gre_proto[ver]); |
9051 |
-- if (!proto || !proto->err_handler) |
9052 |
-- goto drop_unlock; |
9053 |
-- proto->err_handler(skb, info); |
9054 |
-- rcu_read_unlock(); |
9055 |
-- return; |
9056 |
-- |
9057 |
--drop_unlock: |
9058 |
-+ if (proto && proto->err_handler) |
9059 |
-+ proto->err_handler(skb, info); |
9060 |
- rcu_read_unlock(); |
9061 |
--drop: |
9062 |
-- kfree_skb(skb); |
9063 |
- } |
9064 |
- |
9065 |
- static const struct net_protocol net_gre_protocol = { |
9066 |
-diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c |
9067 |
-index 5395e45..23ef31b 100644 |
9068 |
---- a/net/ipv4/icmp.c |
9069 |
-+++ b/net/ipv4/icmp.c |
9070 |
-@@ -380,6 +380,7 @@ static struct rtable *icmp_route_lookup(struct net *net, |
9071 |
- struct icmp_bxm *param) |
9072 |
- { |
9073 |
- struct rtable *rt, *rt2; |
9074 |
-+ struct flowi4 fl4_dec; |
9075 |
- int err; |
9076 |
- |
9077 |
- memset(fl4, 0, sizeof(*fl4)); |
9078 |
-@@ -408,19 +409,19 @@ static struct rtable *icmp_route_lookup(struct net *net, |
9079 |
- } else |
9080 |
- return rt; |
9081 |
- |
9082 |
-- err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(fl4), AF_INET); |
9083 |
-+ err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4_dec), AF_INET); |
9084 |
- if (err) |
9085 |
- goto relookup_failed; |
9086 |
- |
9087 |
-- if (inet_addr_type(net, fl4->saddr) == RTN_LOCAL) { |
9088 |
-- rt2 = __ip_route_output_key(net, fl4); |
9089 |
-+ if (inet_addr_type(net, fl4_dec.saddr) == RTN_LOCAL) { |
9090 |
-+ rt2 = __ip_route_output_key(net, &fl4_dec); |
9091 |
- if (IS_ERR(rt2)) |
9092 |
- err = PTR_ERR(rt2); |
9093 |
- } else { |
9094 |
- struct flowi4 fl4_2 = {}; |
9095 |
- unsigned long orefdst; |
9096 |
- |
9097 |
-- fl4_2.daddr = fl4->saddr; |
9098 |
-+ fl4_2.daddr = fl4_dec.saddr; |
9099 |
- rt2 = ip_route_output_key(net, &fl4_2); |
9100 |
- if (IS_ERR(rt2)) { |
9101 |
- err = PTR_ERR(rt2); |
9102 |
-@@ -428,7 +429,7 @@ static struct rtable *icmp_route_lookup(struct net *net, |
9103 |
- } |
9104 |
- /* Ugh! */ |
9105 |
- orefdst = skb_in->_skb_refdst; /* save old refdst */ |
9106 |
-- err = ip_route_input(skb_in, fl4->daddr, fl4->saddr, |
9107 |
-+ err = ip_route_input(skb_in, fl4_dec.daddr, fl4_dec.saddr, |
9108 |
- RT_TOS(tos), rt2->dst.dev); |
9109 |
- |
9110 |
- dst_release(&rt2->dst); |
9111 |
-@@ -440,10 +441,11 @@ static struct rtable *icmp_route_lookup(struct net *net, |
9112 |
- goto relookup_failed; |
9113 |
- |
9114 |
- rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst, |
9115 |
-- flowi4_to_flowi(fl4), NULL, |
9116 |
-+ flowi4_to_flowi(&fl4_dec), NULL, |
9117 |
- XFRM_LOOKUP_ICMP); |
9118 |
- if (!IS_ERR(rt2)) { |
9119 |
- dst_release(&rt->dst); |
9120 |
-+ memcpy(fl4, &fl4_dec, sizeof(*fl4)); |
9121 |
- rt = rt2; |
9122 |
- } else if (PTR_ERR(rt2) == -EPERM) { |
9123 |
- if (rt) |
9124 |
-diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c |
9125 |
-index f1d27f6..283c0a2 100644 |
9126 |
---- a/net/ipv4/igmp.c |
9127 |
-+++ b/net/ipv4/igmp.c |
9128 |
-@@ -1718,7 +1718,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, |
9129 |
- |
9130 |
- pmc->sfcount[sfmode]--; |
9131 |
- for (j=0; j<i; j++) |
9132 |
-- (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); |
9133 |
-+ (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]); |
9134 |
- } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { |
9135 |
- #ifdef CONFIG_IP_MULTICAST |
9136 |
- struct ip_sf_list *psf; |
9137 |
-diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c |
9138 |
-index 3c0369a..984ec65 100644 |
9139 |
---- a/net/ipv4/inet_hashtables.c |
9140 |
-+++ b/net/ipv4/inet_hashtables.c |
9141 |
-@@ -21,6 +21,7 @@ |
9142 |
- |
9143 |
- #include <net/inet_connection_sock.h> |
9144 |
- #include <net/inet_hashtables.h> |
9145 |
-+#include <net/secure_seq.h> |
9146 |
- #include <net/ip.h> |
9147 |
- |
9148 |
- /* |
9149 |
-diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c |
9150 |
-index ce616d9..6877645 100644 |
9151 |
---- a/net/ipv4/inetpeer.c |
9152 |
-+++ b/net/ipv4/inetpeer.c |
9153 |
-@@ -19,6 +19,7 @@ |
9154 |
- #include <linux/net.h> |
9155 |
- #include <net/ip.h> |
9156 |
- #include <net/inetpeer.h> |
9157 |
-+#include <net/secure_seq.h> |
9158 |
- |
9159 |
- /* |
9160 |
- * Theory of operations. |
9161 |
-diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c |
9162 |
-index 84f26e8..0c99db4 100644 |
9163 |
---- a/net/ipv4/ip_output.c |
9164 |
-+++ b/net/ipv4/ip_output.c |
9165 |
-@@ -734,7 +734,7 @@ static inline int ip_ufo_append_data(struct sock *sk, |
9166 |
- int getfrag(void *from, char *to, int offset, int len, |
9167 |
- int odd, struct sk_buff *skb), |
9168 |
- void *from, int length, int hh_len, int fragheaderlen, |
9169 |
-- int transhdrlen, int mtu, unsigned int flags) |
9170 |
-+ int transhdrlen, int maxfraglen, unsigned int flags) |
9171 |
- { |
9172 |
- struct sk_buff *skb; |
9173 |
- int err; |
9174 |
-@@ -767,7 +767,7 @@ static inline int ip_ufo_append_data(struct sock *sk, |
9175 |
- skb->csum = 0; |
9176 |
- |
9177 |
- /* specify the length of each IP datagram fragment */ |
9178 |
-- skb_shinfo(skb)->gso_size = mtu - fragheaderlen; |
9179 |
-+ skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen; |
9180 |
- skb_shinfo(skb)->gso_type = SKB_GSO_UDP; |
9181 |
- __skb_queue_tail(queue, skb); |
9182 |
- } |
9183 |
-@@ -831,7 +831,7 @@ static int __ip_append_data(struct sock *sk, |
9184 |
- (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { |
9185 |
- err = ip_ufo_append_data(sk, queue, getfrag, from, length, |
9186 |
- hh_len, fragheaderlen, transhdrlen, |
9187 |
-- mtu, flags); |
9188 |
-+ maxfraglen, flags); |
9189 |
- if (err) |
9190 |
- goto error; |
9191 |
- return 0; |
9192 |
-diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c |
9193 |
-index 30a7763..f81af8d 100644 |
9194 |
---- a/net/ipv4/ipmr.c |
9195 |
-+++ b/net/ipv4/ipmr.c |
9196 |
-@@ -1796,7 +1796,7 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb) |
9197 |
- struct flowi4 fl4 = { |
9198 |
- .daddr = iph->daddr, |
9199 |
- .saddr = iph->saddr, |
9200 |
-- .flowi4_tos = iph->tos, |
9201 |
-+ .flowi4_tos = RT_TOS(iph->tos), |
9202 |
- .flowi4_oif = rt->rt_oif, |
9203 |
- .flowi4_iif = rt->rt_iif, |
9204 |
- .flowi4_mark = rt->rt_mark, |
9205 |
-diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c |
9206 |
-index 3e61faf..f52d41e 100644 |
9207 |
---- a/net/ipv4/netfilter/nf_nat_proto_common.c |
9208 |
-+++ b/net/ipv4/netfilter/nf_nat_proto_common.c |
9209 |
-@@ -12,6 +12,7 @@ |
9210 |
- #include <linux/ip.h> |
9211 |
- |
9212 |
- #include <linux/netfilter.h> |
9213 |
-+#include <net/secure_seq.h> |
9214 |
- #include <net/netfilter/nf_nat.h> |
9215 |
- #include <net/netfilter/nf_nat_core.h> |
9216 |
- #include <net/netfilter/nf_nat_rule.h> |
9217 |
-diff --git a/net/ipv4/route.c b/net/ipv4/route.c |
9218 |
-index aa13ef1..cdabdbf 100644 |
9219 |
---- a/net/ipv4/route.c |
9220 |
-+++ b/net/ipv4/route.c |
9221 |
-@@ -108,6 +108,7 @@ |
9222 |
- #ifdef CONFIG_SYSCTL |
9223 |
- #include <linux/sysctl.h> |
9224 |
- #endif |
9225 |
-+#include <net/secure_seq.h> |
9226 |
- |
9227 |
- #define RT_FL_TOS(oldflp4) \ |
9228 |
- ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) |
9229 |
-@@ -725,6 +726,7 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) |
9230 |
- ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
9231 |
- (rt1->rt_mark ^ rt2->rt_mark) | |
9232 |
- (rt1->rt_key_tos ^ rt2->rt_key_tos) | |
9233 |
-+ (rt1->rt_route_iif ^ rt2->rt_route_iif) | |
9234 |
- (rt1->rt_oif ^ rt2->rt_oif) | |
9235 |
- (rt1->rt_iif ^ rt2->rt_iif)) == 0; |
9236 |
- } |
9237 |
-@@ -1703,7 +1705,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt) |
9238 |
- memset(&fl4, 0, sizeof(fl4)); |
9239 |
- fl4.daddr = iph->daddr; |
9240 |
- fl4.saddr = iph->saddr; |
9241 |
-- fl4.flowi4_tos = iph->tos; |
9242 |
-+ fl4.flowi4_tos = RT_TOS(iph->tos); |
9243 |
- fl4.flowi4_oif = rt->dst.dev->ifindex; |
9244 |
- fl4.flowi4_iif = skb->dev->ifindex; |
9245 |
- fl4.flowi4_mark = skb->mark; |
9246 |
-@@ -2281,8 +2283,8 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, |
9247 |
- if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | |
9248 |
- ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | |
9249 |
- (rth->rt_iif ^ iif) | |
9250 |
-- rth->rt_oif | |
9251 |
- (rth->rt_key_tos ^ tos)) == 0 && |
9252 |
-+ rt_is_input_route(rth) && |
9253 |
- rth->rt_mark == skb->mark && |
9254 |
- net_eq(dev_net(rth->dst.dev), net) && |
9255 |
- !rt_is_expired(rth)) { |
9256 |
-diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
9257 |
-index 708dc20..b3e6956 100644 |
9258 |
---- a/net/ipv4/tcp_ipv4.c |
9259 |
-+++ b/net/ipv4/tcp_ipv4.c |
9260 |
-@@ -72,6 +72,7 @@ |
9261 |
- #include <net/timewait_sock.h> |
9262 |
- #include <net/xfrm.h> |
9263 |
- #include <net/netdma.h> |
9264 |
-+#include <net/secure_seq.h> |
9265 |
- |
9266 |
- #include <linux/inet.h> |
9267 |
- #include <linux/ipv6.h> |
9268 |
-diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c |
9269 |
-index 3b5669a..5591236 100644 |
9270 |
---- a/net/ipv6/af_inet6.c |
9271 |
-+++ b/net/ipv6/af_inet6.c |
9272 |
-@@ -1078,6 +1078,8 @@ static int __init inet6_init(void) |
9273 |
- goto out; |
9274 |
- } |
9275 |
- |
9276 |
-+ initialize_hashidentrnd(); |
9277 |
-+ |
9278 |
- err = proto_register(&tcpv6_prot, 1); |
9279 |
- if (err) |
9280 |
- goto out; |
9281 |
-diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c |
9282 |
-index b531972..73f1a00 100644 |
9283 |
---- a/net/ipv6/inet6_hashtables.c |
9284 |
-+++ b/net/ipv6/inet6_hashtables.c |
9285 |
-@@ -20,6 +20,7 @@ |
9286 |
- #include <net/inet_connection_sock.h> |
9287 |
- #include <net/inet_hashtables.h> |
9288 |
- #include <net/inet6_hashtables.h> |
9289 |
-+#include <net/secure_seq.h> |
9290 |
- #include <net/ip.h> |
9291 |
- |
9292 |
- int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) |
9293 |
-diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
9294 |
-index 9d4b165..1661296 100644 |
9295 |
---- a/net/ipv6/ip6_output.c |
9296 |
-+++ b/net/ipv6/ip6_output.c |
9297 |
-@@ -596,6 +596,35 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) |
9298 |
- return offset; |
9299 |
- } |
9300 |
- |
9301 |
-+static u32 hashidentrnd __read_mostly; |
9302 |
-+#define FID_HASH_SZ 16 |
9303 |
-+static u32 ipv6_fragmentation_id[FID_HASH_SZ]; |
9304 |
-+ |
9305 |
-+void __init initialize_hashidentrnd(void) |
9306 |
-+{ |
9307 |
-+ get_random_bytes(&hashidentrnd, sizeof(hashidentrnd)); |
9308 |
-+} |
9309 |
-+ |
9310 |
-+static u32 __ipv6_select_ident(const struct in6_addr *addr) |
9311 |
-+{ |
9312 |
-+ u32 newid, oldid, hash = jhash2((u32 *)addr, 4, hashidentrnd); |
9313 |
-+ u32 *pid = &ipv6_fragmentation_id[hash % FID_HASH_SZ]; |
9314 |
-+ |
9315 |
-+ do { |
9316 |
-+ oldid = *pid; |
9317 |
-+ newid = oldid + 1; |
9318 |
-+ if (!(hash + newid)) |
9319 |
-+ newid++; |
9320 |
-+ } while (cmpxchg(pid, oldid, newid) != oldid); |
9321 |
-+ |
9322 |
-+ return hash + newid; |
9323 |
-+} |
9324 |
-+ |
9325 |
-+void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) |
9326 |
-+{ |
9327 |
-+ fhdr->identification = htonl(__ipv6_select_ident(&rt->rt6i_dst.addr)); |
9328 |
-+} |
9329 |
-+ |
9330 |
- int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
9331 |
- { |
9332 |
- struct sk_buff *frag; |
9333 |
-@@ -680,7 +709,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
9334 |
- skb_reset_network_header(skb); |
9335 |
- memcpy(skb_network_header(skb), tmp_hdr, hlen); |
9336 |
- |
9337 |
-- ipv6_select_ident(fh); |
9338 |
-+ ipv6_select_ident(fh, rt); |
9339 |
- fh->nexthdr = nexthdr; |
9340 |
- fh->reserved = 0; |
9341 |
- fh->frag_off = htons(IP6_MF); |
9342 |
-@@ -826,7 +855,7 @@ slow_path: |
9343 |
- fh->nexthdr = nexthdr; |
9344 |
- fh->reserved = 0; |
9345 |
- if (!frag_id) { |
9346 |
-- ipv6_select_ident(fh); |
9347 |
-+ ipv6_select_ident(fh, rt); |
9348 |
- frag_id = fh->identification; |
9349 |
- } else |
9350 |
- fh->identification = frag_id; |
9351 |
-@@ -1072,7 +1101,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, |
9352 |
- int getfrag(void *from, char *to, int offset, int len, |
9353 |
- int odd, struct sk_buff *skb), |
9354 |
- void *from, int length, int hh_len, int fragheaderlen, |
9355 |
-- int transhdrlen, int mtu,unsigned int flags) |
9356 |
-+ int transhdrlen, int mtu,unsigned int flags, |
9357 |
-+ struct rt6_info *rt) |
9358 |
- |
9359 |
- { |
9360 |
- struct sk_buff *skb; |
9361 |
-@@ -1116,7 +1146,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, |
9362 |
- skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - |
9363 |
- sizeof(struct frag_hdr)) & ~7; |
9364 |
- skb_shinfo(skb)->gso_type = SKB_GSO_UDP; |
9365 |
-- ipv6_select_ident(&fhdr); |
9366 |
-+ ipv6_select_ident(&fhdr, rt); |
9367 |
- skb_shinfo(skb)->ip6_frag_id = fhdr.identification; |
9368 |
- __skb_queue_tail(&sk->sk_write_queue, skb); |
9369 |
- |
9370 |
-@@ -1282,7 +1312,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, |
9371 |
- |
9372 |
- err = ip6_ufo_append_data(sk, getfrag, from, length, |
9373 |
- hh_len, fragheaderlen, |
9374 |
-- transhdrlen, mtu, flags); |
9375 |
-+ transhdrlen, mtu, flags, rt); |
9376 |
- if (err) |
9377 |
- goto error; |
9378 |
- return 0; |
9379 |
-diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c |
9380 |
-index 87551ca..7c43e86 100644 |
9381 |
---- a/net/ipv6/tcp_ipv6.c |
9382 |
-+++ b/net/ipv6/tcp_ipv6.c |
9383 |
-@@ -61,6 +61,7 @@ |
9384 |
- #include <net/timewait_sock.h> |
9385 |
- #include <net/netdma.h> |
9386 |
- #include <net/inet_common.h> |
9387 |
-+#include <net/secure_seq.h> |
9388 |
- |
9389 |
- #include <asm/uaccess.h> |
9390 |
- |
9391 |
-diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c |
9392 |
-index 328985c..29213b5 100644 |
9393 |
---- a/net/ipv6/udp.c |
9394 |
-+++ b/net/ipv6/udp.c |
9395 |
-@@ -1359,7 +1359,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features) |
9396 |
- fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); |
9397 |
- fptr->nexthdr = nexthdr; |
9398 |
- fptr->reserved = 0; |
9399 |
-- ipv6_select_ident(fptr); |
9400 |
-+ ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb)); |
9401 |
- |
9402 |
- /* Fragment the skb. ipv6 header and the remaining fields of the |
9403 |
- * fragment header are updated in ipv6_gso_segment() |
9404 |
-diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c |
9405 |
-index a8193f5..d2726a7 100644 |
9406 |
---- a/net/l2tp/l2tp_eth.c |
9407 |
-+++ b/net/l2tp/l2tp_eth.c |
9408 |
-@@ -103,7 +103,7 @@ static struct net_device_ops l2tp_eth_netdev_ops = { |
9409 |
- static void l2tp_eth_dev_setup(struct net_device *dev) |
9410 |
- { |
9411 |
- ether_setup(dev); |
9412 |
-- |
9413 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
9414 |
- dev->netdev_ops = &l2tp_eth_netdev_ops; |
9415 |
- dev->destructor = free_netdev; |
9416 |
- } |
9417 |
-diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c |
9418 |
-index dee30ae..895eec1 100644 |
9419 |
---- a/net/mac80211/iface.c |
9420 |
-+++ b/net/mac80211/iface.c |
9421 |
-@@ -699,6 +699,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { |
9422 |
- static void ieee80211_if_setup(struct net_device *dev) |
9423 |
- { |
9424 |
- ether_setup(dev); |
9425 |
-+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
9426 |
- dev->netdev_ops = &ieee80211_dataif_ops; |
9427 |
- dev->destructor = free_netdev; |
9428 |
- } |
9429 |
-diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c |
9430 |
-index 699c79a..a178cb3 100644 |
9431 |
---- a/net/netfilter/ipvs/ip_vs_ctl.c |
9432 |
-+++ b/net/netfilter/ipvs/ip_vs_ctl.c |
9433 |
-@@ -3771,6 +3771,7 @@ err_sock: |
9434 |
- void ip_vs_control_cleanup(void) |
9435 |
- { |
9436 |
- EnterFunction(2); |
9437 |
-+ unregister_netdevice_notifier(&ip_vs_dst_notifier); |
9438 |
- ip_vs_genl_unregister(); |
9439 |
- nf_unregister_sockopt(&ip_vs_sockopts); |
9440 |
- LeaveFunction(2); |
9441 |
-diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c |
9442 |
-index b6ea6af..69400e3 100644 |
9443 |
---- a/net/sched/sch_sfq.c |
9444 |
-+++ b/net/sched/sch_sfq.c |
9445 |
-@@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) |
9446 |
- /* Return Congestion Notification only if we dropped a packet |
9447 |
- * from this flow. |
9448 |
- */ |
9449 |
-- return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; |
9450 |
-+ if (qlen != slot->qlen) |
9451 |
-+ return NET_XMIT_CN; |
9452 |
-+ |
9453 |
-+ /* As we dropped a packet, better let upper stack know this */ |
9454 |
-+ qdisc_tree_decrease_qlen(sch, 1); |
9455 |
-+ return NET_XMIT_SUCCESS; |
9456 |
- } |
9457 |
- |
9458 |
- static struct sk_buff * |
9459 |
-diff --git a/net/socket.c b/net/socket.c |
9460 |
-index 02dc82d..ed46dbb 100644 |
9461 |
---- a/net/socket.c |
9462 |
-+++ b/net/socket.c |
9463 |
-@@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) |
9464 |
- #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) |
9465 |
- #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) |
9466 |
- |
9467 |
-+struct used_address { |
9468 |
-+ struct sockaddr_storage name; |
9469 |
-+ unsigned int name_len; |
9470 |
-+}; |
9471 |
-+ |
9472 |
- static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
9473 |
-- struct msghdr *msg_sys, unsigned flags, int nosec) |
9474 |
-+ struct msghdr *msg_sys, unsigned flags, |
9475 |
-+ struct used_address *used_address) |
9476 |
- { |
9477 |
- struct compat_msghdr __user *msg_compat = |
9478 |
- (struct compat_msghdr __user *)msg; |
9479 |
-@@ -1953,8 +1959,28 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
9480 |
- |
9481 |
- if (sock->file->f_flags & O_NONBLOCK) |
9482 |
- msg_sys->msg_flags |= MSG_DONTWAIT; |
9483 |
-- err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, |
9484 |
-- total_len); |
9485 |
-+ /* |
9486 |
-+ * If this is sendmmsg() and current destination address is same as |
9487 |
-+ * previously succeeded address, omit asking LSM's decision. |
9488 |
-+ * used_address->name_len is initialized to UINT_MAX so that the first |
9489 |
-+ * destination address never matches. |
9490 |
-+ */ |
9491 |
-+ if (used_address && used_address->name_len == msg_sys->msg_namelen && |
9492 |
-+ !memcmp(&used_address->name, msg->msg_name, |
9493 |
-+ used_address->name_len)) { |
9494 |
-+ err = sock_sendmsg_nosec(sock, msg_sys, total_len); |
9495 |
-+ goto out_freectl; |
9496 |
-+ } |
9497 |
-+ err = sock_sendmsg(sock, msg_sys, total_len); |
9498 |
-+ /* |
9499 |
-+ * If this is sendmmsg() and sending to current destination address was |
9500 |
-+ * successful, remember it. |
9501 |
-+ */ |
9502 |
-+ if (used_address && err >= 0) { |
9503 |
-+ used_address->name_len = msg_sys->msg_namelen; |
9504 |
-+ memcpy(&used_address->name, msg->msg_name, |
9505 |
-+ used_address->name_len); |
9506 |
-+ } |
9507 |
- |
9508 |
- out_freectl: |
9509 |
- if (ctl_buf != ctl) |
9510 |
-@@ -1979,7 +2005,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) |
9511 |
- if (!sock) |
9512 |
- goto out; |
9513 |
- |
9514 |
-- err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); |
9515 |
-+ err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
9516 |
- |
9517 |
- fput_light(sock->file, fput_needed); |
9518 |
- out: |
9519 |
-@@ -1998,6 +2024,10 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
9520 |
- struct mmsghdr __user *entry; |
9521 |
- struct compat_mmsghdr __user *compat_entry; |
9522 |
- struct msghdr msg_sys; |
9523 |
-+ struct used_address used_address; |
9524 |
-+ |
9525 |
-+ if (vlen > UIO_MAXIOV) |
9526 |
-+ vlen = UIO_MAXIOV; |
9527 |
- |
9528 |
- datagrams = 0; |
9529 |
- |
9530 |
-@@ -2005,27 +2035,22 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
9531 |
- if (!sock) |
9532 |
- return err; |
9533 |
- |
9534 |
-- err = sock_error(sock->sk); |
9535 |
-- if (err) |
9536 |
-- goto out_put; |
9537 |
-- |
9538 |
-+ used_address.name_len = UINT_MAX; |
9539 |
- entry = mmsg; |
9540 |
- compat_entry = (struct compat_mmsghdr __user *)mmsg; |
9541 |
-+ err = 0; |
9542 |
- |
9543 |
- while (datagrams < vlen) { |
9544 |
-- /* |
9545 |
-- * No need to ask LSM for more than the first datagram. |
9546 |
-- */ |
9547 |
- if (MSG_CMSG_COMPAT & flags) { |
9548 |
- err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
9549 |
-- &msg_sys, flags, datagrams); |
9550 |
-+ &msg_sys, flags, &used_address); |
9551 |
- if (err < 0) |
9552 |
- break; |
9553 |
- err = __put_user(err, &compat_entry->msg_len); |
9554 |
- ++compat_entry; |
9555 |
- } else { |
9556 |
- err = __sys_sendmsg(sock, (struct msghdr __user *)entry, |
9557 |
-- &msg_sys, flags, datagrams); |
9558 |
-+ &msg_sys, flags, &used_address); |
9559 |
- if (err < 0) |
9560 |
- break; |
9561 |
- err = put_user(err, &entry->msg_len); |
9562 |
-@@ -2037,29 +2062,11 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
9563 |
- ++datagrams; |
9564 |
- } |
9565 |
- |
9566 |
--out_put: |
9567 |
- fput_light(sock->file, fput_needed); |
9568 |
- |
9569 |
-- if (err == 0) |
9570 |
-- return datagrams; |
9571 |
-- |
9572 |
-- if (datagrams != 0) { |
9573 |
-- /* |
9574 |
-- * We may send less entries than requested (vlen) if the |
9575 |
-- * sock is non blocking... |
9576 |
-- */ |
9577 |
-- if (err != -EAGAIN) { |
9578 |
-- /* |
9579 |
-- * ... or if sendmsg returns an error after we |
9580 |
-- * send some datagrams, where we record the |
9581 |
-- * error to return on the next call or if the |
9582 |
-- * app asks about it using getsockopt(SO_ERROR). |
9583 |
-- */ |
9584 |
-- sock->sk->sk_err = -err; |
9585 |
-- } |
9586 |
-- |
9587 |
-+ /* We only return an error if no datagrams were able to be sent */ |
9588 |
-+ if (datagrams != 0) |
9589 |
- return datagrams; |
9590 |
-- } |
9591 |
- |
9592 |
- return err; |
9593 |
- } |
9594 |
-diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c |
9595 |
-index 58064d9..791ab2e 100644 |
9596 |
---- a/net/xfrm/xfrm_algo.c |
9597 |
-+++ b/net/xfrm/xfrm_algo.c |
9598 |
-@@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = { |
9599 |
- .desc = { |
9600 |
- .sadb_alg_id = SADB_X_EALG_AESCTR, |
9601 |
- .sadb_alg_ivlen = 8, |
9602 |
-- .sadb_alg_minbits = 128, |
9603 |
-- .sadb_alg_maxbits = 256 |
9604 |
-+ .sadb_alg_minbits = 160, |
9605 |
-+ .sadb_alg_maxbits = 288 |
9606 |
- } |
9607 |
- }, |
9608 |
- }; |
9609 |
-diff --git a/sound/core/timer.c b/sound/core/timer.c |
9610 |
-index 7c1cbf0..950eed0 100644 |
9611 |
---- a/sound/core/timer.c |
9612 |
-+++ b/sound/core/timer.c |
9613 |
-@@ -531,6 +531,8 @@ int snd_timer_stop(struct snd_timer_instance *timeri) |
9614 |
- if (err < 0) |
9615 |
- return err; |
9616 |
- timer = timeri->timer; |
9617 |
-+ if (!timer) |
9618 |
-+ return -EINVAL; |
9619 |
- spin_lock_irqsave(&timer->lock, flags); |
9620 |
- timeri->cticks = timeri->ticks; |
9621 |
- timeri->pticks = 0; |
9622 |
-diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c |
9623 |
-index ff29380..c49317c 100644 |
9624 |
---- a/sound/soc/codecs/sgtl5000.c |
9625 |
-+++ b/sound/soc/codecs/sgtl5000.c |
9626 |
-@@ -33,73 +33,31 @@ |
9627 |
- #define SGTL5000_DAP_REG_OFFSET 0x0100 |
9628 |
- #define SGTL5000_MAX_REG_OFFSET 0x013A |
9629 |
- |
9630 |
--/* default value of sgtl5000 registers except DAP */ |
9631 |
--static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = { |
9632 |
-- 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */ |
9633 |
-- 0x0000, /* 0x0002, CHIP_DIG_POWER. */ |
9634 |
-- 0x0008, /* 0x0004, CHIP_CKL_CTRL */ |
9635 |
-- 0x0010, /* 0x0006, CHIP_I2S_CTRL */ |
9636 |
-- 0x0000, /* 0x0008, reserved */ |
9637 |
-- 0x0008, /* 0x000A, CHIP_SSS_CTRL */ |
9638 |
-- 0x0000, /* 0x000C, reserved */ |
9639 |
-- 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */ |
9640 |
-- 0x3c3c, /* 0x0010, CHIP_DAC_VOL */ |
9641 |
-- 0x0000, /* 0x0012, reserved */ |
9642 |
-- 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */ |
9643 |
-- 0x0000, /* 0x0016, reserved */ |
9644 |
-- 0x0000, /* 0x0018, reserved */ |
9645 |
-- 0x0000, /* 0x001A, reserved */ |
9646 |
-- 0x0000, /* 0x001E, reserved */ |
9647 |
-- 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */ |
9648 |
-- 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */ |
9649 |
-- 0x0111, /* 0x0024, CHIP_ANN_CTRL */ |
9650 |
-- 0x0000, /* 0x0026, CHIP_LINREG_CTRL */ |
9651 |
-- 0x0000, /* 0x0028, CHIP_REF_CTRL */ |
9652 |
-- 0x0000, /* 0x002A, CHIP_MIC_CTRL */ |
9653 |
-- 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */ |
9654 |
-- 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */ |
9655 |
-- 0x7060, /* 0x0030, CHIP_ANA_POWER */ |
9656 |
-- 0x5000, /* 0x0032, CHIP_PLL_CTRL */ |
9657 |
-- 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */ |
9658 |
-- 0x0000, /* 0x0036, CHIP_ANA_STATUS */ |
9659 |
-- 0x0000, /* 0x0038, reserved */ |
9660 |
-- 0x0000, /* 0x003A, CHIP_ANA_TEST2 */ |
9661 |
-- 0x0000, /* 0x003C, CHIP_SHORT_CTRL */ |
9662 |
-- 0x0000, /* reserved */ |
9663 |
--}; |
9664 |
-- |
9665 |
--/* default value of dap registers */ |
9666 |
--static const u16 sgtl5000_dap_regs[] = { |
9667 |
-- 0x0000, /* 0x0100, DAP_CONTROL */ |
9668 |
-- 0x0000, /* 0x0102, DAP_PEQ */ |
9669 |
-- 0x0040, /* 0x0104, DAP_BASS_ENHANCE */ |
9670 |
-- 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */ |
9671 |
-- 0x0000, /* 0x0108, DAP_AUDIO_EQ */ |
9672 |
-- 0x0040, /* 0x010A, DAP_SGTL_SURROUND */ |
9673 |
-- 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */ |
9674 |
-- 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */ |
9675 |
-- 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */ |
9676 |
-- 0x0000, /* 0x0112, reserved */ |
9677 |
-- 0x0000, /* 0x0114, reserved */ |
9678 |
-- 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */ |
9679 |
-- 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */ |
9680 |
-- 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */ |
9681 |
-- 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */ |
9682 |
-- 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */ |
9683 |
-- 0x8000, /* 0x0120, DAP_MAIN_CHAN */ |
9684 |
-- 0x0000, /* 0x0122, DAP_MIX_CHAN */ |
9685 |
-- 0x0510, /* 0x0124, DAP_AVC_CTRL */ |
9686 |
-- 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */ |
9687 |
-- 0x0028, /* 0x0128, DAP_AVC_ATTACK */ |
9688 |
-- 0x0050, /* 0x012A, DAP_AVC_DECAY */ |
9689 |
-- 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */ |
9690 |
-- 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */ |
9691 |
-- 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */ |
9692 |
-- 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */ |
9693 |
-- 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */ |
9694 |
-- 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */ |
9695 |
-- 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */ |
9696 |
-- 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */ |
9697 |
-+/* default value of sgtl5000 registers */ |
9698 |
-+static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = { |
9699 |
-+ [SGTL5000_CHIP_CLK_CTRL] = 0x0008, |
9700 |
-+ [SGTL5000_CHIP_I2S_CTRL] = 0x0010, |
9701 |
-+ [SGTL5000_CHIP_SSS_CTRL] = 0x0008, |
9702 |
-+ [SGTL5000_CHIP_DAC_VOL] = 0x3c3c, |
9703 |
-+ [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f, |
9704 |
-+ [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818, |
9705 |
-+ [SGTL5000_CHIP_ANA_CTRL] = 0x0111, |
9706 |
-+ [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404, |
9707 |
-+ [SGTL5000_CHIP_ANA_POWER] = 0x7060, |
9708 |
-+ [SGTL5000_CHIP_PLL_CTRL] = 0x5000, |
9709 |
-+ [SGTL5000_DAP_BASS_ENHANCE] = 0x0040, |
9710 |
-+ [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f, |
9711 |
-+ [SGTL5000_DAP_SURROUND] = 0x0040, |
9712 |
-+ [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f, |
9713 |
-+ [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f, |
9714 |
-+ [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f, |
9715 |
-+ [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f, |
9716 |
-+ [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f, |
9717 |
-+ [SGTL5000_DAP_MAIN_CHAN] = 0x8000, |
9718 |
-+ [SGTL5000_DAP_AVC_CTRL] = 0x0510, |
9719 |
-+ [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473, |
9720 |
-+ [SGTL5000_DAP_AVC_ATTACK] = 0x0028, |
9721 |
-+ [SGTL5000_DAP_AVC_DECAY] = 0x0050, |
9722 |
- }; |
9723 |
- |
9724 |
- /* regulator supplies for sgtl5000, VDDD is an optional external supply */ |
9725 |
-@@ -1022,12 +980,10 @@ static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state) |
9726 |
- static int sgtl5000_restore_regs(struct snd_soc_codec *codec) |
9727 |
- { |
9728 |
- u16 *cache = codec->reg_cache; |
9729 |
-- int i; |
9730 |
-- int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1; |
9731 |
-+ u16 reg; |
9732 |
- |
9733 |
- /* restore regular registers */ |
9734 |
-- for (i = 0; i < regular_regs; i++) { |
9735 |
-- int reg = i << 1; |
9736 |
-+ for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { |
9737 |
- |
9738 |
- /* this regs depends on the others */ |
9739 |
- if (reg == SGTL5000_CHIP_ANA_POWER || |
9740 |
-@@ -1037,35 +993,31 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) |
9741 |
- reg == SGTL5000_CHIP_CLK_CTRL) |
9742 |
- continue; |
9743 |
- |
9744 |
-- snd_soc_write(codec, reg, cache[i]); |
9745 |
-+ snd_soc_write(codec, reg, cache[reg]); |
9746 |
- } |
9747 |
- |
9748 |
- /* restore dap registers */ |
9749 |
-- for (i = SGTL5000_DAP_REG_OFFSET >> 1; |
9750 |
-- i < SGTL5000_MAX_REG_OFFSET >> 1; i++) { |
9751 |
-- int reg = i << 1; |
9752 |
-- |
9753 |
-- snd_soc_write(codec, reg, cache[i]); |
9754 |
-- } |
9755 |
-+ for (reg = SGTL5000_DAP_REG_OFFSET; reg < SGTL5000_MAX_REG_OFFSET; reg += 2) |
9756 |
-+ snd_soc_write(codec, reg, cache[reg]); |
9757 |
- |
9758 |
- /* |
9759 |
- * restore power and other regs according |
9760 |
- * to set_power() and set_clock() |
9761 |
- */ |
9762 |
- snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, |
9763 |
-- cache[SGTL5000_CHIP_LINREG_CTRL >> 1]); |
9764 |
-+ cache[SGTL5000_CHIP_LINREG_CTRL]); |
9765 |
- |
9766 |
- snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, |
9767 |
-- cache[SGTL5000_CHIP_ANA_POWER >> 1]); |
9768 |
-+ cache[SGTL5000_CHIP_ANA_POWER]); |
9769 |
- |
9770 |
- snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, |
9771 |
-- cache[SGTL5000_CHIP_CLK_CTRL >> 1]); |
9772 |
-+ cache[SGTL5000_CHIP_CLK_CTRL]); |
9773 |
- |
9774 |
- snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL, |
9775 |
-- cache[SGTL5000_CHIP_REF_CTRL >> 1]); |
9776 |
-+ cache[SGTL5000_CHIP_REF_CTRL]); |
9777 |
- |
9778 |
- snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL, |
9779 |
-- cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]); |
9780 |
-+ cache[SGTL5000_CHIP_LINE_OUT_CTRL]); |
9781 |
- return 0; |
9782 |
- } |
9783 |
- |
9784 |
-@@ -1460,16 +1412,6 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, |
9785 |
- if (!sgtl5000) |
9786 |
- return -ENOMEM; |
9787 |
- |
9788 |
-- /* |
9789 |
-- * copy DAP default values to default value array. |
9790 |
-- * sgtl5000 register space has a big hole, merge it |
9791 |
-- * at init phase makes life easy. |
9792 |
-- * FIXME: should we drop 'const' of sgtl5000_regs? |
9793 |
-- */ |
9794 |
-- memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)), |
9795 |
-- sgtl5000_dap_regs, |
9796 |
-- SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET); |
9797 |
-- |
9798 |
- i2c_set_clientdata(client, sgtl5000); |
9799 |
- |
9800 |
- ret = snd_soc_register_codec(&client->dev, |
9801 |
-diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c |
9802 |
-index 4432ef7..a213813 100644 |
9803 |
---- a/sound/usb/caiaq/input.c |
9804 |
-+++ b/sound/usb/caiaq/input.c |
9805 |
-@@ -30,7 +30,7 @@ static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; |
9806 |
- static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, |
9807 |
- KEY_5, KEY_6, KEY_7 }; |
9808 |
- static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, |
9809 |
-- KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; |
9810 |
-+ KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 }; |
9811 |
- |
9812 |
- static unsigned short keycode_kore[] = { |
9813 |
- KEY_FN_F1, /* "menu" */ |
9814 |
-diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c |
9815 |
-index b0ef9f5..05842c8 100644 |
9816 |
---- a/sound/usb/endpoint.c |
9817 |
-+++ b/sound/usb/endpoint.c |
9818 |
-@@ -352,7 +352,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) |
9819 |
- continue; |
9820 |
- } |
9821 |
- if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || |
9822 |
-- ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) { |
9823 |
-+ ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { |
9824 |
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", |
9825 |
- dev->devnum, iface_no, altno); |
9826 |
- continue; |
9827 |
-diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
9828 |
-index c22fa76..c04d7c7 100644 |
9829 |
---- a/sound/usb/mixer.c |
9830 |
-+++ b/sound/usb/mixer.c |
9831 |
-@@ -1191,6 +1191,11 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void |
9832 |
- |
9833 |
- if (state->mixer->protocol == UAC_VERSION_1) { |
9834 |
- csize = hdr->bControlSize; |
9835 |
-+ if (!csize) { |
9836 |
-+ snd_printdd(KERN_ERR "usbaudio: unit %u: " |
9837 |
-+ "invalid bControlSize == 0\n", unitid); |
9838 |
-+ return -EINVAL; |
9839 |
-+ } |
9840 |
- channels = (hdr->bLength - 7) / csize - 1; |
9841 |
- bmaControls = hdr->bmaControls; |
9842 |
- } else { |
9843 |
-@@ -1934,15 +1939,13 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) |
9844 |
- struct mixer_build state; |
9845 |
- int err; |
9846 |
- const struct usbmix_ctl_map *map; |
9847 |
-- struct usb_host_interface *hostif; |
9848 |
- void *p; |
9849 |
- |
9850 |
-- hostif = mixer->chip->ctrl_intf; |
9851 |
- memset(&state, 0, sizeof(state)); |
9852 |
- state.chip = mixer->chip; |
9853 |
- state.mixer = mixer; |
9854 |
-- state.buffer = hostif->extra; |
9855 |
-- state.buflen = hostif->extralen; |
9856 |
-+ state.buffer = mixer->hostif->extra; |
9857 |
-+ state.buflen = mixer->hostif->extralen; |
9858 |
- |
9859 |
- /* check the mapping table */ |
9860 |
- for (map = usbmix_ctl_maps; map->id; map++) { |
9861 |
-@@ -1955,7 +1958,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) |
9862 |
- } |
9863 |
- |
9864 |
- p = NULL; |
9865 |
-- while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) { |
9866 |
-+ while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen, |
9867 |
-+ p, UAC_OUTPUT_TERMINAL)) != NULL) { |
9868 |
- if (mixer->protocol == UAC_VERSION_1) { |
9869 |
- struct uac1_output_terminal_descriptor *desc = p; |
9870 |
- |
9871 |
-@@ -2162,17 +2166,15 @@ int snd_usb_mixer_activate(struct usb_mixer_interface *mixer) |
9872 |
- /* create the handler for the optional status interrupt endpoint */ |
9873 |
- static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) |
9874 |
- { |
9875 |
-- struct usb_host_interface *hostif; |
9876 |
- struct usb_endpoint_descriptor *ep; |
9877 |
- void *transfer_buffer; |
9878 |
- int buffer_length; |
9879 |
- unsigned int epnum; |
9880 |
- |
9881 |
-- hostif = mixer->chip->ctrl_intf; |
9882 |
- /* we need one interrupt input endpoint */ |
9883 |
-- if (get_iface_desc(hostif)->bNumEndpoints < 1) |
9884 |
-+ if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1) |
9885 |
- return 0; |
9886 |
-- ep = get_endpoint(hostif, 0); |
9887 |
-+ ep = get_endpoint(mixer->hostif, 0); |
9888 |
- if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep)) |
9889 |
- return 0; |
9890 |
- |
9891 |
-@@ -2202,7 +2204,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, |
9892 |
- }; |
9893 |
- struct usb_mixer_interface *mixer; |
9894 |
- struct snd_info_entry *entry; |
9895 |
-- struct usb_host_interface *host_iface; |
9896 |
- int err; |
9897 |
- |
9898 |
- strcpy(chip->card->mixername, "USB Mixer"); |
9899 |
-@@ -2219,8 +2220,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, |
9900 |
- return -ENOMEM; |
9901 |
- } |
9902 |
- |
9903 |
-- host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; |
9904 |
-- switch (get_iface_desc(host_iface)->bInterfaceProtocol) { |
9905 |
-+ mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; |
9906 |
-+ switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) { |
9907 |
- case UAC_VERSION_1: |
9908 |
- default: |
9909 |
- mixer->protocol = UAC_VERSION_1; |
9910 |
-diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h |
9911 |
-index ae1a14d..81b2d8a 100644 |
9912 |
---- a/sound/usb/mixer.h |
9913 |
-+++ b/sound/usb/mixer.h |
9914 |
-@@ -3,6 +3,7 @@ |
9915 |
- |
9916 |
- struct usb_mixer_interface { |
9917 |
- struct snd_usb_audio *chip; |
9918 |
-+ struct usb_host_interface *hostif; |
9919 |
- struct list_head list; |
9920 |
- unsigned int ignore_ctl_error; |
9921 |
- struct urb *urb; |
9922 |
|
9923 |
Deleted: genpatches-2.6/trunk/3.1/1002_linux-3.0.3.patch |
9924 |
=================================================================== |
9925 |
--- genpatches-2.6/trunk/3.1/1002_linux-3.0.3.patch 2011-08-29 15:02:13 UTC (rev 1967) |
9926 |
+++ genpatches-2.6/trunk/3.1/1002_linux-3.0.3.patch 2011-08-29 15:03:18 UTC (rev 1968) |
9927 |
@@ -1,608 +0,0 @@ |
9928 |
-diff --git a/Documentation/virtual/lguest/lguest.c b/Documentation/virtual/lguest/lguest.c |
9929 |
-index cd9d6af..aec80e5 100644 |
9930 |
---- a/Documentation/virtual/lguest/lguest.c |
9931 |
-+++ b/Documentation/virtual/lguest/lguest.c |
9932 |
-@@ -2008,6 +2008,9 @@ int main(int argc, char *argv[]) |
9933 |
- /* We use a simple helper to copy the arguments separated by spaces. */ |
9934 |
- concat((char *)(boot + 1), argv+optind+2); |
9935 |
- |
9936 |
-+ /* Set kernel alignment to 16M (CONFIG_PHYSICAL_ALIGN) */ |
9937 |
-+ boot->hdr.kernel_alignment = 0x1000000; |
9938 |
-+ |
9939 |
- /* Boot protocol version: 2.07 supports the fields for lguest. */ |
9940 |
- boot->hdr.version = 0x207; |
9941 |
- |
9942 |
-diff --git a/Makefile b/Makefile |
9943 |
-index 794fa28..c44d720 100644 |
9944 |
---- a/Makefile |
9945 |
-+++ b/Makefile |
9946 |
-@@ -1,6 +1,6 @@ |
9947 |
- VERSION = 3 |
9948 |
- PATCHLEVEL = 0 |
9949 |
--SUBLEVEL = 2 |
9950 |
-+SUBLEVEL = 3 |
9951 |
- EXTRAVERSION = |
9952 |
- NAME = Sneaky Weasel |
9953 |
- |
9954 |
-diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c |
9955 |
-index 645b84b..7ad43c6 100644 |
9956 |
---- a/drivers/gpu/drm/radeon/atombios_dp.c |
9957 |
-+++ b/drivers/gpu/drm/radeon/atombios_dp.c |
9958 |
-@@ -613,6 +613,18 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, |
9959 |
- return true; |
9960 |
- } |
9961 |
- |
9962 |
-+bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) |
9963 |
-+{ |
9964 |
-+ u8 link_status[DP_LINK_STATUS_SIZE]; |
9965 |
-+ struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
9966 |
-+ |
9967 |
-+ if (!radeon_dp_get_link_status(radeon_connector, link_status)) |
9968 |
-+ return false; |
9969 |
-+ if (dp_channel_eq_ok(link_status, dig->dp_lane_count)) |
9970 |
-+ return false; |
9971 |
-+ return true; |
9972 |
-+} |
9973 |
-+ |
9974 |
- struct radeon_dp_link_train_info { |
9975 |
- struct radeon_device *rdev; |
9976 |
- struct drm_encoder *encoder; |
9977 |
-diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c |
9978 |
-index 6d6b5f1..6ab6c41 100644 |
9979 |
---- a/drivers/gpu/drm/radeon/radeon_connectors.c |
9980 |
-+++ b/drivers/gpu/drm/radeon/radeon_connectors.c |
9981 |
-@@ -60,18 +60,20 @@ void radeon_connector_hotplug(struct drm_connector *connector) |
9982 |
- |
9983 |
- radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
9984 |
- |
9985 |
-- /* powering up/down the eDP panel generates hpd events which |
9986 |
-- * can interfere with modesetting. |
9987 |
-- */ |
9988 |
-- if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) |
9989 |
-+ /* if the connector is already off, don't turn it back on */ |
9990 |
-+ if (connector->dpms != DRM_MODE_DPMS_ON) |
9991 |
- return; |
9992 |
- |
9993 |
-- /* pre-r600 did not always have the hpd pins mapped accurately to connectors */ |
9994 |
-- if (rdev->family >= CHIP_R600) { |
9995 |
-- if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) |
9996 |
-+ /* just deal with DP (not eDP) here. */ |
9997 |
-+ if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { |
9998 |
-+ int saved_dpms = connector->dpms; |
9999 |
-+ |
10000 |
-+ if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) && |
10001 |
-+ radeon_dp_needs_link_train(radeon_connector)) |
10002 |
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); |
10003 |
- else |
10004 |
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); |
10005 |
-+ connector->dpms = saved_dpms; |
10006 |
- } |
10007 |
- } |
10008 |
- |
10009 |
-diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c |
10010 |
-index b293487..319d85d 100644 |
10011 |
---- a/drivers/gpu/drm/radeon/radeon_encoders.c |
10012 |
-+++ b/drivers/gpu/drm/radeon/radeon_encoders.c |
10013 |
-@@ -2323,6 +2323,9 @@ radeon_add_atom_encoder(struct drm_device *dev, |
10014 |
- default: |
10015 |
- encoder->possible_crtcs = 0x3; |
10016 |
- break; |
10017 |
-+ case 4: |
10018 |
-+ encoder->possible_crtcs = 0xf; |
10019 |
-+ break; |
10020 |
- case 6: |
10021 |
- encoder->possible_crtcs = 0x3f; |
10022 |
- break; |
10023 |
-diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h |
10024 |
-index d09031c..68820f5 100644 |
10025 |
---- a/drivers/gpu/drm/radeon/radeon_mode.h |
10026 |
-+++ b/drivers/gpu/drm/radeon/radeon_mode.h |
10027 |
-@@ -479,6 +479,7 @@ extern void radeon_dp_set_link_config(struct drm_connector *connector, |
10028 |
- struct drm_display_mode *mode); |
10029 |
- extern void radeon_dp_link_train(struct drm_encoder *encoder, |
10030 |
- struct drm_connector *connector); |
10031 |
-+extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); |
10032 |
- extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); |
10033 |
- extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); |
10034 |
- extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); |
10035 |
-diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c |
10036 |
-index 1a409c5..c316294 100644 |
10037 |
---- a/drivers/hwmon/ibmaem.c |
10038 |
-+++ b/drivers/hwmon/ibmaem.c |
10039 |
-@@ -432,13 +432,15 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, |
10040 |
- aem_send_message(ipmi); |
10041 |
- |
10042 |
- res = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); |
10043 |
-- if (!res) |
10044 |
-- return -ETIMEDOUT; |
10045 |
-+ if (!res) { |
10046 |
-+ res = -ETIMEDOUT; |
10047 |
-+ goto out; |
10048 |
-+ } |
10049 |
- |
10050 |
- if (ipmi->rx_result || ipmi->rx_msg_len != rs_size || |
10051 |
- memcmp(&rs_resp->id, &system_x_id, sizeof(system_x_id))) { |
10052 |
-- kfree(rs_resp); |
10053 |
-- return -ENOENT; |
10054 |
-+ res = -ENOENT; |
10055 |
-+ goto out; |
10056 |
- } |
10057 |
- |
10058 |
- switch (size) { |
10059 |
-@@ -463,8 +465,11 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, |
10060 |
- break; |
10061 |
- } |
10062 |
- } |
10063 |
-+ res = 0; |
10064 |
- |
10065 |
-- return 0; |
10066 |
-+out: |
10067 |
-+ kfree(rs_resp); |
10068 |
-+ return res; |
10069 |
- } |
10070 |
- |
10071 |
- /* Update AEM energy registers */ |
10072 |
-diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c |
10073 |
-index b6c5d37..1ae8913 100644 |
10074 |
---- a/drivers/net/wireless/ath/ath5k/base.c |
10075 |
-+++ b/drivers/net/wireless/ath/ath5k/base.c |
10076 |
-@@ -1748,6 +1748,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) |
10077 |
- |
10078 |
- if (dma_mapping_error(sc->dev, bf->skbaddr)) { |
10079 |
- ATH5K_ERR(sc, "beacon DMA mapping failed\n"); |
10080 |
-+ dev_kfree_skb_any(skb); |
10081 |
-+ bf->skb = NULL; |
10082 |
- return -EIO; |
10083 |
- } |
10084 |
- |
10085 |
-@@ -1832,8 +1834,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
10086 |
- ath5k_txbuf_free_skb(sc, avf->bbuf); |
10087 |
- avf->bbuf->skb = skb; |
10088 |
- ret = ath5k_beacon_setup(sc, avf->bbuf); |
10089 |
-- if (ret) |
10090 |
-- avf->bbuf->skb = NULL; |
10091 |
- out: |
10092 |
- return ret; |
10093 |
- } |
10094 |
-@@ -1854,6 +1854,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) |
10095 |
- struct ath5k_vif *avf; |
10096 |
- struct ath5k_buf *bf; |
10097 |
- struct sk_buff *skb; |
10098 |
-+ int err; |
10099 |
- |
10100 |
- ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); |
10101 |
- |
10102 |
-@@ -1902,11 +1903,6 @@ ath5k_beacon_send(struct ath5k_softc *sc) |
10103 |
- |
10104 |
- avf = (void *)vif->drv_priv; |
10105 |
- bf = avf->bbuf; |
10106 |
-- if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || |
10107 |
-- sc->opmode == NL80211_IFTYPE_MONITOR)) { |
10108 |
-- ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); |
10109 |
-- return; |
10110 |
-- } |
10111 |
- |
10112 |
- /* |
10113 |
- * Stop any current dma and put the new frame on the queue. |
10114 |
-@@ -1920,8 +1916,17 @@ ath5k_beacon_send(struct ath5k_softc *sc) |
10115 |
- |
10116 |
- /* refresh the beacon for AP or MESH mode */ |
10117 |
- if (sc->opmode == NL80211_IFTYPE_AP || |
10118 |
-- sc->opmode == NL80211_IFTYPE_MESH_POINT) |
10119 |
-- ath5k_beacon_update(sc->hw, vif); |
10120 |
-+ sc->opmode == NL80211_IFTYPE_MESH_POINT) { |
10121 |
-+ err = ath5k_beacon_update(sc->hw, vif); |
10122 |
-+ if (err) |
10123 |
-+ return; |
10124 |
-+ } |
10125 |
-+ |
10126 |
-+ if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || |
10127 |
-+ sc->opmode == NL80211_IFTYPE_MONITOR)) { |
10128 |
-+ ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf->skb); |
10129 |
-+ return; |
10130 |
-+ } |
10131 |
- |
10132 |
- trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]); |
10133 |
- |
10134 |
-diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c |
10135 |
-index 6766f46..4bb5fff 100644 |
10136 |
---- a/drivers/staging/rtl8192u/r819xU_firmware.c |
10137 |
-+++ b/drivers/staging/rtl8192u/r819xU_firmware.c |
10138 |
-@@ -399,10 +399,7 @@ download_firmware_fail: |
10139 |
- |
10140 |
- } |
10141 |
- |
10142 |
-- |
10143 |
-- |
10144 |
-- |
10145 |
-- |
10146 |
-- |
10147 |
-- |
10148 |
-+MODULE_FIRMWARE("RTL8192U/boot.img"); |
10149 |
-+MODULE_FIRMWARE("RTL8192U/main.img"); |
10150 |
-+MODULE_FIRMWARE("RTL8192U/data.img"); |
10151 |
- |
10152 |
-diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c |
10153 |
-index 385acb8..3f94ac3 100644 |
10154 |
---- a/drivers/usb/class/usbtmc.c |
10155 |
-+++ b/drivers/usb/class/usbtmc.c |
10156 |
-@@ -268,7 +268,7 @@ usbtmc_abort_bulk_in_status: |
10157 |
- dev_err(dev, "usb_bulk_msg returned %d\n", rv); |
10158 |
- goto exit; |
10159 |
- } |
10160 |
-- } while ((actual = max_size) && |
10161 |
-+ } while ((actual == max_size) && |
10162 |
- (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); |
10163 |
- |
10164 |
- if (actual == max_size) { |
10165 |
-diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c |
10166 |
-index c962608..26678ca 100644 |
10167 |
---- a/drivers/usb/core/config.c |
10168 |
-+++ b/drivers/usb/core/config.c |
10169 |
-@@ -123,10 +123,11 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, |
10170 |
- } |
10171 |
- |
10172 |
- if (usb_endpoint_xfer_isoc(&ep->desc)) |
10173 |
-- max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1) * |
10174 |
-- (desc->bmAttributes + 1); |
10175 |
-+ max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * |
10176 |
-+ le16_to_cpu(ep->desc.wMaxPacketSize); |
10177 |
- else if (usb_endpoint_xfer_int(&ep->desc)) |
10178 |
-- max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1); |
10179 |
-+ max_tx = le16_to_cpu(ep->desc.wMaxPacketSize) * |
10180 |
-+ (desc->bMaxBurst + 1); |
10181 |
- else |
10182 |
- max_tx = 999999; |
10183 |
- if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { |
10184 |
-@@ -134,10 +135,10 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, |
10185 |
- "config %d interface %d altsetting %d ep %d: " |
10186 |
- "setting to %d\n", |
10187 |
- usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", |
10188 |
-- desc->wBytesPerInterval, |
10189 |
-+ le16_to_cpu(desc->wBytesPerInterval), |
10190 |
- cfgno, inum, asnum, ep->desc.bEndpointAddress, |
10191 |
- max_tx); |
10192 |
-- ep->ss_ep_comp.wBytesPerInterval = max_tx; |
10193 |
-+ ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx); |
10194 |
- } |
10195 |
- } |
10196 |
- |
10197 |
-diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c |
10198 |
-index 04b90ad..e9f004e 100644 |
10199 |
---- a/drivers/usb/host/pci-quirks.c |
10200 |
-+++ b/drivers/usb/host/pci-quirks.c |
10201 |
-@@ -803,7 +803,7 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) |
10202 |
- |
10203 |
- /* If the BIOS owns the HC, signal that the OS wants it, and wait */ |
10204 |
- if (val & XHCI_HC_BIOS_OWNED) { |
10205 |
-- writel(val & XHCI_HC_OS_OWNED, base + ext_cap_offset); |
10206 |
-+ writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); |
10207 |
- |
10208 |
- /* Wait for 5 seconds with 10 microsecond polling interval */ |
10209 |
- timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, |
10210 |
-diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c |
10211 |
-index f5fe1ac..9824761 100644 |
10212 |
---- a/drivers/usb/host/xhci.c |
10213 |
-+++ b/drivers/usb/host/xhci.c |
10214 |
-@@ -345,7 +345,8 @@ static void xhci_event_ring_work(unsigned long arg) |
10215 |
- spin_lock_irqsave(&xhci->lock, flags); |
10216 |
- temp = xhci_readl(xhci, &xhci->op_regs->status); |
10217 |
- xhci_dbg(xhci, "op reg status = 0x%x\n", temp); |
10218 |
-- if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { |
10219 |
-+ if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) || |
10220 |
-+ (xhci->xhc_state & XHCI_STATE_HALTED)) { |
10221 |
- xhci_dbg(xhci, "HW died, polling stopped.\n"); |
10222 |
- spin_unlock_irqrestore(&xhci->lock, flags); |
10223 |
- return; |
10224 |
-@@ -939,8 +940,11 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, |
10225 |
- return 0; |
10226 |
- } |
10227 |
- |
10228 |
-+ xhci = hcd_to_xhci(hcd); |
10229 |
-+ if (xhci->xhc_state & XHCI_STATE_HALTED) |
10230 |
-+ return -ENODEV; |
10231 |
-+ |
10232 |
- if (check_virt_dev) { |
10233 |
-- xhci = hcd_to_xhci(hcd); |
10234 |
- if (!udev->slot_id || !xhci->devs |
10235 |
- || !xhci->devs[udev->slot_id]) { |
10236 |
- printk(KERN_DEBUG "xHCI %s called with unaddressed " |
10237 |
-@@ -1242,7 +1246,8 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
10238 |
- xhci_urb_free_priv(xhci, urb_priv); |
10239 |
- return ret; |
10240 |
- } |
10241 |
-- if (xhci->xhc_state & XHCI_STATE_DYING) { |
10242 |
-+ if ((xhci->xhc_state & XHCI_STATE_DYING) || |
10243 |
-+ (xhci->xhc_state & XHCI_STATE_HALTED)) { |
10244 |
- xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " |
10245 |
- "non-responsive xHCI host.\n", |
10246 |
- urb->ep->desc.bEndpointAddress, urb); |
10247 |
-@@ -2667,7 +2672,10 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) |
10248 |
- int i, ret; |
10249 |
- |
10250 |
- ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); |
10251 |
-- if (ret <= 0) |
10252 |
-+ /* If the host is halted due to driver unload, we still need to free the |
10253 |
-+ * device. |
10254 |
-+ */ |
10255 |
-+ if (ret <= 0 && ret != -ENODEV) |
10256 |
- return; |
10257 |
- |
10258 |
- virt_dev = xhci->devs[udev->slot_id]; |
10259 |
-@@ -2681,7 +2689,8 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) |
10260 |
- spin_lock_irqsave(&xhci->lock, flags); |
10261 |
- /* Don't disable the slot if the host controller is dead. */ |
10262 |
- state = xhci_readl(xhci, &xhci->op_regs->status); |
10263 |
-- if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { |
10264 |
-+ if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) || |
10265 |
-+ (xhci->xhc_state & XHCI_STATE_HALTED)) { |
10266 |
- xhci_free_virt_device(xhci, udev->slot_id); |
10267 |
- spin_unlock_irqrestore(&xhci->lock, flags); |
10268 |
- return; |
10269 |
-diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c |
10270 |
-index 6aeb363..548338c 100644 |
10271 |
---- a/drivers/usb/musb/musb_gadget.c |
10272 |
-+++ b/drivers/usb/musb/musb_gadget.c |
10273 |
-@@ -1698,6 +1698,8 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) |
10274 |
- |
10275 |
- is_on = !!is_on; |
10276 |
- |
10277 |
-+ pm_runtime_get_sync(musb->controller); |
10278 |
-+ |
10279 |
- /* NOTE: this assumes we are sensing vbus; we'd rather |
10280 |
- * not pullup unless the B-session is active. |
10281 |
- */ |
10282 |
-@@ -1707,6 +1709,9 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) |
10283 |
- musb_pullup(musb, is_on); |
10284 |
- } |
10285 |
- spin_unlock_irqrestore(&musb->lock, flags); |
10286 |
-+ |
10287 |
-+ pm_runtime_put(musb->controller); |
10288 |
-+ |
10289 |
- return 0; |
10290 |
- } |
10291 |
- |
10292 |
-diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c |
10293 |
-index 2e06b90..9afb361 100644 |
10294 |
---- a/drivers/usb/serial/ftdi_sio.c |
10295 |
-+++ b/drivers/usb/serial/ftdi_sio.c |
10296 |
-@@ -1171,7 +1171,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, |
10297 |
- case FT2232H: /* FT2232H chip */ |
10298 |
- case FT4232H: /* FT4232H chip */ |
10299 |
- case FT232H: /* FT232H chip */ |
10300 |
-- if ((baud <= 12000000) & (baud >= 1200)) { |
10301 |
-+ if ((baud <= 12000000) && (baud >= 1200)) { |
10302 |
- div_value = ftdi_2232h_baud_to_divisor(baud); |
10303 |
- } else if (baud < 1200) { |
10304 |
- div_value = ftdi_232bm_baud_to_divisor(baud); |
10305 |
-diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c |
10306 |
-index 60b25d8..8156561 100644 |
10307 |
---- a/drivers/usb/serial/option.c |
10308 |
-+++ b/drivers/usb/serial/option.c |
10309 |
-@@ -148,6 +148,10 @@ static void option_instat_callback(struct urb *urb); |
10310 |
- #define HUAWEI_PRODUCT_K4505 0x1464 |
10311 |
- #define HUAWEI_PRODUCT_K3765 0x1465 |
10312 |
- #define HUAWEI_PRODUCT_E14AC 0x14AC |
10313 |
-+#define HUAWEI_PRODUCT_K3770 0x14C9 |
10314 |
-+#define HUAWEI_PRODUCT_K3771 0x14CA |
10315 |
-+#define HUAWEI_PRODUCT_K4510 0x14CB |
10316 |
-+#define HUAWEI_PRODUCT_K4511 0x14CC |
10317 |
- #define HUAWEI_PRODUCT_ETS1220 0x1803 |
10318 |
- #define HUAWEI_PRODUCT_E353 0x1506 |
10319 |
- |
10320 |
-@@ -547,6 +551,14 @@ static const struct usb_device_id option_ids[] = { |
10321 |
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, |
10322 |
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, |
10323 |
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, |
10324 |
-+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, |
10325 |
-+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, |
10326 |
-+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, |
10327 |
-+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) }, |
10328 |
-+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) }, |
10329 |
-+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) }, |
10330 |
-+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, |
10331 |
-+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, |
10332 |
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, |
10333 |
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
10334 |
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
10335 |
-diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c |
10336 |
-index 54a9dab..27f9ae4 100644 |
10337 |
---- a/drivers/usb/serial/qcserial.c |
10338 |
-+++ b/drivers/usb/serial/qcserial.c |
10339 |
-@@ -45,6 +45,7 @@ static const struct usb_device_id id_table[] = { |
10340 |
- {USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ |
10341 |
- {USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ |
10342 |
- {USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */ |
10343 |
-+ {USB_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ |
10344 |
- {USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */ |
10345 |
- {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ |
10346 |
- {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ |
10347 |
-diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h |
10348 |
-index ccff348..3041a97 100644 |
10349 |
---- a/drivers/usb/storage/unusual_devs.h |
10350 |
-+++ b/drivers/usb/storage/unusual_devs.h |
10351 |
-@@ -1988,6 +1988,16 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100, |
10352 |
- "Micro Mini 1GB", |
10353 |
- USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), |
10354 |
- |
10355 |
-+/* |
10356 |
-+ * Nick Bowler <nbowler@××××××××××××.com> |
10357 |
-+ * SCSI stack spams (otherwise harmless) error messages. |
10358 |
-+ */ |
10359 |
-+UNUSUAL_DEV( 0xc251, 0x4003, 0x0100, 0x0100, |
10360 |
-+ "Keil Software, Inc.", |
10361 |
-+ "V2M MotherBoard", |
10362 |
-+ USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
10363 |
-+ US_FL_NOT_LOCKABLE), |
10364 |
-+ |
10365 |
- /* Reported by Andrew Simmons <andrew.simmons@×××××.com> */ |
10366 |
- UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, |
10367 |
- "DataStor", |
10368 |
-diff --git a/mm/vmalloc.c b/mm/vmalloc.c |
10369 |
-index 1d34d75..d3d451b 100644 |
10370 |
---- a/mm/vmalloc.c |
10371 |
-+++ b/mm/vmalloc.c |
10372 |
-@@ -732,9 +732,10 @@ static void free_unmap_vmap_area_addr(unsigned long addr) |
10373 |
- #define VMAP_BBMAP_BITS_MIN (VMAP_MAX_ALLOC*2) |
10374 |
- #define VMAP_MIN(x, y) ((x) < (y) ? (x) : (y)) /* can't use min() */ |
10375 |
- #define VMAP_MAX(x, y) ((x) > (y) ? (x) : (y)) /* can't use max() */ |
10376 |
--#define VMAP_BBMAP_BITS VMAP_MIN(VMAP_BBMAP_BITS_MAX, \ |
10377 |
-- VMAP_MAX(VMAP_BBMAP_BITS_MIN, \ |
10378 |
-- VMALLOC_PAGES / NR_CPUS / 16)) |
10379 |
-+#define VMAP_BBMAP_BITS \ |
10380 |
-+ VMAP_MIN(VMAP_BBMAP_BITS_MAX, \ |
10381 |
-+ VMAP_MAX(VMAP_BBMAP_BITS_MIN, \ |
10382 |
-+ VMALLOC_PAGES / roundup_pow_of_two(NR_CPUS) / 16)) |
10383 |
- |
10384 |
- #define VMAP_BLOCK_SIZE (VMAP_BBMAP_BITS * PAGE_SIZE) |
10385 |
- |
10386 |
-diff --git a/net/atm/br2684.c b/net/atm/br2684.c |
10387 |
-index 2252c20..52cfd0c 100644 |
10388 |
---- a/net/atm/br2684.c |
10389 |
-+++ b/net/atm/br2684.c |
10390 |
-@@ -242,8 +242,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev, |
10391 |
- if (brdev->payload == p_bridged) { |
10392 |
- skb_push(skb, 2); |
10393 |
- memset(skb->data, 0, 2); |
10394 |
-- } else { /* p_routed */ |
10395 |
-- skb_pull(skb, ETH_HLEN); |
10396 |
- } |
10397 |
- } |
10398 |
- skb_debug(skb); |
10399 |
-diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c |
10400 |
-index 3b53ad5..14eb6ea 100644 |
10401 |
---- a/sound/soc/samsung/jive_wm8750.c |
10402 |
-+++ b/sound/soc/samsung/jive_wm8750.c |
10403 |
-@@ -131,7 +131,7 @@ static struct snd_soc_dai_link jive_dai = { |
10404 |
- .cpu_dai_name = "s3c2412-i2s", |
10405 |
- .codec_dai_name = "wm8750-hifi", |
10406 |
- .platform_name = "samsung-audio", |
10407 |
-- .codec_name = "wm8750-codec.0-0x1a", |
10408 |
-+ .codec_name = "wm8750-codec.0-001a", |
10409 |
- .init = jive_wm8750_init, |
10410 |
- .ops = &jive_ops, |
10411 |
- }; |
10412 |
-diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c |
10413 |
-index 3c271f9..6201710 100644 |
10414 |
---- a/sound/soc/tegra/tegra_pcm.c |
10415 |
-+++ b/sound/soc/tegra/tegra_pcm.c |
10416 |
-@@ -309,9 +309,14 @@ static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) |
10417 |
- |
10418 |
- static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream) |
10419 |
- { |
10420 |
-- struct snd_pcm_substream *substream = pcm->streams[stream].substream; |
10421 |
-- struct snd_dma_buffer *buf = &substream->dma_buffer; |
10422 |
-+ struct snd_pcm_substream *substream; |
10423 |
-+ struct snd_dma_buffer *buf; |
10424 |
-+ |
10425 |
-+ substream = pcm->streams[stream].substream; |
10426 |
-+ if (!substream) |
10427 |
-+ return; |
10428 |
- |
10429 |
-+ buf = &substream->dma_buffer; |
10430 |
- if (!buf->area) |
10431 |
- return; |
10432 |
- |
10433 |
-diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c |
10434 |
-index 0d6738a..7766478 100644 |
10435 |
---- a/sound/soc/tegra/tegra_wm8903.c |
10436 |
-+++ b/sound/soc/tegra/tegra_wm8903.c |
10437 |
-@@ -56,6 +56,7 @@ |
10438 |
- #define GPIO_HP_MUTE BIT(1) |
10439 |
- #define GPIO_INT_MIC_EN BIT(2) |
10440 |
- #define GPIO_EXT_MIC_EN BIT(3) |
10441 |
-+#define GPIO_HP_DET BIT(4) |
10442 |
- |
10443 |
- struct tegra_wm8903 { |
10444 |
- struct tegra_asoc_utils_data util_data; |
10445 |
-@@ -304,6 +305,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) |
10446 |
- snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, |
10447 |
- 1, |
10448 |
- &tegra_wm8903_hp_jack_gpio); |
10449 |
-+ machine->gpio_requested |= GPIO_HP_DET; |
10450 |
- } |
10451 |
- |
10452 |
- snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, |
10453 |
-@@ -429,10 +431,10 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) |
10454 |
- struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
10455 |
- struct tegra_wm8903_platform_data *pdata = machine->pdata; |
10456 |
- |
10457 |
-- snd_soc_unregister_card(card); |
10458 |
-- |
10459 |
-- tegra_asoc_utils_fini(&machine->util_data); |
10460 |
-- |
10461 |
-+ if (machine->gpio_requested & GPIO_HP_DET) |
10462 |
-+ snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, |
10463 |
-+ 1, |
10464 |
-+ &tegra_wm8903_hp_jack_gpio); |
10465 |
- if (machine->gpio_requested & GPIO_EXT_MIC_EN) |
10466 |
- gpio_free(pdata->gpio_ext_mic_en); |
10467 |
- if (machine->gpio_requested & GPIO_INT_MIC_EN) |
10468 |
-@@ -441,6 +443,11 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) |
10469 |
- gpio_free(pdata->gpio_hp_mute); |
10470 |
- if (machine->gpio_requested & GPIO_SPKR_EN) |
10471 |
- gpio_free(pdata->gpio_spkr_en); |
10472 |
-+ machine->gpio_requested = 0; |
10473 |
-+ |
10474 |
-+ snd_soc_unregister_card(card); |
10475 |
-+ |
10476 |
-+ tegra_asoc_utils_fini(&machine->util_data); |
10477 |
- |
10478 |
- kfree(machine); |
10479 |
- |
10480 |
-diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c |
10481 |
-index d0d493c..aa52b3e 100644 |
10482 |
---- a/sound/usb/caiaq/audio.c |
10483 |
-+++ b/sound/usb/caiaq/audio.c |
10484 |
-@@ -614,6 +614,7 @@ static void read_completed(struct urb *urb) |
10485 |
- struct snd_usb_caiaqdev *dev; |
10486 |
- struct urb *out; |
10487 |
- int frame, len, send_it = 0, outframe = 0; |
10488 |
-+ size_t offset = 0; |
10489 |
- |
10490 |
- if (urb->status || !info) |
10491 |
- return; |
10492 |
-@@ -634,7 +635,8 @@ static void read_completed(struct urb *urb) |
10493 |
- len = urb->iso_frame_desc[outframe].actual_length; |
10494 |
- out->iso_frame_desc[outframe].length = len; |
10495 |
- out->iso_frame_desc[outframe].actual_length = 0; |
10496 |
-- out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; |
10497 |
-+ out->iso_frame_desc[outframe].offset = offset; |
10498 |
-+ offset += len; |
10499 |
- |
10500 |
- if (len > 0) { |
10501 |
- spin_lock(&dev->spinlock); |
10502 |
-@@ -650,7 +652,7 @@ static void read_completed(struct urb *urb) |
10503 |
- } |
10504 |
- |
10505 |
- if (send_it) { |
10506 |
-- out->number_of_packets = FRAMES_PER_URB; |
10507 |
-+ out->number_of_packets = outframe; |
10508 |
- out->transfer_flags = URB_ISO_ASAP; |
10509 |
- usb_submit_urb(out, GFP_ATOMIC); |
10510 |
- } |
10511 |
-diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c |
10512 |
-index e02d78c..6c86eca 100644 |
10513 |
---- a/tools/perf/util/config.c |
10514 |
-+++ b/tools/perf/util/config.c |
10515 |
-@@ -399,7 +399,6 @@ static int perf_config_global(void) |
10516 |
- int perf_config(config_fn_t fn, void *data) |
10517 |
- { |
10518 |
- int ret = 0, found = 0; |
10519 |
-- char *repo_config = NULL; |
10520 |
- const char *home = NULL; |
10521 |
- |
10522 |
- /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ |
10523 |
-@@ -421,12 +420,6 @@ int perf_config(config_fn_t fn, void *data) |
10524 |
- free(user_config); |
10525 |
- } |
10526 |
- |
10527 |
-- repo_config = perf_pathdup("config"); |
10528 |
-- if (!access(repo_config, R_OK)) { |
10529 |
-- ret += perf_config_from_file(fn, repo_config, data); |
10530 |
-- found += 1; |
10531 |
-- } |
10532 |
-- free(repo_config); |
10533 |
- if (found == 0) |
10534 |
- return -1; |
10535 |
- return ret; |
10536 |
|
10537 |
Deleted: genpatches-2.6/trunk/3.1/1800_fix-zcache-build.patch |
10538 |
=================================================================== |
10539 |
--- genpatches-2.6/trunk/3.1/1800_fix-zcache-build.patch 2011-08-29 15:02:13 UTC (rev 1967) |
10540 |
+++ genpatches-2.6/trunk/3.1/1800_fix-zcache-build.patch 2011-08-29 15:03:18 UTC (rev 1968) |
10541 |
@@ -1,3343 +0,0 @@ |
10542 |
-diff --git a/drivers/staging/zcache/Makefile b/drivers/staging/zcache/Makefile |
10543 |
-index f5ec64f..e3c945f 100644 |
10544 |
---- a/drivers/staging/zcache/Makefile |
10545 |
-+++ b/drivers/staging/zcache/Makefile |
10546 |
-@@ -1,3 +1,3 @@ |
10547 |
--zcache-y := tmem.o |
10548 |
-+zcache-y := zcache_drv.o tmem.o |
10549 |
- |
10550 |
- obj-$(CONFIG_ZCACHE) += zcache.o |
10551 |
-diff --git a/drivers/staging/zcache/zcache.c b/drivers/staging/zcache/zcache.c |
10552 |
-deleted file mode 100644 |
10553 |
-index 77ac2d4..0000000 |
10554 |
---- a/drivers/staging/zcache/zcache.c |
10555 |
-+++ /dev/null |
10556 |
-@@ -1,1661 +0,0 @@ |
10557 |
--/* |
10558 |
-- * zcache.c |
10559 |
-- * |
10560 |
-- * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp. |
10561 |
-- * Copyright (c) 2010,2011, Nitin Gupta |
10562 |
-- * |
10563 |
-- * Zcache provides an in-kernel "host implementation" for transcendent memory |
10564 |
-- * and, thus indirectly, for cleancache and frontswap. Zcache includes two |
10565 |
-- * page-accessible memory [1] interfaces, both utilizing lzo1x compression: |
10566 |
-- * 1) "compression buddies" ("zbud") is used for ephemeral pages |
10567 |
-- * 2) xvmalloc is used for persistent pages. |
10568 |
-- * Xvmalloc (based on the TLSF allocator) has very low fragmentation |
10569 |
-- * so maximizes space efficiency, while zbud allows pairs (and potentially, |
10570 |
-- * in the future, more than a pair of) compressed pages to be closely linked |
10571 |
-- * so that reclaiming can be done via the kernel's physical-page-oriented |
10572 |
-- * "shrinker" interface. |
10573 |
-- * |
10574 |
-- * [1] For a definition of page-accessible memory (aka PAM), see: |
10575 |
-- * http://marc.info/?l=linux-mm&m=127811271605009 |
10576 |
-- */ |
10577 |
-- |
10578 |
--#include <linux/cpu.h> |
10579 |
--#include <linux/highmem.h> |
10580 |
--#include <linux/list.h> |
10581 |
--#include <linux/lzo.h> |
10582 |
--#include <linux/slab.h> |
10583 |
--#include <linux/spinlock.h> |
10584 |
--#include <linux/types.h> |
10585 |
--#include <linux/atomic.h> |
10586 |
--#include "tmem.h" |
10587 |
-- |
10588 |
--#include "../zram/xvmalloc.h" /* if built in drivers/staging */ |
10589 |
-- |
10590 |
--#if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP)) |
10591 |
--#error "zcache is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" |
10592 |
--#endif |
10593 |
--#ifdef CONFIG_CLEANCACHE |
10594 |
--#include <linux/cleancache.h> |
10595 |
--#endif |
10596 |
--#ifdef CONFIG_FRONTSWAP |
10597 |
--#include <linux/frontswap.h> |
10598 |
--#endif |
10599 |
-- |
10600 |
--#if 0 |
10601 |
--/* this is more aggressive but may cause other problems? */ |
10602 |
--#define ZCACHE_GFP_MASK (GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN) |
10603 |
--#else |
10604 |
--#define ZCACHE_GFP_MASK \ |
10605 |
-- (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) |
10606 |
--#endif |
10607 |
-- |
10608 |
--/********** |
10609 |
-- * Compression buddies ("zbud") provides for packing two (or, possibly |
10610 |
-- * in the future, more) compressed ephemeral pages into a single "raw" |
10611 |
-- * (physical) page and tracking them with data structures so that |
10612 |
-- * the raw pages can be easily reclaimed. |
10613 |
-- * |
10614 |
-- * A zbud page ("zbpg") is an aligned page containing a list_head, |
10615 |
-- * a lock, and two "zbud headers". The remainder of the physical |
10616 |
-- * page is divided up into aligned 64-byte "chunks" which contain |
10617 |
-- * the compressed data for zero, one, or two zbuds. Each zbpg |
10618 |
-- * resides on: (1) an "unused list" if it has no zbuds; (2) a |
10619 |
-- * "buddied" list if it is fully populated with two zbuds; or |
10620 |
-- * (3) one of PAGE_SIZE/64 "unbuddied" lists indexed by how many chunks |
10621 |
-- * the one unbuddied zbud uses. The data inside a zbpg cannot be |
10622 |
-- * read or written unless the zbpg's lock is held. |
10623 |
-- */ |
10624 |
-- |
10625 |
--#define ZBH_SENTINEL 0x43214321 |
10626 |
--#define ZBPG_SENTINEL 0xdeadbeef |
10627 |
-- |
10628 |
--#define ZBUD_MAX_BUDS 2 |
10629 |
-- |
10630 |
--struct zbud_hdr { |
10631 |
-- uint32_t pool_id; |
10632 |
-- struct tmem_oid oid; |
10633 |
-- uint32_t index; |
10634 |
-- uint16_t size; /* compressed size in bytes, zero means unused */ |
10635 |
-- DECL_SENTINEL |
10636 |
--}; |
10637 |
-- |
10638 |
--struct zbud_page { |
10639 |
-- struct list_head bud_list; |
10640 |
-- spinlock_t lock; |
10641 |
-- struct zbud_hdr buddy[ZBUD_MAX_BUDS]; |
10642 |
-- DECL_SENTINEL |
10643 |
-- /* followed by NUM_CHUNK aligned CHUNK_SIZE-byte chunks */ |
10644 |
--}; |
10645 |
-- |
10646 |
--#define CHUNK_SHIFT 6 |
10647 |
--#define CHUNK_SIZE (1 << CHUNK_SHIFT) |
10648 |
--#define CHUNK_MASK (~(CHUNK_SIZE-1)) |
10649 |
--#define NCHUNKS (((PAGE_SIZE - sizeof(struct zbud_page)) & \ |
10650 |
-- CHUNK_MASK) >> CHUNK_SHIFT) |
10651 |
--#define MAX_CHUNK (NCHUNKS-1) |
10652 |
-- |
10653 |
--static struct { |
10654 |
-- struct list_head list; |
10655 |
-- unsigned count; |
10656 |
--} zbud_unbuddied[NCHUNKS]; |
10657 |
--/* list N contains pages with N chunks USED and NCHUNKS-N unused */ |
10658 |
--/* element 0 is never used but optimizing that isn't worth it */ |
10659 |
--static unsigned long zbud_cumul_chunk_counts[NCHUNKS]; |
10660 |
-- |
10661 |
--struct list_head zbud_buddied_list; |
10662 |
--static unsigned long zcache_zbud_buddied_count; |
10663 |
-- |
10664 |
--/* protects the buddied list and all unbuddied lists */ |
10665 |
--static DEFINE_SPINLOCK(zbud_budlists_spinlock); |
10666 |
-- |
10667 |
--static LIST_HEAD(zbpg_unused_list); |
10668 |
--static unsigned long zcache_zbpg_unused_list_count; |
10669 |
-- |
10670 |
--/* protects the unused page list */ |
10671 |
--static DEFINE_SPINLOCK(zbpg_unused_list_spinlock); |
10672 |
-- |
10673 |
--static atomic_t zcache_zbud_curr_raw_pages; |
10674 |
--static atomic_t zcache_zbud_curr_zpages; |
10675 |
--static unsigned long zcache_zbud_curr_zbytes; |
10676 |
--static unsigned long zcache_zbud_cumul_zpages; |
10677 |
--static unsigned long zcache_zbud_cumul_zbytes; |
10678 |
--static unsigned long zcache_compress_poor; |
10679 |
-- |
10680 |
--/* forward references */ |
10681 |
--static void *zcache_get_free_page(void); |
10682 |
--static void zcache_free_page(void *p); |
10683 |
-- |
10684 |
--/* |
10685 |
-- * zbud helper functions |
10686 |
-- */ |
10687 |
-- |
10688 |
--static inline unsigned zbud_max_buddy_size(void) |
10689 |
--{ |
10690 |
-- return MAX_CHUNK << CHUNK_SHIFT; |
10691 |
--} |
10692 |
-- |
10693 |
--static inline unsigned zbud_size_to_chunks(unsigned size) |
10694 |
--{ |
10695 |
-- BUG_ON(size == 0 || size > zbud_max_buddy_size()); |
10696 |
-- return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT; |
10697 |
--} |
10698 |
-- |
10699 |
--static inline int zbud_budnum(struct zbud_hdr *zh) |
10700 |
--{ |
10701 |
-- unsigned offset = (unsigned long)zh & (PAGE_SIZE - 1); |
10702 |
-- struct zbud_page *zbpg = NULL; |
10703 |
-- unsigned budnum = -1U; |
10704 |
-- int i; |
10705 |
-- |
10706 |
-- for (i = 0; i < ZBUD_MAX_BUDS; i++) |
10707 |
-- if (offset == offsetof(typeof(*zbpg), buddy[i])) { |
10708 |
-- budnum = i; |
10709 |
-- break; |
10710 |
-- } |
10711 |
-- BUG_ON(budnum == -1U); |
10712 |
-- return budnum; |
10713 |
--} |
10714 |
-- |
10715 |
--static char *zbud_data(struct zbud_hdr *zh, unsigned size) |
10716 |
--{ |
10717 |
-- struct zbud_page *zbpg; |
10718 |
-- char *p; |
10719 |
-- unsigned budnum; |
10720 |
-- |
10721 |
-- ASSERT_SENTINEL(zh, ZBH); |
10722 |
-- budnum = zbud_budnum(zh); |
10723 |
-- BUG_ON(size == 0 || size > zbud_max_buddy_size()); |
10724 |
-- zbpg = container_of(zh, struct zbud_page, buddy[budnum]); |
10725 |
-- ASSERT_SPINLOCK(&zbpg->lock); |
10726 |
-- p = (char *)zbpg; |
10727 |
-- if (budnum == 0) |
10728 |
-- p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & |
10729 |
-- CHUNK_MASK); |
10730 |
-- else if (budnum == 1) |
10731 |
-- p += PAGE_SIZE - ((size + CHUNK_SIZE - 1) & CHUNK_MASK); |
10732 |
-- return p; |
10733 |
--} |
10734 |
-- |
10735 |
--/* |
10736 |
-- * zbud raw page management |
10737 |
-- */ |
10738 |
-- |
10739 |
--static struct zbud_page *zbud_alloc_raw_page(void) |
10740 |
--{ |
10741 |
-- struct zbud_page *zbpg = NULL; |
10742 |
-- struct zbud_hdr *zh0, *zh1; |
10743 |
-- bool recycled = 0; |
10744 |
-- |
10745 |
-- /* if any pages on the zbpg list, use one */ |
10746 |
-- spin_lock(&zbpg_unused_list_spinlock); |
10747 |
-- if (!list_empty(&zbpg_unused_list)) { |
10748 |
-- zbpg = list_first_entry(&zbpg_unused_list, |
10749 |
-- struct zbud_page, bud_list); |
10750 |
-- list_del_init(&zbpg->bud_list); |
10751 |
-- zcache_zbpg_unused_list_count--; |
10752 |
-- recycled = 1; |
10753 |
-- } |
10754 |
-- spin_unlock(&zbpg_unused_list_spinlock); |
10755 |
-- if (zbpg == NULL) |
10756 |
-- /* none on zbpg list, try to get a kernel page */ |
10757 |
-- zbpg = zcache_get_free_page(); |
10758 |
-- if (likely(zbpg != NULL)) { |
10759 |
-- INIT_LIST_HEAD(&zbpg->bud_list); |
10760 |
-- zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; |
10761 |
-- spin_lock_init(&zbpg->lock); |
10762 |
-- if (recycled) { |
10763 |
-- ASSERT_INVERTED_SENTINEL(zbpg, ZBPG); |
10764 |
-- SET_SENTINEL(zbpg, ZBPG); |
10765 |
-- BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); |
10766 |
-- BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); |
10767 |
-- } else { |
10768 |
-- atomic_inc(&zcache_zbud_curr_raw_pages); |
10769 |
-- INIT_LIST_HEAD(&zbpg->bud_list); |
10770 |
-- SET_SENTINEL(zbpg, ZBPG); |
10771 |
-- zh0->size = 0; zh1->size = 0; |
10772 |
-- tmem_oid_set_invalid(&zh0->oid); |
10773 |
-- tmem_oid_set_invalid(&zh1->oid); |
10774 |
-- } |
10775 |
-- } |
10776 |
-- return zbpg; |
10777 |
--} |
10778 |
-- |
10779 |
--static void zbud_free_raw_page(struct zbud_page *zbpg) |
10780 |
--{ |
10781 |
-- struct zbud_hdr *zh0 = &zbpg->buddy[0], *zh1 = &zbpg->buddy[1]; |
10782 |
-- |
10783 |
-- ASSERT_SENTINEL(zbpg, ZBPG); |
10784 |
-- BUG_ON(!list_empty(&zbpg->bud_list)); |
10785 |
-- ASSERT_SPINLOCK(&zbpg->lock); |
10786 |
-- BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); |
10787 |
-- BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); |
10788 |
-- INVERT_SENTINEL(zbpg, ZBPG); |
10789 |
-- spin_unlock(&zbpg->lock); |
10790 |
-- spin_lock(&zbpg_unused_list_spinlock); |
10791 |
-- list_add(&zbpg->bud_list, &zbpg_unused_list); |
10792 |
-- zcache_zbpg_unused_list_count++; |
10793 |
-- spin_unlock(&zbpg_unused_list_spinlock); |
10794 |
--} |
10795 |
-- |
10796 |
--/* |
10797 |
-- * core zbud handling routines |
10798 |
-- */ |
10799 |
-- |
10800 |
--static unsigned zbud_free(struct zbud_hdr *zh) |
10801 |
--{ |
10802 |
-- unsigned size; |
10803 |
-- |
10804 |
-- ASSERT_SENTINEL(zh, ZBH); |
10805 |
-- BUG_ON(!tmem_oid_valid(&zh->oid)); |
10806 |
-- size = zh->size; |
10807 |
-- BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); |
10808 |
-- zh->size = 0; |
10809 |
-- tmem_oid_set_invalid(&zh->oid); |
10810 |
-- INVERT_SENTINEL(zh, ZBH); |
10811 |
-- zcache_zbud_curr_zbytes -= size; |
10812 |
-- atomic_dec(&zcache_zbud_curr_zpages); |
10813 |
-- return size; |
10814 |
--} |
10815 |
-- |
10816 |
--static void zbud_free_and_delist(struct zbud_hdr *zh) |
10817 |
--{ |
10818 |
-- unsigned chunks; |
10819 |
-- struct zbud_hdr *zh_other; |
10820 |
-- unsigned budnum = zbud_budnum(zh), size; |
10821 |
-- struct zbud_page *zbpg = |
10822 |
-- container_of(zh, struct zbud_page, buddy[budnum]); |
10823 |
-- |
10824 |
-- spin_lock(&zbpg->lock); |
10825 |
-- if (list_empty(&zbpg->bud_list)) { |
10826 |
-- /* ignore zombie page... see zbud_evict_pages() */ |
10827 |
-- spin_unlock(&zbpg->lock); |
10828 |
-- return; |
10829 |
-- } |
10830 |
-- size = zbud_free(zh); |
10831 |
-- ASSERT_SPINLOCK(&zbpg->lock); |
10832 |
-- zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0]; |
10833 |
-- if (zh_other->size == 0) { /* was unbuddied: unlist and free */ |
10834 |
-- chunks = zbud_size_to_chunks(size) ; |
10835 |
-- spin_lock(&zbud_budlists_spinlock); |
10836 |
-- BUG_ON(list_empty(&zbud_unbuddied[chunks].list)); |
10837 |
-- list_del_init(&zbpg->bud_list); |
10838 |
-- zbud_unbuddied[chunks].count--; |
10839 |
-- spin_unlock(&zbud_budlists_spinlock); |
10840 |
-- zbud_free_raw_page(zbpg); |
10841 |
-- } else { /* was buddied: move remaining buddy to unbuddied list */ |
10842 |
-- chunks = zbud_size_to_chunks(zh_other->size) ; |
10843 |
-- spin_lock(&zbud_budlists_spinlock); |
10844 |
-- list_del_init(&zbpg->bud_list); |
10845 |
-- zcache_zbud_buddied_count--; |
10846 |
-- list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list); |
10847 |
-- zbud_unbuddied[chunks].count++; |
10848 |
-- spin_unlock(&zbud_budlists_spinlock); |
10849 |
-- spin_unlock(&zbpg->lock); |
10850 |
-- } |
10851 |
--} |
10852 |
-- |
10853 |
--static struct zbud_hdr *zbud_create(uint32_t pool_id, struct tmem_oid *oid, |
10854 |
-- uint32_t index, struct page *page, |
10855 |
-- void *cdata, unsigned size) |
10856 |
--{ |
10857 |
-- struct zbud_hdr *zh0, *zh1, *zh = NULL; |
10858 |
-- struct zbud_page *zbpg = NULL, *ztmp; |
10859 |
-- unsigned nchunks; |
10860 |
-- char *to; |
10861 |
-- int i, found_good_buddy = 0; |
10862 |
-- |
10863 |
-- nchunks = zbud_size_to_chunks(size) ; |
10864 |
-- for (i = MAX_CHUNK - nchunks + 1; i > 0; i--) { |
10865 |
-- spin_lock(&zbud_budlists_spinlock); |
10866 |
-- if (!list_empty(&zbud_unbuddied[i].list)) { |
10867 |
-- list_for_each_entry_safe(zbpg, ztmp, |
10868 |
-- &zbud_unbuddied[i].list, bud_list) { |
10869 |
-- if (spin_trylock(&zbpg->lock)) { |
10870 |
-- found_good_buddy = i; |
10871 |
-- goto found_unbuddied; |
10872 |
-- } |
10873 |
-- } |
10874 |
-- } |
10875 |
-- spin_unlock(&zbud_budlists_spinlock); |
10876 |
-- } |
10877 |
-- /* didn't find a good buddy, try allocating a new page */ |
10878 |
-- zbpg = zbud_alloc_raw_page(); |
10879 |
-- if (unlikely(zbpg == NULL)) |
10880 |
-- goto out; |
10881 |
-- /* ok, have a page, now compress the data before taking locks */ |
10882 |
-- spin_lock(&zbpg->lock); |
10883 |
-- spin_lock(&zbud_budlists_spinlock); |
10884 |
-- list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list); |
10885 |
-- zbud_unbuddied[nchunks].count++; |
10886 |
-- zh = &zbpg->buddy[0]; |
10887 |
-- goto init_zh; |
10888 |
-- |
10889 |
--found_unbuddied: |
10890 |
-- ASSERT_SPINLOCK(&zbpg->lock); |
10891 |
-- zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; |
10892 |
-- BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0))); |
10893 |
-- if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */ |
10894 |
-- ASSERT_SENTINEL(zh0, ZBH); |
10895 |
-- zh = zh1; |
10896 |
-- } else if (zh1->size != 0) { /* buddy1 in use, buddy0 is vacant */ |
10897 |
-- ASSERT_SENTINEL(zh1, ZBH); |
10898 |
-- zh = zh0; |
10899 |
-- } else |
10900 |
-- BUG(); |
10901 |
-- list_del_init(&zbpg->bud_list); |
10902 |
-- zbud_unbuddied[found_good_buddy].count--; |
10903 |
-- list_add_tail(&zbpg->bud_list, &zbud_buddied_list); |
10904 |
-- zcache_zbud_buddied_count++; |
10905 |
-- |
10906 |
--init_zh: |
10907 |
-- SET_SENTINEL(zh, ZBH); |
10908 |
-- zh->size = size; |
10909 |
-- zh->index = index; |
10910 |
-- zh->oid = *oid; |
10911 |
-- zh->pool_id = pool_id; |
10912 |
-- /* can wait to copy the data until the list locks are dropped */ |
10913 |
-- spin_unlock(&zbud_budlists_spinlock); |
10914 |
-- |
10915 |
-- to = zbud_data(zh, size); |
10916 |
-- memcpy(to, cdata, size); |
10917 |
-- spin_unlock(&zbpg->lock); |
10918 |
-- zbud_cumul_chunk_counts[nchunks]++; |
10919 |
-- atomic_inc(&zcache_zbud_curr_zpages); |
10920 |
-- zcache_zbud_cumul_zpages++; |
10921 |
-- zcache_zbud_curr_zbytes += size; |
10922 |
-- zcache_zbud_cumul_zbytes += size; |
10923 |
--out: |
10924 |
-- return zh; |
10925 |
--} |
10926 |
-- |
10927 |
--static int zbud_decompress(struct page *page, struct zbud_hdr *zh) |
10928 |
--{ |
10929 |
-- struct zbud_page *zbpg; |
10930 |
-- unsigned budnum = zbud_budnum(zh); |
10931 |
-- size_t out_len = PAGE_SIZE; |
10932 |
-- char *to_va, *from_va; |
10933 |
-- unsigned size; |
10934 |
-- int ret = 0; |
10935 |
-- |
10936 |
-- zbpg = container_of(zh, struct zbud_page, buddy[budnum]); |
10937 |
-- spin_lock(&zbpg->lock); |
10938 |
-- if (list_empty(&zbpg->bud_list)) { |
10939 |
-- /* ignore zombie page... see zbud_evict_pages() */ |
10940 |
-- ret = -EINVAL; |
10941 |
-- goto out; |
10942 |
-- } |
10943 |
-- ASSERT_SENTINEL(zh, ZBH); |
10944 |
-- BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); |
10945 |
-- to_va = kmap_atomic(page, KM_USER0); |
10946 |
-- size = zh->size; |
10947 |
-- from_va = zbud_data(zh, size); |
10948 |
-- ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len); |
10949 |
-- BUG_ON(ret != LZO_E_OK); |
10950 |
-- BUG_ON(out_len != PAGE_SIZE); |
10951 |
-- kunmap_atomic(to_va, KM_USER0); |
10952 |
--out: |
10953 |
-- spin_unlock(&zbpg->lock); |
10954 |
-- return ret; |
10955 |
--} |
10956 |
-- |
10957 |
--/* |
10958 |
-- * The following routines handle shrinking of ephemeral pages by evicting |
10959 |
-- * pages "least valuable" first. |
10960 |
-- */ |
10961 |
-- |
10962 |
--static unsigned long zcache_evicted_raw_pages; |
10963 |
--static unsigned long zcache_evicted_buddied_pages; |
10964 |
--static unsigned long zcache_evicted_unbuddied_pages; |
10965 |
-- |
10966 |
--static struct tmem_pool *zcache_get_pool_by_id(uint32_t poolid); |
10967 |
--static void zcache_put_pool(struct tmem_pool *pool); |
10968 |
-- |
10969 |
--/* |
10970 |
-- * Flush and free all zbuds in a zbpg, then free the pageframe |
10971 |
-- */ |
10972 |
--static void zbud_evict_zbpg(struct zbud_page *zbpg) |
10973 |
--{ |
10974 |
-- struct zbud_hdr *zh; |
10975 |
-- int i, j; |
10976 |
-- uint32_t pool_id[ZBUD_MAX_BUDS], index[ZBUD_MAX_BUDS]; |
10977 |
-- struct tmem_oid oid[ZBUD_MAX_BUDS]; |
10978 |
-- struct tmem_pool *pool; |
10979 |
-- |
10980 |
-- ASSERT_SPINLOCK(&zbpg->lock); |
10981 |
-- BUG_ON(!list_empty(&zbpg->bud_list)); |
10982 |
-- for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) { |
10983 |
-- zh = &zbpg->buddy[i]; |
10984 |
-- if (zh->size) { |
10985 |
-- pool_id[j] = zh->pool_id; |
10986 |
-- oid[j] = zh->oid; |
10987 |
-- index[j] = zh->index; |
10988 |
-- j++; |
10989 |
-- zbud_free(zh); |
10990 |
-- } |
10991 |
-- } |
10992 |
-- spin_unlock(&zbpg->lock); |
10993 |
-- for (i = 0; i < j; i++) { |
10994 |
-- pool = zcache_get_pool_by_id(pool_id[i]); |
10995 |
-- if (pool != NULL) { |
10996 |
-- tmem_flush_page(pool, &oid[i], index[i]); |
10997 |
-- zcache_put_pool(pool); |
10998 |
-- } |
10999 |
-- } |
11000 |
-- ASSERT_SENTINEL(zbpg, ZBPG); |
11001 |
-- spin_lock(&zbpg->lock); |
11002 |
-- zbud_free_raw_page(zbpg); |
11003 |
--} |
11004 |
-- |
11005 |
--/* |
11006 |
-- * Free nr pages. This code is funky because we want to hold the locks |
11007 |
-- * protecting various lists for as short a time as possible, and in some |
11008 |
-- * circumstances the list may change asynchronously when the list lock is |
11009 |
-- * not held. In some cases we also trylock not only to avoid waiting on a |
11010 |
-- * page in use by another cpu, but also to avoid potential deadlock due to |
11011 |
-- * lock inversion. |
11012 |
-- */ |
11013 |
--static void zbud_evict_pages(int nr) |
11014 |
--{ |
11015 |
-- struct zbud_page *zbpg; |
11016 |
-- int i; |
11017 |
-- |
11018 |
-- /* first try freeing any pages on unused list */ |
11019 |
--retry_unused_list: |
11020 |
-- spin_lock_bh(&zbpg_unused_list_spinlock); |
11021 |
-- if (!list_empty(&zbpg_unused_list)) { |
11022 |
-- /* can't walk list here, since it may change when unlocked */ |
11023 |
-- zbpg = list_first_entry(&zbpg_unused_list, |
11024 |
-- struct zbud_page, bud_list); |
11025 |
-- list_del_init(&zbpg->bud_list); |
11026 |
-- zcache_zbpg_unused_list_count--; |
11027 |
-- atomic_dec(&zcache_zbud_curr_raw_pages); |
11028 |
-- spin_unlock_bh(&zbpg_unused_list_spinlock); |
11029 |
-- zcache_free_page(zbpg); |
11030 |
-- zcache_evicted_raw_pages++; |
11031 |
-- if (--nr <= 0) |
11032 |
-- goto out; |
11033 |
-- goto retry_unused_list; |
11034 |
-- } |
11035 |
-- spin_unlock_bh(&zbpg_unused_list_spinlock); |
11036 |
-- |
11037 |
-- /* now try freeing unbuddied pages, starting with least space avail */ |
11038 |
-- for (i = 0; i < MAX_CHUNK; i++) { |
11039 |
--retry_unbud_list_i: |
11040 |
-- spin_lock_bh(&zbud_budlists_spinlock); |
11041 |
-- if (list_empty(&zbud_unbuddied[i].list)) { |
11042 |
-- spin_unlock_bh(&zbud_budlists_spinlock); |
11043 |
-- continue; |
11044 |
-- } |
11045 |
-- list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { |
11046 |
-- if (unlikely(!spin_trylock(&zbpg->lock))) |
11047 |
-- continue; |
11048 |
-- list_del_init(&zbpg->bud_list); |
11049 |
-- zbud_unbuddied[i].count--; |
11050 |
-- spin_unlock(&zbud_budlists_spinlock); |
11051 |
-- zcache_evicted_unbuddied_pages++; |
11052 |
-- /* want budlists unlocked when doing zbpg eviction */ |
11053 |
-- zbud_evict_zbpg(zbpg); |
11054 |
-- local_bh_enable(); |
11055 |
-- if (--nr <= 0) |
11056 |
-- goto out; |
11057 |
-- goto retry_unbud_list_i; |
11058 |
-- } |
11059 |
-- spin_unlock_bh(&zbud_budlists_spinlock); |
11060 |
-- } |
11061 |
-- |
11062 |
-- /* as a last resort, free buddied pages */ |
11063 |
--retry_bud_list: |
11064 |
-- spin_lock_bh(&zbud_budlists_spinlock); |
11065 |
-- if (list_empty(&zbud_buddied_list)) { |
11066 |
-- spin_unlock_bh(&zbud_budlists_spinlock); |
11067 |
-- goto out; |
11068 |
-- } |
11069 |
-- list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { |
11070 |
-- if (unlikely(!spin_trylock(&zbpg->lock))) |
11071 |
-- continue; |
11072 |
-- list_del_init(&zbpg->bud_list); |
11073 |
-- zcache_zbud_buddied_count--; |
11074 |
-- spin_unlock(&zbud_budlists_spinlock); |
11075 |
-- zcache_evicted_buddied_pages++; |
11076 |
-- /* want budlists unlocked when doing zbpg eviction */ |
11077 |
-- zbud_evict_zbpg(zbpg); |
11078 |
-- local_bh_enable(); |
11079 |
-- if (--nr <= 0) |
11080 |
-- goto out; |
11081 |
-- goto retry_bud_list; |
11082 |
-- } |
11083 |
-- spin_unlock_bh(&zbud_budlists_spinlock); |
11084 |
--out: |
11085 |
-- return; |
11086 |
--} |
11087 |
-- |
11088 |
--static void zbud_init(void) |
11089 |
--{ |
11090 |
-- int i; |
11091 |
-- |
11092 |
-- INIT_LIST_HEAD(&zbud_buddied_list); |
11093 |
-- zcache_zbud_buddied_count = 0; |
11094 |
-- for (i = 0; i < NCHUNKS; i++) { |
11095 |
-- INIT_LIST_HEAD(&zbud_unbuddied[i].list); |
11096 |
-- zbud_unbuddied[i].count = 0; |
11097 |
-- } |
11098 |
--} |
11099 |
-- |
11100 |
--#ifdef CONFIG_SYSFS |
11101 |
--/* |
11102 |
-- * These sysfs routines show a nice distribution of how many zbpg's are |
11103 |
-- * currently (and have ever been placed) in each unbuddied list. It's fun |
11104 |
-- * to watch but can probably go away before final merge. |
11105 |
-- */ |
11106 |
--static int zbud_show_unbuddied_list_counts(char *buf) |
11107 |
--{ |
11108 |
-- int i; |
11109 |
-- char *p = buf; |
11110 |
-- |
11111 |
-- for (i = 0; i < NCHUNKS - 1; i++) |
11112 |
-- p += sprintf(p, "%u ", zbud_unbuddied[i].count); |
11113 |
-- p += sprintf(p, "%d\n", zbud_unbuddied[i].count); |
11114 |
-- return p - buf; |
11115 |
--} |
11116 |
-- |
11117 |
--static int zbud_show_cumul_chunk_counts(char *buf) |
11118 |
--{ |
11119 |
-- unsigned long i, chunks = 0, total_chunks = 0, sum_total_chunks = 0; |
11120 |
-- unsigned long total_chunks_lte_21 = 0, total_chunks_lte_32 = 0; |
11121 |
-- unsigned long total_chunks_lte_42 = 0; |
11122 |
-- char *p = buf; |
11123 |
-- |
11124 |
-- for (i = 0; i < NCHUNKS; i++) { |
11125 |
-- p += sprintf(p, "%lu ", zbud_cumul_chunk_counts[i]); |
11126 |
-- chunks += zbud_cumul_chunk_counts[i]; |
11127 |
-- total_chunks += zbud_cumul_chunk_counts[i]; |
11128 |
-- sum_total_chunks += i * zbud_cumul_chunk_counts[i]; |
11129 |
-- if (i == 21) |
11130 |
-- total_chunks_lte_21 = total_chunks; |
11131 |
-- if (i == 32) |
11132 |
-- total_chunks_lte_32 = total_chunks; |
11133 |
-- if (i == 42) |
11134 |
-- total_chunks_lte_42 = total_chunks; |
11135 |
-- } |
11136 |
-- p += sprintf(p, "<=21:%lu <=32:%lu <=42:%lu, mean:%lu\n", |
11137 |
-- total_chunks_lte_21, total_chunks_lte_32, total_chunks_lte_42, |
11138 |
-- chunks == 0 ? 0 : sum_total_chunks / chunks); |
11139 |
-- return p - buf; |
11140 |
--} |
11141 |
--#endif |
11142 |
-- |
11143 |
--/********** |
11144 |
-- * This "zv" PAM implementation combines the TLSF-based xvMalloc |
11145 |
-- * with lzo1x compression to maximize the amount of data that can |
11146 |
-- * be packed into a physical page. |
11147 |
-- * |
11148 |
-- * Zv represents a PAM page with the index and object (plus a "size" value |
11149 |
-- * necessary for decompression) immediately preceding the compressed data. |
11150 |
-- */ |
11151 |
-- |
11152 |
--#define ZVH_SENTINEL 0x43214321 |
11153 |
-- |
11154 |
--struct zv_hdr { |
11155 |
-- uint32_t pool_id; |
11156 |
-- struct tmem_oid oid; |
11157 |
-- uint32_t index; |
11158 |
-- DECL_SENTINEL |
11159 |
--}; |
11160 |
-- |
11161 |
--static const int zv_max_page_size = (PAGE_SIZE / 8) * 7; |
11162 |
-- |
11163 |
--static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, |
11164 |
-- struct tmem_oid *oid, uint32_t index, |
11165 |
-- void *cdata, unsigned clen) |
11166 |
--{ |
11167 |
-- struct page *page; |
11168 |
-- struct zv_hdr *zv = NULL; |
11169 |
-- uint32_t offset; |
11170 |
-- int ret; |
11171 |
-- |
11172 |
-- BUG_ON(!irqs_disabled()); |
11173 |
-- ret = xv_malloc(xvpool, clen + sizeof(struct zv_hdr), |
11174 |
-- &page, &offset, ZCACHE_GFP_MASK); |
11175 |
-- if (unlikely(ret)) |
11176 |
-- goto out; |
11177 |
-- zv = kmap_atomic(page, KM_USER0) + offset; |
11178 |
-- zv->index = index; |
11179 |
-- zv->oid = *oid; |
11180 |
-- zv->pool_id = pool_id; |
11181 |
-- SET_SENTINEL(zv, ZVH); |
11182 |
-- memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); |
11183 |
-- kunmap_atomic(zv, KM_USER0); |
11184 |
--out: |
11185 |
-- return zv; |
11186 |
--} |
11187 |
-- |
11188 |
--static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) |
11189 |
--{ |
11190 |
-- unsigned long flags; |
11191 |
-- struct page *page; |
11192 |
-- uint32_t offset; |
11193 |
-- uint16_t size; |
11194 |
-- |
11195 |
-- ASSERT_SENTINEL(zv, ZVH); |
11196 |
-- size = xv_get_object_size(zv) - sizeof(*zv); |
11197 |
-- BUG_ON(size == 0 || size > zv_max_page_size); |
11198 |
-- INVERT_SENTINEL(zv, ZVH); |
11199 |
-- page = virt_to_page(zv); |
11200 |
-- offset = (unsigned long)zv & ~PAGE_MASK; |
11201 |
-- local_irq_save(flags); |
11202 |
-- xv_free(xvpool, page, offset); |
11203 |
-- local_irq_restore(flags); |
11204 |
--} |
11205 |
-- |
11206 |
--static void zv_decompress(struct page *page, struct zv_hdr *zv) |
11207 |
--{ |
11208 |
-- size_t clen = PAGE_SIZE; |
11209 |
-- char *to_va; |
11210 |
-- unsigned size; |
11211 |
-- int ret; |
11212 |
-- |
11213 |
-- ASSERT_SENTINEL(zv, ZVH); |
11214 |
-- size = xv_get_object_size(zv) - sizeof(*zv); |
11215 |
-- BUG_ON(size == 0 || size > zv_max_page_size); |
11216 |
-- to_va = kmap_atomic(page, KM_USER0); |
11217 |
-- ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), |
11218 |
-- size, to_va, &clen); |
11219 |
-- kunmap_atomic(to_va, KM_USER0); |
11220 |
-- BUG_ON(ret != LZO_E_OK); |
11221 |
-- BUG_ON(clen != PAGE_SIZE); |
11222 |
--} |
11223 |
-- |
11224 |
--/* |
11225 |
-- * zcache core code starts here |
11226 |
-- */ |
11227 |
-- |
11228 |
--/* useful stats not collected by cleancache or frontswap */ |
11229 |
--static unsigned long zcache_flush_total; |
11230 |
--static unsigned long zcache_flush_found; |
11231 |
--static unsigned long zcache_flobj_total; |
11232 |
--static unsigned long zcache_flobj_found; |
11233 |
--static unsigned long zcache_failed_eph_puts; |
11234 |
--static unsigned long zcache_failed_pers_puts; |
11235 |
-- |
11236 |
--#define MAX_POOLS_PER_CLIENT 16 |
11237 |
-- |
11238 |
--static struct { |
11239 |
-- struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; |
11240 |
-- struct xv_pool *xvpool; |
11241 |
--} zcache_client; |
11242 |
-- |
11243 |
--/* |
11244 |
-- * Tmem operations assume the poolid implies the invoking client. |
11245 |
-- * Zcache only has one client (the kernel itself), so translate |
11246 |
-- * the poolid into the tmem_pool allocated for it. A KVM version |
11247 |
-- * of zcache would have one client per guest and each client might |
11248 |
-- * have a poolid==N. |
11249 |
-- */ |
11250 |
--static struct tmem_pool *zcache_get_pool_by_id(uint32_t poolid) |
11251 |
--{ |
11252 |
-- struct tmem_pool *pool = NULL; |
11253 |
-- |
11254 |
-- if (poolid >= 0) { |
11255 |
-- pool = zcache_client.tmem_pools[poolid]; |
11256 |
-- if (pool != NULL) |
11257 |
-- atomic_inc(&pool->refcount); |
11258 |
-- } |
11259 |
-- return pool; |
11260 |
--} |
11261 |
-- |
11262 |
--static void zcache_put_pool(struct tmem_pool *pool) |
11263 |
--{ |
11264 |
-- if (pool != NULL) |
11265 |
-- atomic_dec(&pool->refcount); |
11266 |
--} |
11267 |
-- |
11268 |
--/* counters for debugging */ |
11269 |
--static unsigned long zcache_failed_get_free_pages; |
11270 |
--static unsigned long zcache_failed_alloc; |
11271 |
--static unsigned long zcache_put_to_flush; |
11272 |
--static unsigned long zcache_aborted_preload; |
11273 |
--static unsigned long zcache_aborted_shrink; |
11274 |
-- |
11275 |
--/* |
11276 |
-- * Ensure that memory allocation requests in zcache don't result |
11277 |
-- * in direct reclaim requests via the shrinker, which would cause |
11278 |
-- * an infinite loop. Maybe a GFP flag would be better? |
11279 |
-- */ |
11280 |
--static DEFINE_SPINLOCK(zcache_direct_reclaim_lock); |
11281 |
-- |
11282 |
--/* |
11283 |
-- * for now, used named slabs so can easily track usage; later can |
11284 |
-- * either just use kmalloc, or perhaps add a slab-like allocator |
11285 |
-- * to more carefully manage total memory utilization |
11286 |
-- */ |
11287 |
--static struct kmem_cache *zcache_objnode_cache; |
11288 |
--static struct kmem_cache *zcache_obj_cache; |
11289 |
--static atomic_t zcache_curr_obj_count = ATOMIC_INIT(0); |
11290 |
--static unsigned long zcache_curr_obj_count_max; |
11291 |
--static atomic_t zcache_curr_objnode_count = ATOMIC_INIT(0); |
11292 |
--static unsigned long zcache_curr_objnode_count_max; |
11293 |
-- |
11294 |
--/* |
11295 |
-- * to avoid memory allocation recursion (e.g. due to direct reclaim), we |
11296 |
-- * preload all necessary data structures so the hostops callbacks never |
11297 |
-- * actually do a malloc |
11298 |
-- */ |
11299 |
--struct zcache_preload { |
11300 |
-- void *page; |
11301 |
-- struct tmem_obj *obj; |
11302 |
-- int nr; |
11303 |
-- struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH]; |
11304 |
--}; |
11305 |
--static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; |
11306 |
-- |
11307 |
--static int zcache_do_preload(struct tmem_pool *pool) |
11308 |
--{ |
11309 |
-- struct zcache_preload *kp; |
11310 |
-- struct tmem_objnode *objnode; |
11311 |
-- struct tmem_obj *obj; |
11312 |
-- void *page; |
11313 |
-- int ret = -ENOMEM; |
11314 |
-- |
11315 |
-- if (unlikely(zcache_objnode_cache == NULL)) |
11316 |
-- goto out; |
11317 |
-- if (unlikely(zcache_obj_cache == NULL)) |
11318 |
-- goto out; |
11319 |
-- if (!spin_trylock(&zcache_direct_reclaim_lock)) { |
11320 |
-- zcache_aborted_preload++; |
11321 |
-- goto out; |
11322 |
-- } |
11323 |
-- preempt_disable(); |
11324 |
-- kp = &__get_cpu_var(zcache_preloads); |
11325 |
-- while (kp->nr < ARRAY_SIZE(kp->objnodes)) { |
11326 |
-- preempt_enable_no_resched(); |
11327 |
-- objnode = kmem_cache_alloc(zcache_objnode_cache, |
11328 |
-- ZCACHE_GFP_MASK); |
11329 |
-- if (unlikely(objnode == NULL)) { |
11330 |
-- zcache_failed_alloc++; |
11331 |
-- goto unlock_out; |
11332 |
-- } |
11333 |
-- preempt_disable(); |
11334 |
-- kp = &__get_cpu_var(zcache_preloads); |
11335 |
-- if (kp->nr < ARRAY_SIZE(kp->objnodes)) |
11336 |
-- kp->objnodes[kp->nr++] = objnode; |
11337 |
-- else |
11338 |
-- kmem_cache_free(zcache_objnode_cache, objnode); |
11339 |
-- } |
11340 |
-- preempt_enable_no_resched(); |
11341 |
-- obj = kmem_cache_alloc(zcache_obj_cache, ZCACHE_GFP_MASK); |
11342 |
-- if (unlikely(obj == NULL)) { |
11343 |
-- zcache_failed_alloc++; |
11344 |
-- goto unlock_out; |
11345 |
-- } |
11346 |
-- page = (void *)__get_free_page(ZCACHE_GFP_MASK); |
11347 |
-- if (unlikely(page == NULL)) { |
11348 |
-- zcache_failed_get_free_pages++; |
11349 |
-- kmem_cache_free(zcache_obj_cache, obj); |
11350 |
-- goto unlock_out; |
11351 |
-- } |
11352 |
-- preempt_disable(); |
11353 |
-- kp = &__get_cpu_var(zcache_preloads); |
11354 |
-- if (kp->obj == NULL) |
11355 |
-- kp->obj = obj; |
11356 |
-- else |
11357 |
-- kmem_cache_free(zcache_obj_cache, obj); |
11358 |
-- if (kp->page == NULL) |
11359 |
-- kp->page = page; |
11360 |
-- else |
11361 |
-- free_page((unsigned long)page); |
11362 |
-- ret = 0; |
11363 |
--unlock_out: |
11364 |
-- spin_unlock(&zcache_direct_reclaim_lock); |
11365 |
--out: |
11366 |
-- return ret; |
11367 |
--} |
11368 |
-- |
11369 |
--static void *zcache_get_free_page(void) |
11370 |
--{ |
11371 |
-- struct zcache_preload *kp; |
11372 |
-- void *page; |
11373 |
-- |
11374 |
-- kp = &__get_cpu_var(zcache_preloads); |
11375 |
-- page = kp->page; |
11376 |
-- BUG_ON(page == NULL); |
11377 |
-- kp->page = NULL; |
11378 |
-- return page; |
11379 |
--} |
11380 |
-- |
11381 |
--static void zcache_free_page(void *p) |
11382 |
--{ |
11383 |
-- free_page((unsigned long)p); |
11384 |
--} |
11385 |
-- |
11386 |
--/* |
11387 |
-- * zcache implementation for tmem host ops |
11388 |
-- */ |
11389 |
-- |
11390 |
--static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) |
11391 |
--{ |
11392 |
-- struct tmem_objnode *objnode = NULL; |
11393 |
-- unsigned long count; |
11394 |
-- struct zcache_preload *kp; |
11395 |
-- |
11396 |
-- kp = &__get_cpu_var(zcache_preloads); |
11397 |
-- if (kp->nr <= 0) |
11398 |
-- goto out; |
11399 |
-- objnode = kp->objnodes[kp->nr - 1]; |
11400 |
-- BUG_ON(objnode == NULL); |
11401 |
-- kp->objnodes[kp->nr - 1] = NULL; |
11402 |
-- kp->nr--; |
11403 |
-- count = atomic_inc_return(&zcache_curr_objnode_count); |
11404 |
-- if (count > zcache_curr_objnode_count_max) |
11405 |
-- zcache_curr_objnode_count_max = count; |
11406 |
--out: |
11407 |
-- return objnode; |
11408 |
--} |
11409 |
-- |
11410 |
--static void zcache_objnode_free(struct tmem_objnode *objnode, |
11411 |
-- struct tmem_pool *pool) |
11412 |
--{ |
11413 |
-- atomic_dec(&zcache_curr_objnode_count); |
11414 |
-- BUG_ON(atomic_read(&zcache_curr_objnode_count) < 0); |
11415 |
-- kmem_cache_free(zcache_objnode_cache, objnode); |
11416 |
--} |
11417 |
-- |
11418 |
--static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) |
11419 |
--{ |
11420 |
-- struct tmem_obj *obj = NULL; |
11421 |
-- unsigned long count; |
11422 |
-- struct zcache_preload *kp; |
11423 |
-- |
11424 |
-- kp = &__get_cpu_var(zcache_preloads); |
11425 |
-- obj = kp->obj; |
11426 |
-- BUG_ON(obj == NULL); |
11427 |
-- kp->obj = NULL; |
11428 |
-- count = atomic_inc_return(&zcache_curr_obj_count); |
11429 |
-- if (count > zcache_curr_obj_count_max) |
11430 |
-- zcache_curr_obj_count_max = count; |
11431 |
-- return obj; |
11432 |
--} |
11433 |
-- |
11434 |
--static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) |
11435 |
--{ |
11436 |
-- atomic_dec(&zcache_curr_obj_count); |
11437 |
-- BUG_ON(atomic_read(&zcache_curr_obj_count) < 0); |
11438 |
-- kmem_cache_free(zcache_obj_cache, obj); |
11439 |
--} |
11440 |
-- |
11441 |
--static struct tmem_hostops zcache_hostops = { |
11442 |
-- .obj_alloc = zcache_obj_alloc, |
11443 |
-- .obj_free = zcache_obj_free, |
11444 |
-- .objnode_alloc = zcache_objnode_alloc, |
11445 |
-- .objnode_free = zcache_objnode_free, |
11446 |
--}; |
11447 |
-- |
11448 |
--/* |
11449 |
-- * zcache implementations for PAM page descriptor ops |
11450 |
-- */ |
11451 |
-- |
11452 |
--static atomic_t zcache_curr_eph_pampd_count = ATOMIC_INIT(0); |
11453 |
--static unsigned long zcache_curr_eph_pampd_count_max; |
11454 |
--static atomic_t zcache_curr_pers_pampd_count = ATOMIC_INIT(0); |
11455 |
--static unsigned long zcache_curr_pers_pampd_count_max; |
11456 |
-- |
11457 |
--/* forward reference */ |
11458 |
--static int zcache_compress(struct page *from, void **out_va, size_t *out_len); |
11459 |
-- |
11460 |
--static void *zcache_pampd_create(struct tmem_pool *pool, struct tmem_oid *oid, |
11461 |
-- uint32_t index, struct page *page) |
11462 |
--{ |
11463 |
-- void *pampd = NULL, *cdata; |
11464 |
-- size_t clen; |
11465 |
-- int ret; |
11466 |
-- bool ephemeral = is_ephemeral(pool); |
11467 |
-- unsigned long count; |
11468 |
-- |
11469 |
-- if (ephemeral) { |
11470 |
-- ret = zcache_compress(page, &cdata, &clen); |
11471 |
-- if (ret == 0) |
11472 |
-- |
11473 |
-- goto out; |
11474 |
-- if (clen == 0 || clen > zbud_max_buddy_size()) { |
11475 |
-- zcache_compress_poor++; |
11476 |
-- goto out; |
11477 |
-- } |
11478 |
-- pampd = (void *)zbud_create(pool->pool_id, oid, index, |
11479 |
-- page, cdata, clen); |
11480 |
-- if (pampd != NULL) { |
11481 |
-- count = atomic_inc_return(&zcache_curr_eph_pampd_count); |
11482 |
-- if (count > zcache_curr_eph_pampd_count_max) |
11483 |
-- zcache_curr_eph_pampd_count_max = count; |
11484 |
-- } |
11485 |
-- } else { |
11486 |
-- /* |
11487 |
-- * FIXME: This is all the "policy" there is for now. |
11488 |
-- * 3/4 totpages should allow ~37% of RAM to be filled with |
11489 |
-- * compressed frontswap pages |
11490 |
-- */ |
11491 |
-- if (atomic_read(&zcache_curr_pers_pampd_count) > |
11492 |
-- 3 * totalram_pages / 4) |
11493 |
-- goto out; |
11494 |
-- ret = zcache_compress(page, &cdata, &clen); |
11495 |
-- if (ret == 0) |
11496 |
-- goto out; |
11497 |
-- if (clen > zv_max_page_size) { |
11498 |
-- zcache_compress_poor++; |
11499 |
-- goto out; |
11500 |
-- } |
11501 |
-- pampd = (void *)zv_create(zcache_client.xvpool, pool->pool_id, |
11502 |
-- oid, index, cdata, clen); |
11503 |
-- if (pampd == NULL) |
11504 |
-- goto out; |
11505 |
-- count = atomic_inc_return(&zcache_curr_pers_pampd_count); |
11506 |
-- if (count > zcache_curr_pers_pampd_count_max) |
11507 |
-- zcache_curr_pers_pampd_count_max = count; |
11508 |
-- } |
11509 |
--out: |
11510 |
-- return pampd; |
11511 |
--} |
11512 |
-- |
11513 |
--/* |
11514 |
-- * fill the pageframe corresponding to the struct page with the data |
11515 |
-- * from the passed pampd |
11516 |
-- */ |
11517 |
--static int zcache_pampd_get_data(struct page *page, void *pampd, |
11518 |
-- struct tmem_pool *pool) |
11519 |
--{ |
11520 |
-- int ret = 0; |
11521 |
-- |
11522 |
-- if (is_ephemeral(pool)) |
11523 |
-- ret = zbud_decompress(page, pampd); |
11524 |
-- else |
11525 |
-- zv_decompress(page, pampd); |
11526 |
-- return ret; |
11527 |
--} |
11528 |
-- |
11529 |
--/* |
11530 |
-- * free the pampd and remove it from any zcache lists |
11531 |
-- * pampd must no longer be pointed to from any tmem data structures! |
11532 |
-- */ |
11533 |
--static void zcache_pampd_free(void *pampd, struct tmem_pool *pool) |
11534 |
--{ |
11535 |
-- if (is_ephemeral(pool)) { |
11536 |
-- zbud_free_and_delist((struct zbud_hdr *)pampd); |
11537 |
-- atomic_dec(&zcache_curr_eph_pampd_count); |
11538 |
-- BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0); |
11539 |
-- } else { |
11540 |
-- zv_free(zcache_client.xvpool, (struct zv_hdr *)pampd); |
11541 |
-- atomic_dec(&zcache_curr_pers_pampd_count); |
11542 |
-- BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0); |
11543 |
-- } |
11544 |
--} |
11545 |
-- |
11546 |
--static struct tmem_pamops zcache_pamops = { |
11547 |
-- .create = zcache_pampd_create, |
11548 |
-- .get_data = zcache_pampd_get_data, |
11549 |
-- .free = zcache_pampd_free, |
11550 |
--}; |
11551 |
-- |
11552 |
--/* |
11553 |
-- * zcache compression/decompression and related per-cpu stuff |
11554 |
-- */ |
11555 |
-- |
11556 |
--#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS |
11557 |
--#define LZO_DSTMEM_PAGE_ORDER 1 |
11558 |
--static DEFINE_PER_CPU(unsigned char *, zcache_workmem); |
11559 |
--static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); |
11560 |
-- |
11561 |
--static int zcache_compress(struct page *from, void **out_va, size_t *out_len) |
11562 |
--{ |
11563 |
-- int ret = 0; |
11564 |
-- unsigned char *dmem = __get_cpu_var(zcache_dstmem); |
11565 |
-- unsigned char *wmem = __get_cpu_var(zcache_workmem); |
11566 |
-- char *from_va; |
11567 |
-- |
11568 |
-- BUG_ON(!irqs_disabled()); |
11569 |
-- if (unlikely(dmem == NULL || wmem == NULL)) |
11570 |
-- goto out; /* no buffer, so can't compress */ |
11571 |
-- from_va = kmap_atomic(from, KM_USER0); |
11572 |
-- mb(); |
11573 |
-- ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem); |
11574 |
-- BUG_ON(ret != LZO_E_OK); |
11575 |
-- *out_va = dmem; |
11576 |
-- kunmap_atomic(from_va, KM_USER0); |
11577 |
-- ret = 1; |
11578 |
--out: |
11579 |
-- return ret; |
11580 |
--} |
11581 |
-- |
11582 |
-- |
11583 |
--static int zcache_cpu_notifier(struct notifier_block *nb, |
11584 |
-- unsigned long action, void *pcpu) |
11585 |
--{ |
11586 |
-- int cpu = (long)pcpu; |
11587 |
-- struct zcache_preload *kp; |
11588 |
-- |
11589 |
-- switch (action) { |
11590 |
-- case CPU_UP_PREPARE: |
11591 |
-- per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( |
11592 |
-- GFP_KERNEL | __GFP_REPEAT, |
11593 |
-- LZO_DSTMEM_PAGE_ORDER), |
11594 |
-- per_cpu(zcache_workmem, cpu) = |
11595 |
-- kzalloc(LZO1X_MEM_COMPRESS, |
11596 |
-- GFP_KERNEL | __GFP_REPEAT); |
11597 |
-- break; |
11598 |
-- case CPU_DEAD: |
11599 |
-- case CPU_UP_CANCELED: |
11600 |
-- free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), |
11601 |
-- LZO_DSTMEM_PAGE_ORDER); |
11602 |
-- per_cpu(zcache_dstmem, cpu) = NULL; |
11603 |
-- kfree(per_cpu(zcache_workmem, cpu)); |
11604 |
-- per_cpu(zcache_workmem, cpu) = NULL; |
11605 |
-- kp = &per_cpu(zcache_preloads, cpu); |
11606 |
-- while (kp->nr) { |
11607 |
-- kmem_cache_free(zcache_objnode_cache, |
11608 |
-- kp->objnodes[kp->nr - 1]); |
11609 |
-- kp->objnodes[kp->nr - 1] = NULL; |
11610 |
-- kp->nr--; |
11611 |
-- } |
11612 |
-- kmem_cache_free(zcache_obj_cache, kp->obj); |
11613 |
-- free_page((unsigned long)kp->page); |
11614 |
-- break; |
11615 |
-- default: |
11616 |
-- break; |
11617 |
-- } |
11618 |
-- return NOTIFY_OK; |
11619 |
--} |
11620 |
-- |
11621 |
--static struct notifier_block zcache_cpu_notifier_block = { |
11622 |
-- .notifier_call = zcache_cpu_notifier |
11623 |
--}; |
11624 |
-- |
11625 |
--#ifdef CONFIG_SYSFS |
11626 |
--#define ZCACHE_SYSFS_RO(_name) \ |
11627 |
-- static ssize_t zcache_##_name##_show(struct kobject *kobj, \ |
11628 |
-- struct kobj_attribute *attr, char *buf) \ |
11629 |
-- { \ |
11630 |
-- return sprintf(buf, "%lu\n", zcache_##_name); \ |
11631 |
-- } \ |
11632 |
-- static struct kobj_attribute zcache_##_name##_attr = { \ |
11633 |
-- .attr = { .name = __stringify(_name), .mode = 0444 }, \ |
11634 |
-- .show = zcache_##_name##_show, \ |
11635 |
-- } |
11636 |
-- |
11637 |
--#define ZCACHE_SYSFS_RO_ATOMIC(_name) \ |
11638 |
-- static ssize_t zcache_##_name##_show(struct kobject *kobj, \ |
11639 |
-- struct kobj_attribute *attr, char *buf) \ |
11640 |
-- { \ |
11641 |
-- return sprintf(buf, "%d\n", atomic_read(&zcache_##_name)); \ |
11642 |
-- } \ |
11643 |
-- static struct kobj_attribute zcache_##_name##_attr = { \ |
11644 |
-- .attr = { .name = __stringify(_name), .mode = 0444 }, \ |
11645 |
-- .show = zcache_##_name##_show, \ |
11646 |
-- } |
11647 |
-- |
11648 |
--#define ZCACHE_SYSFS_RO_CUSTOM(_name, _func) \ |
11649 |
-- static ssize_t zcache_##_name##_show(struct kobject *kobj, \ |
11650 |
-- struct kobj_attribute *attr, char *buf) \ |
11651 |
-- { \ |
11652 |
-- return _func(buf); \ |
11653 |
-- } \ |
11654 |
-- static struct kobj_attribute zcache_##_name##_attr = { \ |
11655 |
-- .attr = { .name = __stringify(_name), .mode = 0444 }, \ |
11656 |
-- .show = zcache_##_name##_show, \ |
11657 |
-- } |
11658 |
-- |
11659 |
--ZCACHE_SYSFS_RO(curr_obj_count_max); |
11660 |
--ZCACHE_SYSFS_RO(curr_objnode_count_max); |
11661 |
--ZCACHE_SYSFS_RO(flush_total); |
11662 |
--ZCACHE_SYSFS_RO(flush_found); |
11663 |
--ZCACHE_SYSFS_RO(flobj_total); |
11664 |
--ZCACHE_SYSFS_RO(flobj_found); |
11665 |
--ZCACHE_SYSFS_RO(failed_eph_puts); |
11666 |
--ZCACHE_SYSFS_RO(failed_pers_puts); |
11667 |
--ZCACHE_SYSFS_RO(zbud_curr_zbytes); |
11668 |
--ZCACHE_SYSFS_RO(zbud_cumul_zpages); |
11669 |
--ZCACHE_SYSFS_RO(zbud_cumul_zbytes); |
11670 |
--ZCACHE_SYSFS_RO(zbud_buddied_count); |
11671 |
--ZCACHE_SYSFS_RO(zbpg_unused_list_count); |
11672 |
--ZCACHE_SYSFS_RO(evicted_raw_pages); |
11673 |
--ZCACHE_SYSFS_RO(evicted_unbuddied_pages); |
11674 |
--ZCACHE_SYSFS_RO(evicted_buddied_pages); |
11675 |
--ZCACHE_SYSFS_RO(failed_get_free_pages); |
11676 |
--ZCACHE_SYSFS_RO(failed_alloc); |
11677 |
--ZCACHE_SYSFS_RO(put_to_flush); |
11678 |
--ZCACHE_SYSFS_RO(aborted_preload); |
11679 |
--ZCACHE_SYSFS_RO(aborted_shrink); |
11680 |
--ZCACHE_SYSFS_RO(compress_poor); |
11681 |
--ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages); |
11682 |
--ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages); |
11683 |
--ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count); |
11684 |
--ZCACHE_SYSFS_RO_ATOMIC(curr_objnode_count); |
11685 |
--ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts, |
11686 |
-- zbud_show_unbuddied_list_counts); |
11687 |
--ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts, |
11688 |
-- zbud_show_cumul_chunk_counts); |
11689 |
-- |
11690 |
--static struct attribute *zcache_attrs[] = { |
11691 |
-- &zcache_curr_obj_count_attr.attr, |
11692 |
-- &zcache_curr_obj_count_max_attr.attr, |
11693 |
-- &zcache_curr_objnode_count_attr.attr, |
11694 |
-- &zcache_curr_objnode_count_max_attr.attr, |
11695 |
-- &zcache_flush_total_attr.attr, |
11696 |
-- &zcache_flobj_total_attr.attr, |
11697 |
-- &zcache_flush_found_attr.attr, |
11698 |
-- &zcache_flobj_found_attr.attr, |
11699 |
-- &zcache_failed_eph_puts_attr.attr, |
11700 |
-- &zcache_failed_pers_puts_attr.attr, |
11701 |
-- &zcache_compress_poor_attr.attr, |
11702 |
-- &zcache_zbud_curr_raw_pages_attr.attr, |
11703 |
-- &zcache_zbud_curr_zpages_attr.attr, |
11704 |
-- &zcache_zbud_curr_zbytes_attr.attr, |
11705 |
-- &zcache_zbud_cumul_zpages_attr.attr, |
11706 |
-- &zcache_zbud_cumul_zbytes_attr.attr, |
11707 |
-- &zcache_zbud_buddied_count_attr.attr, |
11708 |
-- &zcache_zbpg_unused_list_count_attr.attr, |
11709 |
-- &zcache_evicted_raw_pages_attr.attr, |
11710 |
-- &zcache_evicted_unbuddied_pages_attr.attr, |
11711 |
-- &zcache_evicted_buddied_pages_attr.attr, |
11712 |
-- &zcache_failed_get_free_pages_attr.attr, |
11713 |
-- &zcache_failed_alloc_attr.attr, |
11714 |
-- &zcache_put_to_flush_attr.attr, |
11715 |
-- &zcache_aborted_preload_attr.attr, |
11716 |
-- &zcache_aborted_shrink_attr.attr, |
11717 |
-- &zcache_zbud_unbuddied_list_counts_attr.attr, |
11718 |
-- &zcache_zbud_cumul_chunk_counts_attr.attr, |
11719 |
-- NULL, |
11720 |
--}; |
11721 |
-- |
11722 |
--static struct attribute_group zcache_attr_group = { |
11723 |
-- .attrs = zcache_attrs, |
11724 |
-- .name = "zcache", |
11725 |
--}; |
11726 |
-- |
11727 |
--#endif /* CONFIG_SYSFS */ |
11728 |
--/* |
11729 |
-- * When zcache is disabled ("frozen"), pools can be created and destroyed, |
11730 |
-- * but all puts (and thus all other operations that require memory allocation) |
11731 |
-- * must fail. If zcache is unfrozen, accepts puts, then frozen again, |
11732 |
-- * data consistency requires all puts while frozen to be converted into |
11733 |
-- * flushes. |
11734 |
-- */ |
11735 |
--static bool zcache_freeze; |
11736 |
-- |
11737 |
--/* |
11738 |
-- * zcache shrinker interface (only useful for ephemeral pages, so zbud only) |
11739 |
-- */ |
11740 |
--static int shrink_zcache_memory(struct shrinker *shrink, |
11741 |
-- struct shrink_control *sc) |
11742 |
--{ |
11743 |
-- int ret = -1; |
11744 |
-- int nr = sc->nr_to_scan; |
11745 |
-- gfp_t gfp_mask = sc->gfp_mask; |
11746 |
-- |
11747 |
-- if (nr >= 0) { |
11748 |
-- if (!(gfp_mask & __GFP_FS)) |
11749 |
-- /* does this case really need to be skipped? */ |
11750 |
-- goto out; |
11751 |
-- if (spin_trylock(&zcache_direct_reclaim_lock)) { |
11752 |
-- zbud_evict_pages(nr); |
11753 |
-- spin_unlock(&zcache_direct_reclaim_lock); |
11754 |
-- } else |
11755 |
-- zcache_aborted_shrink++; |
11756 |
-- } |
11757 |
-- ret = (int)atomic_read(&zcache_zbud_curr_raw_pages); |
11758 |
--out: |
11759 |
-- return ret; |
11760 |
--} |
11761 |
-- |
11762 |
--static struct shrinker zcache_shrinker = { |
11763 |
-- .shrink = shrink_zcache_memory, |
11764 |
-- .seeks = DEFAULT_SEEKS, |
11765 |
--}; |
11766 |
-- |
11767 |
--/* |
11768 |
-- * zcache shims between cleancache/frontswap ops and tmem |
11769 |
-- */ |
11770 |
-- |
11771 |
--static int zcache_put_page(int pool_id, struct tmem_oid *oidp, |
11772 |
-- uint32_t index, struct page *page) |
11773 |
--{ |
11774 |
-- struct tmem_pool *pool; |
11775 |
-- int ret = -1; |
11776 |
-- |
11777 |
-- BUG_ON(!irqs_disabled()); |
11778 |
-- pool = zcache_get_pool_by_id(pool_id); |
11779 |
-- if (unlikely(pool == NULL)) |
11780 |
-- goto out; |
11781 |
-- if (!zcache_freeze && zcache_do_preload(pool) == 0) { |
11782 |
-- /* preload does preempt_disable on success */ |
11783 |
-- ret = tmem_put(pool, oidp, index, page); |
11784 |
-- if (ret < 0) { |
11785 |
-- if (is_ephemeral(pool)) |
11786 |
-- zcache_failed_eph_puts++; |
11787 |
-- else |
11788 |
-- zcache_failed_pers_puts++; |
11789 |
-- } |
11790 |
-- zcache_put_pool(pool); |
11791 |
-- preempt_enable_no_resched(); |
11792 |
-- } else { |
11793 |
-- zcache_put_to_flush++; |
11794 |
-- if (atomic_read(&pool->obj_count) > 0) |
11795 |
-- /* the put fails whether the flush succeeds or not */ |
11796 |
-- (void)tmem_flush_page(pool, oidp, index); |
11797 |
-- zcache_put_pool(pool); |
11798 |
-- } |
11799 |
--out: |
11800 |
-- return ret; |
11801 |
--} |
11802 |
-- |
11803 |
--static int zcache_get_page(int pool_id, struct tmem_oid *oidp, |
11804 |
-- uint32_t index, struct page *page) |
11805 |
--{ |
11806 |
-- struct tmem_pool *pool; |
11807 |
-- int ret = -1; |
11808 |
-- unsigned long flags; |
11809 |
-- |
11810 |
-- local_irq_save(flags); |
11811 |
-- pool = zcache_get_pool_by_id(pool_id); |
11812 |
-- if (likely(pool != NULL)) { |
11813 |
-- if (atomic_read(&pool->obj_count) > 0) |
11814 |
-- ret = tmem_get(pool, oidp, index, page); |
11815 |
-- zcache_put_pool(pool); |
11816 |
-- } |
11817 |
-- local_irq_restore(flags); |
11818 |
-- return ret; |
11819 |
--} |
11820 |
-- |
11821 |
--static int zcache_flush_page(int pool_id, struct tmem_oid *oidp, uint32_t index) |
11822 |
--{ |
11823 |
-- struct tmem_pool *pool; |
11824 |
-- int ret = -1; |
11825 |
-- unsigned long flags; |
11826 |
-- |
11827 |
-- local_irq_save(flags); |
11828 |
-- zcache_flush_total++; |
11829 |
-- pool = zcache_get_pool_by_id(pool_id); |
11830 |
-- if (likely(pool != NULL)) { |
11831 |
-- if (atomic_read(&pool->obj_count) > 0) |
11832 |
-- ret = tmem_flush_page(pool, oidp, index); |
11833 |
-- zcache_put_pool(pool); |
11834 |
-- } |
11835 |
-- if (ret >= 0) |
11836 |
-- zcache_flush_found++; |
11837 |
-- local_irq_restore(flags); |
11838 |
-- return ret; |
11839 |
--} |
11840 |
-- |
11841 |
--static int zcache_flush_object(int pool_id, struct tmem_oid *oidp) |
11842 |
--{ |
11843 |
-- struct tmem_pool *pool; |
11844 |
-- int ret = -1; |
11845 |
-- unsigned long flags; |
11846 |
-- |
11847 |
-- local_irq_save(flags); |
11848 |
-- zcache_flobj_total++; |
11849 |
-- pool = zcache_get_pool_by_id(pool_id); |
11850 |
-- if (likely(pool != NULL)) { |
11851 |
-- if (atomic_read(&pool->obj_count) > 0) |
11852 |
-- ret = tmem_flush_object(pool, oidp); |
11853 |
-- zcache_put_pool(pool); |
11854 |
-- } |
11855 |
-- if (ret >= 0) |
11856 |
-- zcache_flobj_found++; |
11857 |
-- local_irq_restore(flags); |
11858 |
-- return ret; |
11859 |
--} |
11860 |
-- |
11861 |
--static int zcache_destroy_pool(int pool_id) |
11862 |
--{ |
11863 |
-- struct tmem_pool *pool = NULL; |
11864 |
-- int ret = -1; |
11865 |
-- |
11866 |
-- if (pool_id < 0) |
11867 |
-- goto out; |
11868 |
-- pool = zcache_client.tmem_pools[pool_id]; |
11869 |
-- if (pool == NULL) |
11870 |
-- goto out; |
11871 |
-- zcache_client.tmem_pools[pool_id] = NULL; |
11872 |
-- /* wait for pool activity on other cpus to quiesce */ |
11873 |
-- while (atomic_read(&pool->refcount) != 0) |
11874 |
-- ; |
11875 |
-- local_bh_disable(); |
11876 |
-- ret = tmem_destroy_pool(pool); |
11877 |
-- local_bh_enable(); |
11878 |
-- kfree(pool); |
11879 |
-- pr_info("zcache: destroyed pool id=%d\n", pool_id); |
11880 |
--out: |
11881 |
-- return ret; |
11882 |
--} |
11883 |
-- |
11884 |
--static int zcache_new_pool(uint32_t flags) |
11885 |
--{ |
11886 |
-- int poolid = -1; |
11887 |
-- struct tmem_pool *pool; |
11888 |
-- |
11889 |
-- pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); |
11890 |
-- if (pool == NULL) { |
11891 |
-- pr_info("zcache: pool creation failed: out of memory\n"); |
11892 |
-- goto out; |
11893 |
-- } |
11894 |
-- |
11895 |
-- for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) |
11896 |
-- if (zcache_client.tmem_pools[poolid] == NULL) |
11897 |
-- break; |
11898 |
-- if (poolid >= MAX_POOLS_PER_CLIENT) { |
11899 |
-- pr_info("zcache: pool creation failed: max exceeded\n"); |
11900 |
-- kfree(pool); |
11901 |
-- poolid = -1; |
11902 |
-- goto out; |
11903 |
-- } |
11904 |
-- atomic_set(&pool->refcount, 0); |
11905 |
-- pool->client = &zcache_client; |
11906 |
-- pool->pool_id = poolid; |
11907 |
-- tmem_new_pool(pool, flags); |
11908 |
-- zcache_client.tmem_pools[poolid] = pool; |
11909 |
-- pr_info("zcache: created %s tmem pool, id=%d\n", |
11910 |
-- flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", |
11911 |
-- poolid); |
11912 |
--out: |
11913 |
-- return poolid; |
11914 |
--} |
11915 |
-- |
11916 |
--/********** |
11917 |
-- * Two kernel functionalities currently can be layered on top of tmem. |
11918 |
-- * These are "cleancache" which is used as a second-chance cache for clean |
11919 |
-- * page cache pages; and "frontswap" which is used for swap pages |
11920 |
-- * to avoid writes to disk. A generic "shim" is provided here for each |
11921 |
-- * to translate in-kernel semantics to zcache semantics. |
11922 |
-- */ |
11923 |
-- |
11924 |
--#ifdef CONFIG_CLEANCACHE |
11925 |
--static void zcache_cleancache_put_page(int pool_id, |
11926 |
-- struct cleancache_filekey key, |
11927 |
-- pgoff_t index, struct page *page) |
11928 |
--{ |
11929 |
-- u32 ind = (u32) index; |
11930 |
-- struct tmem_oid oid = *(struct tmem_oid *)&key; |
11931 |
-- |
11932 |
-- if (likely(ind == index)) |
11933 |
-- (void)zcache_put_page(pool_id, &oid, index, page); |
11934 |
--} |
11935 |
-- |
11936 |
--static int zcache_cleancache_get_page(int pool_id, |
11937 |
-- struct cleancache_filekey key, |
11938 |
-- pgoff_t index, struct page *page) |
11939 |
--{ |
11940 |
-- u32 ind = (u32) index; |
11941 |
-- struct tmem_oid oid = *(struct tmem_oid *)&key; |
11942 |
-- int ret = -1; |
11943 |
-- |
11944 |
-- if (likely(ind == index)) |
11945 |
-- ret = zcache_get_page(pool_id, &oid, index, page); |
11946 |
-- return ret; |
11947 |
--} |
11948 |
-- |
11949 |
--static void zcache_cleancache_flush_page(int pool_id, |
11950 |
-- struct cleancache_filekey key, |
11951 |
-- pgoff_t index) |
11952 |
--{ |
11953 |
-- u32 ind = (u32) index; |
11954 |
-- struct tmem_oid oid = *(struct tmem_oid *)&key; |
11955 |
-- |
11956 |
-- if (likely(ind == index)) |
11957 |
-- (void)zcache_flush_page(pool_id, &oid, ind); |
11958 |
--} |
11959 |
-- |
11960 |
--static void zcache_cleancache_flush_inode(int pool_id, |
11961 |
-- struct cleancache_filekey key) |
11962 |
--{ |
11963 |
-- struct tmem_oid oid = *(struct tmem_oid *)&key; |
11964 |
-- |
11965 |
-- (void)zcache_flush_object(pool_id, &oid); |
11966 |
--} |
11967 |
-- |
11968 |
--static void zcache_cleancache_flush_fs(int pool_id) |
11969 |
--{ |
11970 |
-- if (pool_id >= 0) |
11971 |
-- (void)zcache_destroy_pool(pool_id); |
11972 |
--} |
11973 |
-- |
11974 |
--static int zcache_cleancache_init_fs(size_t pagesize) |
11975 |
--{ |
11976 |
-- BUG_ON(sizeof(struct cleancache_filekey) != |
11977 |
-- sizeof(struct tmem_oid)); |
11978 |
-- BUG_ON(pagesize != PAGE_SIZE); |
11979 |
-- return zcache_new_pool(0); |
11980 |
--} |
11981 |
-- |
11982 |
--static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) |
11983 |
--{ |
11984 |
-- /* shared pools are unsupported and map to private */ |
11985 |
-- BUG_ON(sizeof(struct cleancache_filekey) != |
11986 |
-- sizeof(struct tmem_oid)); |
11987 |
-- BUG_ON(pagesize != PAGE_SIZE); |
11988 |
-- return zcache_new_pool(0); |
11989 |
--} |
11990 |
-- |
11991 |
--static struct cleancache_ops zcache_cleancache_ops = { |
11992 |
-- .put_page = zcache_cleancache_put_page, |
11993 |
-- .get_page = zcache_cleancache_get_page, |
11994 |
-- .flush_page = zcache_cleancache_flush_page, |
11995 |
-- .flush_inode = zcache_cleancache_flush_inode, |
11996 |
-- .flush_fs = zcache_cleancache_flush_fs, |
11997 |
-- .init_shared_fs = zcache_cleancache_init_shared_fs, |
11998 |
-- .init_fs = zcache_cleancache_init_fs |
11999 |
--}; |
12000 |
-- |
12001 |
--struct cleancache_ops zcache_cleancache_register_ops(void) |
12002 |
--{ |
12003 |
-- struct cleancache_ops old_ops = |
12004 |
-- cleancache_register_ops(&zcache_cleancache_ops); |
12005 |
-- |
12006 |
-- return old_ops; |
12007 |
--} |
12008 |
--#endif |
12009 |
-- |
12010 |
--#ifdef CONFIG_FRONTSWAP |
12011 |
--/* a single tmem poolid is used for all frontswap "types" (swapfiles) */ |
12012 |
--static int zcache_frontswap_poolid = -1; |
12013 |
-- |
12014 |
--/* |
12015 |
-- * Swizzling increases objects per swaptype, increasing tmem concurrency |
12016 |
-- * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS |
12017 |
-- */ |
12018 |
--#define SWIZ_BITS 4 |
12019 |
--#define SWIZ_MASK ((1 << SWIZ_BITS) - 1) |
12020 |
--#define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK)) |
12021 |
--#define iswiz(_ind) (_ind >> SWIZ_BITS) |
12022 |
-- |
12023 |
--static inline struct tmem_oid oswiz(unsigned type, u32 ind) |
12024 |
--{ |
12025 |
-- struct tmem_oid oid = { .oid = { 0 } }; |
12026 |
-- oid.oid[0] = _oswiz(type, ind); |
12027 |
-- return oid; |
12028 |
--} |
12029 |
-- |
12030 |
--static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, |
12031 |
-- struct page *page) |
12032 |
--{ |
12033 |
-- u64 ind64 = (u64)offset; |
12034 |
-- u32 ind = (u32)offset; |
12035 |
-- struct tmem_oid oid = oswiz(type, ind); |
12036 |
-- int ret = -1; |
12037 |
-- unsigned long flags; |
12038 |
-- |
12039 |
-- BUG_ON(!PageLocked(page)); |
12040 |
-- if (likely(ind64 == ind)) { |
12041 |
-- local_irq_save(flags); |
12042 |
-- ret = zcache_put_page(zcache_frontswap_poolid, &oid, |
12043 |
-- iswiz(ind), page); |
12044 |
-- local_irq_restore(flags); |
12045 |
-- } |
12046 |
-- return ret; |
12047 |
--} |
12048 |
-- |
12049 |
--/* returns 0 if the page was successfully gotten from frontswap, -1 if |
12050 |
-- * was not present (should never happen!) */ |
12051 |
--static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, |
12052 |
-- struct page *page) |
12053 |
--{ |
12054 |
-- u64 ind64 = (u64)offset; |
12055 |
-- u32 ind = (u32)offset; |
12056 |
-- struct tmem_oid oid = oswiz(type, ind); |
12057 |
-- int ret = -1; |
12058 |
-- |
12059 |
-- BUG_ON(!PageLocked(page)); |
12060 |
-- if (likely(ind64 == ind)) |
12061 |
-- ret = zcache_get_page(zcache_frontswap_poolid, &oid, |
12062 |
-- iswiz(ind), page); |
12063 |
-- return ret; |
12064 |
--} |
12065 |
-- |
12066 |
--/* flush a single page from frontswap */ |
12067 |
--static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) |
12068 |
--{ |
12069 |
-- u64 ind64 = (u64)offset; |
12070 |
-- u32 ind = (u32)offset; |
12071 |
-- struct tmem_oid oid = oswiz(type, ind); |
12072 |
-- |
12073 |
-- if (likely(ind64 == ind)) |
12074 |
-- (void)zcache_flush_page(zcache_frontswap_poolid, &oid, |
12075 |
-- iswiz(ind)); |
12076 |
--} |
12077 |
-- |
12078 |
--/* flush all pages from the passed swaptype */ |
12079 |
--static void zcache_frontswap_flush_area(unsigned type) |
12080 |
--{ |
12081 |
-- struct tmem_oid oid; |
12082 |
-- int ind; |
12083 |
-- |
12084 |
-- for (ind = SWIZ_MASK; ind >= 0; ind--) { |
12085 |
-- oid = oswiz(type, ind); |
12086 |
-- (void)zcache_flush_object(zcache_frontswap_poolid, &oid); |
12087 |
-- } |
12088 |
--} |
12089 |
-- |
12090 |
--static void zcache_frontswap_init(unsigned ignored) |
12091 |
--{ |
12092 |
-- /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ |
12093 |
-- if (zcache_frontswap_poolid < 0) |
12094 |
-- zcache_frontswap_poolid = zcache_new_pool(TMEM_POOL_PERSIST); |
12095 |
--} |
12096 |
-- |
12097 |
--static struct frontswap_ops zcache_frontswap_ops = { |
12098 |
-- .put_page = zcache_frontswap_put_page, |
12099 |
-- .get_page = zcache_frontswap_get_page, |
12100 |
-- .flush_page = zcache_frontswap_flush_page, |
12101 |
-- .flush_area = zcache_frontswap_flush_area, |
12102 |
-- .init = zcache_frontswap_init |
12103 |
--}; |
12104 |
-- |
12105 |
--struct frontswap_ops zcache_frontswap_register_ops(void) |
12106 |
--{ |
12107 |
-- struct frontswap_ops old_ops = |
12108 |
-- frontswap_register_ops(&zcache_frontswap_ops); |
12109 |
-- |
12110 |
-- return old_ops; |
12111 |
--} |
12112 |
--#endif |
12113 |
-- |
12114 |
--/* |
12115 |
-- * zcache initialization |
12116 |
-- * NOTE FOR NOW zcache MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR |
12117 |
-- * NOTHING HAPPENS! |
12118 |
-- */ |
12119 |
-- |
12120 |
--static int zcache_enabled; |
12121 |
-- |
12122 |
--static int __init enable_zcache(char *s) |
12123 |
--{ |
12124 |
-- zcache_enabled = 1; |
12125 |
-- return 1; |
12126 |
--} |
12127 |
--__setup("zcache", enable_zcache); |
12128 |
-- |
12129 |
--/* allow independent dynamic disabling of cleancache and frontswap */ |
12130 |
-- |
12131 |
--static int use_cleancache = 1; |
12132 |
-- |
12133 |
--static int __init no_cleancache(char *s) |
12134 |
--{ |
12135 |
-- use_cleancache = 0; |
12136 |
-- return 1; |
12137 |
--} |
12138 |
-- |
12139 |
--__setup("nocleancache", no_cleancache); |
12140 |
-- |
12141 |
--static int use_frontswap = 1; |
12142 |
-- |
12143 |
--static int __init no_frontswap(char *s) |
12144 |
--{ |
12145 |
-- use_frontswap = 0; |
12146 |
-- return 1; |
12147 |
--} |
12148 |
-- |
12149 |
--__setup("nofrontswap", no_frontswap); |
12150 |
-- |
12151 |
--static int __init zcache_init(void) |
12152 |
--{ |
12153 |
--#ifdef CONFIG_SYSFS |
12154 |
-- int ret = 0; |
12155 |
-- |
12156 |
-- ret = sysfs_create_group(mm_kobj, &zcache_attr_group); |
12157 |
-- if (ret) { |
12158 |
-- pr_err("zcache: can't create sysfs\n"); |
12159 |
-- goto out; |
12160 |
-- } |
12161 |
--#endif /* CONFIG_SYSFS */ |
12162 |
--#if defined(CONFIG_CLEANCACHE) || defined(CONFIG_FRONTSWAP) |
12163 |
-- if (zcache_enabled) { |
12164 |
-- unsigned int cpu; |
12165 |
-- |
12166 |
-- tmem_register_hostops(&zcache_hostops); |
12167 |
-- tmem_register_pamops(&zcache_pamops); |
12168 |
-- ret = register_cpu_notifier(&zcache_cpu_notifier_block); |
12169 |
-- if (ret) { |
12170 |
-- pr_err("zcache: can't register cpu notifier\n"); |
12171 |
-- goto out; |
12172 |
-- } |
12173 |
-- for_each_online_cpu(cpu) { |
12174 |
-- void *pcpu = (void *)(long)cpu; |
12175 |
-- zcache_cpu_notifier(&zcache_cpu_notifier_block, |
12176 |
-- CPU_UP_PREPARE, pcpu); |
12177 |
-- } |
12178 |
-- } |
12179 |
-- zcache_objnode_cache = kmem_cache_create("zcache_objnode", |
12180 |
-- sizeof(struct tmem_objnode), 0, 0, NULL); |
12181 |
-- zcache_obj_cache = kmem_cache_create("zcache_obj", |
12182 |
-- sizeof(struct tmem_obj), 0, 0, NULL); |
12183 |
--#endif |
12184 |
--#ifdef CONFIG_CLEANCACHE |
12185 |
-- if (zcache_enabled && use_cleancache) { |
12186 |
-- struct cleancache_ops old_ops; |
12187 |
-- |
12188 |
-- zbud_init(); |
12189 |
-- register_shrinker(&zcache_shrinker); |
12190 |
-- old_ops = zcache_cleancache_register_ops(); |
12191 |
-- pr_info("zcache: cleancache enabled using kernel " |
12192 |
-- "transcendent memory and compression buddies\n"); |
12193 |
-- if (old_ops.init_fs != NULL) |
12194 |
-- pr_warning("zcache: cleancache_ops overridden"); |
12195 |
-- } |
12196 |
--#endif |
12197 |
--#ifdef CONFIG_FRONTSWAP |
12198 |
-- if (zcache_enabled && use_frontswap) { |
12199 |
-- struct frontswap_ops old_ops; |
12200 |
-- |
12201 |
-- zcache_client.xvpool = xv_create_pool(); |
12202 |
-- if (zcache_client.xvpool == NULL) { |
12203 |
-- pr_err("zcache: can't create xvpool\n"); |
12204 |
-- goto out; |
12205 |
-- } |
12206 |
-- old_ops = zcache_frontswap_register_ops(); |
12207 |
-- pr_info("zcache: frontswap enabled using kernel " |
12208 |
-- "transcendent memory and xvmalloc\n"); |
12209 |
-- if (old_ops.init != NULL) |
12210 |
-- pr_warning("ktmem: frontswap_ops overridden"); |
12211 |
-- } |
12212 |
--#endif |
12213 |
--out: |
12214 |
-- return ret; |
12215 |
--} |
12216 |
-- |
12217 |
--module_init(zcache_init) |
12218 |
-diff --git a/drivers/staging/zcache/zcache_drv.c b/drivers/staging/zcache/zcache_drv.c |
12219 |
-new file mode 100644 |
12220 |
-index 0000000..77ac2d4 |
12221 |
---- /dev/null |
12222 |
-+++ b/drivers/staging/zcache/zcache_drv.c |
12223 |
-@@ -0,0 +1,1661 @@ |
12224 |
-+/* |
12225 |
-+ * zcache.c |
12226 |
-+ * |
12227 |
-+ * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp. |
12228 |
-+ * Copyright (c) 2010,2011, Nitin Gupta |
12229 |
-+ * |
12230 |
-+ * Zcache provides an in-kernel "host implementation" for transcendent memory |
12231 |
-+ * and, thus indirectly, for cleancache and frontswap. Zcache includes two |
12232 |
-+ * page-accessible memory [1] interfaces, both utilizing lzo1x compression: |
12233 |
-+ * 1) "compression buddies" ("zbud") is used for ephemeral pages |
12234 |
-+ * 2) xvmalloc is used for persistent pages. |
12235 |
-+ * Xvmalloc (based on the TLSF allocator) has very low fragmentation |
12236 |
-+ * so maximizes space efficiency, while zbud allows pairs (and potentially, |
12237 |
-+ * in the future, more than a pair of) compressed pages to be closely linked |
12238 |
-+ * so that reclaiming can be done via the kernel's physical-page-oriented |
12239 |
-+ * "shrinker" interface. |
12240 |
-+ * |
12241 |
-+ * [1] For a definition of page-accessible memory (aka PAM), see: |
12242 |
-+ * http://marc.info/?l=linux-mm&m=127811271605009 |
12243 |
-+ */ |
12244 |
-+ |
12245 |
-+#include <linux/cpu.h> |
12246 |
-+#include <linux/highmem.h> |
12247 |
-+#include <linux/list.h> |
12248 |
-+#include <linux/lzo.h> |
12249 |
-+#include <linux/slab.h> |
12250 |
-+#include <linux/spinlock.h> |
12251 |
-+#include <linux/types.h> |
12252 |
-+#include <linux/atomic.h> |
12253 |
-+#include "tmem.h" |
12254 |
-+ |
12255 |
-+#include "../zram/xvmalloc.h" /* if built in drivers/staging */ |
12256 |
-+ |
12257 |
-+#if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP)) |
12258 |
-+#error "zcache is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" |
12259 |
-+#endif |
12260 |
-+#ifdef CONFIG_CLEANCACHE |
12261 |
-+#include <linux/cleancache.h> |
12262 |
-+#endif |
12263 |
-+#ifdef CONFIG_FRONTSWAP |
12264 |
-+#include <linux/frontswap.h> |
12265 |
-+#endif |
12266 |
-+ |
12267 |
-+#if 0 |
12268 |
-+/* this is more aggressive but may cause other problems? */ |
12269 |
-+#define ZCACHE_GFP_MASK (GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN) |
12270 |
-+#else |
12271 |
-+#define ZCACHE_GFP_MASK \ |
12272 |
-+ (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) |
12273 |
-+#endif |
12274 |
-+ |
12275 |
-+/********** |
12276 |
-+ * Compression buddies ("zbud") provides for packing two (or, possibly |
12277 |
-+ * in the future, more) compressed ephemeral pages into a single "raw" |
12278 |
-+ * (physical) page and tracking them with data structures so that |
12279 |
-+ * the raw pages can be easily reclaimed. |
12280 |
-+ * |
12281 |
-+ * A zbud page ("zbpg") is an aligned page containing a list_head, |
12282 |
-+ * a lock, and two "zbud headers". The remainder of the physical |
12283 |
-+ * page is divided up into aligned 64-byte "chunks" which contain |
12284 |
-+ * the compressed data for zero, one, or two zbuds. Each zbpg |
12285 |
-+ * resides on: (1) an "unused list" if it has no zbuds; (2) a |
12286 |
-+ * "buddied" list if it is fully populated with two zbuds; or |
12287 |
-+ * (3) one of PAGE_SIZE/64 "unbuddied" lists indexed by how many chunks |
12288 |
-+ * the one unbuddied zbud uses. The data inside a zbpg cannot be |
12289 |
-+ * read or written unless the zbpg's lock is held. |
12290 |
-+ */ |
12291 |
-+ |
12292 |
-+#define ZBH_SENTINEL 0x43214321 |
12293 |
-+#define ZBPG_SENTINEL 0xdeadbeef |
12294 |
-+ |
12295 |
-+#define ZBUD_MAX_BUDS 2 |
12296 |
-+ |
12297 |
-+struct zbud_hdr { |
12298 |
-+ uint32_t pool_id; |
12299 |
-+ struct tmem_oid oid; |
12300 |
-+ uint32_t index; |
12301 |
-+ uint16_t size; /* compressed size in bytes, zero means unused */ |
12302 |
-+ DECL_SENTINEL |
12303 |
-+}; |
12304 |
-+ |
12305 |
-+struct zbud_page { |
12306 |
-+ struct list_head bud_list; |
12307 |
-+ spinlock_t lock; |
12308 |
-+ struct zbud_hdr buddy[ZBUD_MAX_BUDS]; |
12309 |
-+ DECL_SENTINEL |
12310 |
-+ /* followed by NUM_CHUNK aligned CHUNK_SIZE-byte chunks */ |
12311 |
-+}; |
12312 |
-+ |
12313 |
-+#define CHUNK_SHIFT 6 |
12314 |
-+#define CHUNK_SIZE (1 << CHUNK_SHIFT) |
12315 |
-+#define CHUNK_MASK (~(CHUNK_SIZE-1)) |
12316 |
-+#define NCHUNKS (((PAGE_SIZE - sizeof(struct zbud_page)) & \ |
12317 |
-+ CHUNK_MASK) >> CHUNK_SHIFT) |
12318 |
-+#define MAX_CHUNK (NCHUNKS-1) |
12319 |
-+ |
12320 |
-+static struct { |
12321 |
-+ struct list_head list; |
12322 |
-+ unsigned count; |
12323 |
-+} zbud_unbuddied[NCHUNKS]; |
12324 |
-+/* list N contains pages with N chunks USED and NCHUNKS-N unused */ |
12325 |
-+/* element 0 is never used but optimizing that isn't worth it */ |
12326 |
-+static unsigned long zbud_cumul_chunk_counts[NCHUNKS]; |
12327 |
-+ |
12328 |
-+struct list_head zbud_buddied_list; |
12329 |
-+static unsigned long zcache_zbud_buddied_count; |
12330 |
-+ |
12331 |
-+/* protects the buddied list and all unbuddied lists */ |
12332 |
-+static DEFINE_SPINLOCK(zbud_budlists_spinlock); |
12333 |
-+ |
12334 |
-+static LIST_HEAD(zbpg_unused_list); |
12335 |
-+static unsigned long zcache_zbpg_unused_list_count; |
12336 |
-+ |
12337 |
-+/* protects the unused page list */ |
12338 |
-+static DEFINE_SPINLOCK(zbpg_unused_list_spinlock); |
12339 |
-+ |
12340 |
-+static atomic_t zcache_zbud_curr_raw_pages; |
12341 |
-+static atomic_t zcache_zbud_curr_zpages; |
12342 |
-+static unsigned long zcache_zbud_curr_zbytes; |
12343 |
-+static unsigned long zcache_zbud_cumul_zpages; |
12344 |
-+static unsigned long zcache_zbud_cumul_zbytes; |
12345 |
-+static unsigned long zcache_compress_poor; |
12346 |
-+ |
12347 |
-+/* forward references */ |
12348 |
-+static void *zcache_get_free_page(void); |
12349 |
-+static void zcache_free_page(void *p); |
12350 |
-+ |
12351 |
-+/* |
12352 |
-+ * zbud helper functions |
12353 |
-+ */ |
12354 |
-+ |
12355 |
-+static inline unsigned zbud_max_buddy_size(void) |
12356 |
-+{ |
12357 |
-+ return MAX_CHUNK << CHUNK_SHIFT; |
12358 |
-+} |
12359 |
-+ |
12360 |
-+static inline unsigned zbud_size_to_chunks(unsigned size) |
12361 |
-+{ |
12362 |
-+ BUG_ON(size == 0 || size > zbud_max_buddy_size()); |
12363 |
-+ return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT; |
12364 |
-+} |
12365 |
-+ |
12366 |
-+static inline int zbud_budnum(struct zbud_hdr *zh) |
12367 |
-+{ |
12368 |
-+ unsigned offset = (unsigned long)zh & (PAGE_SIZE - 1); |
12369 |
-+ struct zbud_page *zbpg = NULL; |
12370 |
-+ unsigned budnum = -1U; |
12371 |
-+ int i; |
12372 |
-+ |
12373 |
-+ for (i = 0; i < ZBUD_MAX_BUDS; i++) |
12374 |
-+ if (offset == offsetof(typeof(*zbpg), buddy[i])) { |
12375 |
-+ budnum = i; |
12376 |
-+ break; |
12377 |
-+ } |
12378 |
-+ BUG_ON(budnum == -1U); |
12379 |
-+ return budnum; |
12380 |
-+} |
12381 |
-+ |
12382 |
-+static char *zbud_data(struct zbud_hdr *zh, unsigned size) |
12383 |
-+{ |
12384 |
-+ struct zbud_page *zbpg; |
12385 |
-+ char *p; |
12386 |
-+ unsigned budnum; |
12387 |
-+ |
12388 |
-+ ASSERT_SENTINEL(zh, ZBH); |
12389 |
-+ budnum = zbud_budnum(zh); |
12390 |
-+ BUG_ON(size == 0 || size > zbud_max_buddy_size()); |
12391 |
-+ zbpg = container_of(zh, struct zbud_page, buddy[budnum]); |
12392 |
-+ ASSERT_SPINLOCK(&zbpg->lock); |
12393 |
-+ p = (char *)zbpg; |
12394 |
-+ if (budnum == 0) |
12395 |
-+ p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & |
12396 |
-+ CHUNK_MASK); |
12397 |
-+ else if (budnum == 1) |
12398 |
-+ p += PAGE_SIZE - ((size + CHUNK_SIZE - 1) & CHUNK_MASK); |
12399 |
-+ return p; |
12400 |
-+} |
12401 |
-+ |
12402 |
-+/* |
12403 |
-+ * zbud raw page management |
12404 |
-+ */ |
12405 |
-+ |
12406 |
-+static struct zbud_page *zbud_alloc_raw_page(void) |
12407 |
-+{ |
12408 |
-+ struct zbud_page *zbpg = NULL; |
12409 |
-+ struct zbud_hdr *zh0, *zh1; |
12410 |
-+ bool recycled = 0; |
12411 |
-+ |
12412 |
-+ /* if any pages on the zbpg list, use one */ |
12413 |
-+ spin_lock(&zbpg_unused_list_spinlock); |
12414 |
-+ if (!list_empty(&zbpg_unused_list)) { |
12415 |
-+ zbpg = list_first_entry(&zbpg_unused_list, |
12416 |
-+ struct zbud_page, bud_list); |
12417 |
-+ list_del_init(&zbpg->bud_list); |
12418 |
-+ zcache_zbpg_unused_list_count--; |
12419 |
-+ recycled = 1; |
12420 |
-+ } |
12421 |
-+ spin_unlock(&zbpg_unused_list_spinlock); |
12422 |
-+ if (zbpg == NULL) |
12423 |
-+ /* none on zbpg list, try to get a kernel page */ |
12424 |
-+ zbpg = zcache_get_free_page(); |
12425 |
-+ if (likely(zbpg != NULL)) { |
12426 |
-+ INIT_LIST_HEAD(&zbpg->bud_list); |
12427 |
-+ zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; |
12428 |
-+ spin_lock_init(&zbpg->lock); |
12429 |
-+ if (recycled) { |
12430 |
-+ ASSERT_INVERTED_SENTINEL(zbpg, ZBPG); |
12431 |
-+ SET_SENTINEL(zbpg, ZBPG); |
12432 |
-+ BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); |
12433 |
-+ BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); |
12434 |
-+ } else { |
12435 |
-+ atomic_inc(&zcache_zbud_curr_raw_pages); |
12436 |
-+ INIT_LIST_HEAD(&zbpg->bud_list); |
12437 |
-+ SET_SENTINEL(zbpg, ZBPG); |
12438 |
-+ zh0->size = 0; zh1->size = 0; |
12439 |
-+ tmem_oid_set_invalid(&zh0->oid); |
12440 |
-+ tmem_oid_set_invalid(&zh1->oid); |
12441 |
-+ } |
12442 |
-+ } |
12443 |
-+ return zbpg; |
12444 |
-+} |
12445 |
-+ |
12446 |
-+static void zbud_free_raw_page(struct zbud_page *zbpg) |
12447 |
-+{ |
12448 |
-+ struct zbud_hdr *zh0 = &zbpg->buddy[0], *zh1 = &zbpg->buddy[1]; |
12449 |
-+ |
12450 |
-+ ASSERT_SENTINEL(zbpg, ZBPG); |
12451 |
-+ BUG_ON(!list_empty(&zbpg->bud_list)); |
12452 |
-+ ASSERT_SPINLOCK(&zbpg->lock); |
12453 |
-+ BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); |
12454 |
-+ BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); |
12455 |
-+ INVERT_SENTINEL(zbpg, ZBPG); |
12456 |
-+ spin_unlock(&zbpg->lock); |
12457 |
-+ spin_lock(&zbpg_unused_list_spinlock); |
12458 |
-+ list_add(&zbpg->bud_list, &zbpg_unused_list); |
12459 |
-+ zcache_zbpg_unused_list_count++; |
12460 |
-+ spin_unlock(&zbpg_unused_list_spinlock); |
12461 |
-+} |
12462 |
-+ |
12463 |
-+/* |
12464 |
-+ * core zbud handling routines |
12465 |
-+ */ |
12466 |
-+ |
12467 |
-+static unsigned zbud_free(struct zbud_hdr *zh) |
12468 |
-+{ |
12469 |
-+ unsigned size; |
12470 |
-+ |
12471 |
-+ ASSERT_SENTINEL(zh, ZBH); |
12472 |
-+ BUG_ON(!tmem_oid_valid(&zh->oid)); |
12473 |
-+ size = zh->size; |
12474 |
-+ BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); |
12475 |
-+ zh->size = 0; |
12476 |
-+ tmem_oid_set_invalid(&zh->oid); |
12477 |
-+ INVERT_SENTINEL(zh, ZBH); |
12478 |
-+ zcache_zbud_curr_zbytes -= size; |
12479 |
-+ atomic_dec(&zcache_zbud_curr_zpages); |
12480 |
-+ return size; |
12481 |
-+} |
12482 |
-+ |
12483 |
-+static void zbud_free_and_delist(struct zbud_hdr *zh) |
12484 |
-+{ |
12485 |
-+ unsigned chunks; |
12486 |
-+ struct zbud_hdr *zh_other; |
12487 |
-+ unsigned budnum = zbud_budnum(zh), size; |
12488 |
-+ struct zbud_page *zbpg = |
12489 |
-+ container_of(zh, struct zbud_page, buddy[budnum]); |
12490 |
-+ |
12491 |
-+ spin_lock(&zbpg->lock); |
12492 |
-+ if (list_empty(&zbpg->bud_list)) { |
12493 |
-+ /* ignore zombie page... see zbud_evict_pages() */ |
12494 |
-+ spin_unlock(&zbpg->lock); |
12495 |
-+ return; |
12496 |
-+ } |
12497 |
-+ size = zbud_free(zh); |
12498 |
-+ ASSERT_SPINLOCK(&zbpg->lock); |
12499 |
-+ zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0]; |
12500 |
-+ if (zh_other->size == 0) { /* was unbuddied: unlist and free */ |
12501 |
-+ chunks = zbud_size_to_chunks(size) ; |
12502 |
-+ spin_lock(&zbud_budlists_spinlock); |
12503 |
-+ BUG_ON(list_empty(&zbud_unbuddied[chunks].list)); |
12504 |
-+ list_del_init(&zbpg->bud_list); |
12505 |
-+ zbud_unbuddied[chunks].count--; |
12506 |
-+ spin_unlock(&zbud_budlists_spinlock); |
12507 |
-+ zbud_free_raw_page(zbpg); |
12508 |
-+ } else { /* was buddied: move remaining buddy to unbuddied list */ |
12509 |
-+ chunks = zbud_size_to_chunks(zh_other->size) ; |
12510 |
-+ spin_lock(&zbud_budlists_spinlock); |
12511 |
-+ list_del_init(&zbpg->bud_list); |
12512 |
-+ zcache_zbud_buddied_count--; |
12513 |
-+ list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list); |
12514 |
-+ zbud_unbuddied[chunks].count++; |
12515 |
-+ spin_unlock(&zbud_budlists_spinlock); |
12516 |
-+ spin_unlock(&zbpg->lock); |
12517 |
-+ } |
12518 |
-+} |
12519 |
-+ |
12520 |
-+static struct zbud_hdr *zbud_create(uint32_t pool_id, struct tmem_oid *oid, |
12521 |
-+ uint32_t index, struct page *page, |
12522 |
-+ void *cdata, unsigned size) |
12523 |
-+{ |
12524 |
-+ struct zbud_hdr *zh0, *zh1, *zh = NULL; |
12525 |
-+ struct zbud_page *zbpg = NULL, *ztmp; |
12526 |
-+ unsigned nchunks; |
12527 |
-+ char *to; |
12528 |
-+ int i, found_good_buddy = 0; |
12529 |
-+ |
12530 |
-+ nchunks = zbud_size_to_chunks(size) ; |
12531 |
-+ for (i = MAX_CHUNK - nchunks + 1; i > 0; i--) { |
12532 |
-+ spin_lock(&zbud_budlists_spinlock); |
12533 |
-+ if (!list_empty(&zbud_unbuddied[i].list)) { |
12534 |
-+ list_for_each_entry_safe(zbpg, ztmp, |
12535 |
-+ &zbud_unbuddied[i].list, bud_list) { |
12536 |
-+ if (spin_trylock(&zbpg->lock)) { |
12537 |
-+ found_good_buddy = i; |
12538 |
-+ goto found_unbuddied; |
12539 |
-+ } |
12540 |
-+ } |
12541 |
-+ } |
12542 |
-+ spin_unlock(&zbud_budlists_spinlock); |
12543 |
-+ } |
12544 |
-+ /* didn't find a good buddy, try allocating a new page */ |
12545 |
-+ zbpg = zbud_alloc_raw_page(); |
12546 |
-+ if (unlikely(zbpg == NULL)) |
12547 |
-+ goto out; |
12548 |
-+ /* ok, have a page, now compress the data before taking locks */ |
12549 |
-+ spin_lock(&zbpg->lock); |
12550 |
-+ spin_lock(&zbud_budlists_spinlock); |
12551 |
-+ list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list); |
12552 |
-+ zbud_unbuddied[nchunks].count++; |
12553 |
-+ zh = &zbpg->buddy[0]; |
12554 |
-+ goto init_zh; |
12555 |
-+ |
12556 |
-+found_unbuddied: |
12557 |
-+ ASSERT_SPINLOCK(&zbpg->lock); |
12558 |
-+ zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; |
12559 |
-+ BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0))); |
12560 |
-+ if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */ |
12561 |
-+ ASSERT_SENTINEL(zh0, ZBH); |
12562 |
-+ zh = zh1; |
12563 |
-+ } else if (zh1->size != 0) { /* buddy1 in use, buddy0 is vacant */ |
12564 |
-+ ASSERT_SENTINEL(zh1, ZBH); |
12565 |
-+ zh = zh0; |
12566 |
-+ } else |
12567 |
-+ BUG(); |
12568 |
-+ list_del_init(&zbpg->bud_list); |
12569 |
-+ zbud_unbuddied[found_good_buddy].count--; |
12570 |
-+ list_add_tail(&zbpg->bud_list, &zbud_buddied_list); |
12571 |
-+ zcache_zbud_buddied_count++; |
12572 |
-+ |
12573 |
-+init_zh: |
12574 |
-+ SET_SENTINEL(zh, ZBH); |
12575 |
-+ zh->size = size; |
12576 |
-+ zh->index = index; |
12577 |
-+ zh->oid = *oid; |
12578 |
-+ zh->pool_id = pool_id; |
12579 |
-+ /* can wait to copy the data until the list locks are dropped */ |
12580 |
-+ spin_unlock(&zbud_budlists_spinlock); |
12581 |
-+ |
12582 |
-+ to = zbud_data(zh, size); |
12583 |
-+ memcpy(to, cdata, size); |
12584 |
-+ spin_unlock(&zbpg->lock); |
12585 |
-+ zbud_cumul_chunk_counts[nchunks]++; |
12586 |
-+ atomic_inc(&zcache_zbud_curr_zpages); |
12587 |
-+ zcache_zbud_cumul_zpages++; |
12588 |
-+ zcache_zbud_curr_zbytes += size; |
12589 |
-+ zcache_zbud_cumul_zbytes += size; |
12590 |
-+out: |
12591 |
-+ return zh; |
12592 |
-+} |
12593 |
-+ |
12594 |
-+static int zbud_decompress(struct page *page, struct zbud_hdr *zh) |
12595 |
-+{ |
12596 |
-+ struct zbud_page *zbpg; |
12597 |
-+ unsigned budnum = zbud_budnum(zh); |
12598 |
-+ size_t out_len = PAGE_SIZE; |
12599 |
-+ char *to_va, *from_va; |
12600 |
-+ unsigned size; |
12601 |
-+ int ret = 0; |
12602 |
-+ |
12603 |
-+ zbpg = container_of(zh, struct zbud_page, buddy[budnum]); |
12604 |
-+ spin_lock(&zbpg->lock); |
12605 |
-+ if (list_empty(&zbpg->bud_list)) { |
12606 |
-+ /* ignore zombie page... see zbud_evict_pages() */ |
12607 |
-+ ret = -EINVAL; |
12608 |
-+ goto out; |
12609 |
-+ } |
12610 |
-+ ASSERT_SENTINEL(zh, ZBH); |
12611 |
-+ BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); |
12612 |
-+ to_va = kmap_atomic(page, KM_USER0); |
12613 |
-+ size = zh->size; |
12614 |
-+ from_va = zbud_data(zh, size); |
12615 |
-+ ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len); |
12616 |
-+ BUG_ON(ret != LZO_E_OK); |
12617 |
-+ BUG_ON(out_len != PAGE_SIZE); |
12618 |
-+ kunmap_atomic(to_va, KM_USER0); |
12619 |
-+out: |
12620 |
-+ spin_unlock(&zbpg->lock); |
12621 |
-+ return ret; |
12622 |
-+} |
12623 |
-+ |
12624 |
-+/* |
12625 |
-+ * The following routines handle shrinking of ephemeral pages by evicting |
12626 |
-+ * pages "least valuable" first. |
12627 |
-+ */ |
12628 |
-+ |
12629 |
-+static unsigned long zcache_evicted_raw_pages; |
12630 |
-+static unsigned long zcache_evicted_buddied_pages; |
12631 |
-+static unsigned long zcache_evicted_unbuddied_pages; |
12632 |
-+ |
12633 |
-+static struct tmem_pool *zcache_get_pool_by_id(uint32_t poolid); |
12634 |
-+static void zcache_put_pool(struct tmem_pool *pool); |
12635 |
-+ |
12636 |
-+/* |
12637 |
-+ * Flush and free all zbuds in a zbpg, then free the pageframe |
12638 |
-+ */ |
12639 |
-+static void zbud_evict_zbpg(struct zbud_page *zbpg) |
12640 |
-+{ |
12641 |
-+ struct zbud_hdr *zh; |
12642 |
-+ int i, j; |
12643 |
-+ uint32_t pool_id[ZBUD_MAX_BUDS], index[ZBUD_MAX_BUDS]; |
12644 |
-+ struct tmem_oid oid[ZBUD_MAX_BUDS]; |
12645 |
-+ struct tmem_pool *pool; |
12646 |
-+ |
12647 |
-+ ASSERT_SPINLOCK(&zbpg->lock); |
12648 |
-+ BUG_ON(!list_empty(&zbpg->bud_list)); |
12649 |
-+ for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) { |
12650 |
-+ zh = &zbpg->buddy[i]; |
12651 |
-+ if (zh->size) { |
12652 |
-+ pool_id[j] = zh->pool_id; |
12653 |
-+ oid[j] = zh->oid; |
12654 |
-+ index[j] = zh->index; |
12655 |
-+ j++; |
12656 |
-+ zbud_free(zh); |
12657 |
-+ } |
12658 |
-+ } |
12659 |
-+ spin_unlock(&zbpg->lock); |
12660 |
-+ for (i = 0; i < j; i++) { |
12661 |
-+ pool = zcache_get_pool_by_id(pool_id[i]); |
12662 |
-+ if (pool != NULL) { |
12663 |
-+ tmem_flush_page(pool, &oid[i], index[i]); |
12664 |
-+ zcache_put_pool(pool); |
12665 |
-+ } |
12666 |
-+ } |
12667 |
-+ ASSERT_SENTINEL(zbpg, ZBPG); |
12668 |
-+ spin_lock(&zbpg->lock); |
12669 |
-+ zbud_free_raw_page(zbpg); |
12670 |
-+} |
12671 |
-+ |
12672 |
-+/* |
12673 |
-+ * Free nr pages. This code is funky because we want to hold the locks |
12674 |
-+ * protecting various lists for as short a time as possible, and in some |
12675 |
-+ * circumstances the list may change asynchronously when the list lock is |
12676 |
-+ * not held. In some cases we also trylock not only to avoid waiting on a |
12677 |
-+ * page in use by another cpu, but also to avoid potential deadlock due to |
12678 |
-+ * lock inversion. |
12679 |
-+ */ |
12680 |
-+static void zbud_evict_pages(int nr) |
12681 |
-+{ |
12682 |
-+ struct zbud_page *zbpg; |
12683 |
-+ int i; |
12684 |
-+ |
12685 |
-+ /* first try freeing any pages on unused list */ |
12686 |
-+retry_unused_list: |
12687 |
-+ spin_lock_bh(&zbpg_unused_list_spinlock); |
12688 |
-+ if (!list_empty(&zbpg_unused_list)) { |
12689 |
-+ /* can't walk list here, since it may change when unlocked */ |
12690 |
-+ zbpg = list_first_entry(&zbpg_unused_list, |
12691 |
-+ struct zbud_page, bud_list); |
12692 |
-+ list_del_init(&zbpg->bud_list); |
12693 |
-+ zcache_zbpg_unused_list_count--; |
12694 |
-+ atomic_dec(&zcache_zbud_curr_raw_pages); |
12695 |
-+ spin_unlock_bh(&zbpg_unused_list_spinlock); |
12696 |
-+ zcache_free_page(zbpg); |
12697 |
-+ zcache_evicted_raw_pages++; |
12698 |
-+ if (--nr <= 0) |
12699 |
-+ goto out; |
12700 |
-+ goto retry_unused_list; |
12701 |
-+ } |
12702 |
-+ spin_unlock_bh(&zbpg_unused_list_spinlock); |
12703 |
-+ |
12704 |
-+ /* now try freeing unbuddied pages, starting with least space avail */ |
12705 |
-+ for (i = 0; i < MAX_CHUNK; i++) { |
12706 |
-+retry_unbud_list_i: |
12707 |
-+ spin_lock_bh(&zbud_budlists_spinlock); |
12708 |
-+ if (list_empty(&zbud_unbuddied[i].list)) { |
12709 |
-+ spin_unlock_bh(&zbud_budlists_spinlock); |
12710 |
-+ continue; |
12711 |
-+ } |
12712 |
-+ list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { |
12713 |
-+ if (unlikely(!spin_trylock(&zbpg->lock))) |
12714 |
-+ continue; |
12715 |
-+ list_del_init(&zbpg->bud_list); |
12716 |
-+ zbud_unbuddied[i].count--; |
12717 |
-+ spin_unlock(&zbud_budlists_spinlock); |
12718 |
-+ zcache_evicted_unbuddied_pages++; |
12719 |
-+ /* want budlists unlocked when doing zbpg eviction */ |
12720 |
-+ zbud_evict_zbpg(zbpg); |
12721 |
-+ local_bh_enable(); |
12722 |
-+ if (--nr <= 0) |
12723 |
-+ goto out; |
12724 |
-+ goto retry_unbud_list_i; |
12725 |
-+ } |
12726 |
-+ spin_unlock_bh(&zbud_budlists_spinlock); |
12727 |
-+ } |
12728 |
-+ |
12729 |
-+ /* as a last resort, free buddied pages */ |
12730 |
-+retry_bud_list: |
12731 |
-+ spin_lock_bh(&zbud_budlists_spinlock); |
12732 |
-+ if (list_empty(&zbud_buddied_list)) { |
12733 |
-+ spin_unlock_bh(&zbud_budlists_spinlock); |
12734 |
-+ goto out; |
12735 |
-+ } |
12736 |
-+ list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { |
12737 |
-+ if (unlikely(!spin_trylock(&zbpg->lock))) |
12738 |
-+ continue; |
12739 |
-+ list_del_init(&zbpg->bud_list); |
12740 |
-+ zcache_zbud_buddied_count--; |
12741 |
-+ spin_unlock(&zbud_budlists_spinlock); |
12742 |
-+ zcache_evicted_buddied_pages++; |
12743 |
-+ /* want budlists unlocked when doing zbpg eviction */ |
12744 |
-+ zbud_evict_zbpg(zbpg); |
12745 |
-+ local_bh_enable(); |
12746 |
-+ if (--nr <= 0) |
12747 |
-+ goto out; |
12748 |
-+ goto retry_bud_list; |
12749 |
-+ } |
12750 |
-+ spin_unlock_bh(&zbud_budlists_spinlock); |
12751 |
-+out: |
12752 |
-+ return; |
12753 |
-+} |
12754 |
-+ |
12755 |
-+static void zbud_init(void) |
12756 |
-+{ |
12757 |
-+ int i; |
12758 |
-+ |
12759 |
-+ INIT_LIST_HEAD(&zbud_buddied_list); |
12760 |
-+ zcache_zbud_buddied_count = 0; |
12761 |
-+ for (i = 0; i < NCHUNKS; i++) { |
12762 |
-+ INIT_LIST_HEAD(&zbud_unbuddied[i].list); |
12763 |
-+ zbud_unbuddied[i].count = 0; |
12764 |
-+ } |
12765 |
-+} |
12766 |
-+ |
12767 |
-+#ifdef CONFIG_SYSFS |
12768 |
-+/* |
12769 |
-+ * These sysfs routines show a nice distribution of how many zbpg's are |
12770 |
-+ * currently (and have ever been placed) in each unbuddied list. It's fun |
12771 |
-+ * to watch but can probably go away before final merge. |
12772 |
-+ */ |
12773 |
-+static int zbud_show_unbuddied_list_counts(char *buf) |
12774 |
-+{ |
12775 |
-+ int i; |
12776 |
-+ char *p = buf; |
12777 |
-+ |
12778 |
-+ for (i = 0; i < NCHUNKS - 1; i++) |
12779 |
-+ p += sprintf(p, "%u ", zbud_unbuddied[i].count); |
12780 |
-+ p += sprintf(p, "%d\n", zbud_unbuddied[i].count); |
12781 |
-+ return p - buf; |
12782 |
-+} |
12783 |
-+ |
12784 |
-+static int zbud_show_cumul_chunk_counts(char *buf) |
12785 |
-+{ |
12786 |
-+ unsigned long i, chunks = 0, total_chunks = 0, sum_total_chunks = 0; |
12787 |
-+ unsigned long total_chunks_lte_21 = 0, total_chunks_lte_32 = 0; |
12788 |
-+ unsigned long total_chunks_lte_42 = 0; |
12789 |
-+ char *p = buf; |
12790 |
-+ |
12791 |
-+ for (i = 0; i < NCHUNKS; i++) { |
12792 |
-+ p += sprintf(p, "%lu ", zbud_cumul_chunk_counts[i]); |
12793 |
-+ chunks += zbud_cumul_chunk_counts[i]; |
12794 |
-+ total_chunks += zbud_cumul_chunk_counts[i]; |
12795 |
-+ sum_total_chunks += i * zbud_cumul_chunk_counts[i]; |
12796 |
-+ if (i == 21) |
12797 |
-+ total_chunks_lte_21 = total_chunks; |
12798 |
-+ if (i == 32) |
12799 |
-+ total_chunks_lte_32 = total_chunks; |
12800 |
-+ if (i == 42) |
12801 |
-+ total_chunks_lte_42 = total_chunks; |
12802 |
-+ } |
12803 |
-+ p += sprintf(p, "<=21:%lu <=32:%lu <=42:%lu, mean:%lu\n", |
12804 |
-+ total_chunks_lte_21, total_chunks_lte_32, total_chunks_lte_42, |
12805 |
-+ chunks == 0 ? 0 : sum_total_chunks / chunks); |
12806 |
-+ return p - buf; |
12807 |
-+} |
12808 |
-+#endif |
12809 |
-+ |
12810 |
-+/********** |
12811 |
-+ * This "zv" PAM implementation combines the TLSF-based xvMalloc |
12812 |
-+ * with lzo1x compression to maximize the amount of data that can |
12813 |
-+ * be packed into a physical page. |
12814 |
-+ * |
12815 |
-+ * Zv represents a PAM page with the index and object (plus a "size" value |
12816 |
-+ * necessary for decompression) immediately preceding the compressed data. |
12817 |
-+ */ |
12818 |
-+ |
12819 |
-+#define ZVH_SENTINEL 0x43214321 |
12820 |
-+ |
12821 |
-+struct zv_hdr { |
12822 |
-+ uint32_t pool_id; |
12823 |
-+ struct tmem_oid oid; |
12824 |
-+ uint32_t index; |
12825 |
-+ DECL_SENTINEL |
12826 |
-+}; |
12827 |
-+ |
12828 |
-+static const int zv_max_page_size = (PAGE_SIZE / 8) * 7; |
12829 |
-+ |
12830 |
-+static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, |
12831 |
-+ struct tmem_oid *oid, uint32_t index, |
12832 |
-+ void *cdata, unsigned clen) |
12833 |
-+{ |
12834 |
-+ struct page *page; |
12835 |
-+ struct zv_hdr *zv = NULL; |
12836 |
-+ uint32_t offset; |
12837 |
-+ int ret; |
12838 |
-+ |
12839 |
-+ BUG_ON(!irqs_disabled()); |
12840 |
-+ ret = xv_malloc(xvpool, clen + sizeof(struct zv_hdr), |
12841 |
-+ &page, &offset, ZCACHE_GFP_MASK); |
12842 |
-+ if (unlikely(ret)) |
12843 |
-+ goto out; |
12844 |
-+ zv = kmap_atomic(page, KM_USER0) + offset; |
12845 |
-+ zv->index = index; |
12846 |
-+ zv->oid = *oid; |
12847 |
-+ zv->pool_id = pool_id; |
12848 |
-+ SET_SENTINEL(zv, ZVH); |
12849 |
-+ memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); |
12850 |
-+ kunmap_atomic(zv, KM_USER0); |
12851 |
-+out: |
12852 |
-+ return zv; |
12853 |
-+} |
12854 |
-+ |
12855 |
-+static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) |
12856 |
-+{ |
12857 |
-+ unsigned long flags; |
12858 |
-+ struct page *page; |
12859 |
-+ uint32_t offset; |
12860 |
-+ uint16_t size; |
12861 |
-+ |
12862 |
-+ ASSERT_SENTINEL(zv, ZVH); |
12863 |
-+ size = xv_get_object_size(zv) - sizeof(*zv); |
12864 |
-+ BUG_ON(size == 0 || size > zv_max_page_size); |
12865 |
-+ INVERT_SENTINEL(zv, ZVH); |
12866 |
-+ page = virt_to_page(zv); |
12867 |
-+ offset = (unsigned long)zv & ~PAGE_MASK; |
12868 |
-+ local_irq_save(flags); |
12869 |
-+ xv_free(xvpool, page, offset); |
12870 |
-+ local_irq_restore(flags); |
12871 |
-+} |
12872 |
-+ |
12873 |
-+static void zv_decompress(struct page *page, struct zv_hdr *zv) |
12874 |
-+{ |
12875 |
-+ size_t clen = PAGE_SIZE; |
12876 |
-+ char *to_va; |
12877 |
-+ unsigned size; |
12878 |
-+ int ret; |
12879 |
-+ |
12880 |
-+ ASSERT_SENTINEL(zv, ZVH); |
12881 |
-+ size = xv_get_object_size(zv) - sizeof(*zv); |
12882 |
-+ BUG_ON(size == 0 || size > zv_max_page_size); |
12883 |
-+ to_va = kmap_atomic(page, KM_USER0); |
12884 |
-+ ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), |
12885 |
-+ size, to_va, &clen); |
12886 |
-+ kunmap_atomic(to_va, KM_USER0); |
12887 |
-+ BUG_ON(ret != LZO_E_OK); |
12888 |
-+ BUG_ON(clen != PAGE_SIZE); |
12889 |
-+} |
12890 |
-+ |
12891 |
-+/* |
12892 |
-+ * zcache core code starts here |
12893 |
-+ */ |
12894 |
-+ |
12895 |
-+/* useful stats not collected by cleancache or frontswap */ |
12896 |
-+static unsigned long zcache_flush_total; |
12897 |
-+static unsigned long zcache_flush_found; |
12898 |
-+static unsigned long zcache_flobj_total; |
12899 |
-+static unsigned long zcache_flobj_found; |
12900 |
-+static unsigned long zcache_failed_eph_puts; |
12901 |
-+static unsigned long zcache_failed_pers_puts; |
12902 |
-+ |
12903 |
-+#define MAX_POOLS_PER_CLIENT 16 |
12904 |
-+ |
12905 |
-+static struct { |
12906 |
-+ struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; |
12907 |
-+ struct xv_pool *xvpool; |
12908 |
-+} zcache_client; |
12909 |
-+ |
12910 |
-+/* |
12911 |
-+ * Tmem operations assume the poolid implies the invoking client. |
12912 |
-+ * Zcache only has one client (the kernel itself), so translate |
12913 |
-+ * the poolid into the tmem_pool allocated for it. A KVM version |
12914 |
-+ * of zcache would have one client per guest and each client might |
12915 |
-+ * have a poolid==N. |
12916 |
-+ */ |
12917 |
-+static struct tmem_pool *zcache_get_pool_by_id(uint32_t poolid) |
12918 |
-+{ |
12919 |
-+ struct tmem_pool *pool = NULL; |
12920 |
-+ |
12921 |
-+ if (poolid >= 0) { |
12922 |
-+ pool = zcache_client.tmem_pools[poolid]; |
12923 |
-+ if (pool != NULL) |
12924 |
-+ atomic_inc(&pool->refcount); |
12925 |
-+ } |
12926 |
-+ return pool; |
12927 |
-+} |
12928 |
-+ |
12929 |
-+static void zcache_put_pool(struct tmem_pool *pool) |
12930 |
-+{ |
12931 |
-+ if (pool != NULL) |
12932 |
-+ atomic_dec(&pool->refcount); |
12933 |
-+} |
12934 |
-+ |
12935 |
-+/* counters for debugging */ |
12936 |
-+static unsigned long zcache_failed_get_free_pages; |
12937 |
-+static unsigned long zcache_failed_alloc; |
12938 |
-+static unsigned long zcache_put_to_flush; |
12939 |
-+static unsigned long zcache_aborted_preload; |
12940 |
-+static unsigned long zcache_aborted_shrink; |
12941 |
-+ |
12942 |
-+/* |
12943 |
-+ * Ensure that memory allocation requests in zcache don't result |
12944 |
-+ * in direct reclaim requests via the shrinker, which would cause |
12945 |
-+ * an infinite loop. Maybe a GFP flag would be better? |
12946 |
-+ */ |
12947 |
-+static DEFINE_SPINLOCK(zcache_direct_reclaim_lock); |
12948 |
-+ |
12949 |
-+/* |
12950 |
-+ * for now, used named slabs so can easily track usage; later can |
12951 |
-+ * either just use kmalloc, or perhaps add a slab-like allocator |
12952 |
-+ * to more carefully manage total memory utilization |
12953 |
-+ */ |
12954 |
-+static struct kmem_cache *zcache_objnode_cache; |
12955 |
-+static struct kmem_cache *zcache_obj_cache; |
12956 |
-+static atomic_t zcache_curr_obj_count = ATOMIC_INIT(0); |
12957 |
-+static unsigned long zcache_curr_obj_count_max; |
12958 |
-+static atomic_t zcache_curr_objnode_count = ATOMIC_INIT(0); |
12959 |
-+static unsigned long zcache_curr_objnode_count_max; |
12960 |
-+ |
12961 |
-+/* |
12962 |
-+ * to avoid memory allocation recursion (e.g. due to direct reclaim), we |
12963 |
-+ * preload all necessary data structures so the hostops callbacks never |
12964 |
-+ * actually do a malloc |
12965 |
-+ */ |
12966 |
-+struct zcache_preload { |
12967 |
-+ void *page; |
12968 |
-+ struct tmem_obj *obj; |
12969 |
-+ int nr; |
12970 |
-+ struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH]; |
12971 |
-+}; |
12972 |
-+static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; |
12973 |
-+ |
12974 |
-+static int zcache_do_preload(struct tmem_pool *pool) |
12975 |
-+{ |
12976 |
-+ struct zcache_preload *kp; |
12977 |
-+ struct tmem_objnode *objnode; |
12978 |
-+ struct tmem_obj *obj; |
12979 |
-+ void *page; |
12980 |
-+ int ret = -ENOMEM; |
12981 |
-+ |
12982 |
-+ if (unlikely(zcache_objnode_cache == NULL)) |
12983 |
-+ goto out; |
12984 |
-+ if (unlikely(zcache_obj_cache == NULL)) |
12985 |
-+ goto out; |
12986 |
-+ if (!spin_trylock(&zcache_direct_reclaim_lock)) { |
12987 |
-+ zcache_aborted_preload++; |
12988 |
-+ goto out; |
12989 |
-+ } |
12990 |
-+ preempt_disable(); |
12991 |
-+ kp = &__get_cpu_var(zcache_preloads); |
12992 |
-+ while (kp->nr < ARRAY_SIZE(kp->objnodes)) { |
12993 |
-+ preempt_enable_no_resched(); |
12994 |
-+ objnode = kmem_cache_alloc(zcache_objnode_cache, |
12995 |
-+ ZCACHE_GFP_MASK); |
12996 |
-+ if (unlikely(objnode == NULL)) { |
12997 |
-+ zcache_failed_alloc++; |
12998 |
-+ goto unlock_out; |
12999 |
-+ } |
13000 |
-+ preempt_disable(); |
13001 |
-+ kp = &__get_cpu_var(zcache_preloads); |
13002 |
-+ if (kp->nr < ARRAY_SIZE(kp->objnodes)) |
13003 |
-+ kp->objnodes[kp->nr++] = objnode; |
13004 |
-+ else |
13005 |
-+ kmem_cache_free(zcache_objnode_cache, objnode); |
13006 |
-+ } |
13007 |
-+ preempt_enable_no_resched(); |
13008 |
-+ obj = kmem_cache_alloc(zcache_obj_cache, ZCACHE_GFP_MASK); |
13009 |
-+ if (unlikely(obj == NULL)) { |
13010 |
-+ zcache_failed_alloc++; |
13011 |
-+ goto unlock_out; |
13012 |
-+ } |
13013 |
-+ page = (void *)__get_free_page(ZCACHE_GFP_MASK); |
13014 |
-+ if (unlikely(page == NULL)) { |
13015 |
-+ zcache_failed_get_free_pages++; |
13016 |
-+ kmem_cache_free(zcache_obj_cache, obj); |
13017 |
-+ goto unlock_out; |
13018 |
-+ } |
13019 |
-+ preempt_disable(); |
13020 |
-+ kp = &__get_cpu_var(zcache_preloads); |
13021 |
-+ if (kp->obj == NULL) |
13022 |
-+ kp->obj = obj; |
13023 |
-+ else |
13024 |
-+ kmem_cache_free(zcache_obj_cache, obj); |
13025 |
-+ if (kp->page == NULL) |
13026 |
-+ kp->page = page; |
13027 |
-+ else |
13028 |
-+ free_page((unsigned long)page); |
13029 |
-+ ret = 0; |
13030 |
-+unlock_out: |
13031 |
-+ spin_unlock(&zcache_direct_reclaim_lock); |
13032 |
-+out: |
13033 |
-+ return ret; |
13034 |
-+} |
13035 |
-+ |
13036 |
-+static void *zcache_get_free_page(void) |
13037 |
-+{ |
13038 |
-+ struct zcache_preload *kp; |
13039 |
-+ void *page; |
13040 |
-+ |
13041 |
-+ kp = &__get_cpu_var(zcache_preloads); |
13042 |
-+ page = kp->page; |
13043 |
-+ BUG_ON(page == NULL); |
13044 |
-+ kp->page = NULL; |
13045 |
-+ return page; |
13046 |
-+} |
13047 |
-+ |
13048 |
-+static void zcache_free_page(void *p) |
13049 |
-+{ |
13050 |
-+ free_page((unsigned long)p); |
13051 |
-+} |
13052 |
-+ |
13053 |
-+/* |
13054 |
-+ * zcache implementation for tmem host ops |
13055 |
-+ */ |
13056 |
-+ |
13057 |
-+static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) |
13058 |
-+{ |
13059 |
-+ struct tmem_objnode *objnode = NULL; |
13060 |
-+ unsigned long count; |
13061 |
-+ struct zcache_preload *kp; |
13062 |
-+ |
13063 |
-+ kp = &__get_cpu_var(zcache_preloads); |
13064 |
-+ if (kp->nr <= 0) |
13065 |
-+ goto out; |
13066 |
-+ objnode = kp->objnodes[kp->nr - 1]; |
13067 |
-+ BUG_ON(objnode == NULL); |
13068 |
-+ kp->objnodes[kp->nr - 1] = NULL; |
13069 |
-+ kp->nr--; |
13070 |
-+ count = atomic_inc_return(&zcache_curr_objnode_count); |
13071 |
-+ if (count > zcache_curr_objnode_count_max) |
13072 |
-+ zcache_curr_objnode_count_max = count; |
13073 |
-+out: |
13074 |
-+ return objnode; |
13075 |
-+} |
13076 |
-+ |
13077 |
-+static void zcache_objnode_free(struct tmem_objnode *objnode, |
13078 |
-+ struct tmem_pool *pool) |
13079 |
-+{ |
13080 |
-+ atomic_dec(&zcache_curr_objnode_count); |
13081 |
-+ BUG_ON(atomic_read(&zcache_curr_objnode_count) < 0); |
13082 |
-+ kmem_cache_free(zcache_objnode_cache, objnode); |
13083 |
-+} |
13084 |
-+ |
13085 |
-+static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) |
13086 |
-+{ |
13087 |
-+ struct tmem_obj *obj = NULL; |
13088 |
-+ unsigned long count; |
13089 |
-+ struct zcache_preload *kp; |
13090 |
-+ |
13091 |
-+ kp = &__get_cpu_var(zcache_preloads); |
13092 |
-+ obj = kp->obj; |
13093 |
-+ BUG_ON(obj == NULL); |
13094 |
-+ kp->obj = NULL; |
13095 |
-+ count = atomic_inc_return(&zcache_curr_obj_count); |
13096 |
-+ if (count > zcache_curr_obj_count_max) |
13097 |
-+ zcache_curr_obj_count_max = count; |
13098 |
-+ return obj; |
13099 |
-+} |
13100 |
-+ |
13101 |
-+static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) |
13102 |
-+{ |
13103 |
-+ atomic_dec(&zcache_curr_obj_count); |
13104 |
-+ BUG_ON(atomic_read(&zcache_curr_obj_count) < 0); |
13105 |
-+ kmem_cache_free(zcache_obj_cache, obj); |
13106 |
-+} |
13107 |
-+ |
13108 |
-+static struct tmem_hostops zcache_hostops = { |
13109 |
-+ .obj_alloc = zcache_obj_alloc, |
13110 |
-+ .obj_free = zcache_obj_free, |
13111 |
-+ .objnode_alloc = zcache_objnode_alloc, |
13112 |
-+ .objnode_free = zcache_objnode_free, |
13113 |
-+}; |
13114 |
-+ |
13115 |
-+/* |
13116 |
-+ * zcache implementations for PAM page descriptor ops |
13117 |
-+ */ |
13118 |
-+ |
13119 |
-+static atomic_t zcache_curr_eph_pampd_count = ATOMIC_INIT(0); |
13120 |
-+static unsigned long zcache_curr_eph_pampd_count_max; |
13121 |
-+static atomic_t zcache_curr_pers_pampd_count = ATOMIC_INIT(0); |
13122 |
-+static unsigned long zcache_curr_pers_pampd_count_max; |
13123 |
-+ |
13124 |
-+/* forward reference */ |
13125 |
-+static int zcache_compress(struct page *from, void **out_va, size_t *out_len); |
13126 |
-+ |
13127 |
-+static void *zcache_pampd_create(struct tmem_pool *pool, struct tmem_oid *oid, |
13128 |
-+ uint32_t index, struct page *page) |
13129 |
-+{ |
13130 |
-+ void *pampd = NULL, *cdata; |
13131 |
-+ size_t clen; |
13132 |
-+ int ret; |
13133 |
-+ bool ephemeral = is_ephemeral(pool); |
13134 |
-+ unsigned long count; |
13135 |
-+ |
13136 |
-+ if (ephemeral) { |
13137 |
-+ ret = zcache_compress(page, &cdata, &clen); |
13138 |
-+ if (ret == 0) |
13139 |
-+ |
13140 |
-+ goto out; |
13141 |
-+ if (clen == 0 || clen > zbud_max_buddy_size()) { |
13142 |
-+ zcache_compress_poor++; |
13143 |
-+ goto out; |
13144 |
-+ } |
13145 |
-+ pampd = (void *)zbud_create(pool->pool_id, oid, index, |
13146 |
-+ page, cdata, clen); |
13147 |
-+ if (pampd != NULL) { |
13148 |
-+ count = atomic_inc_return(&zcache_curr_eph_pampd_count); |
13149 |
-+ if (count > zcache_curr_eph_pampd_count_max) |
13150 |
-+ zcache_curr_eph_pampd_count_max = count; |
13151 |
-+ } |
13152 |
-+ } else { |
13153 |
-+ /* |
13154 |
-+ * FIXME: This is all the "policy" there is for now. |
13155 |
-+ * 3/4 totpages should allow ~37% of RAM to be filled with |
13156 |
-+ * compressed frontswap pages |
13157 |
-+ */ |
13158 |
-+ if (atomic_read(&zcache_curr_pers_pampd_count) > |
13159 |
-+ 3 * totalram_pages / 4) |
13160 |
-+ goto out; |
13161 |
-+ ret = zcache_compress(page, &cdata, &clen); |
13162 |
-+ if (ret == 0) |
13163 |
-+ goto out; |
13164 |
-+ if (clen > zv_max_page_size) { |
13165 |
-+ zcache_compress_poor++; |
13166 |
-+ goto out; |
13167 |
-+ } |
13168 |
-+ pampd = (void *)zv_create(zcache_client.xvpool, pool->pool_id, |
13169 |
-+ oid, index, cdata, clen); |
13170 |
-+ if (pampd == NULL) |
13171 |
-+ goto out; |
13172 |
-+ count = atomic_inc_return(&zcache_curr_pers_pampd_count); |
13173 |
-+ if (count > zcache_curr_pers_pampd_count_max) |
13174 |
-+ zcache_curr_pers_pampd_count_max = count; |
13175 |
-+ } |
13176 |
-+out: |
13177 |
-+ return pampd; |
13178 |
-+} |
13179 |
-+ |
13180 |
-+/* |
13181 |
-+ * fill the pageframe corresponding to the struct page with the data |
13182 |
-+ * from the passed pampd |
13183 |
-+ */ |
13184 |
-+static int zcache_pampd_get_data(struct page *page, void *pampd, |
13185 |
-+ struct tmem_pool *pool) |
13186 |
-+{ |
13187 |
-+ int ret = 0; |
13188 |
-+ |
13189 |
-+ if (is_ephemeral(pool)) |
13190 |
-+ ret = zbud_decompress(page, pampd); |
13191 |
-+ else |
13192 |
-+ zv_decompress(page, pampd); |
13193 |
-+ return ret; |
13194 |
-+} |
13195 |
-+ |
13196 |
-+/* |
13197 |
-+ * free the pampd and remove it from any zcache lists |
13198 |
-+ * pampd must no longer be pointed to from any tmem data structures! |
13199 |
-+ */ |
13200 |
-+static void zcache_pampd_free(void *pampd, struct tmem_pool *pool) |
13201 |
-+{ |
13202 |
-+ if (is_ephemeral(pool)) { |
13203 |
-+ zbud_free_and_delist((struct zbud_hdr *)pampd); |
13204 |
-+ atomic_dec(&zcache_curr_eph_pampd_count); |
13205 |
-+ BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0); |
13206 |
-+ } else { |
13207 |
-+ zv_free(zcache_client.xvpool, (struct zv_hdr *)pampd); |
13208 |
-+ atomic_dec(&zcache_curr_pers_pampd_count); |
13209 |
-+ BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0); |
13210 |
-+ } |
13211 |
-+} |
13212 |
-+ |
13213 |
-+static struct tmem_pamops zcache_pamops = { |
13214 |
-+ .create = zcache_pampd_create, |
13215 |
-+ .get_data = zcache_pampd_get_data, |
13216 |
-+ .free = zcache_pampd_free, |
13217 |
-+}; |
13218 |
-+ |
13219 |
-+/* |
13220 |
-+ * zcache compression/decompression and related per-cpu stuff |
13221 |
-+ */ |
13222 |
-+ |
13223 |
-+#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS |
13224 |
-+#define LZO_DSTMEM_PAGE_ORDER 1 |
13225 |
-+static DEFINE_PER_CPU(unsigned char *, zcache_workmem); |
13226 |
-+static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); |
13227 |
-+ |
13228 |
-+static int zcache_compress(struct page *from, void **out_va, size_t *out_len) |
13229 |
-+{ |
13230 |
-+ int ret = 0; |
13231 |
-+ unsigned char *dmem = __get_cpu_var(zcache_dstmem); |
13232 |
-+ unsigned char *wmem = __get_cpu_var(zcache_workmem); |
13233 |
-+ char *from_va; |
13234 |
-+ |
13235 |
-+ BUG_ON(!irqs_disabled()); |
13236 |
-+ if (unlikely(dmem == NULL || wmem == NULL)) |
13237 |
-+ goto out; /* no buffer, so can't compress */ |
13238 |
-+ from_va = kmap_atomic(from, KM_USER0); |
13239 |
-+ mb(); |
13240 |
-+ ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem); |
13241 |
-+ BUG_ON(ret != LZO_E_OK); |
13242 |
-+ *out_va = dmem; |
13243 |
-+ kunmap_atomic(from_va, KM_USER0); |
13244 |
-+ ret = 1; |
13245 |
-+out: |
13246 |
-+ return ret; |
13247 |
-+} |
13248 |
-+ |
13249 |
-+ |
13250 |
-+static int zcache_cpu_notifier(struct notifier_block *nb, |
13251 |
-+ unsigned long action, void *pcpu) |
13252 |
-+{ |
13253 |
-+ int cpu = (long)pcpu; |
13254 |
-+ struct zcache_preload *kp; |
13255 |
-+ |
13256 |
-+ switch (action) { |
13257 |
-+ case CPU_UP_PREPARE: |
13258 |
-+ per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( |
13259 |
-+ GFP_KERNEL | __GFP_REPEAT, |
13260 |
-+ LZO_DSTMEM_PAGE_ORDER), |
13261 |
-+ per_cpu(zcache_workmem, cpu) = |
13262 |
-+ kzalloc(LZO1X_MEM_COMPRESS, |
13263 |
-+ GFP_KERNEL | __GFP_REPEAT); |
13264 |
-+ break; |
13265 |
-+ case CPU_DEAD: |
13266 |
-+ case CPU_UP_CANCELED: |
13267 |
-+ free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), |
13268 |
-+ LZO_DSTMEM_PAGE_ORDER); |
13269 |
-+ per_cpu(zcache_dstmem, cpu) = NULL; |
13270 |
-+ kfree(per_cpu(zcache_workmem, cpu)); |
13271 |
-+ per_cpu(zcache_workmem, cpu) = NULL; |
13272 |
-+ kp = &per_cpu(zcache_preloads, cpu); |
13273 |
-+ while (kp->nr) { |
13274 |
-+ kmem_cache_free(zcache_objnode_cache, |
13275 |
-+ kp->objnodes[kp->nr - 1]); |
13276 |
-+ kp->objnodes[kp->nr - 1] = NULL; |
13277 |
-+ kp->nr--; |
13278 |
-+ } |
13279 |
-+ kmem_cache_free(zcache_obj_cache, kp->obj); |
13280 |
-+ free_page((unsigned long)kp->page); |
13281 |
-+ break; |
13282 |
-+ default: |
13283 |
-+ break; |
13284 |
-+ } |
13285 |
-+ return NOTIFY_OK; |
13286 |
-+} |
13287 |
-+ |
13288 |
-+static struct notifier_block zcache_cpu_notifier_block = { |
13289 |
-+ .notifier_call = zcache_cpu_notifier |
13290 |
-+}; |
13291 |
-+ |
13292 |
-+#ifdef CONFIG_SYSFS |
13293 |
-+#define ZCACHE_SYSFS_RO(_name) \ |
13294 |
-+ static ssize_t zcache_##_name##_show(struct kobject *kobj, \ |
13295 |
-+ struct kobj_attribute *attr, char *buf) \ |
13296 |
-+ { \ |
13297 |
-+ return sprintf(buf, "%lu\n", zcache_##_name); \ |
13298 |
-+ } \ |
13299 |
-+ static struct kobj_attribute zcache_##_name##_attr = { \ |
13300 |
-+ .attr = { .name = __stringify(_name), .mode = 0444 }, \ |
13301 |
-+ .show = zcache_##_name##_show, \ |
13302 |
-+ } |
13303 |
-+ |
13304 |
-+#define ZCACHE_SYSFS_RO_ATOMIC(_name) \ |
13305 |
-+ static ssize_t zcache_##_name##_show(struct kobject *kobj, \ |
13306 |
-+ struct kobj_attribute *attr, char *buf) \ |
13307 |
-+ { \ |
13308 |
-+ return sprintf(buf, "%d\n", atomic_read(&zcache_##_name)); \ |
13309 |
-+ } \ |
13310 |
-+ static struct kobj_attribute zcache_##_name##_attr = { \ |
13311 |
-+ .attr = { .name = __stringify(_name), .mode = 0444 }, \ |
13312 |
-+ .show = zcache_##_name##_show, \ |
13313 |
-+ } |
13314 |
-+ |
13315 |
-+#define ZCACHE_SYSFS_RO_CUSTOM(_name, _func) \ |
13316 |
-+ static ssize_t zcache_##_name##_show(struct kobject *kobj, \ |
13317 |
-+ struct kobj_attribute *attr, char *buf) \ |
13318 |
-+ { \ |
13319 |
-+ return _func(buf); \ |
13320 |
-+ } \ |
13321 |
-+ static struct kobj_attribute zcache_##_name##_attr = { \ |
13322 |
-+ .attr = { .name = __stringify(_name), .mode = 0444 }, \ |
13323 |
-+ .show = zcache_##_name##_show, \ |
13324 |
-+ } |
13325 |
-+ |
13326 |
-+ZCACHE_SYSFS_RO(curr_obj_count_max); |
13327 |
-+ZCACHE_SYSFS_RO(curr_objnode_count_max); |
13328 |
-+ZCACHE_SYSFS_RO(flush_total); |
13329 |
-+ZCACHE_SYSFS_RO(flush_found); |
13330 |
-+ZCACHE_SYSFS_RO(flobj_total); |
13331 |
-+ZCACHE_SYSFS_RO(flobj_found); |
13332 |
-+ZCACHE_SYSFS_RO(failed_eph_puts); |
13333 |
-+ZCACHE_SYSFS_RO(failed_pers_puts); |
13334 |
-+ZCACHE_SYSFS_RO(zbud_curr_zbytes); |
13335 |
-+ZCACHE_SYSFS_RO(zbud_cumul_zpages); |
13336 |
-+ZCACHE_SYSFS_RO(zbud_cumul_zbytes); |
13337 |
-+ZCACHE_SYSFS_RO(zbud_buddied_count); |
13338 |
-+ZCACHE_SYSFS_RO(zbpg_unused_list_count); |
13339 |
-+ZCACHE_SYSFS_RO(evicted_raw_pages); |
13340 |
-+ZCACHE_SYSFS_RO(evicted_unbuddied_pages); |
13341 |
-+ZCACHE_SYSFS_RO(evicted_buddied_pages); |
13342 |
-+ZCACHE_SYSFS_RO(failed_get_free_pages); |
13343 |
-+ZCACHE_SYSFS_RO(failed_alloc); |
13344 |
-+ZCACHE_SYSFS_RO(put_to_flush); |
13345 |
-+ZCACHE_SYSFS_RO(aborted_preload); |
13346 |
-+ZCACHE_SYSFS_RO(aborted_shrink); |
13347 |
-+ZCACHE_SYSFS_RO(compress_poor); |
13348 |
-+ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages); |
13349 |
-+ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages); |
13350 |
-+ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count); |
13351 |
-+ZCACHE_SYSFS_RO_ATOMIC(curr_objnode_count); |
13352 |
-+ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts, |
13353 |
-+ zbud_show_unbuddied_list_counts); |
13354 |
-+ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts, |
13355 |
-+ zbud_show_cumul_chunk_counts); |
13356 |
-+ |
13357 |
-+static struct attribute *zcache_attrs[] = { |
13358 |
-+ &zcache_curr_obj_count_attr.attr, |
13359 |
-+ &zcache_curr_obj_count_max_attr.attr, |
13360 |
-+ &zcache_curr_objnode_count_attr.attr, |
13361 |
-+ &zcache_curr_objnode_count_max_attr.attr, |
13362 |
-+ &zcache_flush_total_attr.attr, |
13363 |
-+ &zcache_flobj_total_attr.attr, |
13364 |
-+ &zcache_flush_found_attr.attr, |
13365 |
-+ &zcache_flobj_found_attr.attr, |
13366 |
-+ &zcache_failed_eph_puts_attr.attr, |
13367 |
-+ &zcache_failed_pers_puts_attr.attr, |
13368 |
-+ &zcache_compress_poor_attr.attr, |
13369 |
-+ &zcache_zbud_curr_raw_pages_attr.attr, |
13370 |
-+ &zcache_zbud_curr_zpages_attr.attr, |
13371 |
-+ &zcache_zbud_curr_zbytes_attr.attr, |
13372 |
-+ &zcache_zbud_cumul_zpages_attr.attr, |
13373 |
-+ &zcache_zbud_cumul_zbytes_attr.attr, |
13374 |
-+ &zcache_zbud_buddied_count_attr.attr, |
13375 |
-+ &zcache_zbpg_unused_list_count_attr.attr, |
13376 |
-+ &zcache_evicted_raw_pages_attr.attr, |
13377 |
-+ &zcache_evicted_unbuddied_pages_attr.attr, |
13378 |
-+ &zcache_evicted_buddied_pages_attr.attr, |
13379 |
-+ &zcache_failed_get_free_pages_attr.attr, |
13380 |
-+ &zcache_failed_alloc_attr.attr, |
13381 |
-+ &zcache_put_to_flush_attr.attr, |
13382 |
-+ &zcache_aborted_preload_attr.attr, |
13383 |
-+ &zcache_aborted_shrink_attr.attr, |
13384 |
-+ &zcache_zbud_unbuddied_list_counts_attr.attr, |
13385 |
-+ &zcache_zbud_cumul_chunk_counts_attr.attr, |
13386 |
-+ NULL, |
13387 |
-+}; |
13388 |
-+ |
13389 |
-+static struct attribute_group zcache_attr_group = { |
13390 |
-+ .attrs = zcache_attrs, |
13391 |
-+ .name = "zcache", |
13392 |
-+}; |
13393 |
-+ |
13394 |
-+#endif /* CONFIG_SYSFS */ |
13395 |
-+/* |
13396 |
-+ * When zcache is disabled ("frozen"), pools can be created and destroyed, |
13397 |
-+ * but all puts (and thus all other operations that require memory allocation) |
13398 |
-+ * must fail. If zcache is unfrozen, accepts puts, then frozen again, |
13399 |
-+ * data consistency requires all puts while frozen to be converted into |
13400 |
-+ * flushes. |
13401 |
-+ */ |
13402 |
-+static bool zcache_freeze; |
13403 |
-+ |
13404 |
-+/* |
13405 |
-+ * zcache shrinker interface (only useful for ephemeral pages, so zbud only) |
13406 |
-+ */ |
13407 |
-+static int shrink_zcache_memory(struct shrinker *shrink, |
13408 |
-+ struct shrink_control *sc) |
13409 |
-+{ |
13410 |
-+ int ret = -1; |
13411 |
-+ int nr = sc->nr_to_scan; |
13412 |
-+ gfp_t gfp_mask = sc->gfp_mask; |
13413 |
-+ |
13414 |
-+ if (nr >= 0) { |
13415 |
-+ if (!(gfp_mask & __GFP_FS)) |
13416 |
-+ /* does this case really need to be skipped? */ |
13417 |
-+ goto out; |
13418 |
-+ if (spin_trylock(&zcache_direct_reclaim_lock)) { |
13419 |
-+ zbud_evict_pages(nr); |
13420 |
-+ spin_unlock(&zcache_direct_reclaim_lock); |
13421 |
-+ } else |
13422 |
-+ zcache_aborted_shrink++; |
13423 |
-+ } |
13424 |
-+ ret = (int)atomic_read(&zcache_zbud_curr_raw_pages); |
13425 |
-+out: |
13426 |
-+ return ret; |
13427 |
-+} |
13428 |
-+ |
13429 |
-+static struct shrinker zcache_shrinker = { |
13430 |
-+ .shrink = shrink_zcache_memory, |
13431 |
-+ .seeks = DEFAULT_SEEKS, |
13432 |
-+}; |
13433 |
-+ |
13434 |
-+/* |
13435 |
-+ * zcache shims between cleancache/frontswap ops and tmem |
13436 |
-+ */ |
13437 |
-+ |
13438 |
-+static int zcache_put_page(int pool_id, struct tmem_oid *oidp, |
13439 |
-+ uint32_t index, struct page *page) |
13440 |
-+{ |
13441 |
-+ struct tmem_pool *pool; |
13442 |
-+ int ret = -1; |
13443 |
-+ |
13444 |
-+ BUG_ON(!irqs_disabled()); |
13445 |
-+ pool = zcache_get_pool_by_id(pool_id); |
13446 |
-+ if (unlikely(pool == NULL)) |
13447 |
-+ goto out; |
13448 |
-+ if (!zcache_freeze && zcache_do_preload(pool) == 0) { |
13449 |
-+ /* preload does preempt_disable on success */ |
13450 |
-+ ret = tmem_put(pool, oidp, index, page); |
13451 |
-+ if (ret < 0) { |
13452 |
-+ if (is_ephemeral(pool)) |
13453 |
-+ zcache_failed_eph_puts++; |
13454 |
-+ else |
13455 |
-+ zcache_failed_pers_puts++; |
13456 |
-+ } |
13457 |
-+ zcache_put_pool(pool); |
13458 |
-+ preempt_enable_no_resched(); |
13459 |
-+ } else { |
13460 |
-+ zcache_put_to_flush++; |
13461 |
-+ if (atomic_read(&pool->obj_count) > 0) |
13462 |
-+ /* the put fails whether the flush succeeds or not */ |
13463 |
-+ (void)tmem_flush_page(pool, oidp, index); |
13464 |
-+ zcache_put_pool(pool); |
13465 |
-+ } |
13466 |
-+out: |
13467 |
-+ return ret; |
13468 |
-+} |
13469 |
-+ |
13470 |
-+static int zcache_get_page(int pool_id, struct tmem_oid *oidp, |
13471 |
-+ uint32_t index, struct page *page) |
13472 |
-+{ |
13473 |
-+ struct tmem_pool *pool; |
13474 |
-+ int ret = -1; |
13475 |
-+ unsigned long flags; |
13476 |
-+ |
13477 |
-+ local_irq_save(flags); |
13478 |
-+ pool = zcache_get_pool_by_id(pool_id); |
13479 |
-+ if (likely(pool != NULL)) { |
13480 |
-+ if (atomic_read(&pool->obj_count) > 0) |
13481 |
-+ ret = tmem_get(pool, oidp, index, page); |
13482 |
-+ zcache_put_pool(pool); |
13483 |
-+ } |
13484 |
-+ local_irq_restore(flags); |
13485 |
-+ return ret; |
13486 |
-+} |
13487 |
-+ |
13488 |
-+static int zcache_flush_page(int pool_id, struct tmem_oid *oidp, uint32_t index) |
13489 |
-+{ |
13490 |
-+ struct tmem_pool *pool; |
13491 |
-+ int ret = -1; |
13492 |
-+ unsigned long flags; |
13493 |
-+ |
13494 |
-+ local_irq_save(flags); |
13495 |
-+ zcache_flush_total++; |
13496 |
-+ pool = zcache_get_pool_by_id(pool_id); |
13497 |
-+ if (likely(pool != NULL)) { |
13498 |
-+ if (atomic_read(&pool->obj_count) > 0) |
13499 |
-+ ret = tmem_flush_page(pool, oidp, index); |
13500 |
-+ zcache_put_pool(pool); |
13501 |
-+ } |
13502 |
-+ if (ret >= 0) |
13503 |
-+ zcache_flush_found++; |
13504 |
-+ local_irq_restore(flags); |
13505 |
-+ return ret; |
13506 |
-+} |
13507 |
-+ |
13508 |
-+static int zcache_flush_object(int pool_id, struct tmem_oid *oidp) |
13509 |
-+{ |
13510 |
-+ struct tmem_pool *pool; |
13511 |
-+ int ret = -1; |
13512 |
-+ unsigned long flags; |
13513 |
-+ |
13514 |
-+ local_irq_save(flags); |
13515 |
-+ zcache_flobj_total++; |
13516 |
-+ pool = zcache_get_pool_by_id(pool_id); |
13517 |
-+ if (likely(pool != NULL)) { |
13518 |
-+ if (atomic_read(&pool->obj_count) > 0) |
13519 |
-+ ret = tmem_flush_object(pool, oidp); |
13520 |
-+ zcache_put_pool(pool); |
13521 |
-+ } |
13522 |
-+ if (ret >= 0) |
13523 |
-+ zcache_flobj_found++; |
13524 |
-+ local_irq_restore(flags); |
13525 |
-+ return ret; |
13526 |
-+} |
13527 |
-+ |
13528 |
-+static int zcache_destroy_pool(int pool_id) |
13529 |
-+{ |
13530 |
-+ struct tmem_pool *pool = NULL; |
13531 |
-+ int ret = -1; |
13532 |
-+ |
13533 |
-+ if (pool_id < 0) |
13534 |
-+ goto out; |
13535 |
-+ pool = zcache_client.tmem_pools[pool_id]; |
13536 |
-+ if (pool == NULL) |
13537 |
-+ goto out; |
13538 |
-+ zcache_client.tmem_pools[pool_id] = NULL; |
13539 |
-+ /* wait for pool activity on other cpus to quiesce */ |
13540 |
-+ while (atomic_read(&pool->refcount) != 0) |
13541 |
-+ ; |
13542 |
-+ local_bh_disable(); |
13543 |
-+ ret = tmem_destroy_pool(pool); |
13544 |
-+ local_bh_enable(); |
13545 |
-+ kfree(pool); |
13546 |
-+ pr_info("zcache: destroyed pool id=%d\n", pool_id); |
13547 |
-+out: |
13548 |
-+ return ret; |
13549 |
-+} |
13550 |
-+ |
13551 |
-+static int zcache_new_pool(uint32_t flags) |
13552 |
-+{ |
13553 |
-+ int poolid = -1; |
13554 |
-+ struct tmem_pool *pool; |
13555 |
-+ |
13556 |
-+ pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); |
13557 |
-+ if (pool == NULL) { |
13558 |
-+ pr_info("zcache: pool creation failed: out of memory\n"); |
13559 |
-+ goto out; |
13560 |
-+ } |
13561 |
-+ |
13562 |
-+ for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) |
13563 |
-+ if (zcache_client.tmem_pools[poolid] == NULL) |
13564 |
-+ break; |
13565 |
-+ if (poolid >= MAX_POOLS_PER_CLIENT) { |
13566 |
-+ pr_info("zcache: pool creation failed: max exceeded\n"); |
13567 |
-+ kfree(pool); |
13568 |
-+ poolid = -1; |
13569 |
-+ goto out; |
13570 |
-+ } |
13571 |
-+ atomic_set(&pool->refcount, 0); |
13572 |
-+ pool->client = &zcache_client; |
13573 |
-+ pool->pool_id = poolid; |
13574 |
-+ tmem_new_pool(pool, flags); |
13575 |
-+ zcache_client.tmem_pools[poolid] = pool; |
13576 |
-+ pr_info("zcache: created %s tmem pool, id=%d\n", |
13577 |
-+ flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", |
13578 |
-+ poolid); |
13579 |
-+out: |
13580 |
-+ return poolid; |
13581 |
-+} |
13582 |
-+ |
13583 |
-+/********** |
13584 |
-+ * Two kernel functionalities currently can be layered on top of tmem. |
13585 |
-+ * These are "cleancache" which is used as a second-chance cache for clean |
13586 |
-+ * page cache pages; and "frontswap" which is used for swap pages |
13587 |
-+ * to avoid writes to disk. A generic "shim" is provided here for each |
13588 |
-+ * to translate in-kernel semantics to zcache semantics. |
13589 |
-+ */ |
13590 |
-+ |
13591 |
-+#ifdef CONFIG_CLEANCACHE |
13592 |
-+static void zcache_cleancache_put_page(int pool_id, |
13593 |
-+ struct cleancache_filekey key, |
13594 |
-+ pgoff_t index, struct page *page) |
13595 |
-+{ |
13596 |
-+ u32 ind = (u32) index; |
13597 |
-+ struct tmem_oid oid = *(struct tmem_oid *)&key; |
13598 |
-+ |
13599 |
-+ if (likely(ind == index)) |
13600 |
-+ (void)zcache_put_page(pool_id, &oid, index, page); |
13601 |
-+} |
13602 |
-+ |
13603 |
-+static int zcache_cleancache_get_page(int pool_id, |
13604 |
-+ struct cleancache_filekey key, |
13605 |
-+ pgoff_t index, struct page *page) |
13606 |
-+{ |
13607 |
-+ u32 ind = (u32) index; |
13608 |
-+ struct tmem_oid oid = *(struct tmem_oid *)&key; |
13609 |
-+ int ret = -1; |
13610 |
-+ |
13611 |
-+ if (likely(ind == index)) |
13612 |
-+ ret = zcache_get_page(pool_id, &oid, index, page); |
13613 |
-+ return ret; |
13614 |
-+} |
13615 |
-+ |
13616 |
-+static void zcache_cleancache_flush_page(int pool_id, |
13617 |
-+ struct cleancache_filekey key, |
13618 |
-+ pgoff_t index) |
13619 |
-+{ |
13620 |
-+ u32 ind = (u32) index; |
13621 |
-+ struct tmem_oid oid = *(struct tmem_oid *)&key; |
13622 |
-+ |
13623 |
-+ if (likely(ind == index)) |
13624 |
-+ (void)zcache_flush_page(pool_id, &oid, ind); |
13625 |
-+} |
13626 |
-+ |
13627 |
-+static void zcache_cleancache_flush_inode(int pool_id, |
13628 |
-+ struct cleancache_filekey key) |
13629 |
-+{ |
13630 |
-+ struct tmem_oid oid = *(struct tmem_oid *)&key; |
13631 |
-+ |
13632 |
-+ (void)zcache_flush_object(pool_id, &oid); |
13633 |
-+} |
13634 |
-+ |
13635 |
-+static void zcache_cleancache_flush_fs(int pool_id) |
13636 |
-+{ |
13637 |
-+ if (pool_id >= 0) |
13638 |
-+ (void)zcache_destroy_pool(pool_id); |
13639 |
-+} |
13640 |
-+ |
13641 |
-+static int zcache_cleancache_init_fs(size_t pagesize) |
13642 |
-+{ |
13643 |
-+ BUG_ON(sizeof(struct cleancache_filekey) != |
13644 |
-+ sizeof(struct tmem_oid)); |
13645 |
-+ BUG_ON(pagesize != PAGE_SIZE); |
13646 |
-+ return zcache_new_pool(0); |
13647 |
-+} |
13648 |
-+ |
13649 |
-+static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) |
13650 |
-+{ |
13651 |
-+ /* shared pools are unsupported and map to private */ |
13652 |
-+ BUG_ON(sizeof(struct cleancache_filekey) != |
13653 |
-+ sizeof(struct tmem_oid)); |
13654 |
-+ BUG_ON(pagesize != PAGE_SIZE); |
13655 |
-+ return zcache_new_pool(0); |
13656 |
-+} |
13657 |
-+ |
13658 |
-+static struct cleancache_ops zcache_cleancache_ops = { |
13659 |
-+ .put_page = zcache_cleancache_put_page, |
13660 |
-+ .get_page = zcache_cleancache_get_page, |
13661 |
-+ .flush_page = zcache_cleancache_flush_page, |
13662 |
-+ .flush_inode = zcache_cleancache_flush_inode, |
13663 |
-+ .flush_fs = zcache_cleancache_flush_fs, |
13664 |
-+ .init_shared_fs = zcache_cleancache_init_shared_fs, |
13665 |
-+ .init_fs = zcache_cleancache_init_fs |
13666 |
-+}; |
13667 |
-+ |
13668 |
-+struct cleancache_ops zcache_cleancache_register_ops(void) |
13669 |
-+{ |
13670 |
-+ struct cleancache_ops old_ops = |
13671 |
-+ cleancache_register_ops(&zcache_cleancache_ops); |
13672 |
-+ |
13673 |
-+ return old_ops; |
13674 |
-+} |
13675 |
-+#endif |
13676 |
-+ |
13677 |
-+#ifdef CONFIG_FRONTSWAP |
13678 |
-+/* a single tmem poolid is used for all frontswap "types" (swapfiles) */ |
13679 |
-+static int zcache_frontswap_poolid = -1; |
13680 |
-+ |
13681 |
-+/* |
13682 |
-+ * Swizzling increases objects per swaptype, increasing tmem concurrency |
13683 |
-+ * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS |
13684 |
-+ */ |
13685 |
-+#define SWIZ_BITS 4 |
13686 |
-+#define SWIZ_MASK ((1 << SWIZ_BITS) - 1) |
13687 |
-+#define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK)) |
13688 |
-+#define iswiz(_ind) (_ind >> SWIZ_BITS) |
13689 |
-+ |
13690 |
-+static inline struct tmem_oid oswiz(unsigned type, u32 ind) |
13691 |
-+{ |
13692 |
-+ struct tmem_oid oid = { .oid = { 0 } }; |
13693 |
-+ oid.oid[0] = _oswiz(type, ind); |
13694 |
-+ return oid; |
13695 |
-+} |
13696 |
-+ |
13697 |
-+static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, |
13698 |
-+ struct page *page) |
13699 |
-+{ |
13700 |
-+ u64 ind64 = (u64)offset; |
13701 |
-+ u32 ind = (u32)offset; |
13702 |
-+ struct tmem_oid oid = oswiz(type, ind); |
13703 |
-+ int ret = -1; |
13704 |
-+ unsigned long flags; |
13705 |
-+ |
13706 |
-+ BUG_ON(!PageLocked(page)); |
13707 |
-+ if (likely(ind64 == ind)) { |
13708 |
-+ local_irq_save(flags); |
13709 |
-+ ret = zcache_put_page(zcache_frontswap_poolid, &oid, |
13710 |
-+ iswiz(ind), page); |
13711 |
-+ local_irq_restore(flags); |
13712 |
-+ } |
13713 |
-+ return ret; |
13714 |
-+} |
13715 |
-+ |
13716 |
-+/* returns 0 if the page was successfully gotten from frontswap, -1 if |
13717 |
-+ * was not present (should never happen!) */ |
13718 |
-+static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, |
13719 |
-+ struct page *page) |
13720 |
-+{ |
13721 |
-+ u64 ind64 = (u64)offset; |
13722 |
-+ u32 ind = (u32)offset; |
13723 |
-+ struct tmem_oid oid = oswiz(type, ind); |
13724 |
-+ int ret = -1; |
13725 |
-+ |
13726 |
-+ BUG_ON(!PageLocked(page)); |
13727 |
-+ if (likely(ind64 == ind)) |
13728 |
-+ ret = zcache_get_page(zcache_frontswap_poolid, &oid, |
13729 |
-+ iswiz(ind), page); |
13730 |
-+ return ret; |
13731 |
-+} |
13732 |
-+ |
13733 |
-+/* flush a single page from frontswap */ |
13734 |
-+static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) |
13735 |
-+{ |
13736 |
-+ u64 ind64 = (u64)offset; |
13737 |
-+ u32 ind = (u32)offset; |
13738 |
-+ struct tmem_oid oid = oswiz(type, ind); |
13739 |
-+ |
13740 |
-+ if (likely(ind64 == ind)) |
13741 |
-+ (void)zcache_flush_page(zcache_frontswap_poolid, &oid, |
13742 |
-+ iswiz(ind)); |
13743 |
-+} |
13744 |
-+ |
13745 |
-+/* flush all pages from the passed swaptype */ |
13746 |
-+static void zcache_frontswap_flush_area(unsigned type) |
13747 |
-+{ |
13748 |
-+ struct tmem_oid oid; |
13749 |
-+ int ind; |
13750 |
-+ |
13751 |
-+ for (ind = SWIZ_MASK; ind >= 0; ind--) { |
13752 |
-+ oid = oswiz(type, ind); |
13753 |
-+ (void)zcache_flush_object(zcache_frontswap_poolid, &oid); |
13754 |
-+ } |
13755 |
-+} |
13756 |
-+ |
13757 |
-+static void zcache_frontswap_init(unsigned ignored) |
13758 |
-+{ |
13759 |
-+ /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ |
13760 |
-+ if (zcache_frontswap_poolid < 0) |
13761 |
-+ zcache_frontswap_poolid = zcache_new_pool(TMEM_POOL_PERSIST); |
13762 |
-+} |
13763 |
-+ |
13764 |
-+static struct frontswap_ops zcache_frontswap_ops = { |
13765 |
-+ .put_page = zcache_frontswap_put_page, |
13766 |
-+ .get_page = zcache_frontswap_get_page, |
13767 |
-+ .flush_page = zcache_frontswap_flush_page, |
13768 |
-+ .flush_area = zcache_frontswap_flush_area, |
13769 |
-+ .init = zcache_frontswap_init |
13770 |
-+}; |
13771 |
-+ |
13772 |
-+struct frontswap_ops zcache_frontswap_register_ops(void) |
13773 |
-+{ |
13774 |
-+ struct frontswap_ops old_ops = |
13775 |
-+ frontswap_register_ops(&zcache_frontswap_ops); |
13776 |
-+ |
13777 |
-+ return old_ops; |
13778 |
-+} |
13779 |
-+#endif |
13780 |
-+ |
13781 |
-+/* |
13782 |
-+ * zcache initialization |
13783 |
-+ * NOTE FOR NOW zcache MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR |
13784 |
-+ * NOTHING HAPPENS! |
13785 |
-+ */ |
13786 |
-+ |
13787 |
-+static int zcache_enabled; |
13788 |
-+ |
13789 |
-+static int __init enable_zcache(char *s) |
13790 |
-+{ |
13791 |
-+ zcache_enabled = 1; |
13792 |
-+ return 1; |
13793 |
-+} |
13794 |
-+__setup("zcache", enable_zcache); |
13795 |
-+ |
13796 |
-+/* allow independent dynamic disabling of cleancache and frontswap */ |
13797 |
-+ |
13798 |
-+static int use_cleancache = 1; |
13799 |
-+ |
13800 |
-+static int __init no_cleancache(char *s) |
13801 |
-+{ |
13802 |
-+ use_cleancache = 0; |
13803 |
-+ return 1; |
13804 |
-+} |
13805 |
-+ |
13806 |
-+__setup("nocleancache", no_cleancache); |
13807 |
-+ |
13808 |
-+static int use_frontswap = 1; |
13809 |
-+ |
13810 |
-+static int __init no_frontswap(char *s) |
13811 |
-+{ |
13812 |
-+ use_frontswap = 0; |
13813 |
-+ return 1; |
13814 |
-+} |
13815 |
-+ |
13816 |
-+__setup("nofrontswap", no_frontswap); |
13817 |
-+ |
13818 |
-+static int __init zcache_init(void) |
13819 |
-+{ |
13820 |
-+#ifdef CONFIG_SYSFS |
13821 |
-+ int ret = 0; |
13822 |
-+ |
13823 |
-+ ret = sysfs_create_group(mm_kobj, &zcache_attr_group); |
13824 |
-+ if (ret) { |
13825 |
-+ pr_err("zcache: can't create sysfs\n"); |
13826 |
-+ goto out; |
13827 |
-+ } |
13828 |
-+#endif /* CONFIG_SYSFS */ |
13829 |
-+#if defined(CONFIG_CLEANCACHE) || defined(CONFIG_FRONTSWAP) |
13830 |
-+ if (zcache_enabled) { |
13831 |
-+ unsigned int cpu; |
13832 |
-+ |
13833 |
-+ tmem_register_hostops(&zcache_hostops); |
13834 |
-+ tmem_register_pamops(&zcache_pamops); |
13835 |
-+ ret = register_cpu_notifier(&zcache_cpu_notifier_block); |
13836 |
-+ if (ret) { |
13837 |
-+ pr_err("zcache: can't register cpu notifier\n"); |
13838 |
-+ goto out; |
13839 |
-+ } |
13840 |
-+ for_each_online_cpu(cpu) { |
13841 |
-+ void *pcpu = (void *)(long)cpu; |
13842 |
-+ zcache_cpu_notifier(&zcache_cpu_notifier_block, |
13843 |
-+ CPU_UP_PREPARE, pcpu); |
13844 |
-+ } |
13845 |
-+ } |
13846 |
-+ zcache_objnode_cache = kmem_cache_create("zcache_objnode", |
13847 |
-+ sizeof(struct tmem_objnode), 0, 0, NULL); |
13848 |
-+ zcache_obj_cache = kmem_cache_create("zcache_obj", |
13849 |
-+ sizeof(struct tmem_obj), 0, 0, NULL); |
13850 |
-+#endif |
13851 |
-+#ifdef CONFIG_CLEANCACHE |
13852 |
-+ if (zcache_enabled && use_cleancache) { |
13853 |
-+ struct cleancache_ops old_ops; |
13854 |
-+ |
13855 |
-+ zbud_init(); |
13856 |
-+ register_shrinker(&zcache_shrinker); |
13857 |
-+ old_ops = zcache_cleancache_register_ops(); |
13858 |
-+ pr_info("zcache: cleancache enabled using kernel " |
13859 |
-+ "transcendent memory and compression buddies\n"); |
13860 |
-+ if (old_ops.init_fs != NULL) |
13861 |
-+ pr_warning("zcache: cleancache_ops overridden"); |
13862 |
-+ } |
13863 |
-+#endif |
13864 |
-+#ifdef CONFIG_FRONTSWAP |
13865 |
-+ if (zcache_enabled && use_frontswap) { |
13866 |
-+ struct frontswap_ops old_ops; |
13867 |
-+ |
13868 |
-+ zcache_client.xvpool = xv_create_pool(); |
13869 |
-+ if (zcache_client.xvpool == NULL) { |
13870 |
-+ pr_err("zcache: can't create xvpool\n"); |
13871 |
-+ goto out; |
13872 |
-+ } |
13873 |
-+ old_ops = zcache_frontswap_register_ops(); |
13874 |
-+ pr_info("zcache: frontswap enabled using kernel " |
13875 |
-+ "transcendent memory and xvmalloc\n"); |
13876 |
-+ if (old_ops.init != NULL) |
13877 |
-+ pr_warning("ktmem: frontswap_ops overridden"); |
13878 |
-+ } |
13879 |
-+#endif |
13880 |
-+out: |
13881 |
-+ return ret; |
13882 |
-+} |
13883 |
-+ |
13884 |
-+module_init(zcache_init) |