[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 30/46] 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> Acked-by: Tim Deegan <tim@xxxxxxx> --- v2: Nuke XXX and rationalise naming: s/tpidrurw/tpidr_el0/ s/tpidrprw/tpidr_el1/ s/tpidruro/tpidrro_el0/ --- 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 883a681..dce7ea1 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -43,55 +43,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.tpidr_el0 = READ_SYSREG(TPIDR_EL0); + p->arch.tpidrro_el0 = READ_SYSREG(TPIDRRO_EL0); + p->arch.tpidr_el1 = 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(); @@ -100,16 +112,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 */ @@ -117,51 +129,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.tpidr_el0, TPIDR_EL0); + WRITE_SYSREG(n->arch.tpidrro_el0, TPIDRRO_EL0); + WRITE_SYSREG(n->arch.tpidr_el1, 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 ccd698c..0687acf 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -214,8 +214,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, @@ -265,7 +265,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)); @@ -295,8 +295,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)); } @@ -631,14 +631,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 80768d9..8a66719 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 f691c26..04518b3 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -133,30 +133,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 tpidr_el0; + register_t tpidr_el1; + register_t tpidrro_el0; +#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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |