All of lore.kernel.org
 help / color / mirror / Atom feed
From: vijay.kilari@gmail.com
To: Ian.Campbell@citrix.com, julien.grall@linaro.org,
	stefano.stabellini@eu.citrix.com, stefano.stabellini@citrix.com,
	tim@xen.org, xen-devel@lists.xen.org
Cc: Prasun.Kapoor@caviumnetworks.com,
	Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>,
	manish.jaggi@caviumnetworks.com, vijay.kilari@gmail.com
Subject: [PATCH for-4.5 v11 6/7] xen/arm: add SGI handling for GICv3
Date: Fri, 12 Sep 2014 16:39:48 +0530	[thread overview]
Message-ID: <1410520189-9086-7-git-send-email-vijay.kilari@gmail.com> (raw)
In-Reply-To: <1410520189-9086-1-git-send-email-vijay.kilari@gmail.com>

From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>

In ARMv8, write to ICC_SGI1R_EL1 register raises trap to EL2.
Handle the trap and inject SGI to vcpu.

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c              |   15 +++++++++++
 xen/arch/arm/vgic-v3.c            |   54 +++++++++++++++++++++++++++++++++++++
 xen/arch/arm/vgic.c               |    9 +++++++
 xen/include/asm-arm/gic_v3_defs.h |    7 +++++
 xen/include/asm-arm/sysregs.h     |    3 +++
 xen/include/asm-arm/vgic.h        |    3 +++
 6 files changed, 91 insertions(+)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 019991f..25fa8a0 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -41,6 +41,7 @@
 #include "decode.h"
 #include "vtimer.h"
 #include <asm/gic.h>
+#include <asm/vgic.h>
 
 /* The base of the stack must always be double-word aligned, which means
  * that both the kernel half of struct cpu_user_regs (which is pushed in
@@ -1743,6 +1744,20 @@ static void do_sysreg(struct cpu_user_regs *regs,
             domain_crash_synchronous();
         }
         break;
+    case HSR_SYSREG_ICC_SGI1R_EL1:
+        if ( !vgic_emulate(regs, hsr) )
+        {
+            dprintk(XENLOG_WARNING,
+                    "failed emulation of sysreg ICC_SGI1R_EL1 access\n");
+            inject_undef64_exception(regs, hsr.len);
+        }
+        break;
+    case HSR_SYSREG_ICC_SGI0R_EL1:
+    case HSR_SYSREG_ICC_ASGI1R_EL1:
+        /* TBD: Implement to support secure grp0/1 SGI forwarding */
+        dprintk(XENLOG_WARNING,
+                "Emulation of sysreg ICC_SGI0R_EL1/ASGI1R_EL1 not supported\n");
+        inject_undef64_exception(regs, hsr.len);
     default:
  bad_sysreg:
         {
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 71299f4..c65a56a 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -871,6 +871,59 @@ write_ignore_64:
     return 1;
 }
 
+static int vgic_v3_to_sgi(struct vcpu *v, register_t sgir)
+{
+    int virq;
+    int irqmode;
+    enum gic_sgi_mode sgi_mode;
+    unsigned long vcpu_mask = 0;
+
+    irqmode = (sgir >> ICH_SGI_IRQMODE_SHIFT) & ICH_SGI_IRQMODE_MASK;
+    virq = (sgir >> ICH_SGI_IRQ_SHIFT ) & ICH_SGI_IRQ_MASK;
+    /* SGI's are injected at Rdist level 0. ignoring affinity 1, 2, 3 */
+    vcpu_mask = sgir & ICH_SGI_TARGETLIST_MASK;
+
+    /* Map GIC sgi value to enum value */
+    switch ( irqmode )
+    {
+    case ICH_SGI_TARGET_LIST:
+        sgi_mode = SGI_TARGET_LIST;
+        break;
+    case ICH_SGI_TARGET_OTHERS:
+        sgi_mode = SGI_TARGET_OTHERS;
+        break;
+    default:
+        gdprintk(XENLOG_WARNING, "Wrong irq mode in SGI1R_EL1 register\n");
+        return 0;
+    }
+
+    return vgic_to_sgi(v, sgir, sgi_mode, virq, vcpu_mask);
+}
+
+static int vgic_v3_emulate_sysreg(struct cpu_user_regs *regs, union hsr hsr)
+{
+    struct vcpu *v = current;
+    struct hsr_sysreg sysreg = hsr.sysreg;
+    register_t *r = select_user_reg(regs, sysreg.reg);
+
+    ASSERT (hsr.ec == HSR_EC_SYSREG);
+
+    switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
+    {
+    case HSR_SYSREG_ICC_SGI1R_EL1:
+        /* WO */
+        if ( !sysreg.read )
+            return vgic_v3_to_sgi(v, *r);
+        else
+        {
+            gdprintk(XENLOG_WARNING, "Reading SGI1R_EL1 - WO register\n");
+            return 0;
+        }
+    default:
+        return 0;
+    }
+}
+
 static const struct mmio_handler_ops vgic_rdistr_mmio_handler = {
     .read_handler  = vgic_v3_rdistr_mmio_read,
     .write_handler = vgic_v3_rdistr_mmio_write,
@@ -934,6 +987,7 @@ static const struct vgic_ops v3_ops = {
     .domain_init = vgic_v3_domain_init,
     .get_irq_priority = vgic_v3_get_irq_priority,
     .get_target_vcpu  = vgic_v3_get_target_vcpu,
+    .emulate_sysreg  = vgic_v3_emulate_sysreg,
 };
 
 int vgic_v3_init(struct domain *d)
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 4f392b5..0c9bca5 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -435,6 +435,15 @@ void arch_evtchn_inject(struct vcpu *v)
     vgic_vcpu_inject_irq(v, v->domain->arch.evtchn_irq);
 }
 
+int vgic_emulate(struct cpu_user_regs *regs, union hsr hsr)
+{
+    struct vcpu *v = current;
+ 
+    ASSERT(v->domain->arch.vgic.handler->emulate_sysreg != NULL);
+
+    return v->domain->arch.vgic.handler->emulate_sysreg(regs, hsr);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/asm-arm/gic_v3_defs.h b/xen/include/asm-arm/gic_v3_defs.h
index 6c8ff26..13adb53 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -142,6 +142,13 @@
 #define GICH_VMCR_PRIORITY_MASK      0xff
 #define GICH_VMCR_PRIORITY_SHIFT     24
 
+#define ICH_SGI_IRQMODE_SHIFT        40
+#define ICH_SGI_IRQMODE_MASK         0x1
+#define ICH_SGI_TARGET_OTHERS        1
+#define ICH_SGI_TARGET_LIST          0
+#define ICH_SGI_IRQ_SHIFT            24
+#define ICH_SGI_IRQ_MASK             0xf
+#define ICH_SGI_TARGETLIST_MASK      0xffff
 #endif /* __ASM_ARM_GIC_V3_DEFS_H__ */
 
 /*
diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h
index b4616ac..169b7ac 100644
--- a/xen/include/asm-arm/sysregs.h
+++ b/xen/include/asm-arm/sysregs.h
@@ -78,6 +78,9 @@
 #define HSR_SYSREG_PMINTENCLR_EL1 HSR_SYSREG(3,0,c9,c14,2)
 #define HSR_SYSREG_MAIR_EL1       HSR_SYSREG(3,0,c10,c2,0)
 #define HSR_SYSREG_AMAIR_EL1      HSR_SYSREG(3,0,c10,c3,0)
+#define HSR_SYSREG_ICC_SGI1R_EL1  HSR_SYSREG(3,0,c12,c11,5)
+#define HSR_SYSREG_ICC_ASGI1R_EL1 HSR_SYSREG(3,1,c12,c11,6)
+#define HSR_SYSREG_ICC_SGI0R_EL1  HSR_SYSREG(3,2,c12,c11,7)
 #define HSR_SYSREG_CONTEXTIDR_EL1 HSR_SYSREG(3,0,c13,c0,1)
 
 #define HSR_SYSREG_PMCR_EL0       HSR_SYSREG(3,3,c9,c12,0)
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 632d528..5160f17 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -108,6 +108,8 @@ struct vgic_ops {
     /* Get the target vcpu for a given virq. The rank lock is already taken
      * when calling this. */
     struct vcpu *(*get_target_vcpu)(struct vcpu *v, unsigned int irq);
+    /* vGIC sysreg emulation */
+    int (*emulate_sysreg)(struct cpu_user_regs *regs, union hsr hsr);
 };
 
 /* Number of ranks of interrupt registers for a domain */
@@ -183,6 +185,7 @@ extern void vgic_clear_pending_irqs(struct vcpu *v);
 extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq);
 extern struct vgic_irq_rank *vgic_rank_offset(struct vcpu *v, int b, int n, int s);
 extern struct vgic_irq_rank *vgic_rank_irq(struct vcpu *v, unsigned int irq);
+extern int vgic_emulate(struct cpu_user_regs *regs, union hsr hsr);
 extern void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n);
 extern void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n);
 extern void register_vgic_ops(struct domain *d, const struct vgic_ops *ops);
-- 
1.7.9.5

  parent reply	other threads:[~2014-09-12 11:09 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-12 11:09 [PATCH for-4.5 v11 0/7] xen/arm: Add GICv3 support vijay.kilari
2014-09-12 11:09 ` [PATCH for-4.5 v11 1/7] xen/arm: Calculate irq rank from irq number vijay.kilari
2014-09-12 11:09 ` [PATCH for-4.5 v11 2/7] xen/arm: Add vgic callback to read irq priority vijay.kilari
2014-09-12 18:08   ` Stefano Stabellini
2014-09-15  6:15     ` Vijay Kilari
2014-09-15 19:05       ` Stefano Stabellini
2014-09-15 22:09         ` Ian Campbell
2014-09-16  6:49         ` Vijay Kilari
2014-09-23 13:01           ` Stefano Stabellini
2014-09-23 13:09             ` Vijay Kilari
2014-09-12 11:09 ` [PATCH for-4.5 v11 3/7] xen/arm: Add support for GIC v3 vijay.kilari
2014-09-12 11:09 ` [PATCH for-4.5 v11 4/7] xen/arm: Add virtual GICv3 support vijay.kilari
2014-09-12 18:15   ` Stefano Stabellini
2014-09-12 11:09 ` [PATCH for-4.5 v11 5/7] xen/arm: Update Dom0 GIC dt node with GICv3 information vijay.kilari
2014-09-12 11:09 ` vijay.kilari [this message]
2014-09-12 11:09 ` [PATCH for-4.5 v11 7/7] xen/arm: check for GICv3 platform support vijay.kilari

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=1410520189-9086-7-git-send-email-vijay.kilari@gmail.com \
    --to=vijay.kilari@gmail.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=Prasun.Kapoor@caviumnetworks.com \
    --cc=Vijaya.Kumar@caviumnetworks.com \
    --cc=julien.grall@linaro.org \
    --cc=manish.jaggi@caviumnetworks.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.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.