[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |