From: Glauber de Oliveira Costa <gcosta@redhat.com>
To: lguest@ozlabs.org
Cc: glommer@gmail.com, linux-kernel@vger.kernel.org,
virtualization@lists.linux-foundation.org, rusty@rustcorp.com.au,
rostedt@goodmis.org,
Glauber de Oliveira Costa <gcosta@redhat.com>
Subject: [PATCH 13/16] per-vcpu lguest task management
Date: Thu, 20 Dec 2007 11:33:53 -0200 [thread overview]
Message-ID: <11981577021091-git-send-email-gcosta@redhat.com> (raw)
In-Reply-To: <11981576972655-git-send-email-gcosta@redhat.com>
lguest uses tasks to control its running behaviour (like sending
breaks, controlling halted state, etc). In a per-vcpu environment,
each vcpu will have its own underlying task. So this patch
makes the infrastructure for that possible
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
---
drivers/lguest/core.c | 4 +-
drivers/lguest/hypercalls.c | 2 +-
drivers/lguest/interrupts_and_traps.c | 8 ++--
drivers/lguest/lg.h | 14 ++++----
drivers/lguest/lguest_user.c | 56 ++++++++++++++++++--------------
5 files changed, 45 insertions(+), 39 deletions(-)
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 4d0102d..285a465 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -197,7 +197,7 @@ int run_guest(struct lguest_vcpu *vcpu, unsigned long __user *user)
return -ERESTARTSYS;
/* If Waker set break_out, return to Launcher. */
- if (lg->break_out)
+ if (vcpu->break_out)
return -EAGAIN;
/* Check if there are any interrupts which can be delivered
@@ -217,7 +217,7 @@ int run_guest(struct lguest_vcpu *vcpu, unsigned long __user *user)
/* If the Guest asked to be stopped, we sleep. The Guest's
* clock timer or LHCALL_BREAK from the Waker will wake us. */
- if (lg->halted) {
+ if (vcpu->halted) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
continue;
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 4364bc2..41ea2e2 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -86,7 +86,7 @@ static void do_hcall(struct lguest_vcpu *vcpu, struct hcall_args *args)
break;
case LHCALL_HALT:
/* Similarly, this sets the halted flag for run_guest(). */
- lg->halted = 1;
+ vcpu->halted = 1;
break;
case LHCALL_NOTIFY:
lg->pending_notify = args->arg1;
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index b3d444a..10c9aea 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -163,11 +163,11 @@ void maybe_do_interrupt(struct lguest_vcpu *vcpu)
return;
/* If they're halted, interrupts restart them. */
- if (lg->halted) {
+ if (vcpu->halted) {
/* Re-enable interrupts. */
if (put_user(X86_EFLAGS_IF, &lg->lguest_data->irq_enabled))
kill_guest(lg, "Re-enabling interrupts");
- lg->halted = 0;
+ vcpu->halted = 0;
} else {
/* Otherwise we check if they have interrupts disabled. */
u32 irq_enabled;
@@ -500,8 +500,8 @@ static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
/* Remember the first interrupt is the timer interrupt. */
set_bit(0, vcpu->irqs_pending);
/* If the Guest is actually stopped, we need to wake it up. */
- if (vcpu->lg->halted)
- wake_up_process(vcpu->lg->tsk);
+ if (vcpu->halted)
+ wake_up_process(vcpu->tsk);
return HRTIMER_NORESTART;
}
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index f9429ff..b23694e 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -43,6 +43,8 @@ struct lguest;
struct lguest_vcpu {
int vcpu_id;
struct lguest *lg;
+ struct task_struct *tsk;
+ struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */
/* At end of a page shared mapped over lguest_pages in guest. */
unsigned long regs_page;
@@ -55,6 +57,11 @@ struct lguest_vcpu {
/* Virtual clock device */
struct hrtimer hrt;
+ /* Do we need to stop what we're doing and return to userspace? */
+ int break_out;
+ wait_queue_head_t break_wq;
+ int halted;
+
/* Pending virtual interrupts */
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
@@ -65,8 +72,6 @@ struct lguest_vcpu {
struct lguest
{
struct lguest_data __user *lguest_data;
- struct task_struct *tsk;
- struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */
struct lguest_vcpu vcpus[NR_CPUS];
unsigned int nr_vcpus;
@@ -76,15 +81,10 @@ struct lguest
void __user *mem_base;
unsigned long kernel_address;
u32 cr2;
- int halted;
int ts;
u32 esp1;
u8 ss1;
- /* Do we need to stop what we're doing and return to userspace? */
- int break_out;
- wait_queue_head_t break_wq;
-
/* Bitmap of what has changed: see CHANGED_* above. */
int changed;
struct lguest_pages *last_pages;
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 4f51e25..d081db4 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -13,7 +13,8 @@
* LHREQ_BREAK and the value "1" to /dev/lguest to do this. Once the Launcher
* has done whatever needs attention, it writes LHREQ_BREAK and "0" to release
* the Waker. */
-static int break_guest_out(struct lguest *lg, const unsigned long __user *input)
+static int break_guest_out(struct lguest_vcpu *vcpu,
+ const unsigned long __user *input)
{
unsigned long on;
@@ -22,14 +23,15 @@ static int break_guest_out(struct lguest *lg, const unsigned long __user *input)
return -EFAULT;
if (on) {
- lg->break_out = 1;
+ vcpu->break_out = 1;
/* Pop it out of the Guest (may be running on different CPU) */
- wake_up_process(lg->tsk);
+ wake_up_process(vcpu->tsk);
/* Wait for them to reset it */
- return wait_event_interruptible(lg->break_wq, !lg->break_out);
+ return wait_event_interruptible(vcpu->break_wq,
+ !vcpu->break_out);
} else {
- lg->break_out = 0;
- wake_up(&lg->break_wq);
+ vcpu->break_out = 0;
+ wake_up(&vcpu->break_wq);
return 0;
}
}
@@ -66,7 +68,7 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
vcpu = &lg->vcpus[vcpu_id];
/* If you're not the task which owns the Guest, go away. */
- if (current != lg->tsk)
+ if (current != vcpu->tsk)
return -EPERM;
/* If the guest is already dead, we indicate why */
@@ -114,6 +116,19 @@ static int vcpu_start(struct lguest_vcpu *vcpu, int vcpu_id,
* address. */
lguest_arch_setup_regs(vcpu, start_ip);
+ /* Initialize the queue for the waker to wait on */
+ init_waitqueue_head(&vcpu->break_wq);
+
+ /* We keep a pointer to the Launcher task (ie. current task) for when
+ * other Guests want to wake this one (inter-Guest I/O). */
+ vcpu->tsk = current;
+
+ /* We need to keep a pointer to the Launcher's memory map, because if
+ * the Launcher dies we need to clean it up. If we don't keep a
+ * reference, it is destroyed before close() is called. */
+ vcpu->mm = get_task_mm(vcpu->tsk);
+
+
vcpu->lg = container_of((vcpu - vcpu_id), struct lguest, vcpus[0]);
vcpu->lg->nr_vcpus++;
@@ -179,17 +194,6 @@ static int initialize(struct file *file, const unsigned long __user *input)
if (err)
goto free_regs;
- /* 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;
- /* We need to keep a pointer to the Launcher's memory map, because if
- * the Launcher dies we need to clean it up. If we don't keep a
- * reference, it is destroyed before close() is called. */
- lg->mm = get_task_mm(lg->tsk);
-
- /* Initialize the queue for the waker to wait on */
- init_waitqueue_head(&lg->break_wq);
-
/* We remember which CPU's pages this Guest used last, for optimization
* when the same Guest runs on the same CPU twice. */
lg->last_pages = NULL;
@@ -244,7 +248,7 @@ static ssize_t write(struct file *file, const char __user *in,
return -ENOENT;
/* If you're not the task which owns the Guest, you can only break */
- if (lg && current != lg->tsk && req != LHREQ_BREAK)
+ if (lg && current != vcpu->tsk && req != LHREQ_BREAK)
return -EPERM;
switch (req) {
@@ -253,7 +257,7 @@ static ssize_t write(struct file *file, const char __user *in,
case LHREQ_IRQ:
return user_send_irq(vcpu, input);
case LHREQ_BREAK:
- return break_guest_out(lg, input);
+ return break_guest_out(vcpu, input);
default:
return -EINVAL;
}
@@ -278,17 +282,19 @@ 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);
+
+ /* Free up the shadow page tables for the Guest. */
+ free_guest_pagetable(lg);
+
for (i = 0; i < lg->nr_vcpus; i++) {
/* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */
hrtimer_cancel(&lg->vcpus[i].hrt);
/* We can free up the register page we allocated. */
free_page(lg->vcpus[i].regs_page);
+ /* Now all the memory cleanups are done, it's safe to release
+ * the Launcher's memory management structure. */
+ mmput(lg->vcpus[i].mm);
}
- /* 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
- * Launcher's memory management structure. */
- mmput(lg->mm);
/* If lg->dead doesn't contain an error code it will be NULL or a
* kmalloc()ed string, either of which is ok to hand to kfree(). */
if (!IS_ERR(lg->dead))
--
1.5.0.6
next prev parent reply other threads:[~2007-12-20 13:40 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-20 13:33 [PATCH 0/16] lguest: introduce vcpu structure Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 01/16] introduce vcpu struct Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 02/16] adapt lguest launcher to per-cpuness Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 03/16] initialize vcpu Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 04/16] per-cpu run guest Glauber de Oliveira Costa
2007-12-20 13:33 ` Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 05/16] make write() operation smp aware Glauber de Oliveira Costa
2007-12-20 13:33 ` Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 06/16] make hypercalls use the vcpu struct Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 07/16] per-vcpu lguest timers Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 08/16] per-vcpu interrupt processing Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 09/16] map_switcher_in_guest() per-vcpu Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 10/16] make emulate_insn receive a vcpu struct Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 11/16] make registers per-vcpu Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 12/16] replace lguest_arch with lguest_vcpu_arch Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 13/16] per-vcpu lguest task management Glauber de Oliveira Costa
2007-12-20 13:33 ` Glauber de Oliveira Costa [this message]
2007-12-20 13:33 ` [PATCH 14/16] makes special fields be per-vcpu Glauber de Oliveira Costa
2007-12-20 13:33 ` Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 15/16] make pending notifications per-vcpu Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 16/16] per-vcpu lguest pgdir management Glauber de Oliveira Costa
2007-12-20 13:33 ` Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 15/16] make pending notifications per-vcpu Glauber de Oliveira Costa
2007-12-25 23:47 ` [PATCH 13/16] per-vcpu lguest task management Rusty Russell
2007-12-25 23:47 ` Rusty Russell
2007-12-20 13:33 ` [PATCH 12/16] replace lguest_arch with lguest_vcpu_arch Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 11/16] make registers per-vcpu Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 10/16] make emulate_insn receive a vcpu struct Glauber de Oliveira Costa
2007-12-25 23:47 ` [PATCH 09/16] map_switcher_in_guest() per-vcpu Rusty Russell
2007-12-25 23:47 ` Rusty Russell
2007-12-20 13:33 ` Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 08/16] per-vcpu interrupt processing Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 07/16] per-vcpu lguest timers Glauber de Oliveira Costa
2007-12-20 13:33 ` [PATCH 06/16] make hypercalls use the vcpu struct Glauber de Oliveira Costa
2007-12-25 23:40 ` [PATCH 05/16] make write() operation smp aware Rusty Russell
2007-12-25 23:40 ` Rusty Russell
2007-12-25 23:38 ` [PATCH 04/16] per-cpu run guest Rusty Russell
2007-12-25 23:38 ` Rusty Russell
2007-12-20 13:33 ` [PATCH 03/16] initialize vcpu Glauber de Oliveira Costa
2007-12-25 23:35 ` [PATCH 02/16] adapt lguest launcher to per-cpuness Rusty Russell
2007-12-25 23:35 ` Rusty Russell
2007-12-26 14:24 ` Steven Rostedt
2007-12-27 0:08 ` Rusty Russell
2007-12-27 0:08 ` Rusty Russell
2007-12-26 14:24 ` Steven Rostedt
2007-12-20 13:33 ` Glauber de Oliveira Costa
2007-12-25 23:34 ` [PATCH 01/16] introduce vcpu struct Rusty Russell
2007-12-25 23:34 ` Rusty Russell
2007-12-20 13:33 ` Glauber de Oliveira Costa
2007-12-25 23:54 ` [PATCH 0/16] lguest: introduce vcpu structure Rusty Russell
2008-01-06 17:33 ` Glauber de Oliveira Costa
2008-01-06 17:33 ` Glauber de Oliveira Costa
2008-01-07 0:53 ` Rusty Russell
2008-01-07 0:53 ` Rusty Russell
2007-12-25 23:54 ` Rusty Russell
-- strict thread matches above, loose matches on Subject: below --
2008-01-07 13:05 [PATCH 0/16 -v2] lguest smp infrastructure Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 01/16] introduce vcpu struct Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 02/16] adapt lguest launcher to per-cpuness Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 03/16] initialize vcpu Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 04/16] per-cpu run guest Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 05/16] make write() operation smp aware Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 06/16] make hypercalls use the vcpu struct Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 07/16] per-vcpu lguest timers Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 08/16] per-vcpu interrupt processing Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 09/16] map_switcher_in_guest() per-vcpu Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 10/16] make emulate_insn receive a vcpu struct Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 11/16] make registers per-vcpu Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 12/16] replace lguest_arch with lg_vcpu_arch Glauber de Oliveira Costa
2008-01-07 13:05 ` [PATCH 13/16] per-vcpu lguest task management Glauber de Oliveira Costa
2008-01-07 13:05 ` Glauber de Oliveira Costa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=11981577021091-git-send-email-gcosta@redhat.com \
--to=gcosta@redhat.com \
--cc=glommer@gmail.com \
--cc=lguest@ozlabs.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=rusty@rustcorp.com.au \
--cc=virtualization@lists.linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.