@@ -14,41 +14,91 @@ See the License for the specific language governing permissions and
14
14
limitations under the License.
15
15
*/
16
16
17
- use alloc:: alloc:: { alloc, dealloc, Layout } ;
18
17
use core:: ffi:: c_void;
19
18
use core:: ptr:: NonNull ;
20
19
use core:: sync:: atomic:: { AtomicPtr , AtomicU64 , Ordering } ;
21
20
22
21
use hyperlight_guest_bin:: exceptions:: handler;
22
+ use hyperlight_guest_bin:: paging;
23
+
24
+ // Extremely stupid virtual address allocator
25
+ // 0x1_0000_0000 is where the module is
26
+ // we start at
27
+ // 0x100_0000_0000 and go up from there
28
+ static FIRST_VADDR : AtomicU64 = AtomicU64 :: new ( 0x100_0000_0000u64 ) ;
29
+ fn page_fault_handler (
30
+ _exception_number : u64 ,
31
+ info : * mut handler:: ExceptionInfo ,
32
+ _ctx : * mut handler:: Context ,
33
+ page_fault_address : u64 ,
34
+ ) -> bool {
35
+ let error_code = unsafe { ( & raw const ( * info) . error_code ) . read_volatile ( ) } ;
36
+ // TODO: check if this is a guard-region trap (which can't happen
37
+ // right now since we don't actually set the permissions properly
38
+ // in mprotect)
39
+
40
+ // TODO: replace this with some generic virtual memory area data
41
+ // structure in hyperlight core
42
+ if ( error_code & 0x1 ) == 0x0 && page_fault_address >= 0x100_0000_0000u64 {
43
+ unsafe {
44
+ let phys_page = paging:: alloc_phys_pages ( 1 ) ;
45
+ let virt_base = ( page_fault_address & !0xFFF ) as * mut u8 ;
46
+ paging:: map_region (
47
+ phys_page,
48
+ virt_base,
49
+ hyperlight_guest_bin:: OS_PAGE_SIZE as u64 ,
50
+ ) ;
51
+ virt_base. write_bytes ( 0u8 , hyperlight_guest_bin:: OS_PAGE_SIZE as usize ) ;
52
+ }
53
+ return true ; // Try again!
54
+ }
55
+ false
56
+ }
57
+ pub ( crate ) fn register_page_fault_handler ( ) {
58
+ // On amd64, vector 14 is #PF
59
+ // See AMD64 Architecture Programmer's Manual, Volume 2
60
+ // §8.2 Vectors, p. 245
61
+ // Table 8-1: Interrupt Vector Source and Cause
62
+ handler:: handlers[ 14 ] . store ( page_fault_handler as usize as u64 , Ordering :: Release ) ;
63
+ }
23
64
24
65
// Wasmtime Embedding Interface
25
66
26
- /* We don't have proper support for lazy committing an mmap region, or
27
- * for setting up guard pages, because the guest doesn't have an *
28
- * appropriate interrupt handler yet. Consequently, we configure
29
- * wasmtime not to use any guard region, and precommit memory. */
67
+ /* We don't actually have any sensible virtual memory areas, so
68
+ * we just give out virtual addresses very coarsely with
69
+ * probably-more-than-enough space between them, and take over
70
+ * page-fault handling to hardcoded check if memory is in this region
71
+ * (see above) */
30
72
#[ no_mangle]
31
- pub extern "C" fn wasmtime_mmap_new ( size : usize , _prot_flags : u32 , ret : & mut * mut u8 ) -> i32 {
32
- * ret = unsafe { alloc ( Layout :: from_size_align ( size, 0x1000 ) . unwrap ( ) ) } ;
73
+ pub extern "C" fn wasmtime_mmap_new ( _size : usize , _prot_flags : u32 , ret : & mut * mut u8 ) -> i32 {
74
+ if _size > 0x100_0000_0000 {
75
+ panic ! ( "wasmtime_mmap_{:x} {:x}" , _size, _prot_flags) ;
76
+ }
77
+ * ret = FIRST_VADDR . fetch_add ( 0x100_0000_0000 , Ordering :: Relaxed ) as * mut u8 ;
33
78
0
34
79
}
35
80
36
- /* Because of the precommitted memory strategy, we can't generally
37
- * support remap */
81
+ /* Remap is only used for changing the region size (which is presently
82
+ * a no-op, since we just hand out very large regions and treat them all
83
+ * the same), or possibly for changing permissions, which will be a no-op
84
+ * as we don't properly implement permissions at the moment. */
38
85
#[ no_mangle]
39
86
pub extern "C" fn wasmtime_mmap_remap ( addr : * mut u8 , size : usize , prot_flags : u32 ) -> i32 {
40
- panic ! (
41
- "wasmtime_mmap_remap {:x} {:x} {:x}" ,
42
- addr as usize , size, prot_flags
43
- ) ;
87
+ if size > 0x100_0000_0000 {
88
+ panic ! (
89
+ "wasmtime_mmap_remap {:x} {:x} {:x}" ,
90
+ addr as usize , size, prot_flags
91
+ ) ;
92
+ }
93
+ 0
44
94
}
45
95
46
96
#[ no_mangle]
47
- pub extern "C" fn wasmtime_munmap ( ptr : * mut u8 , size : usize ) -> i32 {
48
- unsafe { dealloc ( ptr, Layout :: from_size_align ( size, 0x1000 ) . unwrap ( ) ) } ;
97
+ pub extern "C" fn wasmtime_munmap ( _ptr : * mut u8 , _size : usize ) -> i32 {
49
98
0
50
99
}
51
100
101
+ /* TODO: implement permissions properly */
52
102
#[ no_mangle]
53
103
pub extern "C" fn wasmtime_mprotect ( _ptr : * mut u8 , _size : usize , prot_flags : u32 ) -> i32 {
54
104
/* currently all memory is allocated RWX; we assume that
0 commit comments