@@ -1013,6 +1013,30 @@ void Machine::setup_linux_system_calls()
10131013 SYSPRINT (" clock_gettime(clk=%lld, buf=0x%llX) = %lld\n " ,
10141014 regs.rdi , regs.rsi , regs.rax );
10151015 cpu.set_registers (regs);
1016+ // cpu.machine().threads().suspend_and_yield();
1017+ });
1018+ Machine::install_syscall_handler (
1019+ SYS_clock_nanosleep, [](vCPU& cpu) { // clock_nanosleep
1020+ auto & regs = cpu.registers ();
1021+ // We don't allow sleeping in the guest
1022+ // but we can set the remaining time to the requested value
1023+ const uint64_t g_buf = regs.rdx ;
1024+ const uint64_t g_rem = regs.r10 ;
1025+ struct timespec ts;
1026+ struct timespec ts_rem {};
1027+ cpu.machine ().copy_from_guest (&ts, g_buf, sizeof (ts));
1028+ const int result =
1029+ clock_nanosleep (CLOCK_MONOTONIC, regs.rsi , &ts, &ts_rem);
1030+ if (result < 0 ) {
1031+ regs.rax = -errno;
1032+ } else {
1033+ if (g_rem != 0x0 )
1034+ cpu.machine ().copy_to_guest (g_rem, &ts_rem, sizeof (ts_rem));
1035+ regs.rax = 0 ;
1036+ }
1037+ SYSPRINT (" clock_nanosleep(clk=%lld, flags=%lld, req=0x%llX, rem=%lld) = %lld\n " ,
1038+ regs.rdi , regs.rsi , regs.rdx , regs.r10 , regs.rax );
1039+ cpu.set_registers (regs);
10161040 });
10171041 Machine::install_syscall_handler (
10181042 SYS_exit_group, [](vCPU& cpu)
@@ -1218,9 +1242,14 @@ void Machine::setup_linux_system_calls()
12181242 return ;
12191243 }
12201244 std::array<struct epoll_event , 1024 > guest_events;
1245+ // Only wait for 150ns, as we are *not* pre-empting the guest
1246+ const struct timespec ts {
1247+ .tv_sec = 0 ,
1248+ .tv_nsec = 150 ,
1249+ };
12211250 const int epollfd = cpu.machine ().fds ().translate (vfd);
12221251 const int result =
1223- epoll_wait (epollfd, guest_events.data (), maxevents, timeout );
1252+ epoll_pwait2 (epollfd, guest_events.data (), maxevents, &ts, nullptr );
12241253 // Copy events back to guest
12251254 if (result > 0 )
12261255 {
@@ -1238,7 +1267,8 @@ void Machine::setup_linux_system_calls()
12381267 // XXX: This is a giga hack.
12391268 cpu.machine ().threads ().suspend_and_yield ();
12401269 }
1241- SYSPRINT (" epoll_wait(...) = %lld\n " , regs.rax );
1270+ SYSPRINT (" epoll_wait(fd=%d (%lld), g_events=0x%lX, maxevents=%d, timeout=%d) = %lld\n " ,
1271+ vfd, regs.rdi , g_events, maxevents, timeout, regs.rax );
12421272 cpu.set_registers (regs);
12431273 });
12441274 Machine::install_syscall_handler (
0 commit comments