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:
parent
0b828dfe85
commit
8653afbd07
2 changed files with 36 additions and 33 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 "
|
||||
|
|
Loading…
Add table
Reference in a new issue