diff options
author | Glauber de Oliveira Costa <gcosta@redhat.com> | 2008-01-07 11:05:32 -0200 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-01-30 22:50:11 +1100 |
commit | a53a35a8b485b9c16b73e5177bddaa4321971199 (patch) | |
tree | 8ed96838cb47d1263f63aba6dd6921b3c811f46c /drivers/lguest/lguest_user.c | |
parent | a3863f68b0d7fe2073c0f4efe534ec87a685c4fa (diff) |
lguest: make registers per-vcpu
This is the most obvious per-vcpu field: registers.
So this patch moves it from struct lguest to struct vcpu,
and patch the places in which they are used, accordingly
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/lguest/lguest_user.c')
-rw-r--r-- | drivers/lguest/lguest_user.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index 605db5c49e7..d21d95b2b1f 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c @@ -106,6 +106,19 @@ static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) cpu->lg->nr_cpus++; init_clockdev(cpu); + /* We need a complete page for the Guest registers: they are accessible + * to the Guest and we can only grant it access to whole pages. */ + cpu->regs_page = get_zeroed_page(GFP_KERNEL); + if (!cpu->regs_page) + return -ENOMEM; + + /* We actually put the registers at the bottom of the page. */ + cpu->regs = (void *)cpu->regs_page + PAGE_SIZE - sizeof(*cpu->regs); + + /* Now we initialize the Guest's registers, handing it the start + * address. */ + lguest_arch_setup_regs(cpu, start_ip); + return 0; } @@ -160,16 +173,6 @@ static int initialize(struct file *file, const unsigned long __user *input) if (err) goto release_guest; - /* We need a complete page for the Guest registers: they are accessible - * to the Guest and we can only grant it access to whole pages. */ - lg->regs_page = get_zeroed_page(GFP_KERNEL); - if (!lg->regs_page) { - err = -ENOMEM; - goto release_guest; - } - /* We actually put the registers at the bottom of the page. */ - lg->regs = (void *)lg->regs_page + PAGE_SIZE - sizeof(*lg->regs); - /* Initialize the Guest's shadow page tables, using the toplevel * address the Launcher gave us. This allocates memory, so can * fail. */ @@ -177,10 +180,6 @@ static int initialize(struct file *file, const unsigned long __user *input) if (err) goto free_regs; - /* Now we initialize the Guest's registers, handing it the start - * address. */ - lguest_arch_setup_regs(lg, args[3]); - /* We keep a pointer to the Launcher task (ie. current task) for when * other Guests want to wake this one (inter-Guest I/O). */ lg->tsk = current; @@ -205,7 +204,8 @@ static int initialize(struct file *file, const unsigned long __user *input) return sizeof(args); free_regs: - free_page(lg->regs_page); + /* FIXME: This should be in free_vcpu */ + free_page(lg->cpus[0].regs_page); release_guest: kfree(lg); unlock: @@ -280,9 +280,12 @@ static int close(struct inode *inode, struct file *file) /* We need the big lock, to protect from inter-guest I/O and other * Launchers initializing guests. */ mutex_lock(&lguest_lock); - for (i = 0; i < lg->nr_cpus; i++) + for (i = 0; i < lg->nr_cpus; i++) { /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */ hrtimer_cancel(&lg->cpus[i].hrt); + /* We can free up the register page we allocated. */ + free_page(lg->cpus[i].regs_page); + } /* Free up the shadow page tables for the Guest. */ free_guest_pagetable(lg); /* Now all the memory cleanups are done, it's safe to release the @@ -292,8 +295,6 @@ static int close(struct inode *inode, struct file *file) * kmalloc()ed string, either of which is ok to hand to kfree(). */ if (!IS_ERR(lg->dead)) kfree(lg->dead); - /* We can free up the register page we allocated. */ - free_page(lg->regs_page); /* We clear the entire structure, which also marks it as free for the * next user. */ memset(lg, 0, sizeof(*lg)); |