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>
This commit is contained in:
committed by
Rusty Russell
parent
a3863f68b0
commit
a53a35a8b4
@@ -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));
|
||||
|
Reference in New Issue
Block a user