* [PATCH 2/5] arm/gic: fix gic context switch
2012-06-06 11:22 ` [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer Stefano Stabellini
@ 2012-06-06 11:22 ` Stefano Stabellini
2012-06-26 13:55 ` Ian Campbell
2012-06-06 11:22 ` [PATCH 3/5] xen/gic: support injecting IRQs even to VCPUs not currently running Stefano Stabellini
` (3 subsequent siblings)
4 siblings, 1 reply; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-06 11:22 UTC (permalink / raw)
To: xen-devel; +Cc: Tim.Deegan, david.vrabel, Ian.Campbell, Stefano Stabellini
gic_save/restore_state should also save and restore lr_mask and
event_mask too.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
xen/arch/arm/gic.c | 4 ++++
xen/include/asm-arm/domain.h | 2 ++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 3f9a061..c73f274 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -67,6 +67,8 @@ void gic_save_state(struct vcpu *v)
for ( i=0; i<nr_lrs; i++)
v->arch.gic_lr[i] = GICH[GICH_LR + i];
+ v->arch.lr_mask = gic.lr_mask;
+ v->arch.event_mask = gic.event_mask;
/* Disable until next VCPU scheduled */
GICH[GICH_HCR] = 0;
isb();
@@ -79,6 +81,8 @@ void gic_restore_state(struct vcpu *v)
if ( is_idle_vcpu(v) )
return;
+ gic.lr_mask = v->arch.lr_mask;
+ gic.event_mask = v->arch.event_mask;
for ( i=0; i<nr_lrs; i++)
GICH[GICH_LR + i] = v->arch.gic_lr[i];
GICH[GICH_HCR] = GICH_HCR_EN;
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 230ea8c..3576d50 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -121,6 +121,8 @@ struct arch_vcpu
uint32_t gic_hcr, gic_vmcr, gic_apr;
uint32_t gic_lr[64];
+ uint64_t event_mask;
+ uint64_t lr_mask;
struct {
/*
--
1.7.2.5
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 2/5] arm/gic: fix gic context switch
2012-06-06 11:22 ` [PATCH 2/5] arm/gic: fix gic context switch Stefano Stabellini
@ 2012-06-26 13:55 ` Ian Campbell
0 siblings, 0 replies; 20+ messages in thread
From: Ian Campbell @ 2012-06-26 13:55 UTC (permalink / raw)
To: Stefano Stabellini
Cc: xen-devel@lists.xensource.com, David Vrabel, Tim Deegan (3P)
On Wed, 2012-06-06 at 12:22 +0100, Stefano Stabellini wrote:
> gic_save/restore_state should also save and restore lr_mask and
> event_mask too.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
> ---
> xen/arch/arm/gic.c | 4 ++++
> xen/include/asm-arm/domain.h | 2 ++
> 2 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 3f9a061..c73f274 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -67,6 +67,8 @@ void gic_save_state(struct vcpu *v)
>
> for ( i=0; i<nr_lrs; i++)
> v->arch.gic_lr[i] = GICH[GICH_LR + i];
> + v->arch.lr_mask = gic.lr_mask;
> + v->arch.event_mask = gic.event_mask;
> /* Disable until next VCPU scheduled */
> GICH[GICH_HCR] = 0;
> isb();
> @@ -79,6 +81,8 @@ void gic_restore_state(struct vcpu *v)
> if ( is_idle_vcpu(v) )
> return;
>
> + gic.lr_mask = v->arch.lr_mask;
> + gic.event_mask = v->arch.event_mask;
> for ( i=0; i<nr_lrs; i++)
> GICH[GICH_LR + i] = v->arch.gic_lr[i];
> GICH[GICH_HCR] = GICH_HCR_EN;
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 230ea8c..3576d50 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -121,6 +121,8 @@ struct arch_vcpu
>
> uint32_t gic_hcr, gic_vmcr, gic_apr;
> uint32_t gic_lr[64];
> + uint64_t event_mask;
> + uint64_t lr_mask;
>
> struct {
> /*
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/5] xen/gic: support injecting IRQs even to VCPUs not currently running
2012-06-06 11:22 ` [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer Stefano Stabellini
2012-06-06 11:22 ` [PATCH 2/5] arm/gic: fix gic context switch Stefano Stabellini
@ 2012-06-06 11:22 ` Stefano Stabellini
2012-06-07 12:46 ` Tim Deegan
2012-06-06 11:22 ` [PATCH 4/5] xen/vgic: vgic: support irq enable/disable Stefano Stabellini
` (2 subsequent siblings)
4 siblings, 1 reply; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-06 11:22 UTC (permalink / raw)
To: xen-devel; +Cc: Tim.Deegan, david.vrabel, Ian.Campbell, Stefano Stabellini
The lr_pending list belongs to the vgic rather than the gic, so move it
there.
gic_set_guest_irq should take into account whether the vcpu is currently
running and if it is not it should add the irq to the right lr_pending
list.
When restoring the gic state we need to go through the lr_pending list
because it is possible that some irqs have been "injected" while the
vcpu wasn't running.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
xen/arch/arm/gic.c | 66 +++++++++++++++++++++++++++++------------
xen/arch/arm/gic.h | 2 +-
xen/arch/arm/vgic.c | 3 +-
xen/include/asm-arm/domain.h | 7 ++++
4 files changed, 56 insertions(+), 22 deletions(-)
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index c73f274..2e41d75 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -38,6 +38,7 @@
#define GICH ((volatile uint32_t *) (FIXMAP_ADDR(FIXMAP_GICH) \
+ (GIC_HR_OFFSET & 0xfff)))
static void events_maintenance(struct vcpu *v);
+static void gic_restore_pending_irqs(struct vcpu *v);
/* Global state */
static struct {
@@ -49,13 +50,6 @@ static struct {
spinlock_t lock;
uint64_t event_mask;
uint64_t lr_mask;
- /* lr_pending is used to queue IRQs (struct pending_irq) that the
- * vgic tried to inject in the guest (calling gic_set_guest_irq) but
- * no LRs were available at the time.
- * As soon as an LR is freed we remove the first IRQ from this
- * list and write it to the LR register.
- * lr_pending is a subset of vgic.inflight_irqs. */
- struct list_head lr_pending;
} gic;
irq_desc_t irq_desc[NR_IRQS];
@@ -87,6 +81,8 @@ void gic_restore_state(struct vcpu *v)
GICH[GICH_LR + i] = v->arch.gic_lr[i];
GICH[GICH_HCR] = GICH_HCR_EN;
isb();
+
+ gic_restore_pending_irqs(v);
}
static unsigned int gic_irq_startup(struct irq_desc *desc)
@@ -323,7 +319,6 @@ int __init gic_init(void)
gic.lr_mask = 0ULL;
gic.event_mask = 0ULL;
- INIT_LIST_HEAD(&gic.lr_pending);
spin_unlock(&gic.lock);
@@ -435,17 +430,20 @@ static inline void gic_set_lr(int lr, unsigned int virtual_irq,
((virtual_irq & GICH_LR_VIRTUAL_MASK) << GICH_LR_VIRTUAL_SHIFT);
}
-void gic_set_guest_irq(unsigned int virtual_irq,
+void gic_set_guest_irq(struct vcpu *v, unsigned int virtual_irq,
unsigned int state, unsigned int priority)
{
int i;
struct pending_irq *iter, *n;
- events_maintenance(current);
+ if ( v->is_running )
+ {
+ events_maintenance(v);
+ }
spin_lock_irq(&gic.lock);
- if ( list_empty(&gic.lr_pending) )
+ if ( v->is_running && list_empty(&v->arch.vgic.lr_pending) )
{
i = find_first_zero_bit(&gic.lr_mask, nr_lrs);
if (i < nr_lrs) {
@@ -457,8 +455,8 @@ void gic_set_guest_irq(unsigned int virtual_irq,
}
}
- n = irq_to_pending(current, virtual_irq);
- list_for_each_entry ( iter, &gic.lr_pending, lr_queue )
+ n = irq_to_pending(v, virtual_irq);
+ list_for_each_entry ( iter, &v->arch.vgic.lr_pending, lr_queue )
{
if ( iter->priority > priority )
{
@@ -466,13 +464,40 @@ void gic_set_guest_irq(unsigned int virtual_irq,
goto out;
}
}
- list_add_tail(&n->lr_queue, &gic.lr_pending);
+ list_add_tail(&n->lr_queue, &v->arch.vgic.lr_pending);
out:
spin_unlock_irq(&gic.lock);
return;
}
+static void gic_restore_pending_irqs(struct vcpu *v)
+{
+ int i;
+ struct pending_irq *p;
+
+ /* check for new pending irqs */
+ if ( list_empty(&v->arch.vgic.lr_pending) )
+ return;
+
+ list_for_each_entry ( p, &v->arch.vgic.lr_pending, lr_queue )
+ {
+ i = find_first_zero_bit(&gic.lr_mask, nr_lrs);
+ if ( i < nr_lrs )
+ {
+ gic_set_lr(i, p->irq, GICH_LR_PENDING, p->priority);
+ list_del_init(&p->lr_queue);
+ set_bit(i, &gic.lr_mask);
+ if ( p->irq == VGIC_IRQ_EVTCHN_CALLBACK )
+ set_bit(i, &gic.event_mask);
+ } else
+ {
+ return;
+ }
+ }
+
+}
+
static void gic_inject_irq_start(void)
{
uint32_t hcr;
@@ -582,9 +607,10 @@ static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs *r
{
int i = 0, virq;
uint32_t lr;
+ struct vcpu *v = current;
uint64_t eisr = GICH[GICH_EISR0] | (((uint64_t) GICH[GICH_EISR1]) << 32);
- events_maintenance(current);
+ events_maintenance(v);
while ((i = find_next_bit((const long unsigned int *) &eisr,
sizeof(eisr), i)) < sizeof(eisr)) {
@@ -596,8 +622,8 @@ static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs *r
GICH[GICH_LR + i] = 0;
clear_bit(i, &gic.lr_mask);
- if ( !list_empty(&gic.lr_pending) ) {
- p = list_entry(gic.lr_pending.next, typeof(*p), lr_queue);
+ if ( !list_empty(&v->arch.vgic.lr_pending) ) {
+ p = list_entry(v->arch.vgic.lr_pending.next, typeof(*p), lr_queue);
gic_set_lr(i, p->irq, GICH_LR_PENDING, p->priority);
list_del_init(&p->lr_queue);
set_bit(i, &gic.lr_mask);
@@ -608,14 +634,14 @@ static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs *r
}
spin_unlock_irq(&gic.lock);
- spin_lock(¤t->arch.vgic.lock);
- p = irq_to_pending(current, virq);
+ spin_lock(&v->arch.vgic.lock);
+ p = irq_to_pending(v, virq);
if ( p->desc != NULL ) {
p->desc->status &= ~IRQ_INPROGRESS;
GICC[GICC_DIR] = virq;
}
list_del_init(&p->inflight);
- spin_unlock(¤t->arch.vgic.lock);
+ spin_unlock(&v->arch.vgic.lock);
i++;
}
diff --git a/xen/arch/arm/gic.h b/xen/arch/arm/gic.h
index ac9cf3a..a55e146 100644
--- a/xen/arch/arm/gic.h
+++ b/xen/arch/arm/gic.h
@@ -134,7 +134,7 @@ extern void gic_route_irqs(void);
extern void gic_inject(void);
extern void __cpuinit init_maintenance_interrupt(void);
-extern void gic_set_guest_irq(unsigned int irq,
+extern void gic_set_guest_irq(struct vcpu *v, unsigned int irq,
unsigned int state, unsigned int priority);
extern int gic_route_irq_to_guest(struct domain *d, unsigned int irq,
const char * devname);
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 6eb6ec7..5a624bd 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -112,6 +112,7 @@ int vcpu_vgic_init(struct vcpu *v)
| (1<<(v->vcpu_id+16))
| (1<<(v->vcpu_id+24));
INIT_LIST_HEAD(&v->arch.vgic.inflight_irqs);
+ INIT_LIST_HEAD(&v->arch.vgic.lr_pending);
spin_lock_init(&v->arch.vgic.lock);
return 0;
@@ -568,7 +569,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
else
n->desc = NULL;
- gic_set_guest_irq(irq, GICH_LR_PENDING, priority);
+ gic_set_guest_irq(v, irq, GICH_LR_PENDING, priority);
spin_lock_irqsave(&v->arch.vgic.lock, flags);
list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight )
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 3576d50..2b14545 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -140,6 +140,13 @@ struct arch_vcpu
* As soon as an IRQ is EOI'd by the guest and removed from the
* corresponding LR it is also removed from this list. */
struct list_head inflight_irqs;
+ /* lr_pending is used to queue IRQs (struct pending_irq) that the
+ * vgic tried to inject in the guest (calling gic_set_guest_irq) but
+ * no LRs were available at the time.
+ * As soon as an LR is freed we remove the first IRQ from this
+ * list and write it to the LR register.
+ * lr_pending is a subset of vgic.inflight_irqs. */
+ struct list_head lr_pending;
spinlock_t lock;
} vgic;
--
1.7.2.5
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 3/5] xen/gic: support injecting IRQs even to VCPUs not currently running
2012-06-06 11:22 ` [PATCH 3/5] xen/gic: support injecting IRQs even to VCPUs not currently running Stefano Stabellini
@ 2012-06-07 12:46 ` Tim Deegan
2012-06-07 15:43 ` Stefano Stabellini
2012-06-26 14:07 ` Ian Campbell
0 siblings, 2 replies; 20+ messages in thread
From: Tim Deegan @ 2012-06-07 12:46 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Ian.Campbell, xen-devel, Tim.Deegan, david.vrabel
At 12:22 +0100 on 06 Jun (1338985328), Stefano Stabellini wrote:
> +static void gic_restore_pending_irqs(struct vcpu *v)
> +{
> + int i;
> + struct pending_irq *p;
> +
> + /* check for new pending irqs */
> + if ( list_empty(&v->arch.vgic.lr_pending) )
> + return;
> +
> + list_for_each_entry ( p, &v->arch.vgic.lr_pending, lr_queue )
> + {
> + i = find_first_zero_bit(&gic.lr_mask, nr_lrs);
> + if ( i < nr_lrs )
> + {
> + gic_set_lr(i, p->irq, GICH_LR_PENDING, p->priority);
> + list_del_init(&p->lr_queue);
> + set_bit(i, &gic.lr_mask);
> + if ( p->irq == VGIC_IRQ_EVTCHN_CALLBACK )
> + set_bit(i, &gic.event_mask);
> + } else
> + {
> + return;
> + }
This is a bit ugly - maybe "if ( i >= nr_lrs ) return" above and don't
indent the block?
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 3/5] xen/gic: support injecting IRQs even to VCPUs not currently running
2012-06-07 12:46 ` Tim Deegan
@ 2012-06-07 15:43 ` Stefano Stabellini
2012-06-26 14:07 ` Ian Campbell
1 sibling, 0 replies; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-07 15:43 UTC (permalink / raw)
To: Tim Deegan
Cc: David Vrabel, Ian Campbell, xen-devel@lists.xensource.com,
Tim Deegan (3P), Stefano Stabellini
On Thu, 7 Jun 2012, Tim Deegan wrote:
> At 12:22 +0100 on 06 Jun (1338985328), Stefano Stabellini wrote:
> > +static void gic_restore_pending_irqs(struct vcpu *v)
> > +{
> > + int i;
> > + struct pending_irq *p;
> > +
> > + /* check for new pending irqs */
> > + if ( list_empty(&v->arch.vgic.lr_pending) )
> > + return;
> > +
> > + list_for_each_entry ( p, &v->arch.vgic.lr_pending, lr_queue )
> > + {
> > + i = find_first_zero_bit(&gic.lr_mask, nr_lrs);
> > + if ( i < nr_lrs )
> > + {
> > + gic_set_lr(i, p->irq, GICH_LR_PENDING, p->priority);
> > + list_del_init(&p->lr_queue);
> > + set_bit(i, &gic.lr_mask);
> > + if ( p->irq == VGIC_IRQ_EVTCHN_CALLBACK )
> > + set_bit(i, &gic.event_mask);
> > + } else
> > + {
> > + return;
> > + }
>
> This is a bit ugly - maybe "if ( i >= nr_lrs ) return" above and don't
> indent the block?
>
good idea
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 3/5] xen/gic: support injecting IRQs even to VCPUs not currently running
2012-06-07 12:46 ` Tim Deegan
2012-06-07 15:43 ` Stefano Stabellini
@ 2012-06-26 14:07 ` Ian Campbell
2012-06-26 17:28 ` Stefano Stabellini
1 sibling, 1 reply; 20+ messages in thread
From: Ian Campbell @ 2012-06-26 14:07 UTC (permalink / raw)
To: Tim Deegan
Cc: David Vrabel, xen-devel@lists.xensource.com, Tim Deegan (3P),
Stefano Stabellini
On Thu, 2012-06-07 at 13:46 +0100, Tim Deegan wrote:
> At 12:22 +0100 on 06 Jun (1338985328), Stefano Stabellini wrote:
> > +static void gic_restore_pending_irqs(struct vcpu *v)
> > +{
> > + int i;
> > + struct pending_irq *p;
> > +
> > + /* check for new pending irqs */
> > + if ( list_empty(&v->arch.vgic.lr_pending) )
> > + return;
> > +
> > + list_for_each_entry ( p, &v->arch.vgic.lr_pending, lr_queue )
Is list_for_each_entry on an empty list somehow wrong/buggy/slow?
> > + {
> > + i = find_first_zero_bit(&gic.lr_mask, nr_lrs);
> > + if ( i < nr_lrs )
> > + {
> > + gic_set_lr(i, p->irq, GICH_LR_PENDING, p->priority);
> > + list_del_init(&p->lr_queue);
> > + set_bit(i, &gic.lr_mask);
> > + if ( p->irq == VGIC_IRQ_EVTCHN_CALLBACK )
> > + set_bit(i, &gic.event_mask);
> > + } else
> > + {
> > + return;
> > + }
>
> This is a bit ugly - maybe "if ( i >= nr_lrs ) return" above and don't
> indent the block?
>
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 3/5] xen/gic: support injecting IRQs even to VCPUs not currently running
2012-06-26 14:07 ` Ian Campbell
@ 2012-06-26 17:28 ` Stefano Stabellini
0 siblings, 0 replies; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-26 17:28 UTC (permalink / raw)
To: Ian Campbell
Cc: David Vrabel, xen-devel@lists.xensource.com, Tim (Xen.org),
Tim Deegan (3P), Stefano Stabellini
On Tue, 26 Jun 2012, Ian Campbell wrote:
> On Thu, 2012-06-07 at 13:46 +0100, Tim Deegan wrote:
> > At 12:22 +0100 on 06 Jun (1338985328), Stefano Stabellini wrote:
> > > +static void gic_restore_pending_irqs(struct vcpu *v)
> > > +{
> > > + int i;
> > > + struct pending_irq *p;
> > > +
> > > + /* check for new pending irqs */
> > > + if ( list_empty(&v->arch.vgic.lr_pending) )
> > > + return;
> > > +
> > > + list_for_each_entry ( p, &v->arch.vgic.lr_pending, lr_queue )
>
> Is list_for_each_entry on an empty list somehow wrong/buggy/slow?
Not at all. I'll change it.
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 4/5] xen/vgic: vgic: support irq enable/disable
2012-06-06 11:22 ` [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer Stefano Stabellini
2012-06-06 11:22 ` [PATCH 2/5] arm/gic: fix gic context switch Stefano Stabellini
2012-06-06 11:22 ` [PATCH 3/5] xen/gic: support injecting IRQs even to VCPUs not currently running Stefano Stabellini
@ 2012-06-06 11:22 ` Stefano Stabellini
2012-06-26 14:05 ` Ian Campbell
2012-06-06 11:22 ` [PATCH 5/5] xen/vgic: initialize pending_irqs.lr_queue Stefano Stabellini
2012-06-26 13:55 ` [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer Ian Campbell
4 siblings, 1 reply; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-06 11:22 UTC (permalink / raw)
To: xen-devel; +Cc: Tim.Deegan, david.vrabel, Ian.Campbell, Stefano Stabellini
If vgic_vcpu_inject_irq is called (for example by a device emulator like
vtimer.c) but the corresponding irq is not enabled in the virtual gicd
just queue it in the inflight_irqs list.
When the irq is enabled make sure to call gic_set_guest_irq.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
xen/arch/arm/vgic.c | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 5a624bd..4cdfec5 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -343,6 +343,22 @@ read_as_zero:
return 1;
}
+static void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
+{
+ struct pending_irq *p;
+ unsigned int irq;
+ int i = 0;
+
+ while ( (i = find_next_bit((const long unsigned int *) &r,
+ sizeof(uint32_t), i)) < sizeof(uint32_t) ) {
+ irq = i + (32 * n);
+ p = irq_to_pending(v, irq);
+ if ( !list_empty(&p->inflight) )
+ gic_set_guest_irq(v, irq, GICH_LR_PENDING, p->priority);
+ i++;
+ }
+}
+
static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
{
struct hsr_dabt dabt = info->dabt;
@@ -351,6 +367,7 @@ static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
struct vgic_irq_rank *rank;
int offset = (int)(info->gpa - VGIC_DISTR_BASE_ADDRESS);
int gicd_reg = REG(offset);
+ uint32_t tr;
switch ( gicd_reg )
{
@@ -378,8 +395,10 @@ static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
rank = vgic_irq_rank(v, 8, gicd_reg - GICD_ISENABLER);
if ( rank == NULL) goto write_ignore;
vgic_lock_rank(v, rank);
+ tr = rank->ienable;
rank->ienable |= *r;
vgic_unlock_rank(v, rank);
+ vgic_enable_irqs(v, (*r) & (~tr), gicd_reg - GICD_ISENABLER);
return 1;
case GICD_ICENABLER ... GICD_ICENABLERN:
@@ -569,7 +588,9 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
else
n->desc = NULL;
- gic_set_guest_irq(v, irq, GICH_LR_PENDING, priority);
+ /* the irq is enabled */
+ if ( rank->ienable & (1 << (irq % 32)) )
+ gic_set_guest_irq(v, irq, GICH_LR_PENDING, priority);
spin_lock_irqsave(&v->arch.vgic.lock, flags);
list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight )
--
1.7.2.5
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 4/5] xen/vgic: vgic: support irq enable/disable
2012-06-06 11:22 ` [PATCH 4/5] xen/vgic: vgic: support irq enable/disable Stefano Stabellini
@ 2012-06-26 14:05 ` Ian Campbell
0 siblings, 0 replies; 20+ messages in thread
From: Ian Campbell @ 2012-06-26 14:05 UTC (permalink / raw)
To: Stefano Stabellini
Cc: xen-devel@lists.xensource.com, David Vrabel, Tim Deegan (3P)
On Wed, 2012-06-06 at 12:22 +0100, Stefano Stabellini wrote:
> If vgic_vcpu_inject_irq is called (for example by a device emulator like
> vtimer.c) but the corresponding irq is not enabled in the virtual gicd
> just queue it in the inflight_irqs list.
> When the irq is enabled make sure to call gic_set_guest_irq.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
I had to go reread the comments on inflight_irqs and lr_pending again
(I'm perpetually confused by that stuff) but I think this makes sense.
Acked-by: Ian Campbell <ian.campbell@citrix.com>
> ---
> xen/arch/arm/vgic.c | 23 ++++++++++++++++++++++-
> 1 files changed, 22 insertions(+), 1 deletions(-)
>
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 5a624bd..4cdfec5 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -343,6 +343,22 @@ read_as_zero:
> return 1;
> }
>
> +static void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
> +{
> + struct pending_irq *p;
> + unsigned int irq;
> + int i = 0;
> +
> + while ( (i = find_next_bit((const long unsigned int *) &r,
> + sizeof(uint32_t), i)) < sizeof(uint32_t) ) {
> + irq = i + (32 * n);
> + p = irq_to_pending(v, irq);
> + if ( !list_empty(&p->inflight) )
> + gic_set_guest_irq(v, irq, GICH_LR_PENDING, p->priority);
> + i++;
what you have here is a for loop ;-)
> + }
> +}
> +
> static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
> {
> struct hsr_dabt dabt = info->dabt;
> @@ -351,6 +367,7 @@ static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
> struct vgic_irq_rank *rank;
> int offset = (int)(info->gpa - VGIC_DISTR_BASE_ADDRESS);
> int gicd_reg = REG(offset);
> + uint32_t tr;
>
> switch ( gicd_reg )
> {
> @@ -378,8 +395,10 @@ static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
> rank = vgic_irq_rank(v, 8, gicd_reg - GICD_ISENABLER);
> if ( rank == NULL) goto write_ignore;
> vgic_lock_rank(v, rank);
> + tr = rank->ienable;
> rank->ienable |= *r;
> vgic_unlock_rank(v, rank);
> + vgic_enable_irqs(v, (*r) & (~tr), gicd_reg - GICD_ISENABLER);
> return 1;
>
> case GICD_ICENABLER ... GICD_ICENABLERN:
> @@ -569,7 +588,9 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
> else
> n->desc = NULL;
>
> - gic_set_guest_irq(v, irq, GICH_LR_PENDING, priority);
> + /* the irq is enabled */
> + if ( rank->ienable & (1 << (irq % 32)) )
> + gic_set_guest_irq(v, irq, GICH_LR_PENDING, priority);
>
> spin_lock_irqsave(&v->arch.vgic.lock, flags);
> list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight )
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 5/5] xen/vgic: initialize pending_irqs.lr_queue
2012-06-06 11:22 ` [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer Stefano Stabellini
` (2 preceding siblings ...)
2012-06-06 11:22 ` [PATCH 4/5] xen/vgic: vgic: support irq enable/disable Stefano Stabellini
@ 2012-06-06 11:22 ` Stefano Stabellini
2012-06-26 14:08 ` Ian Campbell
2012-06-26 13:55 ` [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer Ian Campbell
4 siblings, 1 reply; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-06 11:22 UTC (permalink / raw)
To: xen-devel; +Cc: Tim.Deegan, david.vrabel, Ian.Campbell, Stefano Stabellini
Properly initialize all the pending_irqs.lr_queue like we do for
inflight.
Check whether we already have the irq in lr_queue before adding it.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
xen/arch/arm/gic.c | 6 ++++++
xen/arch/arm/vgic.c | 6 ++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 2e41d75..998033a 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -456,6 +456,12 @@ void gic_set_guest_irq(struct vcpu *v, unsigned int virtual_irq,
}
n = irq_to_pending(v, virtual_irq);
+ if ( !list_empty(&n->lr_queue) )
+ {
+ printk(KERN_WARNING "%s: irq %d already in lr_queue\n", __func__,
+ virtual_irq);
+ goto out;
+ }
list_for_each_entry ( iter, &v->arch.vgic.lr_pending, lr_queue )
{
if ( iter->priority > priority )
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 4cdfec5..653e8e5 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -84,7 +84,10 @@ int domain_vgic_init(struct domain *d)
d->arch.vgic.pending_irqs =
xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
for (i=0; i<d->arch.vgic.nr_lines; i++)
+ {
INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
+ INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].lr_queue);
+ }
for (i=0; i<DOMAIN_NR_RANKS(d); i++)
spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
return 0;
@@ -99,7 +102,10 @@ int vcpu_vgic_init(struct vcpu *v)
memset(&v->arch.vgic.pending_irqs, 0, sizeof(v->arch.vgic.pending_irqs));
for (i = 0; i < 32; i++)
+ {
INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].inflight);
+ INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].lr_queue);
+ }
printk("vcpu_vgic_init irq[0] at %p desc is %p\n",
&v->arch.vgic.pending_irqs[0],
v->arch.vgic.pending_irqs[0].desc);
--
1.7.2.5
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 5/5] xen/vgic: initialize pending_irqs.lr_queue
2012-06-06 11:22 ` [PATCH 5/5] xen/vgic: initialize pending_irqs.lr_queue Stefano Stabellini
@ 2012-06-26 14:08 ` Ian Campbell
2012-06-26 17:53 ` Stefano Stabellini
0 siblings, 1 reply; 20+ messages in thread
From: Ian Campbell @ 2012-06-26 14:08 UTC (permalink / raw)
To: Stefano Stabellini
Cc: xen-devel@lists.xensource.com, David Vrabel, Tim Deegan (3P)
On Wed, 2012-06-06 at 12:22 +0100, Stefano Stabellini wrote:
> Properly initialize all the pending_irqs.lr_queue like we do for
> inflight.
> Check whether we already have the irq in lr_queue before adding it.
Should this be a fatal error? Can a guest make this happen?
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> ---
> xen/arch/arm/gic.c | 6 ++++++
> xen/arch/arm/vgic.c | 6 ++++++
> 2 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 2e41d75..998033a 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -456,6 +456,12 @@ void gic_set_guest_irq(struct vcpu *v, unsigned int virtual_irq,
> }
>
> n = irq_to_pending(v, virtual_irq);
> + if ( !list_empty(&n->lr_queue) )
> + {
> + printk(KERN_WARNING "%s: irq %d already in lr_queue\n", __func__,
> + virtual_irq);
> + goto out;
> + }
> list_for_each_entry ( iter, &v->arch.vgic.lr_pending, lr_queue )
> {
> if ( iter->priority > priority )
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 4cdfec5..653e8e5 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -84,7 +84,10 @@ int domain_vgic_init(struct domain *d)
> d->arch.vgic.pending_irqs =
> xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
> for (i=0; i<d->arch.vgic.nr_lines; i++)
> + {
> INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
> + INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].lr_queue);
> + }
> for (i=0; i<DOMAIN_NR_RANKS(d); i++)
> spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
> return 0;
> @@ -99,7 +102,10 @@ int vcpu_vgic_init(struct vcpu *v)
>
> memset(&v->arch.vgic.pending_irqs, 0, sizeof(v->arch.vgic.pending_irqs));
> for (i = 0; i < 32; i++)
> + {
> INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].inflight);
> + INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].lr_queue);
> + }
> printk("vcpu_vgic_init irq[0] at %p desc is %p\n",
> &v->arch.vgic.pending_irqs[0],
> v->arch.vgic.pending_irqs[0].desc);
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 5/5] xen/vgic: initialize pending_irqs.lr_queue
2012-06-26 14:08 ` Ian Campbell
@ 2012-06-26 17:53 ` Stefano Stabellini
2012-06-27 8:52 ` Ian Campbell
0 siblings, 1 reply; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-26 17:53 UTC (permalink / raw)
To: Ian Campbell
Cc: Tim Deegan (3P), xen-devel@lists.xensource.com, David Vrabel,
Stefano Stabellini
On Tue, 26 Jun 2012, Ian Campbell wrote:
> On Wed, 2012-06-06 at 12:22 +0100, Stefano Stabellini wrote:
> > Properly initialize all the pending_irqs.lr_queue like we do for
> > inflight.
> > Check whether we already have the irq in lr_queue before adding it.
>
> Should this be a fatal error? Can a guest make this happen?
it could happen if the guest keeps enabling and disabling the irqs using
the GICD_ICENABLERn and the GICD_ISENABLERn registers.
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > ---
> > xen/arch/arm/gic.c | 6 ++++++
> > xen/arch/arm/vgic.c | 6 ++++++
> > 2 files changed, 12 insertions(+), 0 deletions(-)
> >
> > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> > index 2e41d75..998033a 100644
> > --- a/xen/arch/arm/gic.c
> > +++ b/xen/arch/arm/gic.c
> > @@ -456,6 +456,12 @@ void gic_set_guest_irq(struct vcpu *v, unsigned int virtual_irq,
> > }
> >
> > n = irq_to_pending(v, virtual_irq);
> > + if ( !list_empty(&n->lr_queue) )
> > + {
> > + printk(KERN_WARNING "%s: irq %d already in lr_queue\n", __func__,
> > + virtual_irq);
> > + goto out;
> > + }
> > list_for_each_entry ( iter, &v->arch.vgic.lr_pending, lr_queue )
> > {
> > if ( iter->priority > priority )
> > diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> > index 4cdfec5..653e8e5 100644
> > --- a/xen/arch/arm/vgic.c
> > +++ b/xen/arch/arm/vgic.c
> > @@ -84,7 +84,10 @@ int domain_vgic_init(struct domain *d)
> > d->arch.vgic.pending_irqs =
> > xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
> > for (i=0; i<d->arch.vgic.nr_lines; i++)
> > + {
> > INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
> > + INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].lr_queue);
> > + }
> > for (i=0; i<DOMAIN_NR_RANKS(d); i++)
> > spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
> > return 0;
> > @@ -99,7 +102,10 @@ int vcpu_vgic_init(struct vcpu *v)
> >
> > memset(&v->arch.vgic.pending_irqs, 0, sizeof(v->arch.vgic.pending_irqs));
> > for (i = 0; i < 32; i++)
> > + {
> > INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].inflight);
> > + INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].lr_queue);
> > + }
> > printk("vcpu_vgic_init irq[0] at %p desc is %p\n",
> > &v->arch.vgic.pending_irqs[0],
> > v->arch.vgic.pending_irqs[0].desc);
>
>
>
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 5/5] xen/vgic: initialize pending_irqs.lr_queue
2012-06-26 17:53 ` Stefano Stabellini
@ 2012-06-27 8:52 ` Ian Campbell
2012-06-27 11:06 ` Stefano Stabellini
0 siblings, 1 reply; 20+ messages in thread
From: Ian Campbell @ 2012-06-27 8:52 UTC (permalink / raw)
To: Stefano Stabellini
Cc: xen-devel@lists.xensource.com, David Vrabel, Tim Deegan (3P)
On Tue, 2012-06-26 at 18:53 +0100, Stefano Stabellini wrote:
> On Tue, 26 Jun 2012, Ian Campbell wrote:
> > On Wed, 2012-06-06 at 12:22 +0100, Stefano Stabellini wrote:
> > > Properly initialize all the pending_irqs.lr_queue like we do for
> > > inflight.
> > > Check whether we already have the irq in lr_queue before adding it.
> >
> > Should this be a fatal error? Can a guest make this happen?
>
> it could happen if the guest keeps enabling and disabling the irqs using
> the GICD_ICENABLERn and the GICD_ISENABLERn registers.
Then the printk is probably wrong. At the least it should be a gdprintk
but really I think it is unnecessary.
>
>
> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > > ---
> > > xen/arch/arm/gic.c | 6 ++++++
> > > xen/arch/arm/vgic.c | 6 ++++++
> > > 2 files changed, 12 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> > > index 2e41d75..998033a 100644
> > > --- a/xen/arch/arm/gic.c
> > > +++ b/xen/arch/arm/gic.c
> > > @@ -456,6 +456,12 @@ void gic_set_guest_irq(struct vcpu *v, unsigned int virtual_irq,
> > > }
> > >
> > > n = irq_to_pending(v, virtual_irq);
> > > + if ( !list_empty(&n->lr_queue) )
> > > + {
> > > + printk(KERN_WARNING "%s: irq %d already in lr_queue\n", __func__,
> > > + virtual_irq);
> > > + goto out;
> > > + }
> > > list_for_each_entry ( iter, &v->arch.vgic.lr_pending, lr_queue )
> > > {
> > > if ( iter->priority > priority )
> > > diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> > > index 4cdfec5..653e8e5 100644
> > > --- a/xen/arch/arm/vgic.c
> > > +++ b/xen/arch/arm/vgic.c
> > > @@ -84,7 +84,10 @@ int domain_vgic_init(struct domain *d)
> > > d->arch.vgic.pending_irqs =
> > > xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
> > > for (i=0; i<d->arch.vgic.nr_lines; i++)
> > > + {
> > > INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
> > > + INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].lr_queue);
> > > + }
> > > for (i=0; i<DOMAIN_NR_RANKS(d); i++)
> > > spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
> > > return 0;
> > > @@ -99,7 +102,10 @@ int vcpu_vgic_init(struct vcpu *v)
> > >
> > > memset(&v->arch.vgic.pending_irqs, 0, sizeof(v->arch.vgic.pending_irqs));
> > > for (i = 0; i < 32; i++)
> > > + {
> > > INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].inflight);
> > > + INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].lr_queue);
> > > + }
> > > printk("vcpu_vgic_init irq[0] at %p desc is %p\n",
> > > &v->arch.vgic.pending_irqs[0],
> > > v->arch.vgic.pending_irqs[0].desc);
> >
> >
> >
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 5/5] xen/vgic: initialize pending_irqs.lr_queue
2012-06-27 8:52 ` Ian Campbell
@ 2012-06-27 11:06 ` Stefano Stabellini
0 siblings, 0 replies; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-27 11:06 UTC (permalink / raw)
To: Ian Campbell
Cc: Tim Deegan (3P), xen-devel@lists.xensource.com, David Vrabel,
Stefano Stabellini
On Wed, 27 Jun 2012, Ian Campbell wrote:
> On Tue, 2012-06-26 at 18:53 +0100, Stefano Stabellini wrote:
> > On Tue, 26 Jun 2012, Ian Campbell wrote:
> > > On Wed, 2012-06-06 at 12:22 +0100, Stefano Stabellini wrote:
> > > > Properly initialize all the pending_irqs.lr_queue like we do for
> > > > inflight.
> > > > Check whether we already have the irq in lr_queue before adding it.
> > >
> > > Should this be a fatal error? Can a guest make this happen?
> >
> > it could happen if the guest keeps enabling and disabling the irqs using
> > the GICD_ICENABLERn and the GICD_ISENABLERn registers.
>
> Then the printk is probably wrong. At the least it should be a gdprintk
> but really I think it is unnecessary.
OK, I'll remove it.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer
2012-06-06 11:22 ` [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer Stefano Stabellini
` (3 preceding siblings ...)
2012-06-06 11:22 ` [PATCH 5/5] xen/vgic: initialize pending_irqs.lr_queue Stefano Stabellini
@ 2012-06-26 13:55 ` Ian Campbell
2012-06-26 17:25 ` Stefano Stabellini
4 siblings, 1 reply; 20+ messages in thread
From: Ian Campbell @ 2012-06-26 13:55 UTC (permalink / raw)
To: Stefano Stabellini
Cc: xen-devel@lists.xensource.com, David Vrabel, Tim Deegan (3P)
On Wed, 2012-06-06 at 12:22 +0100, Stefano Stabellini wrote:
> The guest can read the physical counter but it shouldn't be able to
> cause interrupts of the physical timer to go to the hypervisor.
> Trap physical timer reads/writes in vtimer.c instead.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> ---
> xen/arch/arm/time.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
> index 1587fa2..d5b71d7 100644
> --- a/xen/arch/arm/time.c
> +++ b/xen/arch/arm/time.c
> @@ -160,8 +160,8 @@ void __cpuinit init_timer_interrupt(void)
> WRITE_CP64(0, CNTVOFF); /* No VM-specific offset */
> WRITE_CP32(0, CNTKCTL); /* No user-mode access */
> #if USE_HYP_TIMER
> - /* Let the VMs read the physical counter and timer so they can tell time */
> - WRITE_CP32(CNTHCTL_PA|CNTHCTL_TA, CNTHCTL);
> + /* Do not the VMs program the physical timer, only read the physical counter */
"Do not *let* the VMs..." ?
> + WRITE_CP32(CNTHCTL_PA, CNTHCTL);
> #else
> /* Cannot let VMs access physical counter if we are using it */
> WRITE_CP32(0, CNTHCTL);
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer
2012-06-26 13:55 ` [PATCH 1/5] arm/vtimer: do not let the guest interact with the physical timer Ian Campbell
@ 2012-06-26 17:25 ` Stefano Stabellini
0 siblings, 0 replies; 20+ messages in thread
From: Stefano Stabellini @ 2012-06-26 17:25 UTC (permalink / raw)
To: Ian Campbell
Cc: Tim Deegan (3P), xen-devel@lists.xensource.com, David Vrabel,
Stefano Stabellini
On Tue, 26 Jun 2012, Ian Campbell wrote:
> On Wed, 2012-06-06 at 12:22 +0100, Stefano Stabellini wrote:
> > The guest can read the physical counter but it shouldn't be able to
> > cause interrupts of the physical timer to go to the hypervisor.
> > Trap physical timer reads/writes in vtimer.c instead.
> >
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > ---
> > xen/arch/arm/time.c | 4 ++--
> > 1 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
> > index 1587fa2..d5b71d7 100644
> > --- a/xen/arch/arm/time.c
> > +++ b/xen/arch/arm/time.c
> > @@ -160,8 +160,8 @@ void __cpuinit init_timer_interrupt(void)
> > WRITE_CP64(0, CNTVOFF); /* No VM-specific offset */
> > WRITE_CP32(0, CNTKCTL); /* No user-mode access */
> > #if USE_HYP_TIMER
> > - /* Let the VMs read the physical counter and timer so they can tell time */
> > - WRITE_CP32(CNTHCTL_PA|CNTHCTL_TA, CNTHCTL);
> > + /* Do not the VMs program the physical timer, only read the physical counter */
>
> "Do not *let* the VMs..." ?
right..
^ permalink raw reply [flat|nested] 20+ messages in thread