Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 54329
b: refs/heads/master
c: 16dd07b
h: refs/heads/master
i:
  54327: 6d70089
v: v3
  • Loading branch information
Jeff Dike authored and Linus Torvalds committed May 7, 2007
1 parent ff23491 commit 3096f15
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 379 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3ec704e6660aa58505110a50102e57cdb9daa044
refs/heads/master: 16dd07bc6404c8da0bdfeb7a5cde4e4a63991c00
6 changes: 2 additions & 4 deletions trunk/arch/um/include/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,12 @@ extern long syscall_stub_data(struct mm_id * mm_idp,
unsigned long *data, int data_count,
void **addr, void **stub_addr);
extern int map(struct mm_id * mm_idp, unsigned long virt,
unsigned long len, int r, int w, int x, int phys_fd,
unsigned long len, int prot, int phys_fd,
unsigned long long offset, int done, void **data);
extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
int done, void **data);
extern int protect(struct mm_id * mm_idp, unsigned long addr,
unsigned long len, int r, int w, int x, int done,
void **data);
unsigned long len, unsigned int prot, int done, void **data);

/* skas/process.c */
extern int is_skas_winch(int pid, int fd, void *data);
Expand Down Expand Up @@ -342,7 +341,6 @@ extern void maybe_sigio_broken(int fd, int read);

/* skas/trap */
extern void sig_handler_common_skas(int sig, void *sc_ptr);
extern void user_signal(int sig, union uml_pt_regs *regs, int pid);

/* sys-x86_64/prctl.c */
extern int os_arch_prctl(int pid, int code, unsigned long *addr);
Expand Down
8 changes: 2 additions & 6 deletions trunk/arch/um/include/tlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ struct host_vm_op {
struct {
unsigned long addr;
unsigned long len;
unsigned int r:1;
unsigned int w:1;
unsigned int x:1;
unsigned int prot;
int fd;
__u64 offset;
} mmap;
Expand All @@ -27,9 +25,7 @@ struct host_vm_op {
struct {
unsigned long addr;
unsigned long len;
unsigned int r:1;
unsigned int w:1;
unsigned int x:1;
unsigned int prot;
} mprotect;
} u;
};
Expand Down
228 changes: 1 addition & 227 deletions trunk/arch/um/kernel/physmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,229 +21,8 @@
#include "kern.h"
#include "init.h"

struct phys_desc {
struct rb_node rb;
int fd;
__u64 offset;
void *virt;
unsigned long phys;
struct list_head list;
};

static struct rb_root phys_mappings = RB_ROOT;

static struct rb_node **find_rb(void *virt)
{
struct rb_node **n = &phys_mappings.rb_node;
struct phys_desc *d;

while(*n != NULL){
d = rb_entry(*n, struct phys_desc, rb);
if(d->virt == virt)
return n;

if(d->virt > virt)
n = &(*n)->rb_left;
else
n = &(*n)->rb_right;
}

return n;
}

static struct phys_desc *find_phys_mapping(void *virt)
{
struct rb_node **n = find_rb(virt);

if(*n == NULL)
return NULL;

return rb_entry(*n, struct phys_desc, rb);
}

static void insert_phys_mapping(struct phys_desc *desc)
{
struct rb_node **n = find_rb(desc->virt);

if(*n != NULL)
panic("Physical remapping for %p already present",
desc->virt);

rb_link_node(&desc->rb, rb_parent(*n), n);
rb_insert_color(&desc->rb, &phys_mappings);
}

LIST_HEAD(descriptor_mappings);

struct desc_mapping {
int fd;
struct list_head list;
struct list_head pages;
};

static struct desc_mapping *find_mapping(int fd)
{
struct desc_mapping *desc;
struct list_head *ele;

list_for_each(ele, &descriptor_mappings){
desc = list_entry(ele, struct desc_mapping, list);
if(desc->fd == fd)
return desc;
}

return NULL;
}

static struct desc_mapping *descriptor_mapping(int fd)
{
struct desc_mapping *desc;

desc = find_mapping(fd);
if(desc != NULL)
return desc;

desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
if(desc == NULL)
return NULL;

*desc = ((struct desc_mapping)
{ .fd = fd,
.list = LIST_HEAD_INIT(desc->list),
.pages = LIST_HEAD_INIT(desc->pages) });
list_add(&desc->list, &descriptor_mappings);

return desc;
}

int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
{
struct desc_mapping *fd_maps;
struct phys_desc *desc;
unsigned long phys;
int err;

fd_maps = descriptor_mapping(fd);
if(fd_maps == NULL)
return -ENOMEM;

phys = __pa(virt);
desc = find_phys_mapping(virt);
if(desc != NULL)
panic("Address 0x%p is already substituted\n", virt);

err = -ENOMEM;
desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
if(desc == NULL)
goto out;

*desc = ((struct phys_desc)
{ .fd = fd,
.offset = offset,
.virt = virt,
.phys = __pa(virt),
.list = LIST_HEAD_INIT(desc->list) });
insert_phys_mapping(desc);

list_add(&desc->list, &fd_maps->pages);

virt = (void *) ((unsigned long) virt & PAGE_MASK);
err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
if(!err)
goto out;

rb_erase(&desc->rb, &phys_mappings);
kfree(desc);
out:
return err;
}

static int physmem_fd = -1;

static void remove_mapping(struct phys_desc *desc)
{
void *virt = desc->virt;
int err;

rb_erase(&desc->rb, &phys_mappings);
list_del(&desc->list);
kfree(desc);

err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
if(err)
panic("Failed to unmap block device page from physical memory, "
"errno = %d", -err);
}

int physmem_remove_mapping(void *virt)
{
struct phys_desc *desc;

virt = (void *) ((unsigned long) virt & PAGE_MASK);
desc = find_phys_mapping(virt);
if(desc == NULL)
return 0;

remove_mapping(desc);
return 1;
}

void physmem_forget_descriptor(int fd)
{
struct desc_mapping *desc;
struct phys_desc *page;
struct list_head *ele, *next;
__u64 offset;
void *addr;
int err;

desc = find_mapping(fd);
if(desc == NULL)
return;

list_for_each_safe(ele, next, &desc->pages){
page = list_entry(ele, struct phys_desc, list);
offset = page->offset;
addr = page->virt;
remove_mapping(page);
err = os_seek_file(fd, offset);
if(err)
panic("physmem_forget_descriptor - failed to seek "
"to %lld in fd %d, error = %d\n",
offset, fd, -err);
err = os_read_file(fd, addr, PAGE_SIZE);
if(err < 0)
panic("physmem_forget_descriptor - failed to read "
"from fd %d to 0x%p, error = %d\n",
fd, addr, -err);
}

list_del(&desc->list);
kfree(desc);
}

EXPORT_SYMBOL(physmem_forget_descriptor);
EXPORT_SYMBOL(physmem_remove_mapping);
EXPORT_SYMBOL(physmem_subst_mapping);

void arch_free_page(struct page *page, int order)
{
void *virt;
int i;

for(i = 0; i < (1 << order); i++){
virt = __va(page_to_phys(page + i));
physmem_remove_mapping(virt);
}
}

int is_remapped(void *virt)
{
struct phys_desc *desc = find_phys_mapping(virt);

return desc != NULL;
}

/* Changed during early boot */
unsigned long high_physmem;

Expand Down Expand Up @@ -350,14 +129,9 @@ void setup_physmem(unsigned long start, unsigned long reserve_end,

int phys_mapping(unsigned long phys, __u64 *offset_out)
{
struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK));
int fd = -1;

if(desc != NULL){
fd = desc->fd;
*offset_out = desc->offset;
}
else if(phys < physmem_size){
if(phys < physmem_size){
fd = physmem_fd;
*offset_out = phys;
}
Expand Down
21 changes: 11 additions & 10 deletions trunk/arch/um/kernel/skas/tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,17 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
switch(op->type){
case MMAP:
ret = map(&mmu->skas.id, op->u.mmap.addr,
op->u.mmap.len, op->u.mmap.r, op->u.mmap.w,
op->u.mmap.x, op->u.mmap.fd,
op->u.mmap.offset, finished, flush);
op->u.mmap.len, op->u.mmap.prot,
op->u.mmap.fd, op->u.mmap.offset, finished,
flush);
break;
case MUNMAP:
ret = unmap(&mmu->skas.id, op->u.munmap.addr,
op->u.munmap.len, finished, flush);
break;
case MPROTECT:
ret = protect(&mmu->skas.id, op->u.mprotect.addr,
op->u.mprotect.len, op->u.mprotect.r,
op->u.mprotect.w, op->u.mprotect.x,
op->u.mprotect.len, op->u.mprotect.prot,
finished, flush);
break;
default:
Expand Down Expand Up @@ -102,10 +101,10 @@ void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address)
pte_t *pte;
struct mm_struct *mm = vma->vm_mm;
void *flush = NULL;
int r, w, x, err = 0;
int r, w, x, prot, err = 0;
struct mm_id *mm_id;

pgd = pgd_offset(vma->vm_mm, address);
pgd = pgd_offset(mm, address);
if(!pgd_present(*pgd))
goto kill;

Expand All @@ -130,19 +129,21 @@ void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address)
}

mm_id = &mm->context.skas.id;
prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
(x ? UM_PROT_EXEC : 0));
if(pte_newpage(*pte)){
if(pte_present(*pte)){
unsigned long long offset;
int fd;

fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);
err = map(mm_id, address, PAGE_SIZE, r, w, x, fd,
offset, 1, &flush);
err = map(mm_id, address, PAGE_SIZE, prot, fd, offset,
1, &flush);
}
else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);
}
else if(pte_newprot(*pte))
err = protect(mm_id, address, PAGE_SIZE, r, w, x, 1, &flush);
err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);

if(err)
goto kill;
Expand Down
Loading

0 comments on commit 3096f15

Please sign in to comment.