patch-2.1.22 linux/drivers/char/mem.c
Next file: linux/drivers/char/misc.c
Previous file: linux/drivers/char/Config.in
Back to the patch index
Back to the overall index
- Lines: 53
- Date:
Sun Jan 19 15:47:24 1997
- Orig file:
v2.1.21/linux/drivers/char/mem.c
- Orig date:
Mon Dec 30 15:39:07 1996
diff -u --recursive --new-file v2.1.21/linux/drivers/char/mem.c linux/drivers/char/mem.c
@@ -231,14 +231,39 @@
}
/*
- * For fun, somebody might look into using the MMU for this.
- * NOTE! It's not trivial: you have to check that the mapping
- * is a private mapping and if so you can just map in the
- * zero page directly. But shared mappings _have_ to use the
- * physical copy.
+ * For fun, we are using the MMU for this.
*/
static inline unsigned long read_zero_pagealigned(char * buf, unsigned long size)
{
+ struct vm_area_struct * curr_vma;
+ unsigned long addr=(unsigned long)buf;
+
+/*
+ * First we take the most obvious case: when we have one VM area to deal with,
+ * and it's privately mapped.
+ */
+ curr_vma = find_vma(current->mm, addr);
+
+ if ( !(curr_vma->vm_flags & VM_SHARED) &&
+ (addr + size <= curr_vma->vm_end) ) {
+
+ flush_cache_range(current->mm, addr, addr + size);
+ zap_page_range(current->mm, addr, size);
+ zeromap_page_range(addr, size, PAGE_COPY);
+ flush_tlb_range(current->mm, addr, addr + size);
+
+ return 0;
+ }
+
+/*
+ * Ooops, the shared case is hard. Lets do the conventional
+ * zeroing.
+ *
+ * FIXME: same for the multiple-vma case, we dont handle it
+ * now for simplicity, although it's much easier than
+ * the shared case. Not that it should happen often ...
+ */
+
do {
if (clear_user(buf, PAGE_SIZE))
break;
@@ -247,6 +272,7 @@
buf += PAGE_SIZE;
size -= PAGE_SIZE;
} while (size);
+
return size;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov