1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-30 00:00:15 +01:00

avoid using KVM_TRANSLATE in a loop

- determine within HermitCore the guest physical address
=> simplifies the translation from guest virtual to host virtual address
=> reduce the number of syscalls (KVM_TRANSLATE)
This commit is contained in:
Stefan Lankes 2017-11-10 22:17:45 +01:00
parent 0b828dfe85
commit 8653afbd07
2 changed files with 36 additions and 33 deletions

View file

@ -391,6 +391,7 @@ static int initd(void* arg)
int i;
uhyve_cmdsize_t uhyve_cmdsize;
uhyve_cmdval_t uhyve_cmdval;
uhyve_cmdval_t uhyve_cmdval_phys;
uhyve_send(UHYVE_PORT_CMDSIZE,
(unsigned)virt_to_phys((size_t)&uhyve_cmdsize));
@ -402,8 +403,21 @@ static int initd(void* arg)
for(i=0; i<uhyve_cmdsize.envc; i++)
uhyve_cmdval.envp[i] = kmalloc(uhyve_cmdsize.envsz[i] * sizeof(char));
// create a similar structure with guest physical addresses
char** argv_virt = uhyve_cmdval_phys.argv = kmalloc(uhyve_cmdsize.argc * sizeof(char *));
for(i=0; i<uhyve_cmdsize.argc; i++)
uhyve_cmdval_phys.argv[i] = (char*) virt_to_phys((size_t) uhyve_cmdval.argv[i]);
uhyve_cmdval_phys.argv = (char**) virt_to_phys((size_t) uhyve_cmdval_phys.argv);
char** envp_virt = uhyve_cmdval_phys.envp = kmalloc(uhyve_cmdsize.envc * sizeof(char *));
for(i=0; i<uhyve_cmdsize.envc-1; i++)
uhyve_cmdval_phys.envp[i] = (char*) virt_to_phys((size_t) uhyve_cmdval.envp[i]);
// the last element is always NULL
uhyve_cmdval_phys.envp[uhyve_cmdsize.envc-1] = NULL;
uhyve_cmdval_phys.envp = (char**) virt_to_phys((size_t) uhyve_cmdval_phys.envp);
uhyve_send(UHYVE_PORT_CMDVAL,
(unsigned)virt_to_phys((size_t)&uhyve_cmdval));
(unsigned)virt_to_phys((size_t)&uhyve_cmdval_phys));
LOG_INFO("Boot time: %d ms\n", (get_clock_tick() * 1000) / TIMER_FREQ);
libc_start(uhyve_cmdsize.argc, uhyve_cmdval.argv, uhyve_cmdval.envp);
@ -414,6 +428,8 @@ static int initd(void* arg)
for(i=0; i<envc; i++)
kfree(uhyve_cmdval.envp[i]);
kfree(uhyve_cmdval.envp);
kfree(argv_virt);
kfree(envp_virt);
return 0;
}

View file

@ -924,11 +924,11 @@ static int vcpu_loop(void)
val->argc = uhyve_argc;
for(i=0; i<uhyve_argc; i++)
val->argsz[i] = strlen(uhyve_argv[i]);
val->argsz[i] = strlen(uhyve_argv[i]) + 1;
val->envc = uhyve_envc;
for(i=0; i<uhyve_envc; i++)
val->envsz[i] = strlen(uhyve_envp[i]);
val->envsz[i] = strlen(uhyve_envp[i]) + 1;
break;
}
@ -936,42 +936,18 @@ static int vcpu_loop(void)
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; i<uhyve_argc; i++) {
kt.linear_address = (unsigned long long)argv_ptr[i];
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
strcpy(guest_mem + (size_t)kt.physical_address,
uhyve_argv[i]);
}
argv_ptr = (char **)(guest_mem + (size_t)val->argv);
for(i=0; i<uhyve_argc; i++)
strcpy(guest_mem + (size_t)argv_ptr[i], uhyve_argv[i]);
/* env */
kt.linear_address = (unsigned long long)val->envp;
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
env_ptr = (char **)(guest_mem +
(size_t)kt.physical_address);
for(i=0; i<uhyve_envc; i++) {
kt.linear_address = (unsigned long long)env_ptr[i];
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
strcpy(guest_mem + (size_t)kt.physical_address,
uhyve_envp[i]);
}
env_ptr = (char **)(guest_mem + (size_t)val->envp);
for(i=0; i<uhyve_envc; i++)
strcpy(guest_mem + (size_t)env_ptr[i], uhyve_envp[i]);
break;
}
@ -1605,6 +1581,17 @@ int uhyve_loop(int argc, char **argv)
i++;
uhyve_envc = i;
if (uhyve_argc > MAX_ARGC_ENVC) {
fprintf(stderr, "uhyve downsiize envc from %d to %d\n", uhyve_argc, MAX_ARGC_ENVC);
uhyve_argc = MAX_ARGC_ENVC;
}
if (uhyve_envc > MAX_ARGC_ENVC-1) {
fprintf(stderr, "uhyve downsiize envc from %d to %d\n", uhyve_envc, MAX_ARGC_ENVC-1);
uhyve_envc = MAX_ARGC_ENVC-1;
}
printf("envc %d\n", uhyve_envc);
if(uhyve_argc > MAX_ARGC_ENVC || uhyve_envc > MAX_ARGC_ENVC) {
fprintf(stderr, "uhyve cannot forward more than %d command line "
"arguments or environment variables, please consider increasing "