@@ -14,41 +14,91 @@ See the License for the specific language governing permissions and
1414limitations under the License.
1515*/
1616
17- use alloc:: alloc:: { alloc, dealloc, Layout } ;
1817use core:: ffi:: c_void;
1918use core:: ptr:: NonNull ;
2019use core:: sync:: atomic:: { AtomicPtr , AtomicU64 , Ordering } ;
2120
2221use 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+ }
2364
2465// Wasmtime Embedding Interface
2566
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) */
3072#[ 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 ;
3378 0
3479}
3580
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. */
3885#[ no_mangle]
3986pub 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
4494}
4595
4696#[ 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 {
4998 0
5099}
51100
101+ /* TODO: implement permissions properly */
52102#[ no_mangle]
53103pub extern "C" fn wasmtime_mprotect ( _ptr : * mut u8 , _size : usize , prot_flags : u32 ) -> i32 {
54104 /* currently all memory is allocated RWX; we assume that
0 commit comments