diff options
author | dyson <dyson@FreeBSD.org> | 1997-04-06 02:29:45 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1997-04-06 02:29:45 +0000 |
commit | 22d3427970e54f676e2b00c131968543d5e158cf (patch) | |
tree | 7f36ab36e674c55b0016224f8352f9e013e48992 /sys/vm | |
parent | 6bd5a8ae498a480fda8c82b49ba9792836b14e9f (diff) | |
download | FreeBSD-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.c | 20 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 14 | ||||
-rw-r--r-- | sys/vm/vm_map.h | 11 | ||||
-rw-r--r-- | sys/vm/vm_prot.h | 3 |
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 |