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

[Xen-devel] [PATCH 31/45] xen: arm: guest context switching.



One side effect of this is that we now save the full 64-bit
TTBR[0,1] even on a 32-bit hypervisor. This is needed anyway to
support LPAE guests (although this patch doesn't implement anything
other than the context switch).

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 xen/arch/arm/domain.c        |  113 +++++++++++++++++++++++++-----------------
 xen/arch/arm/traps.c         |   14 +++---
 xen/include/asm-arm/cpregs.h |   21 +++++++-
 xen/include/asm-arm/domain.h |   29 ++++++++---
 4 files changed, 115 insertions(+), 62 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 077521e..0323552 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -41,55 +41,67 @@ void idle_loop(void)
 static void ctxt_switch_from(struct vcpu *p)
 {
     /* CP 15 */
-    p->arch.csselr = READ_CP32(CSSELR);
+    p->arch.csselr = READ_SYSREG(CSSELR_EL1);
 
     /* Control Registers */
-    p->arch.actlr = READ_CP32(ACTLR);
-    p->arch.sctlr = READ_CP32(SCTLR);
-    p->arch.cpacr = READ_CP32(CPACR);
+    p->arch.actlr = READ_SYSREG(ACTLR_EL1);
+    p->arch.sctlr = READ_SYSREG(SCTLR_EL1);
+    p->arch.cpacr = READ_SYSREG(CPACR_EL1);
 
-    p->arch.contextidr = READ_CP32(CONTEXTIDR);
-    p->arch.tpidrurw = READ_CP32(TPIDRURW);
-    p->arch.tpidruro = READ_CP32(TPIDRURO);
-    p->arch.tpidrprw = READ_CP32(TPIDRPRW);
+    p->arch.contextidr = READ_SYSREG(CONTEXTIDR_EL1);
+    p->arch.tpidrurw = READ_SYSREG(TPIDR_EL0); /* XXX names */
+    p->arch.tpidruro = READ_SYSREG(TPIDRRO_EL0);
+    p->arch.tpidrprw = READ_SYSREG(TPIDR_EL1);
 
     /* Arch timer */
     virt_timer_save(p);
 
+#if defined(CONFIG_ARM_32)
     /* 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);
+#endif
 
     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.vbar = READ_SYSREG(VBAR_EL1);
+    p->arch.ttbcr = READ_SYSREG(TCR_EL1);
+    p->arch.ttbr0 = READ_SYSREG64(TTBR0_EL1);
+    p->arch.ttbr1 = READ_SYSREG64(TTBR1_EL1);
+    if ( is_pv32_domain(p->domain) )
+        p->arch.dacr = READ_SYSREG(DACR32_EL2);
+    p->arch.par = READ_SYSREG64(PAR_EL1);
+#if defined(CONFIG_ARM_32)
     p->arch.mair0 = READ_CP32(MAIR0);
     p->arch.mair1 = READ_CP32(MAIR1);
+#else
+    p->arch.mair = READ_SYSREG64(MAIR_EL1);
+#endif
 
     /* Fault Status */
+#if defined(CONFIG_ARM_32)
     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);
+#elif defined(CONFIG_ARM_64)
+    p->arch.far = READ_SYSREG64(FAR_EL1);
+    p->arch.esr = READ_SYSREG64(ESR_EL1);
+#endif
+
+    if ( is_pv32_domain(p->domain) )
+        p->arch.ifsr  = READ_SYSREG(IFSR32_EL2);
+    p->arch.afsr0 = READ_SYSREG(AFSR0_EL1);
+    p->arch.afsr1 = READ_SYSREG(AFSR1_EL1);
 
     /* XXX MPU */
 
     /* XXX VFP */
 
-    /* XXX VGIC */
+    /* VGIC */
     gic_save_state(p);
 
     isb();
@@ -98,16 +110,16 @@ static void ctxt_switch_from(struct vcpu *p)
 
 static void ctxt_switch_to(struct vcpu *n)
 {
-    uint32_t hcr;
+    register_t hcr;
 
-    hcr = READ_CP32(HCR);
-    WRITE_CP32(hcr & ~HCR_VM, HCR);
+    hcr = READ_SYSREG(HCR_EL2);
+    WRITE_SYSREG(hcr & ~HCR_VM, HCR_EL2);
     isb();
 
     p2m_load_VTTBR(n->domain);
     isb();
 
-    /* XXX VGIC */
+    /* VGIC */
     gic_restore_state(n);
 
     /* XXX VFP */
@@ -115,51 +127,62 @@ static void ctxt_switch_to(struct vcpu *n)
     /* XXX MPU */
 
     /* Fault Status */
+#if defined(CONFIG_ARM_32)
     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);
+#elif defined(CONFIG_ARM_64)
+    WRITE_SYSREG64(n->arch.far, FAR_EL1);
+    WRITE_SYSREG64(n->arch.esr, ESR_EL1);
+#endif
+
+    if ( is_pv32_domain(n->domain) )
+        WRITE_SYSREG(n->arch.ifsr, IFSR32_EL2);
+    WRITE_SYSREG(n->arch.afsr0, AFSR0_EL1);
+    WRITE_SYSREG(n->arch.afsr1, AFSR1_EL1);
 
     /* 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_SYSREG(n->arch.vbar, VBAR_EL1);
+    WRITE_SYSREG(n->arch.ttbcr, TCR_EL1);
+    WRITE_SYSREG64(n->arch.ttbr0, TTBR0_EL1);
+    WRITE_SYSREG64(n->arch.ttbr1, TTBR1_EL1);
+    if ( is_pv32_domain(n->domain) )
+        WRITE_SYSREG(n->arch.dacr, DACR32_EL2);
+    WRITE_SYSREG64(n->arch.par, PAR_EL1);
+#if defined(CONFIG_ARM_32)
     WRITE_CP32(n->arch.mair0, MAIR0);
     WRITE_CP32(n->arch.mair1, MAIR1);
+#elif defined(CONFIG_ARM_64)
+    WRITE_SYSREG64(n->arch.mair, MAIR_EL1);
+#endif
     isb();
 
     /* Control Registers */
-    WRITE_CP32(n->arch.actlr, ACTLR);
-    WRITE_CP32(n->arch.sctlr, SCTLR);
-    WRITE_CP32(n->arch.cpacr, CPACR);
+    WRITE_SYSREG(n->arch.actlr, ACTLR_EL1);
+    WRITE_SYSREG(n->arch.sctlr, SCTLR_EL1);
+    WRITE_SYSREG(n->arch.cpacr, CPACR_EL1);
 
-    WRITE_CP32(n->arch.contextidr, CONTEXTIDR);
-    WRITE_CP32(n->arch.tpidrurw, TPIDRURW);
-    WRITE_CP32(n->arch.tpidruro, TPIDRURO);
-    WRITE_CP32(n->arch.tpidrprw, TPIDRPRW);
+    WRITE_SYSREG(n->arch.contextidr, CONTEXTIDR_EL1);
+    WRITE_SYSREG(n->arch.tpidrurw, TPIDR_EL0); /* XXX names mismatch */
+    WRITE_SYSREG(n->arch.tpidruro, TPIDRRO_EL0);
+    WRITE_SYSREG(n->arch.tpidrprw, TPIDR_EL1);
 
+#if defined(CONFIG_ARM_32)
     /* 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);
-
+#endif
     isb();
 
     /* CP 15 */
-    WRITE_CP32(n->arch.csselr, CSSELR);
+    WRITE_SYSREG(n->arch.csselr, CSSELR_EL1);
 
     isb();
 
-    WRITE_CP32(hcr, HCR);
+    WRITE_SYSREG(hcr, HCR_EL2);
     isb();
 
     /* This is could trigger an hardware interrupt from the virtual
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index d823242..590e00f 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -219,8 +219,8 @@ void panic_PAR(uint64_t par)
 }
 
 struct reg_ctxt {
-    uint32_t sctlr;
-    uint32_t ttbr0, ttbr1, ttbcr;
+    uint32_t sctlr, ttbcr;
+    uint64_t ttbr0, ttbr1;
 };
 static void _show_registers(struct cpu_user_regs *regs,
                             struct reg_ctxt *ctxt,
@@ -270,7 +270,7 @@ static void _show_registers(struct cpu_user_regs *regs,
         printk("FIQ: R8: %08"PRIx32" R9: %08"PRIx32" R10:%08"PRIx32" 
R11:%08"PRIx32" R12:%08"PRIx32"\n",
                regs->r8_fiq, regs->r9_fiq, regs->r10_fiq, regs->r11_fiq, 
regs->r11_fiq);
         printk("\n");
-        printk("TTBR0 %08"PRIx32" TTBR1 %08"PRIx32" TTBCR %08"PRIx32"\n",
+        printk("TTBR0 %010"PRIx64" TTBR1 %010"PRIx64" TTBCR %08"PRIx32"\n",
                ctxt->ttbr0, ctxt->ttbr1, ctxt->ttbcr);
         printk("SCTLR %08"PRIx32"\n", ctxt->sctlr);
         printk("VTTBR %010"PRIx64"\n", READ_CP64(VTTBR));
@@ -300,8 +300,8 @@ void show_registers(struct cpu_user_regs *regs)
     struct reg_ctxt ctxt;
     ctxt.sctlr = READ_CP32(SCTLR);
     ctxt.ttbcr = READ_CP32(TTBCR);
-    ctxt.ttbr0 = READ_CP32(TTBR0);
-    ctxt.ttbr1 = READ_CP32(TTBR1);
+    ctxt.ttbr0 = READ_CP64(TTBR0);
+    ctxt.ttbr1 = READ_CP64(TTBR1);
     _show_registers(regs, &ctxt, guest_mode(regs));
 }
 
@@ -636,14 +636,14 @@ static void do_cp15_64(struct cpu_user_regs *regs,
 void dump_guest_s1_walk(struct domain *d, vaddr_t addr)
 {
     uint32_t ttbcr = READ_CP32(TTBCR);
-    uint32_t ttbr0 = READ_CP32(TTBR0);
+    uint64_t ttbr0 = READ_CP64(TTBR0);
     paddr_t paddr;
     uint32_t offset;
     uint32_t *first = NULL, *second = NULL;
 
     printk("dom%d VA 0x%08"PRIvaddr"\n", d->domain_id, addr);
     printk("    TTBCR: 0x%08"PRIx32"\n", ttbcr);
-    printk("    TTBR0: 0x%08"PRIx32" = 0x%"PRIpaddr"\n",
+    printk("    TTBR0: 0x%010"PRIx64" = 0x%"PRIpaddr"\n",
            ttbr0, p2m_lookup(d, ttbr0 & PAGE_MASK));
 
     if ( ttbcr & TTBCR_EAE )
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index dc69a06..732f967 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -106,9 +106,9 @@
 #define HCR             p15,4,c1,c1,0   /* Hyp. Configuration Register */
 
 /* CP15 CR2: Translation Table Base and Control Registers */
-#define TTBR0           p15,0,c2,c0,0   /* Translation Table Base Reg. 0 */
-#define TTBR1           p15,0,c2,c0,1   /* Translation Table Base Reg. 1 */
 #define TTBCR           p15,0,c2,c0,2   /* Translatation Table Base Control 
Register */
+#define TTBR0           p15,0,c2        /* Translation Table Base Reg. 0 */
+#define TTBR1           p15,1,c2        /* Translation Table Base Reg. 1 */
 #define HTTBR           p15,4,c2        /* Hyp. Translation Table Base 
Register */
 #define HTCR            p15,4,c2,c0,2   /* Hyp. Translation Control Register */
 #define VTCR            p15,4,c2,c1,2   /* Virtualization Translation Control 
Register */
@@ -225,10 +225,17 @@
 /* Aliases of AArch64 names for use in common code when building for AArch32 */
 #ifdef CONFIG_ARM_32
 /* Alphabetically... */
+#define ACTLR_EL1               ACTLR
+#define AFSR0_EL1               ADFSR
+#define AFSR1_EL1               AIFSR
 #define CCSIDR_EL1              CCSIDR
 #define CLIDR_EL1               CLIDR
+#define CONTEXTIDR_EL1          CONTEXTIDR
+#define CPACR_EL1               CPACR
 #define CSSELR_EL1              CSSELR
+#define DACR32_EL2              DACR
 #define ESR_EL2                 HSR
+#define HCR_EL2                 HCR
 #define ID_AFR0_EL1             ID_AFR0
 #define ID_DFR0_EL1             ID_DFR0
 #define ID_ISAR0_EL1            ID_ISAR0
@@ -243,9 +250,19 @@
 #define ID_MMFR3_EL1            ID_MMFR3
 #define ID_PFR0_EL1             ID_PFR0
 #define ID_PFR1_EL1             ID_PFR1
+#define IFSR32_EL2              IFSR
+#define PAR_EL1                 PAR
+#define SCTLR_EL1               SCTLR
 #define SCTLR_EL2               HSCTLR
+#define TCR_EL1                 TTBCR
+#define TPIDRRO_EL0             TPIDRURO
+#define TPIDR_EL0               TPIDRURW
+#define TPIDR_EL1               TPIDRPRW
 #define TPIDR_EL2               HTPIDR
+#define TTBR0_EL1               TTBR0
 #define TTBR0_EL2               HTTBR
+#define TTBR1_EL1               TTBR1
+#define VBAR_EL1                VBAR
 #define VBAR_EL2                HVBAR
 #define VTCR_EL2                VTCR
 
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index cf75f25..a97ff59 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -134,30 +134,43 @@ struct arch_vcpu
     struct cpu_info *cpu_info;
 
     /* Fault Status */
+#ifdef CONFIG_ARM_32
+    uint32_t dfsr;
     uint32_t dfar, ifar;
-    uint32_t dfsr, ifsr;
-    uint32_t adfsr, aifsr;
+#else
+    uint64_t far;
+    uint32_t esr;
+#endif
+
+    uint32_t ifsr; /* 32-bit guests only */
+    uint32_t afsr0, afsr1;
 
     /* MMU */
-    uint32_t vbar;
+    register_t vbar;
     uint32_t ttbcr;
-    uint32_t ttbr0, ttbr1;
+    uint64_t ttbr0, ttbr1;
 
-    uint32_t dacr;
+    uint32_t dacr; /* 32-bit guests only */
     uint64_t par;
+#ifdef CONFIG_ARM_32
     uint32_t mair0, mair1;
+#else
+    uint64_t mair;
+#endif
 
     /* Control Registers */
     uint32_t actlr, sctlr;
     uint32_t cpacr;
 
     uint32_t contextidr;
-    uint32_t tpidrurw;
-    uint32_t tpidruro;
-    uint32_t tpidrprw;
+    register_t tpidrurw;
+    register_t tpidruro;
+    register_t tpidrprw;
 
+#ifdef CONFIG_ARM_32
     uint32_t teecr, teehbr;
     uint32_t joscr, jmcr;
+#endif
 
     /* CP 15 */
     uint32_t csselr;
-- 
1.7.2.5


_______________________________________________
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®.