diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e566e411..198d1fb27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,9 @@ foreach(MODULE ${KERNEL_MODULES}) target_compile_definitions(${MODULE} PRIVATE -D__KERNEL__) + target_compile_definitions(${MODULE} + PRIVATE -DMAX_ARGC_ENVC=${MAX_ARGC_ENVC}) + target_compile_options(${MODULE} PRIVATE ${HERMIT_KERNEL_FLAGS}) diff --git a/cmake/HermitCore-Configuration.cmake b/cmake/HermitCore-Configuration.cmake index 8ca70e181..84fa7fbc8 100644 --- a/cmake/HermitCore-Configuration.cmake +++ b/cmake/HermitCore-Configuration.cmake @@ -19,6 +19,10 @@ set(KERNEL_STACK_SIZE 8192 CACHE STRING set(DEFAULT_STACK_SIZE 262144 CACHE STRING "Task stack size in bytes") +set(MAX_ARGC_ENVC 128 CACHE STRING + "Maximum number of command line parameters and enviroment variables + forwarded to uhyve") + option(DYNAMIC_TICKS "Don't use a periodic timer event to keep track of time" ON) diff --git a/cmake/HermitCore-Utils.cmake b/cmake/HermitCore-Utils.cmake index f614f5c0f..4655ecaa6 100644 --- a/cmake/HermitCore-Utils.cmake +++ b/cmake/HermitCore-Utils.cmake @@ -99,6 +99,7 @@ function(build_external NAME PATH DEPENDS) -DLOCAL_PREFIX_BASE_DIR=${LOCAL_PREFIX_BASE_DIR} -DCMAKE_INSTALL_MESSAGE=NEVER -DCMAKE_EXPORT_COMPILE_COMMANDS=true + -DMAX_ARGC_ENVC=${MAX_ARGC_ENVC} --no-warn-unused-cli ${DO_PROFILING} ${CMD_VARS} diff --git a/kernel/main.c b/kernel/main.c index ece3fcbff..973e0cb16 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,22 @@ #define HERMIT_PORT 0x494E #define HERMIT_MAGIC 0x7E317 +/* Ports and data structures for command line args + envp forwarding to uhyve */ +#define UHYVE_PORT_CMDSIZE 0x509 +#define UHYVE_PORT_CMDVAL 0x510 + +typedef struct { + int argc; + int argsz[MAX_ARGC_ENVC]; + int envc; + int envsz[MAX_ARGC_ENVC]; +} __attribute__ ((packed)) uhyve_cmdsize_t; + +typedef struct { + char **argv; + char **envp; +} __attribute__ ((packed)) uhyve_cmdval_t; + static struct netif default_netif; static const int sobufsize = 131072; @@ -370,6 +387,37 @@ static int initd(void* arg) // initialize network err = init_netifs(); + if(is_uhyve()) { + int i; + uhyve_cmdsize_t uhyve_cmdsize; + uhyve_cmdval_t uhyve_cmdval; + + uhyve_send(UHYVE_PORT_CMDSIZE, + (unsigned)virt_to_phys((size_t)&uhyve_cmdsize)); + + uhyve_cmdval.argv = kmalloc(uhyve_cmdsize.argc * sizeof(char *)); + for(i=0; iio.data_offset)); + uhyve_cmdsize_t *val = (uhyve_cmdsize_t *) (guest_mem+data); + + val->argc = uhyve_argc; + for(i=0; iargsz[i] = strlen(uhyve_argv[i]); + + val->envc = uhyve_envc; + for(i=0; ienvsz[i] = strlen(uhyve_envp[i]); + + break; + } + + case UHYVE_PORT_CMDVAL: { + int i; + char **argv_ptr, **env_ptr; + struct kvm_translation kt; + unsigned data = *((unsigned*)((size_t)run+run->io.data_offset)); + uhyve_cmdval_t *val = (uhyve_cmdval_t *) (guest_mem+data); + + /* buffers inside uhyve_cmdval are not directlty mapped + * (they are allocated through kmalloc) so we cannot + * used a simple offset as the guest to host, we have to + * walk the guest page table to find the physical address, + * then we can use the offset + */ + + /* argv */ + kt.linear_address = (unsigned long long)val->argv; + kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt); + argv_ptr = (char **)(guest_mem + + (size_t)kt.physical_address); + + for(i=0; ienvp; + kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt); + env_ptr = (char **)(guest_mem + + (size_t)kt.physical_address); + + for(i=0; iio.port, run->io.direction); break; @@ -1510,10 +1592,18 @@ nextslot: no_checkpoint++; } -int uhyve_loop(void) +int uhyve_loop(int argc, char **argv) { const char* hermit_check = getenv("HERMIT_CHECKPOINT"); - int ts = 0; + int ts = 0, i = 0; + + /* argv[0] is 'proxy', do not count it */ + uhyve_argc = argc-1; + uhyve_argv = &argv[1]; + uhyve_envp = environ; + while(uhyve_envp[i] != NULL) + i++; + uhyve_envc = i; if (hermit_check) ts = atoi(hermit_check); diff --git a/usr/tests/CMakeLists.txt b/usr/tests/CMakeLists.txt index e910a016c..716bf8376 100644 --- a/usr/tests/CMakeLists.txt +++ b/usr/tests/CMakeLists.txt @@ -5,6 +5,7 @@ project(hermit_tests C CXX Fortran Go) add_executable(hello hello.c) add_executable(jacobi jacobi.c) +add_executable(argv_envp argv_envp.c) add_executable(hello++ hello++.cpp) add_executable(hellof hellof.f90) add_executable(pi pi.go) diff --git a/usr/tests/argv_envp.c b/usr/tests/argv_envp.c new file mode 100644 index 000000000..7c9f4ed9b --- /dev/null +++ b/usr/tests/argv_envp.c @@ -0,0 +1,21 @@ +#include +#include +#include + +extern char **environ; + +int main(int argc, char **argv) { + int i; + + printf("argc: %d\n", argc); + for(i=0; i