1 |
Author: tomwij |
2 |
Date: 2013-04-29 17:10:10 +0000 (Mon, 29 Apr 2013) |
3 |
New Revision: 2356 |
4 |
|
5 |
Added: |
6 |
genpatches-2.6/trunk/3.9/1700_enable-thinkpad-micled.patch |
7 |
genpatches-2.6/trunk/3.9/2400_kcopy-patch-for-infiniband-driver.patch |
8 |
genpatches-2.6/trunk/3.9/2700_ThinkPad-30-brightness-control-fix.patch |
9 |
genpatches-2.6/trunk/3.9/2900_dev-root-proc-mount-fix.patch |
10 |
Modified: |
11 |
genpatches-2.6/trunk/3.9/0000_README |
12 |
Log: |
13 |
Linux patch 3.9.0. |
14 |
|
15 |
Modified: genpatches-2.6/trunk/3.9/0000_README |
16 |
=================================================================== |
17 |
--- genpatches-2.6/trunk/3.9/0000_README 2013-04-26 21:46:44 UTC (rev 2355) |
18 |
+++ genpatches-2.6/trunk/3.9/0000_README 2013-04-29 17:10:10 UTC (rev 2356) |
19 |
@@ -39,6 +39,26 @@ |
20 |
|
21 |
Individual Patch Descriptions: |
22 |
-------------------------------------------------------------------------- |
23 |
+Patch: 1700_enable-thinkpad-micled.patch |
24 |
+From: https://bugs.gentoo.org/show_bug.cgi?id=449248 |
25 |
+Desc: Enable mic mute led in thinkpads |
26 |
+ |
27 |
+Patch: 1800_memcg-OOM-revert-ZFS-deadlock.patch |
28 |
+From: https://bugs.gentoo.org/show_bug.cgi?id=462066 |
29 |
+Desc: Revert memcg patches that prevent OOM with too many dirty pages. |
30 |
+ |
31 |
+Patch: 2400_kcopy-patch-for-infiniband-driver.patch |
32 |
+From: Alexey Shvetsov <alexxy@g.o> |
33 |
+Desc: Zero copy for infiniband psm userspace driver |
34 |
+ |
35 |
+Patch: 2700_ThinkPad-30-brightness-control-fix.patch |
36 |
+From: Seth Forshee <seth.forshee@×××××××××.com> |
37 |
+Desc: ACPI: Disable Windows 8 compatibility for some Lenovo ThinkPads |
38 |
+ |
39 |
+Patch: 2900_dev-root-proc-mount-fix.patch |
40 |
+From: https://bugs.gentoo.org/show_bug.cgi?id=438380 |
41 |
+Desc: Ensure that /dev/root doesn't appear in /proc/mounts when bootint without an initramfs. |
42 |
+ |
43 |
Patch: 4200_fbcondecor-0.9.6.patch |
44 |
From: http://dev.gentoo.org/~spock |
45 |
Desc: Bootsplash successor by Michal Januszewski ported by Jeremy (bug #452574) |
46 |
|
47 |
Added: genpatches-2.6/trunk/3.9/1700_enable-thinkpad-micled.patch |
48 |
=================================================================== |
49 |
--- genpatches-2.6/trunk/3.9/1700_enable-thinkpad-micled.patch (rev 0) |
50 |
+++ genpatches-2.6/trunk/3.9/1700_enable-thinkpad-micled.patch 2013-04-29 17:10:10 UTC (rev 2356) |
51 |
@@ -0,0 +1,23 @@ |
52 |
+--- a/drivers/platform/x86/thinkpad_acpi.c 2013-02-06 08:46:53.546168051 -0500 |
53 |
++++ b/drivers/platform/x86/thinkpad_acpi.c 2013-02-06 08:52:16.846933455 -0500 |
54 |
+@@ -5056,8 +5056,10 @@ static const char * const tpacpi_led_nam |
55 |
+ "tpacpi::unknown_led2", |
56 |
+ "tpacpi::unknown_led3", |
57 |
+ "tpacpi::thinkvantage", |
58 |
++ "tpacpi::unknown_led4", |
59 |
++ "tpacpi::micmute", |
60 |
+ }; |
61 |
+-#define TPACPI_SAFE_LEDS 0x1081U |
62 |
++#define TPACPI_SAFE_LEDS 0x5081U |
63 |
+ |
64 |
+ static inline bool tpacpi_is_led_restricted(const unsigned int led) |
65 |
+ { |
66 |
+@@ -5280,7 +5282,7 @@ static const struct tpacpi_quirk led_use |
67 |
+ { /* Lenovo */ |
68 |
+ .vendor = PCI_VENDOR_ID_LENOVO, |
69 |
+ .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY, |
70 |
+- .quirks = 0x1fffU, |
71 |
++ .quirks = 0x5fffU, |
72 |
+ }, |
73 |
+ { /* IBM ThinkPads with no EC version string */ |
74 |
+ .vendor = PCI_VENDOR_ID_IBM, |
75 |
|
76 |
Added: genpatches-2.6/trunk/3.9/2400_kcopy-patch-for-infiniband-driver.patch |
77 |
=================================================================== |
78 |
--- genpatches-2.6/trunk/3.9/2400_kcopy-patch-for-infiniband-driver.patch (rev 0) |
79 |
+++ genpatches-2.6/trunk/3.9/2400_kcopy-patch-for-infiniband-driver.patch 2013-04-29 17:10:10 UTC (rev 2356) |
80 |
@@ -0,0 +1,731 @@ |
81 |
+From 1f52075d672a9bdd0069b3ea68be266ef5c229bd Mon Sep 17 00:00:00 2001 |
82 |
+From: Alexey Shvetsov <alexxy@g.o> |
83 |
+Date: Tue, 17 Jan 2012 21:08:49 +0400 |
84 |
+Subject: [PATCH] [kcopy] Add kcopy driver |
85 |
+ |
86 |
+Add kcopy driver from qlogic to implement zero copy for infiniband psm |
87 |
+userspace driver |
88 |
+ |
89 |
+Signed-off-by: Alexey Shvetsov <alexxy@g.o> |
90 |
+--- |
91 |
+ drivers/char/Kconfig | 2 + |
92 |
+ drivers/char/Makefile | 2 + |
93 |
+ drivers/char/kcopy/Kconfig | 17 ++ |
94 |
+ drivers/char/kcopy/Makefile | 4 + |
95 |
+ drivers/char/kcopy/kcopy.c | 646 +++++++++++++++++++++++++++++++++++++++++++ |
96 |
+ 5 files changed, 671 insertions(+) |
97 |
+ create mode 100644 drivers/char/kcopy/Kconfig |
98 |
+ create mode 100644 drivers/char/kcopy/Makefile |
99 |
+ create mode 100644 drivers/char/kcopy/kcopy.c |
100 |
+ |
101 |
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig |
102 |
+index ee94686..5b81449 100644 |
103 |
+--- a/drivers/char/Kconfig |
104 |
++++ b/drivers/char/Kconfig |
105 |
+@@ -6,6 +6,8 @@ menu "Character devices" |
106 |
+ |
107 |
+ source "drivers/tty/Kconfig" |
108 |
+ |
109 |
++source "drivers/char/kcopy/Kconfig" |
110 |
++ |
111 |
+ config DEVKMEM |
112 |
+ bool "/dev/kmem virtual device support" |
113 |
+ default y |
114 |
+diff --git a/drivers/char/Makefile b/drivers/char/Makefile |
115 |
+index 0dc5d7c..be519d6 100644 |
116 |
+--- a/drivers/char/Makefile |
117 |
++++ b/drivers/char/Makefile |
118 |
+@@ -62,3 +62,5 @@ |
119 |
+ js-rtc-y = rtc.o |
120 |
+ |
121 |
+ obj-$(CONFIG_TILE_SROM) += tile-srom.o |
122 |
++ |
123 |
++obj-$(CONFIG_KCOPY) += kcopy/ |
124 |
+diff --git a/drivers/char/kcopy/Kconfig b/drivers/char/kcopy/Kconfig |
125 |
+new file mode 100644 |
126 |
+index 0000000..453ae52 |
127 |
+--- /dev/null |
128 |
++++ b/drivers/char/kcopy/Kconfig |
129 |
+@@ -0,0 +1,17 @@ |
130 |
++# |
131 |
++# KCopy character device configuration |
132 |
++# |
133 |
++ |
134 |
++menu "KCopy" |
135 |
++ |
136 |
++config KCOPY |
137 |
++ tristate "Memory-to-memory copies using kernel assist" |
138 |
++ default m |
139 |
++ ---help--- |
140 |
++ High-performance inter-process memory copies. Can often save a |
141 |
++ memory copy to shared memory in the application. Useful at least |
142 |
++ for MPI applications where the point-to-point nature of vmsplice |
143 |
++ and pipes can be a limiting factor in performance. |
144 |
++ |
145 |
++endmenu |
146 |
++ |
147 |
+diff --git a/drivers/char/kcopy/Makefile b/drivers/char/kcopy/Makefile |
148 |
+new file mode 100644 |
149 |
+index 0000000..9cb269b |
150 |
+--- /dev/null |
151 |
++++ b/drivers/char/kcopy/Makefile |
152 |
+@@ -0,0 +1,4 @@ |
153 |
++# |
154 |
++# Makefile for the kernel character device drivers. |
155 |
++# |
156 |
++obj-$(CONFIG_KCOPY) += kcopy.o |
157 |
+diff --git a/drivers/char/kcopy/kcopy.c b/drivers/char/kcopy/kcopy.c |
158 |
+new file mode 100644 |
159 |
+index 0000000..a9f915c |
160 |
+--- /dev/null |
161 |
++++ b/drivers/char/kcopy/kcopy.c |
162 |
+@@ -0,0 +1,646 @@ |
163 |
++#include <linux/module.h> |
164 |
++#include <linux/fs.h> |
165 |
++#include <linux/cdev.h> |
166 |
++#include <linux/device.h> |
167 |
++#include <linux/mutex.h> |
168 |
++#include <linux/mman.h> |
169 |
++#include <linux/highmem.h> |
170 |
++#include <linux/spinlock.h> |
171 |
++#include <linux/sched.h> |
172 |
++#include <linux/rbtree.h> |
173 |
++#include <linux/rcupdate.h> |
174 |
++#include <linux/uaccess.h> |
175 |
++#include <linux/slab.h> |
176 |
++ |
177 |
++MODULE_LICENSE("GPL"); |
178 |
++MODULE_AUTHOR("Arthur Jones <arthur.jones@××××××.com>"); |
179 |
++MODULE_DESCRIPTION("QLogic kcopy driver"); |
180 |
++ |
181 |
++#define KCOPY_ABI 1 |
182 |
++#define KCOPY_MAX_MINORS 64 |
183 |
++ |
184 |
++struct kcopy_device { |
185 |
++ struct cdev cdev; |
186 |
++ struct class *class; |
187 |
++ struct device *devp[KCOPY_MAX_MINORS]; |
188 |
++ dev_t dev; |
189 |
++ |
190 |
++ struct kcopy_file *kf[KCOPY_MAX_MINORS]; |
191 |
++ struct mutex open_lock; |
192 |
++}; |
193 |
++ |
194 |
++static struct kcopy_device kcopy_dev; |
195 |
++ |
196 |
++/* per file data / one of these is shared per minor */ |
197 |
++struct kcopy_file { |
198 |
++ int count; |
199 |
++ |
200 |
++ /* pid indexed */ |
201 |
++ struct rb_root live_map_tree; |
202 |
++ |
203 |
++ struct mutex map_lock; |
204 |
++}; |
205 |
++ |
206 |
++struct kcopy_map_entry { |
207 |
++ int count; |
208 |
++ struct task_struct *task; |
209 |
++ pid_t pid; |
210 |
++ struct kcopy_file *file; /* file backpointer */ |
211 |
++ |
212 |
++ struct list_head list; /* free map list */ |
213 |
++ struct rb_node node; /* live map tree */ |
214 |
++}; |
215 |
++ |
216 |
++#define KCOPY_GET_SYSCALL 1 |
217 |
++#define KCOPY_PUT_SYSCALL 2 |
218 |
++#define KCOPY_ABI_SYSCALL 3 |
219 |
++ |
220 |
++struct kcopy_syscall { |
221 |
++ __u32 tag; |
222 |
++ pid_t pid; |
223 |
++ __u64 n; |
224 |
++ __u64 src; |
225 |
++ __u64 dst; |
226 |
++}; |
227 |
++ |
228 |
++static const void __user *kcopy_syscall_src(const struct kcopy_syscall *ks) |
229 |
++{ |
230 |
++ return (const void __user *) (unsigned long) ks->src; |
231 |
++} |
232 |
++ |
233 |
++static void __user *kcopy_syscall_dst(const struct kcopy_syscall *ks) |
234 |
++{ |
235 |
++ return (void __user *) (unsigned long) ks->dst; |
236 |
++} |
237 |
++ |
238 |
++static unsigned long kcopy_syscall_n(const struct kcopy_syscall *ks) |
239 |
++{ |
240 |
++ return (unsigned long) ks->n; |
241 |
++} |
242 |
++ |
243 |
++static struct kcopy_map_entry *kcopy_create_entry(struct kcopy_file *file) |
244 |
++{ |
245 |
++ struct kcopy_map_entry *kme = |
246 |
++ kmalloc(sizeof(struct kcopy_map_entry), GFP_KERNEL); |
247 |
++ |
248 |
++ if (!kme) |
249 |
++ return NULL; |
250 |
++ |
251 |
++ kme->count = 1; |
252 |
++ kme->file = file; |
253 |
++ kme->task = current; |
254 |
++ kme->pid = current->tgid; |
255 |
++ INIT_LIST_HEAD(&kme->list); |
256 |
++ |
257 |
++ return kme; |
258 |
++} |
259 |
++ |
260 |
++static struct kcopy_map_entry * |
261 |
++kcopy_lookup_pid(struct rb_root *root, pid_t pid) |
262 |
++{ |
263 |
++ struct rb_node *node = root->rb_node; |
264 |
++ |
265 |
++ while (node) { |
266 |
++ struct kcopy_map_entry *kme = |
267 |
++ container_of(node, struct kcopy_map_entry, node); |
268 |
++ |
269 |
++ if (pid < kme->pid) |
270 |
++ node = node->rb_left; |
271 |
++ else if (pid > kme->pid) |
272 |
++ node = node->rb_right; |
273 |
++ else |
274 |
++ return kme; |
275 |
++ } |
276 |
++ |
277 |
++ return NULL; |
278 |
++} |
279 |
++ |
280 |
++static int kcopy_insert(struct rb_root *root, struct kcopy_map_entry *kme) |
281 |
++{ |
282 |
++ struct rb_node **new = &(root->rb_node); |
283 |
++ struct rb_node *parent = NULL; |
284 |
++ |
285 |
++ while (*new) { |
286 |
++ struct kcopy_map_entry *tkme = |
287 |
++ container_of(*new, struct kcopy_map_entry, node); |
288 |
++ |
289 |
++ parent = *new; |
290 |
++ if (kme->pid < tkme->pid) |
291 |
++ new = &((*new)->rb_left); |
292 |
++ else if (kme->pid > tkme->pid) |
293 |
++ new = &((*new)->rb_right); |
294 |
++ else { |
295 |
++ printk(KERN_INFO "!!! debugging: bad rb tree !!!\n"); |
296 |
++ return -EINVAL; |
297 |
++ } |
298 |
++ } |
299 |
++ |
300 |
++ rb_link_node(&kme->node, parent, new); |
301 |
++ rb_insert_color(&kme->node, root); |
302 |
++ |
303 |
++ return 0; |
304 |
++} |
305 |
++ |
306 |
++static int kcopy_open(struct inode *inode, struct file *filp) |
307 |
++{ |
308 |
++ int ret; |
309 |
++ const int minor = iminor(inode); |
310 |
++ struct kcopy_file *kf = NULL; |
311 |
++ struct kcopy_map_entry *kme; |
312 |
++ struct kcopy_map_entry *okme; |
313 |
++ |
314 |
++ if (minor < 0 || minor >= KCOPY_MAX_MINORS) |
315 |
++ return -ENODEV; |
316 |
++ |
317 |
++ mutex_lock(&kcopy_dev.open_lock); |
318 |
++ |
319 |
++ if (!kcopy_dev.kf[minor]) { |
320 |
++ kf = kmalloc(sizeof(struct kcopy_file), GFP_KERNEL); |
321 |
++ |
322 |
++ if (!kf) { |
323 |
++ ret = -ENOMEM; |
324 |
++ goto bail; |
325 |
++ } |
326 |
++ |
327 |
++ kf->count = 1; |
328 |
++ kf->live_map_tree = RB_ROOT; |
329 |
++ mutex_init(&kf->map_lock); |
330 |
++ kcopy_dev.kf[minor] = kf; |
331 |
++ } else { |
332 |
++ if (filp->f_flags & O_EXCL) { |
333 |
++ ret = -EBUSY; |
334 |
++ goto bail; |
335 |
++ } |
336 |
++ kcopy_dev.kf[minor]->count++; |
337 |
++ } |
338 |
++ |
339 |
++ kme = kcopy_create_entry(kcopy_dev.kf[minor]); |
340 |
++ if (!kme) { |
341 |
++ ret = -ENOMEM; |
342 |
++ goto err_free_kf; |
343 |
++ } |
344 |
++ |
345 |
++ kf = kcopy_dev.kf[minor]; |
346 |
++ |
347 |
++ mutex_lock(&kf->map_lock); |
348 |
++ |
349 |
++ okme = kcopy_lookup_pid(&kf->live_map_tree, kme->pid); |
350 |
++ if (okme) { |
351 |
++ /* pid already exists... */ |
352 |
++ okme->count++; |
353 |
++ kfree(kme); |
354 |
++ kme = okme; |
355 |
++ } else |
356 |
++ ret = kcopy_insert(&kf->live_map_tree, kme); |
357 |
++ |
358 |
++ mutex_unlock(&kf->map_lock); |
359 |
++ |
360 |
++ filp->private_data = kme; |
361 |
++ |
362 |
++ ret = 0; |
363 |
++ goto bail; |
364 |
++ |
365 |
++err_free_kf: |
366 |
++ if (kf) { |
367 |
++ kcopy_dev.kf[minor] = NULL; |
368 |
++ kfree(kf); |
369 |
++ } |
370 |
++bail: |
371 |
++ mutex_unlock(&kcopy_dev.open_lock); |
372 |
++ return ret; |
373 |
++} |
374 |
++ |
375 |
++static int kcopy_flush(struct file *filp, fl_owner_t id) |
376 |
++{ |
377 |
++ struct kcopy_map_entry *kme = filp->private_data; |
378 |
++ struct kcopy_file *kf = kme->file; |
379 |
++ |
380 |
++ if (file_count(filp) == 1) { |
381 |
++ mutex_lock(&kf->map_lock); |
382 |
++ kme->count--; |
383 |
++ |
384 |
++ if (!kme->count) { |
385 |
++ rb_erase(&kme->node, &kf->live_map_tree); |
386 |
++ kfree(kme); |
387 |
++ } |
388 |
++ mutex_unlock(&kf->map_lock); |
389 |
++ } |
390 |
++ |
391 |
++ return 0; |
392 |
++} |
393 |
++ |
394 |
++static int kcopy_release(struct inode *inode, struct file *filp) |
395 |
++{ |
396 |
++ const int minor = iminor(inode); |
397 |
++ |
398 |
++ mutex_lock(&kcopy_dev.open_lock); |
399 |
++ kcopy_dev.kf[minor]->count--; |
400 |
++ if (!kcopy_dev.kf[minor]->count) { |
401 |
++ kfree(kcopy_dev.kf[minor]); |
402 |
++ kcopy_dev.kf[minor] = NULL; |
403 |
++ } |
404 |
++ mutex_unlock(&kcopy_dev.open_lock); |
405 |
++ |
406 |
++ return 0; |
407 |
++} |
408 |
++ |
409 |
++static void kcopy_put_pages(struct page **pages, int npages) |
410 |
++{ |
411 |
++ int j; |
412 |
++ |
413 |
++ for (j = 0; j < npages; j++) |
414 |
++ put_page(pages[j]); |
415 |
++} |
416 |
++ |
417 |
++static int kcopy_validate_task(struct task_struct *p) |
418 |
++{ |
419 |
++ return p && (uid_eq(current_euid(), task_euid(p)) || uid_eq(current_euid(), task_uid(p))); |
420 |
++} |
421 |
++ |
422 |
++static int kcopy_get_pages(struct kcopy_file *kf, pid_t pid, |
423 |
++ struct page **pages, void __user *addr, |
424 |
++ int write, size_t npages) |
425 |
++{ |
426 |
++ int err; |
427 |
++ struct mm_struct *mm; |
428 |
++ struct kcopy_map_entry *rkme; |
429 |
++ |
430 |
++ mutex_lock(&kf->map_lock); |
431 |
++ |
432 |
++ rkme = kcopy_lookup_pid(&kf->live_map_tree, pid); |
433 |
++ if (!rkme || !kcopy_validate_task(rkme->task)) { |
434 |
++ err = -EINVAL; |
435 |
++ goto bail_unlock; |
436 |
++ } |
437 |
++ |
438 |
++ mm = get_task_mm(rkme->task); |
439 |
++ if (unlikely(!mm)) { |
440 |
++ err = -ENOMEM; |
441 |
++ goto bail_unlock; |
442 |
++ } |
443 |
++ |
444 |
++ down_read(&mm->mmap_sem); |
445 |
++ err = get_user_pages(rkme->task, mm, |
446 |
++ (unsigned long) addr, npages, write, 0, |
447 |
++ pages, NULL); |
448 |
++ |
449 |
++ if (err < npages && err > 0) { |
450 |
++ kcopy_put_pages(pages, err); |
451 |
++ err = -ENOMEM; |
452 |
++ } else if (err == npages) |
453 |
++ err = 0; |
454 |
++ |
455 |
++ up_read(&mm->mmap_sem); |
456 |
++ |
457 |
++ mmput(mm); |
458 |
++ |
459 |
++bail_unlock: |
460 |
++ mutex_unlock(&kf->map_lock); |
461 |
++ |
462 |
++ return err; |
463 |
++} |
464 |
++ |
465 |
++static unsigned long kcopy_copy_pages_from_user(void __user *src, |
466 |
++ struct page **dpages, |
467 |
++ unsigned doff, |
468 |
++ unsigned long n) |
469 |
++{ |
470 |
++ struct page *dpage = *dpages; |
471 |
++ char *daddr = kmap(dpage); |
472 |
++ int ret = 0; |
473 |
++ |
474 |
++ while (1) { |
475 |
++ const unsigned long nleft = PAGE_SIZE - doff; |
476 |
++ const unsigned long nc = (n < nleft) ? n : nleft; |
477 |
++ |
478 |
++ /* if (copy_from_user(daddr + doff, src, nc)) { */ |
479 |
++ if (__copy_from_user_nocache(daddr + doff, src, nc)) { |
480 |
++ ret = -EFAULT; |
481 |
++ goto bail; |
482 |
++ } |
483 |
++ |
484 |
++ n -= nc; |
485 |
++ if (n == 0) |
486 |
++ break; |
487 |
++ |
488 |
++ doff += nc; |
489 |
++ doff &= ~PAGE_MASK; |
490 |
++ if (doff == 0) { |
491 |
++ kunmap(dpage); |
492 |
++ dpages++; |
493 |
++ dpage = *dpages; |
494 |
++ daddr = kmap(dpage); |
495 |
++ } |
496 |
++ |
497 |
++ src += nc; |
498 |
++ } |
499 |
++ |
500 |
++bail: |
501 |
++ kunmap(dpage); |
502 |
++ |
503 |
++ return ret; |
504 |
++} |
505 |
++ |
506 |
++static unsigned long kcopy_copy_pages_to_user(void __user *dst, |
507 |
++ struct page **spages, |
508 |
++ unsigned soff, |
509 |
++ unsigned long n) |
510 |
++{ |
511 |
++ struct page *spage = *spages; |
512 |
++ const char *saddr = kmap(spage); |
513 |
++ int ret = 0; |
514 |
++ |
515 |
++ while (1) { |
516 |
++ const unsigned long nleft = PAGE_SIZE - soff; |
517 |
++ const unsigned long nc = (n < nleft) ? n : nleft; |
518 |
++ |
519 |
++ if (copy_to_user(dst, saddr + soff, nc)) { |
520 |
++ ret = -EFAULT; |
521 |
++ goto bail; |
522 |
++ } |
523 |
++ |
524 |
++ n -= nc; |
525 |
++ if (n == 0) |
526 |
++ break; |
527 |
++ |
528 |
++ soff += nc; |
529 |
++ soff &= ~PAGE_MASK; |
530 |
++ if (soff == 0) { |
531 |
++ kunmap(spage); |
532 |
++ spages++; |
533 |
++ spage = *spages; |
534 |
++ saddr = kmap(spage); |
535 |
++ } |
536 |
++ |
537 |
++ dst += nc; |
538 |
++ } |
539 |
++ |
540 |
++bail: |
541 |
++ kunmap(spage); |
542 |
++ |
543 |
++ return ret; |
544 |
++} |
545 |
++ |
546 |
++static unsigned long kcopy_copy_to_user(void __user *dst, |
547 |
++ struct kcopy_file *kf, pid_t pid, |
548 |
++ void __user *src, |
549 |
++ unsigned long n) |
550 |
++{ |
551 |
++ struct page **pages; |
552 |
++ const int pages_len = PAGE_SIZE / sizeof(struct page *); |
553 |
++ int ret = 0; |
554 |
++ |
555 |
++ pages = (struct page **) __get_free_page(GFP_KERNEL); |
556 |
++ if (!pages) { |
557 |
++ ret = -ENOMEM; |
558 |
++ goto bail; |
559 |
++ } |
560 |
++ |
561 |
++ while (n) { |
562 |
++ const unsigned long soff = (unsigned long) src & ~PAGE_MASK; |
563 |
++ const unsigned long spages_left = |
564 |
++ (soff + n + PAGE_SIZE - 1) >> PAGE_SHIFT; |
565 |
++ const unsigned long spages_cp = |
566 |
++ min_t(unsigned long, spages_left, pages_len); |
567 |
++ const unsigned long sbytes = |
568 |
++ PAGE_SIZE - soff + (spages_cp - 1) * PAGE_SIZE; |
569 |
++ const unsigned long nbytes = min_t(unsigned long, sbytes, n); |
570 |
++ |
571 |
++ ret = kcopy_get_pages(kf, pid, pages, src, 0, spages_cp); |
572 |
++ if (unlikely(ret)) |
573 |
++ goto bail_free; |
574 |
++ |
575 |
++ ret = kcopy_copy_pages_to_user(dst, pages, soff, nbytes); |
576 |
++ kcopy_put_pages(pages, spages_cp); |
577 |
++ if (ret) |
578 |
++ goto bail_free; |
579 |
++ dst = (char *) dst + nbytes; |
580 |
++ src = (char *) src + nbytes; |
581 |
++ |
582 |
++ n -= nbytes; |
583 |
++ } |
584 |
++ |
585 |
++bail_free: |
586 |
++ free_page((unsigned long) pages); |
587 |
++bail: |
588 |
++ return ret; |
589 |
++} |
590 |
++ |
591 |
++static unsigned long kcopy_copy_from_user(const void __user *src, |
592 |
++ struct kcopy_file *kf, pid_t pid, |
593 |
++ void __user *dst, |
594 |
++ unsigned long n) |
595 |
++{ |
596 |
++ struct page **pages; |
597 |
++ const int pages_len = PAGE_SIZE / sizeof(struct page *); |
598 |
++ int ret = 0; |
599 |
++ |
600 |
++ pages = (struct page **) __get_free_page(GFP_KERNEL); |
601 |
++ if (!pages) { |
602 |
++ ret = -ENOMEM; |
603 |
++ goto bail; |
604 |
++ } |
605 |
++ |
606 |
++ while (n) { |
607 |
++ const unsigned long doff = (unsigned long) dst & ~PAGE_MASK; |
608 |
++ const unsigned long dpages_left = |
609 |
++ (doff + n + PAGE_SIZE - 1) >> PAGE_SHIFT; |
610 |
++ const unsigned long dpages_cp = |
611 |
++ min_t(unsigned long, dpages_left, pages_len); |
612 |
++ const unsigned long dbytes = |
613 |
++ PAGE_SIZE - doff + (dpages_cp - 1) * PAGE_SIZE; |
614 |
++ const unsigned long nbytes = min_t(unsigned long, dbytes, n); |
615 |
++ |
616 |
++ ret = kcopy_get_pages(kf, pid, pages, dst, 1, dpages_cp); |
617 |
++ if (unlikely(ret)) |
618 |
++ goto bail_free; |
619 |
++ |
620 |
++ ret = kcopy_copy_pages_from_user((void __user *) src, |
621 |
++ pages, doff, nbytes); |
622 |
++ kcopy_put_pages(pages, dpages_cp); |
623 |
++ if (ret) |
624 |
++ goto bail_free; |
625 |
++ |
626 |
++ dst = (char *) dst + nbytes; |
627 |
++ src = (char *) src + nbytes; |
628 |
++ |
629 |
++ n -= nbytes; |
630 |
++ } |
631 |
++ |
632 |
++bail_free: |
633 |
++ free_page((unsigned long) pages); |
634 |
++bail: |
635 |
++ return ret; |
636 |
++} |
637 |
++ |
638 |
++static int kcopy_do_get(struct kcopy_map_entry *kme, pid_t pid, |
639 |
++ const void __user *src, void __user *dst, |
640 |
++ unsigned long n) |
641 |
++{ |
642 |
++ struct kcopy_file *kf = kme->file; |
643 |
++ int ret = 0; |
644 |
++ |
645 |
++ if (n == 0) { |
646 |
++ ret = -EINVAL; |
647 |
++ goto bail; |
648 |
++ } |
649 |
++ |
650 |
++ ret = kcopy_copy_to_user(dst, kf, pid, (void __user *) src, n); |
651 |
++ |
652 |
++bail: |
653 |
++ return ret; |
654 |
++} |
655 |
++ |
656 |
++static int kcopy_do_put(struct kcopy_map_entry *kme, const void __user *src, |
657 |
++ pid_t pid, void __user *dst, |
658 |
++ unsigned long n) |
659 |
++{ |
660 |
++ struct kcopy_file *kf = kme->file; |
661 |
++ int ret = 0; |
662 |
++ |
663 |
++ if (n == 0) { |
664 |
++ ret = -EINVAL; |
665 |
++ goto bail; |
666 |
++ } |
667 |
++ |
668 |
++ ret = kcopy_copy_from_user(src, kf, pid, (void __user *) dst, n); |
669 |
++ |
670 |
++bail: |
671 |
++ return ret; |
672 |
++} |
673 |
++ |
674 |
++static int kcopy_do_abi(u32 __user *dst) |
675 |
++{ |
676 |
++ u32 val = KCOPY_ABI; |
677 |
++ int err; |
678 |
++ |
679 |
++ err = put_user(val, dst); |
680 |
++ if (err) |
681 |
++ return -EFAULT; |
682 |
++ |
683 |
++ return 0; |
684 |
++} |
685 |
++ |
686 |
++ssize_t kcopy_write(struct file *filp, const char __user *data, size_t cnt, |
687 |
++ loff_t *o) |
688 |
++{ |
689 |
++ struct kcopy_map_entry *kme = filp->private_data; |
690 |
++ struct kcopy_syscall ks; |
691 |
++ int err = 0; |
692 |
++ const void __user *src; |
693 |
++ void __user *dst; |
694 |
++ unsigned long n; |
695 |
++ |
696 |
++ if (cnt != sizeof(struct kcopy_syscall)) { |
697 |
++ err = -EINVAL; |
698 |
++ goto bail; |
699 |
++ } |
700 |
++ |
701 |
++ err = copy_from_user(&ks, data, cnt); |
702 |
++ if (unlikely(err)) |
703 |
++ goto bail; |
704 |
++ |
705 |
++ src = kcopy_syscall_src(&ks); |
706 |
++ dst = kcopy_syscall_dst(&ks); |
707 |
++ n = kcopy_syscall_n(&ks); |
708 |
++ if (ks.tag == KCOPY_GET_SYSCALL) |
709 |
++ err = kcopy_do_get(kme, ks.pid, src, dst, n); |
710 |
++ else if (ks.tag == KCOPY_PUT_SYSCALL) |
711 |
++ err = kcopy_do_put(kme, src, ks.pid, dst, n); |
712 |
++ else if (ks.tag == KCOPY_ABI_SYSCALL) |
713 |
++ err = kcopy_do_abi(dst); |
714 |
++ else |
715 |
++ err = -EINVAL; |
716 |
++ |
717 |
++bail: |
718 |
++ return err ? err : cnt; |
719 |
++} |
720 |
++ |
721 |
++static const struct file_operations kcopy_fops = { |
722 |
++ .owner = THIS_MODULE, |
723 |
++ .open = kcopy_open, |
724 |
++ .release = kcopy_release, |
725 |
++ .flush = kcopy_flush, |
726 |
++ .write = kcopy_write, |
727 |
++}; |
728 |
++ |
729 |
++static int __init kcopy_init(void) |
730 |
++{ |
731 |
++ int ret; |
732 |
++ const char *name = "kcopy"; |
733 |
++ int i; |
734 |
++ int ninit = 0; |
735 |
++ |
736 |
++ mutex_init(&kcopy_dev.open_lock); |
737 |
++ |
738 |
++ ret = alloc_chrdev_region(&kcopy_dev.dev, 0, KCOPY_MAX_MINORS, name); |
739 |
++ if (ret) |
740 |
++ goto bail; |
741 |
++ |
742 |
++ kcopy_dev.class = class_create(THIS_MODULE, (char *) name); |
743 |
++ |
744 |
++ if (IS_ERR(kcopy_dev.class)) { |
745 |
++ ret = PTR_ERR(kcopy_dev.class); |
746 |
++ printk(KERN_ERR "kcopy: Could not create " |
747 |
++ "device class (err %d)\n", -ret); |
748 |
++ goto bail_chrdev; |
749 |
++ } |
750 |
++ |
751 |
++ cdev_init(&kcopy_dev.cdev, &kcopy_fops); |
752 |
++ ret = cdev_add(&kcopy_dev.cdev, kcopy_dev.dev, KCOPY_MAX_MINORS); |
753 |
++ if (ret < 0) { |
754 |
++ printk(KERN_ERR "kcopy: Could not add cdev (err %d)\n", |
755 |
++ -ret); |
756 |
++ goto bail_class; |
757 |
++ } |
758 |
++ |
759 |
++ for (i = 0; i < KCOPY_MAX_MINORS; i++) { |
760 |
++ char devname[8]; |
761 |
++ const int minor = MINOR(kcopy_dev.dev) + i; |
762 |
++ const dev_t dev = MKDEV(MAJOR(kcopy_dev.dev), minor); |
763 |
++ |
764 |
++ snprintf(devname, sizeof(devname), "kcopy%02d", i); |
765 |
++ kcopy_dev.devp[i] = |
766 |
++ device_create(kcopy_dev.class, NULL, |
767 |
++ dev, NULL, devname); |
768 |
++ |
769 |
++ if (IS_ERR(kcopy_dev.devp[i])) { |
770 |
++ ret = PTR_ERR(kcopy_dev.devp[i]); |
771 |
++ printk(KERN_ERR "kcopy: Could not create " |
772 |
++ "devp %d (err %d)\n", i, -ret); |
773 |
++ goto bail_cdev_add; |
774 |
++ } |
775 |
++ |
776 |
++ ninit++; |
777 |
++ } |
778 |
++ |
779 |
++ ret = 0; |
780 |
++ goto bail; |
781 |
++ |
782 |
++bail_cdev_add: |
783 |
++ for (i = 0; i < ninit; i++) |
784 |
++ device_unregister(kcopy_dev.devp[i]); |
785 |
++ |
786 |
++ cdev_del(&kcopy_dev.cdev); |
787 |
++bail_class: |
788 |
++ class_destroy(kcopy_dev.class); |
789 |
++bail_chrdev: |
790 |
++ unregister_chrdev_region(kcopy_dev.dev, KCOPY_MAX_MINORS); |
791 |
++bail: |
792 |
++ return ret; |
793 |
++} |
794 |
++ |
795 |
++static void __exit kcopy_fini(void) |
796 |
++{ |
797 |
++ int i; |
798 |
++ |
799 |
++ for (i = 0; i < KCOPY_MAX_MINORS; i++) |
800 |
++ device_unregister(kcopy_dev.devp[i]); |
801 |
++ |
802 |
++ cdev_del(&kcopy_dev.cdev); |
803 |
++ class_destroy(kcopy_dev.class); |
804 |
++ unregister_chrdev_region(kcopy_dev.dev, KCOPY_MAX_MINORS); |
805 |
++} |
806 |
++ |
807 |
++module_init(kcopy_init); |
808 |
++module_exit(kcopy_fini); |
809 |
+-- |
810 |
+1.7.10 |
811 |
+ |
812 |
|
813 |
Added: genpatches-2.6/trunk/3.9/2700_ThinkPad-30-brightness-control-fix.patch |
814 |
=================================================================== |
815 |
--- genpatches-2.6/trunk/3.9/2700_ThinkPad-30-brightness-control-fix.patch (rev 0) |
816 |
+++ genpatches-2.6/trunk/3.9/2700_ThinkPad-30-brightness-control-fix.patch 2013-04-29 17:10:10 UTC (rev 2356) |
817 |
@@ -0,0 +1,81 @@ |
818 |
+diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c |
819 |
+index cb96296..6c242ed 100644 |
820 |
+--- a/drivers/acpi/blacklist.c |
821 |
++++ b/drivers/acpi/blacklist.c |
822 |
+@@ -193,6 +193,13 @@ static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) |
823 |
+ return 0; |
824 |
+ } |
825 |
+ |
826 |
++static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) |
827 |
++{ |
828 |
++ printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
829 |
++ acpi_osi_setup("!Windows 2012"); |
830 |
++ return 0; |
831 |
++} |
832 |
++ |
833 |
+ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { |
834 |
+ { |
835 |
+ .callback = dmi_disable_osi_vista, |
836 |
+@@ -269,6 +276,61 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { |
837 |
+ }, |
838 |
+ |
839 |
+ /* |
840 |
++ * The following Lenovo models have a broken workaround in the |
841 |
++ * acpi_video backlight implementation to meet the Windows 8 |
842 |
++ * requirement of 101 backlight levels. Reverting to pre-Win8 |
843 |
++ * behavior fixes the problem. |
844 |
++ */ |
845 |
++ { |
846 |
++ .callback = dmi_disable_osi_win8, |
847 |
++ .ident = "Lenovo ThinkPad L430", |
848 |
++ .matches = { |
849 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
850 |
++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L430"), |
851 |
++ }, |
852 |
++ }, |
853 |
++ { |
854 |
++ .callback = dmi_disable_osi_win8, |
855 |
++ .ident = "Lenovo ThinkPad T430s", |
856 |
++ .matches = { |
857 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
858 |
++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), |
859 |
++ }, |
860 |
++ }, |
861 |
++ { |
862 |
++ .callback = dmi_disable_osi_win8, |
863 |
++ .ident = "Lenovo ThinkPad T530", |
864 |
++ .matches = { |
865 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
866 |
++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T530"), |
867 |
++ }, |
868 |
++ }, |
869 |
++ { |
870 |
++ .callback = dmi_disable_osi_win8, |
871 |
++ .ident = "Lenovo ThinkPad W530", |
872 |
++ .matches = { |
873 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
874 |
++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"), |
875 |
++ }, |
876 |
++ }, |
877 |
++ { |
878 |
++ .callback = dmi_disable_osi_win8, |
879 |
++ .ident = "Lenovo ThinkPad X1 Carbon", |
880 |
++ .matches = { |
881 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
882 |
++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"), |
883 |
++ }, |
884 |
++ }, |
885 |
++ { |
886 |
++ .callback = dmi_disable_osi_win8, |
887 |
++ .ident = "Lenovo ThinkPad X230", |
888 |
++ .matches = { |
889 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
890 |
++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), |
891 |
++ }, |
892 |
++ }, |
893 |
++ |
894 |
++ /* |
895 |
+ * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
896 |
+ * Linux ignores it, except for the machines enumerated below. |
897 |
+ */ |
898 |
+ |
899 |
|
900 |
Added: genpatches-2.6/trunk/3.9/2900_dev-root-proc-mount-fix.patch |
901 |
=================================================================== |
902 |
--- genpatches-2.6/trunk/3.9/2900_dev-root-proc-mount-fix.patch (rev 0) |
903 |
+++ genpatches-2.6/trunk/3.9/2900_dev-root-proc-mount-fix.patch 2013-04-29 17:10:10 UTC (rev 2356) |
904 |
@@ -0,0 +1,29 @@ |
905 |
+--- a/init/do_mounts.c 2013-01-25 19:11:11.609802424 -0500 |
906 |
++++ b/init/do_mounts.c 2013-01-25 19:14:20.606053568 -0500 |
907 |
+@@ -461,7 +461,10 @@ void __init change_floppy(char *fmt, ... |
908 |
+ va_start(args, fmt); |
909 |
+ vsprintf(buf, fmt, args); |
910 |
+ va_end(args); |
911 |
+- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); |
912 |
++ if (saved_root_name[0]) |
913 |
++ fd = sys_open(saved_root_name, O_RDWR | O_NDELAY, 0); |
914 |
++ else |
915 |
++ fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); |
916 |
+ if (fd >= 0) { |
917 |
+ sys_ioctl(fd, FDEJECT, 0); |
918 |
+ sys_close(fd); |
919 |
+@@ -505,7 +508,13 @@ void __init mount_root(void) |
920 |
+ #endif |
921 |
+ #ifdef CONFIG_BLOCK |
922 |
+ create_dev("/dev/root", ROOT_DEV); |
923 |
+- mount_block_root("/dev/root", root_mountflags); |
924 |
++ if (saved_root_name[0]) { |
925 |
++ create_dev(saved_root_name, ROOT_DEV); |
926 |
++ mount_block_root(saved_root_name, root_mountflags); |
927 |
++ } else { |
928 |
++ create_dev("/dev/root", ROOT_DEV); |
929 |
++ mount_block_root("/dev/root", root_mountflags); |
930 |
++ } |
931 |
+ #endif |
932 |
+ } |
933 |
+ |