|
@@ -2012,7 +2012,8 @@ static int aligned_vwrite(char *buf, char *addr, unsigned long count)
|
|
|
|
|
|
long vread(char *buf, char *addr, unsigned long count)
|
|
|
{
|
|
|
- struct vm_struct *tmp;
|
|
|
+ struct vmap_area *va;
|
|
|
+ struct vm_struct *vm;
|
|
|
char *vaddr, *buf_start = buf;
|
|
|
unsigned long buflen = count;
|
|
|
unsigned long n;
|
|
@@ -2021,10 +2022,17 @@ long vread(char *buf, char *addr, unsigned long count)
|
|
|
if ((unsigned long) addr + count < count)
|
|
|
count = -(unsigned long) addr;
|
|
|
|
|
|
- read_lock(&vmlist_lock);
|
|
|
- for (tmp = vmlist; count && tmp; tmp = tmp->next) {
|
|
|
- vaddr = (char *) tmp->addr;
|
|
|
- if (addr >= vaddr + tmp->size - PAGE_SIZE)
|
|
|
+ spin_lock(&vmap_area_lock);
|
|
|
+ list_for_each_entry(va, &vmap_area_list, list) {
|
|
|
+ if (!count)
|
|
|
+ break;
|
|
|
+
|
|
|
+ if (!(va->flags & VM_VM_AREA))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ vm = va->vm;
|
|
|
+ vaddr = (char *) vm->addr;
|
|
|
+ if (addr >= vaddr + vm->size - PAGE_SIZE)
|
|
|
continue;
|
|
|
while (addr < vaddr) {
|
|
|
if (count == 0)
|
|
@@ -2034,10 +2042,10 @@ long vread(char *buf, char *addr, unsigned long count)
|
|
|
addr++;
|
|
|
count--;
|
|
|
}
|
|
|
- n = vaddr + tmp->size - PAGE_SIZE - addr;
|
|
|
+ n = vaddr + vm->size - PAGE_SIZE - addr;
|
|
|
if (n > count)
|
|
|
n = count;
|
|
|
- if (!(tmp->flags & VM_IOREMAP))
|
|
|
+ if (!(vm->flags & VM_IOREMAP))
|
|
|
aligned_vread(buf, addr, n);
|
|
|
else /* IOREMAP area is treated as memory hole */
|
|
|
memset(buf, 0, n);
|
|
@@ -2046,7 +2054,7 @@ long vread(char *buf, char *addr, unsigned long count)
|
|
|
count -= n;
|
|
|
}
|
|
|
finished:
|
|
|
- read_unlock(&vmlist_lock);
|
|
|
+ spin_unlock(&vmap_area_lock);
|
|
|
|
|
|
if (buf == buf_start)
|
|
|
return 0;
|
|
@@ -2085,7 +2093,8 @@ finished:
|
|
|
|
|
|
long vwrite(char *buf, char *addr, unsigned long count)
|
|
|
{
|
|
|
- struct vm_struct *tmp;
|
|
|
+ struct vmap_area *va;
|
|
|
+ struct vm_struct *vm;
|
|
|
char *vaddr;
|
|
|
unsigned long n, buflen;
|
|
|
int copied = 0;
|
|
@@ -2095,10 +2104,17 @@ long vwrite(char *buf, char *addr, unsigned long count)
|
|
|
count = -(unsigned long) addr;
|
|
|
buflen = count;
|
|
|
|
|
|
- read_lock(&vmlist_lock);
|
|
|
- for (tmp = vmlist; count && tmp; tmp = tmp->next) {
|
|
|
- vaddr = (char *) tmp->addr;
|
|
|
- if (addr >= vaddr + tmp->size - PAGE_SIZE)
|
|
|
+ spin_lock(&vmap_area_lock);
|
|
|
+ list_for_each_entry(va, &vmap_area_list, list) {
|
|
|
+ if (!count)
|
|
|
+ break;
|
|
|
+
|
|
|
+ if (!(va->flags & VM_VM_AREA))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ vm = va->vm;
|
|
|
+ vaddr = (char *) vm->addr;
|
|
|
+ if (addr >= vaddr + vm->size - PAGE_SIZE)
|
|
|
continue;
|
|
|
while (addr < vaddr) {
|
|
|
if (count == 0)
|
|
@@ -2107,10 +2123,10 @@ long vwrite(char *buf, char *addr, unsigned long count)
|
|
|
addr++;
|
|
|
count--;
|
|
|
}
|
|
|
- n = vaddr + tmp->size - PAGE_SIZE - addr;
|
|
|
+ n = vaddr + vm->size - PAGE_SIZE - addr;
|
|
|
if (n > count)
|
|
|
n = count;
|
|
|
- if (!(tmp->flags & VM_IOREMAP)) {
|
|
|
+ if (!(vm->flags & VM_IOREMAP)) {
|
|
|
aligned_vwrite(buf, addr, n);
|
|
|
copied++;
|
|
|
}
|
|
@@ -2119,7 +2135,7 @@ long vwrite(char *buf, char *addr, unsigned long count)
|
|
|
count -= n;
|
|
|
}
|
|
|
finished:
|
|
|
- read_unlock(&vmlist_lock);
|
|
|
+ spin_unlock(&vmap_area_lock);
|
|
|
if (!copied)
|
|
|
return 0;
|
|
|
return buflen;
|