[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH V2 18/40] arm: context switch a bunch of guest state.



I haven't investigated what if any of this could be done lazily.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 xen/arch/arm/domain.c         |  122 +++++++++++++++++++++++++++++++++++++++--
 xen/arch/arm/gic.c            |   25 ++++++++-
 xen/arch/arm/gic.h            |    9 ++-
 xen/include/asm-arm/cpregs.h  |   29 +++++++++-
 xen/include/asm-arm/domain.h  |   33 ++++++++++-
 xen/include/public/arch-arm.h |    3 +
 6 files changed, 208 insertions(+), 13 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 931261b..d11be78 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -36,12 +36,124 @@ void idle_loop(void)
 
 static void ctxt_switch_from(struct vcpu *p)
 {
+    /* CP 15 */
+    p->arch.csselr = READ_CP32(CSSELR);
+
+    /* Control Registers */
+    p->arch.actlr = READ_CP32(ACTLR);
+    p->arch.sctlr = READ_CP32(SCTLR);
+    p->arch.cpacr = READ_CP32(CPACR);
+
+    p->arch.contextidr = READ_CP32(CONTEXTIDR);
+    p->arch.tpidrurw = READ_CP32(TPIDRURW);
+    p->arch.tpidruro = READ_CP32(TPIDRURO);
+    p->arch.tpidrprw = READ_CP32(TPIDRPRW);
+
+    /* XXX only save these if ThumbEE e.g. ID_PFR0.THUMB_EE_SUPPORT */
+    p->arch.teecr = READ_CP32(TEECR);
+    p->arch.teehbr = READ_CP32(TEEHBR);
+
+    p->arch.joscr = READ_CP32(JOSCR);
+    p->arch.jmcr = READ_CP32(JMCR);
+
+    isb();
+
+    /* MMU */
+    p->arch.vbar = READ_CP32(VBAR);
+    p->arch.ttbcr = READ_CP32(TTBCR);
+    /* XXX save 64 bit TTBR if guest is LPAE */
+    p->arch.ttbr0 = READ_CP32(TTBR0);
+    p->arch.ttbr1 = READ_CP32(TTBR1);
+
+    p->arch.dacr = READ_CP32(DACR);
+    p->arch.par = READ_CP64(PAR);
+    p->arch.mair0 = READ_CP32(MAIR0);
+    p->arch.mair1 = READ_CP32(MAIR1);
+
+    /* Fault Status */
+    p->arch.dfar = READ_CP32(DFAR);
+    p->arch.ifar = READ_CP32(IFAR);
+    p->arch.dfsr = READ_CP32(DFSR);
+    p->arch.ifsr = READ_CP32(IFSR);
+    p->arch.adfsr = READ_CP32(ADFSR);
+    p->arch.aifsr = READ_CP32(AIFSR);
+
+    /* XXX MPU */
+
+    /* XXX VFP */
+
+    /* XXX VGIC */
+    gic_save_state(p);
+
+    isb();
     context_saved(p);
 }
 
 static void ctxt_switch_to(struct vcpu *n)
 {
+    uint32_t hcr;
+
+    hcr = READ_CP32(HCR);
+    WRITE_CP32(hcr & ~HCR_VM, HCR);
+    isb();
+
     p2m_load_VTTBR(n->domain);
+    isb();
+
+    /* XXX VGIC */
+    gic_restore_state(n);
+
+    /* XXX VFP */
+
+    /* XXX MPU */
+
+    /* Fault Status */
+    WRITE_CP32(n->arch.dfar, DFAR);
+    WRITE_CP32(n->arch.ifar, IFAR);
+    WRITE_CP32(n->arch.dfsr, DFSR);
+    WRITE_CP32(n->arch.ifsr, IFSR);
+    WRITE_CP32(n->arch.adfsr, ADFSR);
+    WRITE_CP32(n->arch.aifsr, AIFSR);
+
+    /* MMU */
+    WRITE_CP32(n->arch.vbar, VBAR);
+    WRITE_CP32(n->arch.ttbcr, TTBCR);
+    /* XXX restore 64 bit TTBR if guest is LPAE */
+    WRITE_CP32(n->arch.ttbr0, TTBR0);
+    WRITE_CP32(n->arch.ttbr1, TTBR1);
+
+    WRITE_CP32(n->arch.dacr, DACR);
+    WRITE_CP64(n->arch.par, PAR);
+    WRITE_CP32(n->arch.mair0, MAIR0);
+    WRITE_CP32(n->arch.mair1, MAIR1);
+    isb();
+
+    /* Control Registers */
+    WRITE_CP32(n->arch.actlr, ACTLR);
+    WRITE_CP32(n->arch.sctlr, SCTLR);
+    WRITE_CP32(n->arch.cpacr, CPACR);
+
+    WRITE_CP32(n->arch.contextidr, CONTEXTIDR);
+    WRITE_CP32(n->arch.tpidrurw, TPIDRURW);
+    WRITE_CP32(n->arch.tpidruro, TPIDRURO);
+    WRITE_CP32(n->arch.tpidrprw, TPIDRPRW);
+
+    /* XXX only restore these if ThumbEE e.g. ID_PFR0.THUMB_EE_SUPPORT */
+    WRITE_CP32(n->arch.teecr, TEECR);
+    WRITE_CP32(n->arch.teehbr, TEEHBR);
+
+    WRITE_CP32(n->arch.joscr, JOSCR);
+    WRITE_CP32(n->arch.jmcr, JMCR);
+
+    isb();
+
+    /* CP 15 */
+    WRITE_CP32(n->arch.csselr, CSSELR);
+
+    isb();
+
+    WRITE_CP32(hcr, HCR);
+    isb();
 }
 
 static void schedule_tail(struct vcpu *prev)
@@ -258,6 +370,7 @@ static int is_guest_psr(uint32_t psr)
 int arch_set_info_guest(
     struct vcpu *v, vcpu_guest_context_u c)
 {
+    struct vcpu_guest_context *ctxt = c.nat;
     struct cpu_user_regs *regs = &c.nat->user_regs;
 
     if ( !is_guest_psr(regs->cpsr) )
@@ -276,11 +389,10 @@ int arch_set_info_guest(
 
     v->arch.cpu_info->guest_cpu_user_regs = *regs;
 
-    /* XXX other state:
-     * - SCTLR
-     * - TTBR0/1
-     * - TTBCR
-     */
+    v->arch.sctlr = ctxt->sctlr;
+    v->arch.ttbr0 = ctxt->ttbr0;
+    v->arch.ttbr1 = ctxt->ttbr1;
+    v->arch.ttbcr = ctxt->ttbcr;
 
     clear_bit(_VPF_down, &v->pause_flags);
 
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 1a2b95f..339c327 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -61,6 +61,30 @@ static struct {
 irq_desc_t irq_desc[NR_IRQS];
 unsigned nr_lrs;
 
+void gic_save_state(struct vcpu *v)
+{
+    int i;
+
+    for ( i=0; i<nr_lrs; i++)
+        v->arch.gic_lr[i] = GICH[GICH_LR + i];
+    /* Disable until next VCPU scheduled */
+    GICH[GICH_HCR] = 0;
+    isb();
+}
+
+void gic_restore_state(struct vcpu *v)
+{
+    int i;
+
+    if ( is_idle_vcpu(v) )
+        return;
+
+    for ( i=0; i<nr_lrs; i++)
+        GICH[GICH_LR + i] = v->arch.gic_lr[i];
+    GICH[GICH_HCR] = GICH_HCR_EN;
+    isb();
+}
+
 static unsigned int gic_irq_startup(struct irq_desc *desc)
 {
     uint32_t enabler;
@@ -263,7 +287,6 @@ static void __cpuinit gic_hyp_init(void)
     vtr = GICH[GICH_VTR];
     nr_lrs  = (vtr & GICH_VTR_NRLRGS) + 1;
 
-    GICH[GICH_HCR] = GICH_HCR_EN;
     GICH[GICH_MISR] = GICH_MISR_EOI;
 }
 
diff --git a/xen/arch/arm/gic.h b/xen/arch/arm/gic.h
index ff8d0a2..ac9cf3a 100644
--- a/xen/arch/arm/gic.h
+++ b/xen/arch/arm/gic.h
@@ -70,8 +70,8 @@
 #define GICH_MISR       (0x10/4)
 #define GICH_EISR0      (0x20/4)
 #define GICH_EISR1      (0x24/4)
-#define GICH_ELRSR0     (0x30/4)
-#define GICH_ELRSR1     (0x34/4)
+#define GICH_ELSR0      (0x30/4)
+#define GICH_ELSR1      (0x34/4)
 #define GICH_APR        (0xF0/4)
 #define GICH_LR         (0x100/4)
 
@@ -149,6 +149,11 @@ extern void gic_init_secondary_cpu(void);
 extern void gic_disable_cpu(void);
 /* setup the gic virtual interface for a guest */
 extern void gicv_setup(struct domain *d);
+
+/* Context switch */
+extern void gic_save_state(struct vcpu *v);
+extern void gic_restore_state(struct vcpu *v);
+
 #endif
 
 /*
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index 7a0b49a..bd46942 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -88,6 +88,19 @@
  * arguments, which are cp,opc1,crn,crm,opc2.
  */
 
+/* Coprocessor 14 */
+
+/* CP14 CR0: */
+#define TEECR           p14,6,c0,c0,0   /* ThumbEE Configuration Register */
+
+/* CP14 CR1: */
+#define TEEHBR          p14,6,c1,c0,0   /* ThumbEE Handler Base Register */
+#define JOSCR           p14,7,c1,c0,0   /* Jazelle OS Control Register */
+
+/* CP14 CR2: */
+#define JMCR            p14,7,c2,c0,0   /* Jazelle Main Configuration Register 
*/
+
+
 /* Coprocessor 15 */
 
 /* CP15 CR0: CPUID and Cache Type Registers */
@@ -112,6 +125,8 @@
 
 /* CP15 CR1: System Control Registers */
 #define SCTLR           p15,0,c1,c0,0   /* System Control Register */
+#define ACTLR           p15,0,c1,c0,1   /* Auxiliary Control Register */
+#define CPACR           p15,0,c1,c0,2   /* Coprocessor Access Control Register 
*/
 #define SCR             p15,0,c1,c1,0   /* Secure Configuration Register */
 #define NSACR           p15,0,c1,c1,2   /* Non-Secure Access Control Register 
*/
 #define HSCTLR          p15,4,c1,c0,0   /* Hyp. System Control Register */
@@ -127,12 +142,15 @@
 #define VTTBR           p15,6,c2        /* Virtualization Translation Table 
Base Register */
 
 /* CP15 CR3: Domain Access Control Register */
+#define DACR            p15,0,c3,c0,0   /* Domain Access Control Register */
 
 /* CP15 CR4: */
 
 /* CP15 CR5: Fault Status Registers */
 #define DFSR            p15,0,c5,c0,0   /* Data Fault Status Register */
 #define IFSR            p15,0,c5,c0,1   /* Instruction Fault Status Register */
+#define ADFSR           p15,0,c5,c1,0   /* Auxiliary Data Fault Status 
Register */
+#define AIFSR           p15,0,c5,c1,1   /* Auxiliary Instruction Fault Status 
Register */
 #define HSR             p15,4,c5,c2,0   /* Hyp. Syndrome Register */
 
 /* CP15 CR6: Fault Address Registers */
@@ -144,6 +162,7 @@
 
 /* CP15 CR7: Cache and address translation operations */
 #define PAR             p15,0,c7        /* Physical Address Register */
+
 #define ICIALLUIS       p15,0,c7,c1,0   /* Invalidate all instruction caches 
to PoU inner shareable */
 #define BPIALLIS        p15,0,c7,c1,6   /* Invalidate entire branch predictor 
array inner shareable */
 #define ICIALLU         p15,0,c7,c5,0   /* Invalidate all instruction caches 
to PoU */
@@ -192,20 +211,24 @@
 /* CP15 CR9: */
 
 /* CP15 CR10: */
-#define MAIR0           p15,0,c10,c2,0  /* Memory Attribute Indirection 
Register 0 */
-#define MAIR1           p15,0,c10,c2,1  /* Memory Attribute Indirection 
Register 1 */
+#define MAIR0           p15,0,c10,c2,0  /* Memory Attribute Indirection 
Register 0 AKA PRRR */
+#define MAIR1           p15,0,c10,c2,1  /* Memory Attribute Indirection 
Register 1 AKA NMRR */
 #define HMAIR0          p15,4,c10,c2,0  /* Hyp. Memory Attribute Indirection 
Register 0 */
 #define HMAIR1          p15,4,c10,c2,1  /* Hyp. Memory Attribute Indirection 
Register 1 */
 
 /* CP15 CR11: DMA Operations for TCM Access */
 
 /* CP15 CR12:  */
+#define VBAR            p15,0,c12,c0,0  /* Vector Base Address Register */
 #define HVBAR           p15,4,c12,c0,0  /* Hyp. Vector Base Address Register */
 
 /* CP15 CR13:  */
 #define FCSEIDR         p15,0,c13,c0,0  /* FCSE Process ID Register */
 #define CONTEXTIDR      p15,0,c13,c0,1  /* Context ID Register */
-#define HTPIDR          p15,4,c13,c0,2  /* Hyp. Software Thread ID Register */
+#define TPIDRURW        p15,0,c13,c0,2  /* Software Thread ID, User, R/W */
+#define TPIDRURO        p15,0,c13,c0,3  /* Software Thread ID, User, R/O */
+#define TPIDRPRW        p15,0,c13,c0,4  /* Software Thread ID, Priveleged */
+#define HTPIDR          p15,4,c13,c0,2  /* HYp Software Thread Id Register */
 
 /* CP15 CR14:  */
 #define CNTPCT          p15,0,c14       /* Time counter value */
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index f295a82..620b26e 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -81,8 +81,37 @@ struct arch_vcpu
      */
     struct cpu_info *cpu_info;
 
-    uint32_t sctlr;
-    uint32_t ttbr0, ttbr1, ttbcr;
+    /* Fault Status */
+    uint32_t dfar, ifar;
+    uint32_t dfsr, ifsr;
+    uint32_t adfsr, aifsr;
+
+    /* MMU */
+    uint32_t vbar;
+    uint32_t ttbcr;
+    uint32_t ttbr0, ttbr1;
+
+    uint32_t dacr;
+    uint64_t par;
+    uint32_t mair0, mair1;
+
+    /* Control Registers */
+    uint32_t actlr, sctlr;
+    uint32_t cpacr;
+
+    uint32_t contextidr;
+    uint32_t tpidrurw;
+    uint32_t tpidruro;
+    uint32_t tpidrprw;
+
+    uint32_t teecr, teehbr;
+    uint32_t joscr, jmcr;
+
+    /* CP 15 */
+    uint32_t csselr;
+
+    uint32_t gic_hcr, gic_vmcr, gic_apr;
+    uint32_t gic_lr[64];
 
     struct {
         struct vgic_irq_rank private_irqs;
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index e439727..e915cbf 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -124,6 +124,9 @@ typedef uint32_t xen_ulong_t;
 
 struct vcpu_guest_context {
     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
+
+    uint32_t sctlr;
+    uint32_t ttbr0, ttbr1, ttbcr;
 };
 typedef struct vcpu_guest_context vcpu_guest_context_t;
 DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-- 
1.7.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.