[PATCH 07/16] per-vcpu lguest timers

2008-01-07 Thread Glauber de Oliveira Costa
Here, I introduce per-vcpu timers. With this, we can have
local expiries, needed for accounting time in smp guests

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/hypercalls.c   |2 +-
 drivers/lguest/interrupts_and_traps.c |   20 ++--
 drivers/lguest/lg.h   |   10 +-
 drivers/lguest/lguest_user.c  |   12 +++-
 4 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 9417601..1bf133e 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -78,7 +78,7 @@ static void do_hcall(struct lg_vcpu *vcpu, struct hcall_args 
*args)
guest_set_pmd(lg, args->arg1, args->arg2);
break;
case LHCALL_SET_CLOCKEVENT:
-   guest_set_clockevent(lg, args->arg1);
+   guest_set_clockevent(vcpu, args->arg1);
break;
case LHCALL_TS:
/* This sets the TS flag, as we saw used in run_guest(). */
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 2b66f79..3be18a6 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -470,13 +470,13 @@ void copy_traps(const struct lguest *lg, struct 
desc_struct *idt,
  * infrastructure to set a callback at that time.
  *
  * 0 means "turn off the clock". */
-void guest_set_clockevent(struct lguest *lg, unsigned long delta)
+void guest_set_clockevent(struct lg_vcpu *vcpu, unsigned long delta)
 {
ktime_t expires;
 
if (unlikely(delta == 0)) {
/* Clock event device is shutting down. */
-   hrtimer_cancel(&lg->hrt);
+   hrtimer_cancel(&vcpu->hrt);
return;
}
 
@@ -484,25 +484,25 @@ void guest_set_clockevent(struct lguest *lg, unsigned 
long delta)
 * all the time between now and the timer interrupt it asked for.  This
 * is almost always the right thing to do. */
expires = ktime_add_ns(ktime_get_real(), delta);
-   hrtimer_start(&lg->hrt, expires, HRTIMER_MODE_ABS);
+   hrtimer_start(&vcpu->hrt, expires, HRTIMER_MODE_ABS);
 }
 
 /* This is the function called when the Guest's timer expires. */
 static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
 {
-   struct lguest *lg = container_of(timer, struct lguest, hrt);
+   struct lg_vcpu *vcpu = container_of(timer, struct lg_vcpu, hrt);
 
/* Remember the first interrupt is the timer interrupt. */
-   set_bit(0, lg->irqs_pending);
+   set_bit(0, vcpu->lg->irqs_pending);
/* If the Guest is actually stopped, we need to wake it up. */
-   if (lg->halted)
-   wake_up_process(lg->tsk);
+   if (vcpu->lg->halted)
+   wake_up_process(vcpu->lg->tsk);
return HRTIMER_NORESTART;
 }
 
 /* This sets up the timer for this Guest. */
-void init_clockdev(struct lguest *lg)
+void init_clockdev(struct lg_vcpu *vcpu)
 {
-   hrtimer_init(&lg->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
-   lg->hrt.function = clockdev_fn;
+   hrtimer_init(&vcpu->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
+   vcpu->hrt.function = clockdev_fn;
 }
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 13a991a..9c90fd3 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -47,6 +47,9 @@ struct lg_vcpu {
/* If a hypercall was asked for, this points to the arguments. */
struct hcall_args *hcall;
u32 next_hcall;
+
+   /* Virtual clock device */
+   struct hrtimer hrt;
 };
 
 /* The private info the thread maintains about the guest. */
@@ -95,9 +98,6 @@ struct lguest
 
struct lguest_arch arch;
 
-   /* Virtual clock device */
-   struct hrtimer hrt;
-
/* Pending virtual interrupts */
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 };
@@ -145,8 +145,8 @@ void setup_default_idt_entries(struct lguest_ro_state 
*state,
   const unsigned long *def);
 void copy_traps(const struct lguest *lg, struct desc_struct *idt,
const unsigned long *def);
-void guest_set_clockevent(struct lguest *lg, unsigned long delta);
-void init_clockdev(struct lguest *lg);
+void guest_set_clockevent(struct lg_vcpu *vcpu, unsigned long delta);
+void init_clockdev(struct lg_vcpu *vcpu);
 bool check_syscall_vector(struct lguest *lg);
 int init_interrupts(void);
 void free_interrupts(void);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index d176004..cd2b0bf 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -104,6 +104,9 @@ static int vcpu_start(struct lg_vcpu *vcpu, int vcpu_id,
 
vcpu->vcpu_id = vcpu_id;
 
+   /* The timer for lguest's clock needs initialization. */
+   init_clockdev(vcpu);
+
vcpu->lg = container_of((vcpu - vcpu_id), struct lguest, vcpus[0]);
vcp

[PATCH 07/16] per-vcpu lguest timers

2007-12-20 Thread Glauber de Oliveira Costa
Here, I introduce per-vcpu timers. With this, we can have
local expiries, needed for accounting time in smp guests

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 drivers/lguest/hypercalls.c   |2 +-
 drivers/lguest/interrupts_and_traps.c |   20 ++--
 drivers/lguest/lg.h   |   10 +-
 drivers/lguest/lguest_user.c  |   12 +++-
 4 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 62da355..4364bc2 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -78,7 +78,7 @@ static void do_hcall(struct lguest_vcpu *vcpu, struct 
hcall_args *args)
guest_set_pmd(lg, args->arg1, args->arg2);
break;
case LHCALL_SET_CLOCKEVENT:
-   guest_set_clockevent(lg, args->arg1);
+   guest_set_clockevent(vcpu, args->arg1);
break;
case LHCALL_TS:
/* This sets the TS flag, as we saw used in run_guest(). */
diff --git a/drivers/lguest/interrupts_and_traps.c 
b/drivers/lguest/interrupts_and_traps.c
index 2b66f79..189d66e 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -470,13 +470,13 @@ void copy_traps(const struct lguest *lg, struct 
desc_struct *idt,
  * infrastructure to set a callback at that time.
  *
  * 0 means "turn off the clock". */
-void guest_set_clockevent(struct lguest *lg, unsigned long delta)
+void guest_set_clockevent(struct lguest_vcpu *vcpu, unsigned long delta)
 {
ktime_t expires;
 
if (unlikely(delta == 0)) {
/* Clock event device is shutting down. */
-   hrtimer_cancel(&lg->hrt);
+   hrtimer_cancel(&vcpu->hrt);
return;
}
 
@@ -484,25 +484,25 @@ void guest_set_clockevent(struct lguest *lg, unsigned 
long delta)
 * all the time between now and the timer interrupt it asked for.  This
 * is almost always the right thing to do. */
expires = ktime_add_ns(ktime_get_real(), delta);
-   hrtimer_start(&lg->hrt, expires, HRTIMER_MODE_ABS);
+   hrtimer_start(&vcpu->hrt, expires, HRTIMER_MODE_ABS);
 }
 
 /* This is the function called when the Guest's timer expires. */
 static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
 {
-   struct lguest *lg = container_of(timer, struct lguest, hrt);
+   struct lguest_vcpu *vcpu = container_of(timer, struct lguest_vcpu, hrt);
 
/* Remember the first interrupt is the timer interrupt. */
-   set_bit(0, lg->irqs_pending);
+   set_bit(0, vcpu->lg->irqs_pending);
/* If the Guest is actually stopped, we need to wake it up. */
-   if (lg->halted)
-   wake_up_process(lg->tsk);
+   if (vcpu->lg->halted)
+   wake_up_process(vcpu->lg->tsk);
return HRTIMER_NORESTART;
 }
 
 /* This sets up the timer for this Guest. */
-void init_clockdev(struct lguest *lg)
+void init_clockdev(struct lguest_vcpu *vcpu)
 {
-   hrtimer_init(&lg->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
-   lg->hrt.function = clockdev_fn;
+   hrtimer_init(&vcpu->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
+   vcpu->hrt.function = clockdev_fn;
 }
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 696cdf1..0205409 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -47,6 +47,9 @@ struct lguest_vcpu {
/* If a hypercall was asked for, this points to the arguments. */
struct hcall_args *hcall;
u32 next_hcall;
+
+   /* Virtual clock device */
+   struct hrtimer hrt;
 };
 
 /* The private info the thread maintains about the guest. */
@@ -95,9 +98,6 @@ struct lguest
 
struct lguest_arch arch;
 
-   /* Virtual clock device */
-   struct hrtimer hrt;
-
/* Pending virtual interrupts */
DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 };
@@ -150,8 +150,8 @@ void setup_default_idt_entries(struct lguest_ro_state 
*state,
   const unsigned long *def);
 void copy_traps(const struct lguest *lg, struct desc_struct *idt,
const unsigned long *def);
-void guest_set_clockevent(struct lguest *lg, unsigned long delta);
-void init_clockdev(struct lguest *lg);
+void guest_set_clockevent(struct lguest_vcpu *vcpu, unsigned long delta);
+void init_clockdev(struct lguest_vcpu *vcpu);
 bool check_syscall_vector(struct lguest *lg);
 int init_interrupts(void);
 void free_interrupts(void);
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index ae5bf4c..7481e82 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -97,6 +97,9 @@ static int vcpu_start(struct lguest_vcpu *vcpu, int vcpu_id,
 {
vcpu->vcpu_id = vcpu_id;
 
+   /* The timer for lguest's clock needs initialization. */
+   init_clockdev(vcpu);
+
vcpu->lg = container_of((vcpu - vcpu_id), st