2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
7 #include "linux/stddef.h"
8 #include "linux/sched.h"
9 #include "linux/config.h"
12 #include "asm/pgtable.h"
14 #include "user_util.h"
21 static int do_ops(union mm_context
*mmu
, struct host_vm_op
*ops
, int last
,
22 int finished
, void **flush
)
24 struct host_vm_op
*op
;
27 for(i
= 0; i
<= last
&& !ret
; i
++){
31 ret
= map(&mmu
->skas
.id
, op
->u
.mmap
.addr
,
32 op
->u
.mmap
.len
, op
->u
.mmap
.r
, op
->u
.mmap
.w
,
33 op
->u
.mmap
.x
, op
->u
.mmap
.fd
,
34 op
->u
.mmap
.offset
, finished
, flush
);
37 ret
= unmap(&mmu
->skas
.id
,
38 (void *) op
->u
.munmap
.addr
,
39 op
->u
.munmap
.len
, finished
, flush
);
42 ret
= protect(&mmu
->skas
.id
, op
->u
.mprotect
.addr
,
43 op
->u
.mprotect
.len
, op
->u
.mprotect
.r
,
44 op
->u
.mprotect
.w
, op
->u
.mprotect
.x
,
48 printk("Unknown op type %d in do_ops\n", op
->type
);
58 static void fix_range(struct mm_struct
*mm
, unsigned long start_addr
,
59 unsigned long end_addr
, int force
)
61 if(!proc_mm
&& (end_addr
> CONFIG_STUB_START
))
62 end_addr
= CONFIG_STUB_START
;
64 fix_range_common(mm
, start_addr
, end_addr
, force
, do_ops
);
67 void __flush_tlb_one_skas(unsigned long addr
)
69 flush_tlb_kernel_range_common(addr
, addr
+ PAGE_SIZE
);
72 void flush_tlb_range_skas(struct vm_area_struct
*vma
, unsigned long start
,
75 if(vma
->vm_mm
== NULL
)
76 flush_tlb_kernel_range_common(start
, end
);
77 else fix_range(vma
->vm_mm
, start
, end
, 0);
80 void flush_tlb_mm_skas(struct mm_struct
*mm
)
84 /* Don't bother flushing if this address space is about to be
87 if(atomic_read(&mm
->mm_users
) == 0)
90 end
= proc_mm
? task_size
: CONFIG_STUB_START
;
91 fix_range(mm
, 0, end
, 0);
94 void force_flush_all_skas(void)
96 unsigned long end
= proc_mm
? task_size
: CONFIG_STUB_START
;
97 fix_range(current
->mm
, 0, end
, 1);