support vdso which borrows clocksource from linux

This commit is contained in:
NAKAMURA Gou
2016-03-28 14:42:49 +09:00
parent a587c8f5e5
commit 41bb2ab5e6
17 changed files with 689 additions and 18 deletions

View File

@@ -40,6 +40,7 @@ static void ap_wait(void)
kmalloc_init();
sched_init();
arch_start_pvclock();
if (find_command_line("hidos")) {
init_host_syscall_channel();

View File

@@ -86,6 +86,7 @@ int prepare_process_ranges_args_envs(struct thread *thread,
struct process_vm *vm = proc->vm;
struct address_space *as = vm->address_space;
long aout_base;
int error;
n = p->num_sections;
@@ -324,6 +325,14 @@ int prepare_process_ranges_args_envs(struct thread *thread,
dkprintf("env OK\n");
if (pn->enable_vdso) {
error = arch_map_vdso(vm);
if (error) {
kprintf("ERROR: mapping vdso pages. %d\n", error);
goto err;
}
}
p->rprocess = (unsigned long)thread;
p->rpgtable = virt_to_phys(as->page_table);

View File

@@ -1,6 +1,8 @@
#ifndef _LINUX_AUXVEC_H
#define _LINUX_AUXVEC_H
#include <arch/auxvec.h>
/* Symbolic values for the entries in the auxiliary table
put on the initial stack */
#define AT_NULL 0 /* end of vector */

View File

@@ -292,7 +292,7 @@ struct user
unsigned long int u_debugreg [8];
};
#define AUXV_LEN 16
#define AUXV_LEN 18
struct vm_range {
struct list_head list;
@@ -557,6 +557,8 @@ struct process_vm {
struct process *proc; /* process that reside on the same page */
void *opt;
void (*free_cb)(struct process_vm *, void *);
void *vdso_addr;
void *vvar_addr;
ihk_spinlock_t page_table_lock;
ihk_spinlock_t memory_range_lock;

View File

@@ -38,6 +38,7 @@
#define SCD_MSG_SYSCALL_ONESIDE 0x4
#define SCD_MSG_SEND_SIGNAL 0x8
#define SCD_MSG_CLEANUP_PROCESS 0x9
#define SCD_MSG_GET_VDSO_INFO 0xa
#define SCD_MSG_PROCFS_CREATE 0x10
#define SCD_MSG_PROCFS_DELETE 0x11
@@ -176,6 +177,8 @@ struct program_load_desc {
int pgid;
int cred[8];
int reloc;
char enable_vdso;
char padding[7];
unsigned long entry;
unsigned long user_start;
unsigned long user_end;
@@ -361,5 +364,25 @@ intptr_t do_mmap(intptr_t addr0, size_t len0, int prot, int flags, int fd,
off_t off0);
typedef int32_t key_t;
int do_shmget(key_t key, size_t size, int shmflg);
struct process_vm;
int arch_map_vdso(struct process_vm *vm); /* arch dependent */
int arch_setup_vdso(void);
#define VDSO_MAXPAGES 2
struct vdso {
long busy;
int vdso_npages;
char vvar_is_global;
char hpet_is_global;
char pvti_is_global;
char padding;
long vdso_physlist[VDSO_MAXPAGES];
void *vvar_virt;
long vvar_phys;
void *hpet_virt;
long hpet_phys;
void *pvti_virt;
long pvti_phys;
};
#endif

View File

@@ -343,6 +343,8 @@ static void post_init(void)
ihk_mc_spinlock_init(&syscall_lock);
}
arch_setup_vdso();
arch_start_pvclock();
ap_start();
sysfs_init();

View File

@@ -498,23 +498,30 @@ static int copy_user_pte(void *arg0, page_table_t src_pt, pte_t *src_ptep, void
goto out;
}
dkprintf("copy_user_pte(): 0x%lx PTE found\n", pgaddr);
dkprintf("copy_user_pte(): page size: %d\n", pgsize);
npages = pgsize / PAGE_SIZE;
virt = ihk_mc_alloc_aligned_pages(npages, pgalign, IHK_MC_AP_NOWAIT);
if (!virt) {
kprintf("ERROR: copy_user_pte() allocating new page\n");
error = -ENOMEM;
goto out;
if (args->new_vrflag & VR_REMOTE) {
phys = src_phys;
attr = pte_get_attr(src_ptep, pgsize);
}
phys = virt_to_phys(virt);
dkprintf("copy_user_pte(): phys page allocated\n");
else {
dkprintf("copy_user_pte(): 0x%lx PTE found\n", pgaddr);
dkprintf("copy_user_pte(): page size: %d\n", pgsize);
memcpy(virt, src_kvirt, pgsize);
dkprintf("copy_user_pte(): memcpy OK\n");
npages = pgsize / PAGE_SIZE;
virt = ihk_mc_alloc_aligned_pages(npages, pgalign, IHK_MC_AP_NOWAIT);
if (!virt) {
kprintf("ERROR: copy_user_pte() allocating new page\n");
error = -ENOMEM;
goto out;
}
phys = virt_to_phys(virt);
dkprintf("copy_user_pte(): phys page allocated\n");
memcpy(virt, src_kvirt, pgsize);
dkprintf("copy_user_pte(): memcpy OK\n");
attr = arch_vrflag_to_ptattr(args->new_vrflag, PF_POPULATE, NULL);
}
attr = arch_vrflag_to_ptattr(args->new_vrflag, PF_POPULATE, NULL);
error = ihk_mc_pt_set_range(args->new_vm->address_space->page_table, args->new_vm, pgaddr, pgaddr+pgsize, phys, attr);
if (error) {
args->fault_addr = (intptr_t)pgaddr;
@@ -1815,6 +1822,11 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
p[s_ind--] = AT_CLKTCK;
p[s_ind--] = at_rand; /* AT_RANDOM */
p[s_ind--] = AT_RANDOM;
#ifndef AT_SYSINFO_EHDR
#define AT_SYSINFO_EHDR AT_IGNORE
#endif
p[s_ind--] = (long)(thread->vm->vdso_addr);
p[s_ind--] = (thread->vm->vdso_addr)? AT_SYSINFO_EHDR: AT_IGNORE;
/* Save auxiliary vector for later use. */
memcpy(proc->saved_auxv, &p[s_ind + 1], sizeof(proc->saved_auxv));