summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-3.10/0108-vchiq-create_pagelist-copes-with-vmalloc-memory.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-3.10/0108-vchiq-create_pagelist-copes-with-vmalloc-memory.patch')
-rw-r--r--target/linux/brcm2708/patches-3.10/0108-vchiq-create_pagelist-copes-with-vmalloc-memory.patch143
1 files changed, 0 insertions, 143 deletions
diff --git a/target/linux/brcm2708/patches-3.10/0108-vchiq-create_pagelist-copes-with-vmalloc-memory.patch b/target/linux/brcm2708/patches-3.10/0108-vchiq-create_pagelist-copes-with-vmalloc-memory.patch
deleted file mode 100644
index befcaa1a82..0000000000
--- a/target/linux/brcm2708/patches-3.10/0108-vchiq-create_pagelist-copes-with-vmalloc-memory.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From f3978e548747dfe988016ef7c99fe50975da90df Mon Sep 17 00:00:00 2001
-From: Vincent Sanders <vincent.sanders@collabora.co.uk>
-Date: Mon, 2 Sep 2013 16:44:57 +0100
-Subject: [PATCH 108/196] vchiq: create_pagelist copes with vmalloc memory
-
-Signed-off-by: Daniel Stone <daniels@collabora.com>
----
- .../interface/vchiq_arm/vchiq_2835_arm.c | 83 ++++++++++++++--------
- 1 file changed, 53 insertions(+), 30 deletions(-)
-
-diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
-index 2b5fa56..b3bdaa2 100644
---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
-+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
-@@ -374,6 +374,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
- unsigned int num_pages, offset, i;
- char *addr, *base_addr, *next_addr;
- int run, addridx, actual_pages;
-+ unsigned long *need_release;
-
- offset = (unsigned int)buf & (PAGE_SIZE - 1);
- num_pages = (count + offset + PAGE_SIZE - 1) / PAGE_SIZE;
-@@ -384,9 +385,10 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
- ** list
- */
- pagelist = kmalloc(sizeof(PAGELIST_T) +
-- (num_pages * sizeof(unsigned long)) +
-- (num_pages * sizeof(pages[0])),
-- GFP_KERNEL);
-+ (num_pages * sizeof(unsigned long)) +
-+ sizeof(unsigned long) +
-+ (num_pages * sizeof(pages[0])),
-+ GFP_KERNEL);
-
- vchiq_log_trace(vchiq_arm_log_level,
- "create_pagelist - %x", (unsigned int)pagelist);
-@@ -394,28 +396,44 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
- return -ENOMEM;
-
- addrs = pagelist->addrs;
-- pages = (struct page **)(addrs + num_pages);
-+ need_release = (unsigned long *)(addrs + num_pages);
-+ pages = (struct page **)(addrs + num_pages + 1);
-
-- down_read(&task->mm->mmap_sem);
-- actual_pages = get_user_pages(task, task->mm,
-- (unsigned long)buf & ~(PAGE_SIZE - 1), num_pages,
-- (type == PAGELIST_READ) /*Write */ , 0 /*Force */ ,
-- pages, NULL /*vmas */);
-- up_read(&task->mm->mmap_sem);
--
-- if (actual_pages != num_pages)
-- {
-- /* This is probably due to the process being killed */
-- while (actual_pages > 0)
-- {
-- actual_pages--;
-- page_cache_release(pages[actual_pages]);
-- }
-- kfree(pagelist);
-- if (actual_pages == 0)
-- actual_pages = -ENOMEM;
-- return actual_pages;
-- }
-+ if (is_vmalloc_addr(buf)) {
-+ for (actual_pages = 0; actual_pages < num_pages; actual_pages++) {
-+ pages[actual_pages] = vmalloc_to_page(buf + (actual_pages * PAGE_SIZE));
-+ }
-+ *need_release = 0; /* do not try and release vmalloc pages */
-+ } else {
-+ down_read(&task->mm->mmap_sem);
-+ actual_pages = get_user_pages(task, task->mm,
-+ (unsigned long)buf & ~(PAGE_SIZE - 1),
-+ num_pages,
-+ (type == PAGELIST_READ) /*Write */ ,
-+ 0 /*Force */ ,
-+ pages,
-+ NULL /*vmas */);
-+ up_read(&task->mm->mmap_sem);
-+
-+ if (actual_pages != num_pages) {
-+ vchiq_log_info(vchiq_arm_log_level,
-+ "create_pagelist - only %d/%d pages locked",
-+ actual_pages,
-+ num_pages);
-+
-+ /* This is probably due to the process being killed */
-+ while (actual_pages > 0)
-+ {
-+ actual_pages--;
-+ page_cache_release(pages[actual_pages]);
-+ }
-+ kfree(pagelist);
-+ if (actual_pages == 0)
-+ actual_pages = -ENOMEM;
-+ return actual_pages;
-+ }
-+ *need_release = 1; /* release user pages */
-+ }
-
- pagelist->length = count;
- pagelist->type = type;
-@@ -482,6 +500,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
- static void
- free_pagelist(PAGELIST_T *pagelist, int actual)
- {
-+ unsigned long *need_release;
- struct page **pages;
- unsigned int num_pages, i;
-
-@@ -492,7 +511,8 @@ free_pagelist(PAGELIST_T *pagelist, int actual)
- (pagelist->length + pagelist->offset + PAGE_SIZE - 1) /
- PAGE_SIZE;
-
-- pages = (struct page **)(pagelist->addrs + num_pages);
-+ need_release = (unsigned long *)(pagelist->addrs + num_pages);
-+ pages = (struct page **)(pagelist->addrs + num_pages + 1);
-
- /* Deal with any partial cache lines (fragments) */
- if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) {
-@@ -528,11 +548,14 @@ free_pagelist(PAGELIST_T *pagelist, int actual)
- up(&g_free_fragments_sema);
- }
-
-- for (i = 0; i < num_pages; i++) {
-- if (pagelist->type != PAGELIST_WRITE)
-- set_page_dirty(pages[i]);
-- page_cache_release(pages[i]);
-- }
-+ if (*need_release) {
-+ for (i = 0; i < num_pages; i++) {
-+ if (pagelist->type != PAGELIST_WRITE)
-+ set_page_dirty(pages[i]);
-+
-+ page_cache_release(pages[i]);
-+ }
-+ }
-
- kfree(pagelist);
- }
---
-1.9.1
-