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;
|
int i;
|
||||||
uhyve_cmdsize_t uhyve_cmdsize;
|
uhyve_cmdsize_t uhyve_cmdsize;
|
||||||
uhyve_cmdval_t uhyve_cmdval;
|
uhyve_cmdval_t uhyve_cmdval;
|
||||||
|
uhyve_cmdval_t uhyve_cmdval_phys;
|
||||||
|
|
||||||
uhyve_send(UHYVE_PORT_CMDSIZE,
|
uhyve_send(UHYVE_PORT_CMDSIZE,
|
||||||
(unsigned)virt_to_phys((size_t)&uhyve_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++)
|
for(i=0; i<uhyve_cmdsize.envc; i++)
|
||||||
uhyve_cmdval.envp[i] = kmalloc(uhyve_cmdsize.envsz[i] * sizeof(char));
|
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,
|
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);
|
LOG_INFO("Boot time: %d ms\n", (get_clock_tick() * 1000) / TIMER_FREQ);
|
||||||
libc_start(uhyve_cmdsize.argc, uhyve_cmdval.argv, uhyve_cmdval.envp);
|
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++)
|
for(i=0; i<envc; i++)
|
||||||
kfree(uhyve_cmdval.envp[i]);
|
kfree(uhyve_cmdval.envp[i]);
|
||||||
kfree(uhyve_cmdval.envp);
|
kfree(uhyve_cmdval.envp);
|
||||||
|
kfree(argv_virt);
|
||||||
|
kfree(envp_virt);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -924,11 +924,11 @@ static int vcpu_loop(void)
|
||||||
|
|
||||||
val->argc = uhyve_argc;
|
val->argc = uhyve_argc;
|
||||||
for(i=0; i<uhyve_argc; i++)
|
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;
|
val->envc = uhyve_envc;
|
||||||
for(i=0; i<uhyve_envc; i++)
|
for(i=0; i<uhyve_envc; i++)
|
||||||
val->envsz[i] = strlen(uhyve_envp[i]);
|
val->envsz[i] = strlen(uhyve_envp[i]) + 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -936,42 +936,18 @@ static int vcpu_loop(void)
|
||||||
case UHYVE_PORT_CMDVAL: {
|
case UHYVE_PORT_CMDVAL: {
|
||||||
int i;
|
int i;
|
||||||
char **argv_ptr, **env_ptr;
|
char **argv_ptr, **env_ptr;
|
||||||
struct kvm_translation kt;
|
|
||||||
unsigned data = *((unsigned*)((size_t)run+run->io.data_offset));
|
unsigned data = *((unsigned*)((size_t)run+run->io.data_offset));
|
||||||
uhyve_cmdval_t *val = (uhyve_cmdval_t *) (guest_mem+data);
|
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 */
|
/* argv */
|
||||||
kt.linear_address = (unsigned long long)val->argv;
|
argv_ptr = (char **)(guest_mem + (size_t)val->argv);
|
||||||
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
|
for(i=0; i<uhyve_argc; i++)
|
||||||
argv_ptr = (char **)(guest_mem +
|
strcpy(guest_mem + (size_t)argv_ptr[i], uhyve_argv[i]);
|
||||||
(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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* env */
|
/* env */
|
||||||
kt.linear_address = (unsigned long long)val->envp;
|
env_ptr = (char **)(guest_mem + (size_t)val->envp);
|
||||||
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
|
for(i=0; i<uhyve_envc; i++)
|
||||||
env_ptr = (char **)(guest_mem +
|
strcpy(guest_mem + (size_t)env_ptr[i], uhyve_envp[i]);
|
||||||
(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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1605,6 +1581,17 @@ int uhyve_loop(int argc, char **argv)
|
||||||
i++;
|
i++;
|
||||||
uhyve_envc = 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) {
|
if(uhyve_argc > MAX_ARGC_ENVC || uhyve_envc > MAX_ARGC_ENVC) {
|
||||||
fprintf(stderr, "uhyve cannot forward more than %d command line "
|
fprintf(stderr, "uhyve cannot forward more than %d command line "
|
||||||
"arguments or environment variables, please consider increasing "
|
"arguments or environment variables, please consider increasing "
|
||||||
|
|
Loading…
Add table
Reference in a new issue