@@ -111,6 +111,8 @@ char* invoke_trustlet(const int trustlet_id, char* args, uint64_t output_size){
111111 call .invokation .data = invoke_data ;
112112 call .invokation .data_size = sizeof (struct trustlet_invokation );
113113
114+ static void * read_buffer = NULL ;
115+ static size_t read_buffer_size = 0 ;
114116retry :
115117 void * return_buffer_address = NULL ;
116118 int ret = ioctl (con , VMPL_WR , & call );
@@ -146,7 +148,7 @@ char* invoke_trustlet(const int trustlet_id, char* args, uint64_t output_size){
146148 } else if (ret == guestRequestRead ) {
147149 struct guest_request_args * arg = invoke_data -> guest_request_args .ptr ;
148150 int fd = arg -> read .fd ;
149- void * read_buffer = & arg -> read .buf [0 ];
151+ char * buf = & arg -> read .buf [0 ];
150152 int count = arg -> read .count ;
151153 if (count > sizeof (arg -> read .buf )) {
152154 count = sizeof (arg -> read .buf );
@@ -156,7 +158,6 @@ char* invoke_trustlet(const int trustlet_id, char* args, uint64_t output_size){
156158 if (arg -> read .offset == (uint64_t )-1 ) {
157159 // dir read
158160 // XXX: code adopted from read_dir() of linux pal of gramine
159- char * buf = read_buffer ;
160161 char dirbuf [1024 ];
161162 // gcc does not provide a wrapper for getdents64
162163 int size = syscall (SYS_getdents64 , fd , dirbuf , sizeof (dirbuf ));
@@ -201,12 +202,45 @@ char* invoke_trustlet(const int trustlet_id, char* args, uint64_t output_size){
201202 }
202203 } else {
203204 // file read
204- read_bytes = pread (fd , read_buffer , count , arg -> read .offset );
205+ read_bytes = pread (fd , buf , count , arg -> read .offset );
205206 }
206207 arg -> read .count = read_bytes ;
207208 invoke_data -> invokation_type = requestRead ;
208209 debug_printf ("Guest request: read: fd=%d, offset=%ld, count=%lu\n" , fd , arg -> read .offset , arg -> read .count );
209210 goto retry ;
211+ } else if (ret == guestRequestRead2 ) {
212+ struct guest_request_args * arg = invoke_data -> guest_request_args .ptr ;
213+ int fd = arg -> read2 .fd ;
214+ uint64_t read_size = arg -> read2 .count ;
215+ if (!read_buffer ) {
216+ read_buffer = aligned_alloc (4096 , read_size );
217+ if (!read_buffer ) {
218+ debug_printf ("Failed to allocate read buffer!\n" );
219+ goto exit ;
220+ }
221+ read_buffer_size = read_size ;
222+ } else if (read_buffer_size < read_size ) {
223+ free (read_buffer );
224+ read_buffer = aligned_alloc (4096 , read_size );
225+ if (!read_buffer ) {
226+ debug_printf ("Failed to reallocate read buffer!\n" );
227+ goto exit ;
228+ }
229+ read_buffer_size = read_size ;
230+ }
231+ int read_bytes = pread (fd , read_buffer , read_size , arg -> read2 .offset );
232+ arg -> read2 .ptr = (uint64_t )read_buffer ;
233+ arg -> read2 .bufsize = read_size ;
234+ arg -> read2 .count = read_bytes ;
235+ invoke_data -> invokation_type = requestRead2 ;
236+ debug_printf ("Guest request: read2: ptr=%lx, fd=%d, offset=%ld, count=%lu\n" , arg -> read2 .ptr , fd , arg -> read2 .offset , arg -> read2 .count );
237+ #if 0
238+ for (int i = 0 ; i < 64 ; i ++ ) {
239+ debug_printf ("%02x " , ((uint8_t * )read_buffer )[i ]);
240+ }
241+ debug_printf ("\n" );
242+ #endif
243+ goto retry ;
210244 } else if (ret == guestRequestMmap ) {
211245 struct guest_request_args * arg = invoke_data -> guest_request_args .ptr ;
212246 debug_printf ("Guest request: mmap: fd=%d, size=%ld, offset=%ld, addr_offset=%ld\n" , (int )arg -> mmap .fd , arg -> mmap .size , arg -> mmap .offset , arg -> mmap .addr_offset );
@@ -224,6 +258,8 @@ char* invoke_trustlet(const int trustlet_id, char* args, uint64_t output_size){
224258exit :
225259
226260 free (mmap_read_buffer );
261+ if (read_buffer )
262+ free (read_buffer );
227263 return return_buffer_address ;
228264}
229265
0 commit comments