# This patch merges some physmem mapping changes. This stuff is all going # away, but it's here to keep the two trees in sync. Index: um/arch/um/drivers/ubd_kern.c =================================================================== --- um.orig/arch/um/drivers/ubd_kern.c 2004-08-05 22:40:58.000000000 -0400 +++ um/arch/um/drivers/ubd_kern.c 2004-08-05 22:43:39.000000000 -0400 @@ -1004,7 +1004,7 @@ * to write the data to disk first, then we can map the disk * page in and continue normally from there. */ - if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){ + if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer, dev->fd, io_req->offset + dev->cow.data_offset)){ io_req->map_fd = dev->fd; io_req->map_offset = io_req->offset + dev->cow.data_offset; @@ -1134,12 +1134,20 @@ } static int ubd_check_remapped(int fd, unsigned long address, int is_write, - __u64 offset) + __u64 offset, int is_user) { __u64 bitmap_offset; unsigned long new_bitmap[2]; int i, err, n; + /* This can only fix kernelspace faults */ + if(is_user) + return(0); + + /* ubd-mmap is only enabled in skas mode */ + if(CHOOSE_MODE(1, 0)) + return(0); + /* If it's not a write access, we can't do anything about it */ if(!is_write) return(0); Index: um/arch/um/include/mem.h =================================================================== --- um.orig/arch/um/include/mem.h 2004-08-05 22:40:58.000000000 -0400 +++ um/arch/um/include/mem.h 2004-08-05 22:43:39.000000000 -0400 @@ -10,7 +10,7 @@ extern int phys_mapping(unsigned long phys, __u64 *offset_out); extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w); -extern int is_remapped(void *virt); +extern int is_remapped(const void *virt, int fd, __u64 offset); extern int physmem_remove_mapping(void *virt); extern void physmem_forget_descriptor(int fd); Index: um/arch/um/include/mem_kern.h =================================================================== --- um.orig/arch/um/include/mem_kern.h 2004-08-05 22:40:58.000000000 -0400 +++ um/arch/um/include/mem_kern.h 2004-08-05 22:43:39.000000000 -0400 @@ -11,7 +11,7 @@ struct remapper { struct list_head list; - int (*proc)(int, unsigned long, int, __u64); + int (*proc)(int, unsigned long, int, __u64, int); }; extern void register_remapper(struct remapper *info); Index: um/arch/um/kernel/physmem.c =================================================================== --- um.orig/arch/um/kernel/physmem.c 2004-08-05 22:40:58.000000000 -0400 +++ um/arch/um/kernel/physmem.c 2004-08-05 22:43:39.000000000 -0400 @@ -122,14 +122,19 @@ unsigned long phys; int err; + phys = __pa(virt); + desc = find_virtmem_hash(&virtmem_hash, (void *) virt); + if(desc != NULL){ + if((virt != desc->virt) || (fd != desc->fd) || + (offset != desc->offset)) + panic("Address 0x%p is already substituted\n", virt); + return(0); + } + fd_maps = descriptor_mapping(fd); if(fd_maps == NULL) return(-ENOMEM); - phys = __pa(virt); - if(find_virtmem_hash(&virtmem_hash, virt) != NULL) - panic("Address 0x%p is already substituted\n", virt); - err = -ENOMEM; desc = kmalloc(sizeof(*desc), GFP_ATOMIC); if(desc == NULL) @@ -200,6 +205,9 @@ if(desc == NULL) return; + if(!list_empty(&desc->pages)) + printk("Still have mapped pages on fd %d\n", fd); + list_for_each_safe(ele, next, &desc->pages){ page = list_entry(ele, struct phys_desc, list); offset = page->offset; @@ -232,9 +240,16 @@ } } -int is_remapped(void *virt) +int is_remapped(const void *virt, int fd, __u64 offset) { - return(find_virtmem_hash(&virtmem_hash, virt) != NULL); + struct phys_desc *desc; + + desc = find_virtmem_hash(&virtmem_hash, (void *) virt); + if(desc == NULL) + return(0); + if(offset != desc->offset) + printk("offset mismatch\n"); + return(find_virtmem_hash(&virtmem_hash, (void *) virt) != NULL); } /* Changed during early boot */ Index: um/arch/um/kernel/trap_kern.c =================================================================== --- um.orig/arch/um/kernel/trap_kern.c 2004-08-05 22:40:58.000000000 -0400 +++ um/arch/um/kernel/trap_kern.c 2004-08-05 22:43:39.000000000 -0400 @@ -114,7 +114,7 @@ list_add(&info->list, &physmem_remappers); } -static int check_remapped_addr(unsigned long address, int is_write) +static int check_remapped_addr(unsigned long address, int is_write, int is_user) { struct remapper *remapper; struct list_head *ele; @@ -127,7 +127,7 @@ list_for_each(ele, &physmem_remappers){ remapper = list_entry(ele, struct remapper, list); - if((*remapper->proc)(fd, address, is_write, offset)) + if((*remapper->proc)(fd, address, is_write, offset, is_user)) return(1); } @@ -145,7 +145,7 @@ flush_tlb_kernel_vm(); return(0); } - else if(check_remapped_addr(address & PAGE_MASK, is_write)) + else if(check_remapped_addr(address & PAGE_MASK, is_write, is_user)) return(0); else if(current->mm == NULL) panic("Segfault with no mm");