summaryrefslogtreecommitdiffstats
path: root/drivers/lguest/lguest_user.c
diff options
context:
space:
mode:
authorGlauber de Oliveira Costa <gcosta@redhat.com>2008-01-07 11:05:32 -0200
committerRusty Russell <rusty@rustcorp.com.au>2008-01-30 22:50:11 +1100
commita53a35a8b485b9c16b73e5177bddaa4321971199 (patch)
tree8ed96838cb47d1263f63aba6dd6921b3c811f46c /drivers/lguest/lguest_user.c
parenta3863f68b0d7fe2073c0f4efe534ec87a685c4fa (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.c37
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));