* [PATCH V2] xen: arm: fix guest register access.
@ 2012-12-19 14:56 Ian Campbell
2012-12-20 11:30 ` Tim Deegan
2013-01-15 11:27 ` Ian Campbell
0 siblings, 2 replies; 7+ messages in thread
From: Ian Campbell @ 2012-12-19 14:56 UTC (permalink / raw)
To: xen-devel; +Cc: tim, stefano.stabellini, Ian Campbell
We weren't taking the guest mode (CPSR) into account and would always
access the user version of the registers.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
v2: Fix r8 vs r8_fiq thinko.
---
xen/arch/arm/traps.c | 62 ++++++++++++++++++++++++++++++++++++++++++-
xen/arch/arm/vgic.c | 4 +-
xen/arch/arm/vpl011.c | 4 +-
xen/arch/arm/vtimer.c | 7 +++--
xen/include/asm-arm/regs.h | 6 ++++
5 files changed, 74 insertions(+), 9 deletions(-)
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index bddd7d4..f42e4e9 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -73,6 +73,64 @@ static void print_xen_info(void)
debug, print_tainted(taint_str));
}
+uint32_t *select_user_reg(struct cpu_user_regs *regs, int reg)
+{
+ BUG_ON( guest_mode(regs) );
+
+ /*
+ * We rely heavily on the layout of cpu_user_regs to avoid having
+ * to handle all of the registers individually. Use BUILD_BUG_ON to
+ * ensure that things which expect are contiguous actually are.
+ */
+#define REGOFFS(R) offsetof(struct cpu_user_regs, R)
+
+ switch ( reg ) {
+ case 0 ... 7: /* Unbanked registers */
+ BUILD_BUG_ON(REGOFFS(r0) + 7*sizeof(uint32_t) != REGOFFS(r7));
+ return ®s->r0 + reg;
+ case 8 ... 12: /* Register banked in FIQ mode */
+ BUILD_BUG_ON(REGOFFS(r8_fiq) + 4*sizeof(uint32_t) != REGOFFS(r12_fiq));
+ if ( fiq_mode(regs) )
+ return ®s->r8_fiq + reg - 8;
+ else
+ return ®s->r8 + reg - 8;
+ case 13 ... 14: /* Banked SP + LR registers */
+ BUILD_BUG_ON(REGOFFS(sp_fiq) + 1*sizeof(uint32_t) != REGOFFS(lr_fiq));
+ BUILD_BUG_ON(REGOFFS(sp_irq) + 1*sizeof(uint32_t) != REGOFFS(lr_irq));
+ BUILD_BUG_ON(REGOFFS(sp_svc) + 1*sizeof(uint32_t) != REGOFFS(lr_svc));
+ BUILD_BUG_ON(REGOFFS(sp_abt) + 1*sizeof(uint32_t) != REGOFFS(lr_abt));
+ BUILD_BUG_ON(REGOFFS(sp_und) + 1*sizeof(uint32_t) != REGOFFS(lr_und));
+ switch ( regs->cpsr & PSR_MODE_MASK )
+ {
+ case PSR_MODE_USR:
+ case PSR_MODE_SYS: /* Sys regs are the usr regs */
+ if ( reg == 13 )
+ return ®s->sp_usr;
+ else /* lr_usr == lr in a user frame */
+ return ®s->lr;
+ case PSR_MODE_FIQ:
+ return ®s->sp_fiq + reg - 13;
+ case PSR_MODE_IRQ:
+ return ®s->sp_irq + reg - 13;
+ case PSR_MODE_SVC:
+ return ®s->sp_svc + reg - 13;
+ case PSR_MODE_ABT:
+ return ®s->sp_abt + reg - 13;
+ case PSR_MODE_UND:
+ return ®s->sp_und + reg - 13;
+ case PSR_MODE_MON:
+ case PSR_MODE_HYP:
+ default:
+ BUG();
+ }
+ case 15: /* PC */
+ return ®s->pc;
+ default:
+ BUG();
+ }
+#undef REGOFFS
+}
+
static const char *decode_fsc(uint32_t fsc, int *level)
{
const char *msg = NULL;
@@ -448,7 +506,7 @@ static void do_debug_trap(struct cpu_user_regs *regs, unsigned int code)
switch ( code ) {
case 0xe0 ... 0xef:
reg = code - 0xe0;
- r = ®s->r0 + reg;
+ r = select_user_reg(regs, reg);
printk("DOM%d: R%d = %#010"PRIx32" at %#010"PRIx32"\n",
domid, reg, *r, regs->pc);
break;
@@ -518,7 +576,7 @@ static void do_cp15_32(struct cpu_user_regs *regs,
union hsr hsr)
{
struct hsr_cp32 cp32 = hsr.cp32;
- uint32_t *r = ®s->r0 + cp32.reg;
+ uint32_t *r = select_user_reg(regs, cp32.reg);
if ( !cp32.ccvalid ) {
dprintk(XENLOG_ERR, "cp_15(32): need to handle invalid condition codes\n");
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 7d1a5ad..39b9775 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -160,7 +160,7 @@ static int vgic_distr_mmio_read(struct vcpu *v, mmio_info_t *info)
{
struct hsr_dabt dabt = info->dabt;
struct cpu_user_regs *regs = guest_cpu_user_regs();
- uint32_t *r = ®s->r0 + dabt.reg;
+ uint32_t *r = select_user_reg(regs, dabt.reg);
struct vgic_irq_rank *rank;
int offset = (int)(info->gpa - VGIC_DISTR_BASE_ADDRESS);
int gicd_reg = REG(offset);
@@ -372,7 +372,7 @@ static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
{
struct hsr_dabt dabt = info->dabt;
struct cpu_user_regs *regs = guest_cpu_user_regs();
- uint32_t *r = ®s->r0 + dabt.reg;
+ uint32_t *r = select_user_reg(regs, dabt.reg);
struct vgic_irq_rank *rank;
int offset = (int)(info->gpa - VGIC_DISTR_BASE_ADDRESS);
int gicd_reg = REG(offset);
diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
index 1522667..7dcee90 100644
--- a/xen/arch/arm/vpl011.c
+++ b/xen/arch/arm/vpl011.c
@@ -92,7 +92,7 @@ static int uart0_mmio_read(struct vcpu *v, mmio_info_t *info)
{
struct hsr_dabt dabt = info->dabt;
struct cpu_user_regs *regs = guest_cpu_user_regs();
- uint32_t *r = ®s->r0 + dabt.reg;
+ uint32_t *r = select_user_reg(regs, dabt.reg);
int offset = (int)(info->gpa - UART0_START);
switch ( offset )
@@ -114,7 +114,7 @@ static int uart0_mmio_write(struct vcpu *v, mmio_info_t *info)
{
struct hsr_dabt dabt = info->dabt;
struct cpu_user_regs *regs = guest_cpu_user_regs();
- uint32_t *r = ®s->r0 + dabt.reg;
+ uint32_t *r = select_user_reg(regs, dabt.reg);
int offset = (int)(info->gpa - UART0_START);
switch ( offset )
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index 1c45f4a..fc452e3 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -22,6 +22,7 @@
#include <xen/timer.h>
#include <xen/sched.h>
#include <asm/gic.h>
+#include <asm/regs.h>
extern s_time_t ticks_to_ns(uint64_t ticks);
extern uint64_t ns_to_ticks(s_time_t ns);
@@ -49,7 +50,7 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr)
{
struct vcpu *v = current;
struct hsr_cp32 cp32 = hsr.cp32;
- uint32_t *r = ®s->r0 + cp32.reg;
+ uint32_t *r = select_user_reg(regs, cp32.reg);
s_time_t now;
switch ( hsr.bits & HSR_CP32_REGS_MASK )
@@ -101,8 +102,8 @@ static int vtimer_emulate_64(struct cpu_user_regs *regs, union hsr hsr)
{
struct vcpu *v = current;
struct hsr_cp64 cp64 = hsr.cp64;
- uint32_t *r1 = ®s->r0 + cp64.reg1;
- uint32_t *r2 = ®s->r0 + cp64.reg2;
+ uint32_t *r1 = select_user_reg(regs, cp64.reg1);
+ uint32_t *r2 = select_user_reg(regs, cp64.reg2);
uint64_t ticks;
s_time_t now;
diff --git a/xen/include/asm-arm/regs.h b/xen/include/asm-arm/regs.h
index 54f6ed8..7486944 100644
--- a/xen/include/asm-arm/regs.h
+++ b/xen/include/asm-arm/regs.h
@@ -30,6 +30,12 @@
#define return_reg(v) ((v)->arch.cpu_info->guest_cpu_user_regs.r0)
+/*
+ * Returns a pointer to the given register value in regs, taking the
+ * processor mode (CPSR) into account.
+ */
+extern uint32_t *select_user_reg(struct cpu_user_regs *regs, int reg);
+
#endif /* __ARM_REGS_H__ */
/*
* Local variables:
--
1.7.2.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH V2] xen: arm: fix guest register access.
2012-12-19 14:56 [PATCH V2] xen: arm: fix guest register access Ian Campbell
@ 2012-12-20 11:30 ` Tim Deegan
2012-12-20 11:53 ` Ian Campbell
2013-01-04 15:59 ` Ian Campbell
2013-01-15 11:27 ` Ian Campbell
1 sibling, 2 replies; 7+ messages in thread
From: Tim Deegan @ 2012-12-20 11:30 UTC (permalink / raw)
To: Ian Campbell; +Cc: stefano.stabellini, xen-devel
At 14:56 +0000 on 19 Dec (1355929001), Ian Campbell wrote:
> We weren't taking the guest mode (CPSR) into account and would always
> access the user version of the registers.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH V2] xen: arm: fix guest register access.
2012-12-20 11:30 ` Tim Deegan
@ 2012-12-20 11:53 ` Ian Campbell
2013-01-04 15:59 ` Ian Campbell
1 sibling, 0 replies; 7+ messages in thread
From: Ian Campbell @ 2012-12-20 11:53 UTC (permalink / raw)
To: Tim Deegan; +Cc: Stefano Stabellini, xen-devel@lists.xen.org
On Thu, 2012-12-20 at 11:30 +0000, Tim Deegan wrote:
> At 14:56 +0000 on 19 Dec (1355929001), Ian Campbell wrote:
> > We weren't taking the guest mode (CPSR) into account and would always
> > access the user version of the registers.
> >
> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
>
> Acked-by: Tim Deegan <tim@xen.org>
Applied, thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH V2] xen: arm: fix guest register access.
2012-12-20 11:30 ` Tim Deegan
2012-12-20 11:53 ` Ian Campbell
@ 2013-01-04 15:59 ` Ian Campbell
1 sibling, 0 replies; 7+ messages in thread
From: Ian Campbell @ 2013-01-04 15:59 UTC (permalink / raw)
To: Tim Deegan; +Cc: Stefano Stabellini, xen-devel@lists.xen.org
On Thu, 2012-12-20 at 11:30 +0000, Tim Deegan wrote:
> At 14:56 +0000 on 19 Dec (1355929001), Ian Campbell wrote:
> > We weren't taking the guest mode (CPSR) into account and would always
> > access the user version of the registers.
> >
> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
>
> Acked-by: Tim Deegan <tim@xen.org>
Thanks.
I applied this last year and forgot to push. Now done.
Ian.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH V2] xen: arm: fix guest register access.
2012-12-19 14:56 [PATCH V2] xen: arm: fix guest register access Ian Campbell
2012-12-20 11:30 ` Tim Deegan
@ 2013-01-15 11:27 ` Ian Campbell
2013-01-15 11:54 ` Stefano Stabellini
1 sibling, 1 reply; 7+ messages in thread
From: Ian Campbell @ 2013-01-15 11:27 UTC (permalink / raw)
To: xen-devel@lists.xen.org; +Cc: Tim (Xen.org), Stefano Stabellini
On Wed, 2012-12-19 at 14:56 +0000, Ian Campbell wrote:
> @@ -73,6 +73,64 @@ static void print_xen_info(void)
> debug, print_tainted(taint_str));
> }
>
> +uint32_t *select_user_reg(struct cpu_user_regs *regs, int reg)
> +{
> + BUG_ON( guest_mode(regs) );
I was obviously on crack here.
8<--------------------------
>From a53486a9aa6c0bd9512ac5e213119c6bda27e3b6 Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@citrix.com>
Date: Tue, 15 Jan 2013 11:25:05 +0000
Subject: [PATCH] xen: arm: fix assert in select_user_reg
The condition was inverted.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
xen/arch/arm/traps.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index f42e4e9..8afcf0c 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -75,7 +75,7 @@ static void print_xen_info(void)
uint32_t *select_user_reg(struct cpu_user_regs *regs, int reg)
{
- BUG_ON( guest_mode(regs) );
+ BUG_ON( !guest_mode(regs) );
/*
* We rely heavily on the layout of cpu_user_regs to avoid having
--
1.7.2.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH V2] xen: arm: fix guest register access.
2013-01-15 11:27 ` Ian Campbell
@ 2013-01-15 11:54 ` Stefano Stabellini
2013-01-17 16:48 ` Ian Campbell
0 siblings, 1 reply; 7+ messages in thread
From: Stefano Stabellini @ 2013-01-15 11:54 UTC (permalink / raw)
To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), xen-devel@lists.xen.org
On Tue, 15 Jan 2013, Ian Campbell wrote:
> On Wed, 2012-12-19 at 14:56 +0000, Ian Campbell wrote:
> > @@ -73,6 +73,64 @@ static void print_xen_info(void)
> > debug, print_tainted(taint_str));
> > }
> >
> > +uint32_t *select_user_reg(struct cpu_user_regs *regs, int reg)
> > +{
> > + BUG_ON( guest_mode(regs) );
>
> I was obviously on crack here.
>
> 8<--------------------------
>
> From a53486a9aa6c0bd9512ac5e213119c6bda27e3b6 Mon Sep 17 00:00:00 2001
> From: Ian Campbell <ian.campbell@citrix.com>
> Date: Tue, 15 Jan 2013 11:25:05 +0000
> Subject: [PATCH] xen: arm: fix assert in select_user_reg
>
> The condition was inverted.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> xen/arch/arm/traps.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index f42e4e9..8afcf0c 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -75,7 +75,7 @@ static void print_xen_info(void)
>
> uint32_t *select_user_reg(struct cpu_user_regs *regs, int reg)
> {
> - BUG_ON( guest_mode(regs) );
> + BUG_ON( !guest_mode(regs) );
>
> /*
> * We rely heavily on the layout of cpu_user_regs to avoid having
> --
> 1.7.2.5
>
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH V2] xen: arm: fix guest register access.
2013-01-15 11:54 ` Stefano Stabellini
@ 2013-01-17 16:48 ` Ian Campbell
0 siblings, 0 replies; 7+ messages in thread
From: Ian Campbell @ 2013-01-17 16:48 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Tim (Xen.org), xen-devel@lists.xen.org
> > From a53486a9aa6c0bd9512ac5e213119c6bda27e3b6 Mon Sep 17 00:00:00 2001
> > From: Ian Campbell <ian.campbell@citrix.com>
> > Date: Tue, 15 Jan 2013 11:25:05 +0000
> > Subject: [PATCH] xen: arm: fix assert in select_user_reg
> >
> > The condition was inverted.
> >
> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
>
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Thanks, applied.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-01-17 16:48 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-19 14:56 [PATCH V2] xen: arm: fix guest register access Ian Campbell
2012-12-20 11:30 ` Tim Deegan
2012-12-20 11:53 ` Ian Campbell
2013-01-04 15:59 ` Ian Campbell
2013-01-15 11:27 ` Ian Campbell
2013-01-15 11:54 ` Stefano Stabellini
2013-01-17 16:48 ` Ian Campbell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).