summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-04-06 02:29:45 +0000
committerdyson <dyson@FreeBSD.org>1997-04-06 02:29:45 +0000
commit22d3427970e54f676e2b00c131968543d5e158cf (patch)
tree7f36ab36e674c55b0016224f8352f9e013e48992 /sys/vm
parent6bd5a8ae498a480fda8c82b49ba9792836b14e9f (diff)
downloadFreeBSD-src-22d3427970e54f676e2b00c131968543d5e158cf.zip
FreeBSD-src-22d3427970e54f676e2b00c131968543d5e158cf.tar.gz
Fix the gdb executable modify problem. Thanks to the detective work
by Alan Cox <alc@cs.rice.edu>, and his description of the problem. The bug was primarily in procfs_mem, but the mistake likely happened due to the lack of vm system support for the operation. I added better support for selective marking of page dirty flags so that vm_map_pageable(wiring) will not cause this problem again. The code in procfs_mem is now less bogus (but maybe still a little so.)
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_fault.c20
-rw-r--r--sys/vm/vm_map.c14
-rw-r--r--sys/vm/vm_map.h11
-rw-r--r--sys/vm/vm_prot.h3
4 files changed, 31 insertions, 17 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 854b685..92f9ae9 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -66,7 +66,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id$
+ * $Id: vm_fault.c,v 1.66 1997/02/22 09:48:15 peter Exp $
*/
/*
@@ -123,11 +123,11 @@ int vm_fault_additional_pages __P((vm_page_t, int, int, vm_page_t *, int *));
* Caller may hold no locks.
*/
int
-vm_fault(map, vaddr, fault_type, change_wiring)
+vm_fault(map, vaddr, fault_type, fault_flags)
vm_map_t map;
vm_offset_t vaddr;
vm_prot_t fault_type;
- boolean_t change_wiring;
+ int fault_flags;
{
vm_object_t first_object;
vm_pindex_t first_pindex;
@@ -210,7 +210,7 @@ RetryFault:;
* to COW .text. We simply keep .text from ever being COW'ed
* and take the heat that one cannot debug wired .text sections.
*/
- if ((change_wiring == VM_FAULT_USER_WIRE) && (entry->eflags & MAP_ENTRY_NEEDS_COPY)) {
+ if (((fault_flags & VM_FAULT_WIRE_MASK) == VM_FAULT_USER_WIRE) && (entry->eflags & MAP_ENTRY_NEEDS_COPY)) {
if(entry->protection & VM_PROT_WRITE) {
int tresult;
vm_map_lookup_done(map, entry);
@@ -333,7 +333,7 @@ RetryFault:;
}
break;
}
- if (((object->type != OBJT_DEFAULT) && (!change_wiring || wired))
+ if (((object->type != OBJT_DEFAULT) && (((fault_flags & VM_FAULT_WIRE_MASK) == 0) || wired))
|| (object == first_object)) {
if (pindex >= object->size) {
@@ -354,7 +354,7 @@ RetryFault:;
}
}
readrest:
- if (object->type != OBJT_DEFAULT && (!change_wiring || wired)) {
+ if (object->type != OBJT_DEFAULT && (((fault_flags & VM_FAULT_WIRE_MASK) == 0) || wired)) {
int rv;
int faultcount;
int reqpage;
@@ -788,7 +788,7 @@ readrest:
* written NOW. This will save on the pmap_is_modified() calls
* later.
*/
- if (fault_type & VM_PROT_WRITE) {
+ if (fault_flags & VM_FAULT_DIRTY) {
m->dirty = VM_PAGE_BITS_ALL;
}
}
@@ -798,16 +798,18 @@ readrest:
m->flags &= ~PG_ZERO;
pmap_enter(map->pmap, vaddr, VM_PAGE_TO_PHYS(m), prot, wired);
- if ((change_wiring == 0) && (wired == 0))
+ if (((fault_flags & VM_FAULT_WIRE_MASK) == 0) && (wired == 0))
pmap_prefault(map->pmap, vaddr, entry, first_object);
m->flags |= PG_MAPPED|PG_REFERENCED;
+ if (fault_flags & VM_FAULT_HOLD)
+ vm_page_hold(m);
/*
* If the page is not wired down, then put it where the pageout daemon
* can find it.
*/
- if (change_wiring) {
+ if (fault_flags & VM_FAULT_WIRE_MASK) {
if (wired)
vm_page_wire(m);
else
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 4019a8b..95b2817 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id$
+ * $Id: vm_map.c,v 1.72 1997/02/22 09:48:23 peter Exp $
*/
/*
@@ -2323,13 +2323,21 @@ RetryLookup:;
vm_map_unlock_read(old_map);
goto RetryLookup;
}
+
/*
* Check whether this task is allowed to have this page.
+ * Note the special case for MAP_ENTRY_COW
+ * pages with an override. This is to implement a forced
+ * COW for debuggers.
*/
prot = entry->protection;
- if ((fault_type & (prot)) != fault_type)
- RETURN(KERN_PROTECTION_FAILURE);
+ if ((fault_type & VM_PROT_OVERRIDE_WRITE) == 0 ||
+ (entry->eflags & MAP_ENTRY_COW) == 0 ||
+ (entry->wired_count != 0)) {
+ if ((fault_type & (prot)) != fault_type)
+ RETURN(KERN_PROTECTION_FAILURE);
+ }
/*
* If this page is not pageable, we have to get it for all possible
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index 05e264a..d1905ad6 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id$
+ * $Id: vm_map.h,v 1.24 1997/02/22 09:48:24 peter Exp $
*/
/*
@@ -243,9 +243,12 @@ typedef struct {
/*
* vm_fault option flags
*/
-#define VM_FAULT_NORMAL 0
-#define VM_FAULT_CHANGE_WIRING 1
-#define VM_FAULT_USER_WIRE 2
+#define VM_FAULT_NORMAL 0 /* Nothing special */
+#define VM_FAULT_CHANGE_WIRING 1 /* Change the wiring as appropriate */
+#define VM_FAULT_USER_WIRE 2 /* Likewise, but for user purposes */
+#define VM_FAULT_WIRE_MASK (VM_FAULT_CHANGE_WIRING|VM_FAULT_USER_WIRE)
+#define VM_FAULT_HOLD 4 /* Hold the page */
+#define VM_FAULT_DIRTY 8 /* Dirty the page */
#ifdef KERNEL
extern vm_offset_t kentry_data;
diff --git a/sys/vm/vm_prot.h b/sys/vm/vm_prot.h
index f5aa65f..cdddcea 100644
--- a/sys/vm/vm_prot.h
+++ b/sys/vm/vm_prot.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id$
+ * $Id: vm_prot.h,v 1.7 1997/02/22 09:48:38 peter Exp $
*/
/*
@@ -80,6 +80,7 @@
#define VM_PROT_READ ((vm_prot_t) 0x01) /* read permission */
#define VM_PROT_WRITE ((vm_prot_t) 0x02) /* write permission */
#define VM_PROT_EXECUTE ((vm_prot_t) 0x04) /* execute permission */
+#define VM_PROT_OVERRIDE_WRITE ((vm_prot_t) 0x08) /* write, overriding permission for COW */
/*
* The default protection for newly-created virtual memory
OpenPOWER on IntegriCloud