Date: Wed, 1 Jul 2015 15:22:02 GMT From: mihai@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r287815 - soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm Message-ID: <201507011522.t61FM2MC089768@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mihai Date: Wed Jul 1 15:22:01 2015 New Revision: 287815 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=287815 Log: sys: arm: vmm: call the low-level primitives to initialize, run and clean a virtual machine Added: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp_helpers.h Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.c soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.h soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.S soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.h Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.c ============================================================================== --- soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.c Wed Jul 1 15:15:58 2015 (r287814) +++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.c Wed Jul 1 15:22:01 2015 (r287815) @@ -7,15 +7,23 @@ #include <sys/pcpu.h> #include <sys/proc.h> #include <sys/sysctl.h> +#include <sys/lock.h> +#include <sys/mutex.h> + #include <vm/vm.h> #include <vm/pmap.h> +#include <machine/cpu-v6.h> #include <machine/vmm.h> #include <machine/vmm_dev.h> #include "mmu.h" #include "arm.h" +#include "hyp.h" + +#define HANDLED 1 +#define UNHANDLED 0 MALLOC_DEFINE(M_HYP, "ARM VMM HYP", "ARM VMM HYP"); @@ -27,12 +35,43 @@ lpae_pd_entry_t *hyp_l1pd; char *stack; +static uint64_t vmid_generation = 1; +static struct mtx vmid_generation_mtx; + +static void set_vttbr(struct hyp* hyp) { + if (hyp->vmid_generation && + ((hyp->vmid_generation & ~VMID_GENERATION_MASK) != + (atomic_load_64(&vmid_generation) & ~VMID_GENERATION_MASK))) + goto out; + + mtx_lock(&vmid_generation_mtx); + + /* Another VCPU has change the VMID already */ + if (hyp->vmid_generation && + ((hyp->vmid_generation & ~VMID_GENERATION_MASK) != + (vmid_generation & ~VMID_GENERATION_MASK))) { + mtx_unlock(&vmid_generation_mtx); + goto out; + } + + vmid_generation++; + if (!(vmid_generation & VMID_GENERATION_MASK)) + vmid_generation++; + + hyp->vmid_generation = vmid_generation; + mtx_unlock(&vmid_generation_mtx); +out: + hyp->vttbr = BUILD_VTTBR((hyp->vmid_generation & VMID_GENERATION_MASK), hyp->l1pd_phys); +} + static int arm_init(int ipinum) { char *stack_top; lpae_vm_paddr_t phys_hyp_l1pd; + mtx_init(&vmid_generation_mtx, "vmid_generation_mtx", NULL, MTX_DEF); + stack = malloc(PAGE_SIZE, M_HYP, M_WAITOK | M_ZERO); stack_top = stack + PAGE_SIZE; @@ -100,20 +139,18 @@ arm_cleanup(void) { printf("%s before vmm_call_hyp\n", __func__); - vmm_call_hyp((void *) vtophys(vmm_stub_install), (void *)vtophys(&hypervisor_stub_vect[0])); printf("%s after vmm_call_hyp\n", __func__); printf("%s before freestack\n", __func__); - free(stack, M_HYP); - printf("%s before lpae_vmcleanup\n", __func__); + printf("%s before lpae_vmcleanup\n", __func__); lpae_vmcleanup(NULL); - printf("%s before vmm_call_hyp\n", __func__); free(hyp_l1pd, M_HYP); + mtx_destroy(&vmid_generation_mtx); return 0; } @@ -128,19 +165,79 @@ static void * arm_vminit(struct vm *vm, pmap_t pmap) { - return NULL; + struct hyp *hyp; + struct hypctx *hypctx; + int i; + + hyp = malloc(sizeof(struct hyp), M_HYP, M_WAITOK | M_ZERO); + if ((uintptr_t)hyp & PAGE_MASK) { + panic("malloc of struct hyp not aligned on %d byte boundary", + PAGE_SIZE); + } + hyp->vm = vm; + + hyp->l1pd_phys = (lpae_pd_entry_t) vtophys(&hyp->l1pd[0]); + set_vttbr(hyp); + + for (i = 0; i < VM_MAXCPU; i++) { + hypctx = &hyp->ctx[i]; + hypctx->vcpu = i; + hypctx->hyp = hyp; + hypctx->hcr = HCR_GUEST_MASK; + hypctx->midr = cpu_ident(); + hypctx->mpidr = (cp15_mpidr_get() & MPIDR_SMP_MASK) | + MPIDR_AFF1_LEVEL(i) | + MPIDR_AFF0_LEVEL(i); + } + + lpae_vmmmap_set(NULL, + (lpae_vm_vaddr_t)hyp, + (lpae_vm_paddr_t)vtophys(hyp), + sizeof(struct hyp), + VM_PROT_READ | VM_PROT_WRITE); + + return (hyp); } static int arm_vmrun(void *arg, int vcpu, register_t rip, pmap_t pmap, void *rend_cookie, void *suspended_cookie) { + int rc; + int handled; + struct hyp *hyp; + struct hypctx *hypctx; + struct vm *vm; + + hyp = arg; + hypctx = &hyp->ctx[vcpu]; + vm = hyp->vm; + + do { + handled = UNHANDLED; + + rc = vmm_call_hyp((void *)hyp_enter_guest, hypctx); + + handled = HANDLED; + + } while(handled); return 0; } static void arm_vmcleanup(void *arg) { + struct hyp *hyp = arg; + + /* Unmap from HYP-mode the hyp tructure */ + lpae_vmmmap_set(NULL, + (lpae_vm_vaddr_t)hyp, + (lpae_vm_paddr_t)vtophys(hyp), + sizeof(struct hyp), + VM_PROT_NONE); + + lpae_vmcleanup(&(hyp->l1pd[0])); + free(hyp, M_HYP); } static int Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.h ============================================================================== --- soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.h Wed Jul 1 15:15:58 2015 (r287814) +++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/arm.h Wed Jul 1 15:22:01 2015 (r287815) @@ -2,15 +2,16 @@ #include <machine/reg.h> struct hypctx { + uint32_t vcpu; struct hyp* hyp; - struct reg regs; - uint32_t hcr; uint32_t midr; uint32_t mpidr; + struct reg regs; + uint32_t sp_und; uint32_t lr_und; uint32_t spsr_und; @@ -66,14 +67,27 @@ struct hyp { lpae_pd_entry_t l1pd[2 * LPAE_L1_ENTRIES]; lpae_pd_entry_t vttbr; - struct hypctx ctx[VM_MAXCPU]; + uint64_t vmid_generation; struct vm *vm; -}; + lpae_pd_entry_t l1pd_phys; + struct hypctx ctx[VM_MAXCPU]; + }; CTASSERT((offsetof(struct hyp, l1pd) & PAGE_MASK) == 0); uint64_t vmm_call_hyp(void *hyp_func_addr, ...); -void vmm_stub_install(void *hypervisor_stub_vect); +extern void vmm_stub_install(void *hypervisor_stub_vect); +extern int hyp_enter_guest(struct hypctx *hypctx); #define LOW(x) (x & 0xFFFFFFFF) #define HIGH(x) LOW(x >> 32) + +#define VMID_GENERATION_MASK ((1UL<<8) - 1) +#define BUILD_VTTBR(VMID, PTADDR) ((VMID << 48) | PTADDR); + +#define MPIDR_SMP_MASK (0x3 << 30) +#define MPIDR_AFF1_LEVEL(x) ((x >> 2) << 8) +#define MPIDR_AFF0_LEVEL(x) ((x & 0x3) << 0) + + + Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.S ============================================================================== --- soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.S Wed Jul 1 15:15:58 2015 (r287814) +++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.S Wed Jul 1 15:22:01 2015 (r287815) @@ -6,8 +6,9 @@ #include <machine/sysreg.h> #include <machine/cpuconf.h> -#include "hyp_assym.h" #include "hyp.h" +#include "hyp_assym.h" +#include "hyp_helpers.h" .text .globl hyp_code_start Modified: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.h ============================================================================== --- soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.h Wed Jul 1 15:15:58 2015 (r287814) +++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp.h Wed Jul 1 15:22:01 2015 (r287815) @@ -109,7 +109,7 @@ */ #define HCR_GUEST_MASK (HCR_TSW | HCR_TAC | HCR_TIDCP | \ HCR_TSC | HCR_TWE | HCR_TWI | HCR_BSU_IS | HCR_FB | \ - HCR_AMO | HCR_IMO | HCR_FMO | HCR_SWIO | HCR_VM + HCR_AMO | HCR_IMO | HCR_FMO | HCR_SWIO | HCR_VM) /* Hyp Coprocessor Trap Register */ #define HCPTR_TCP(x) (1 << x) @@ -148,258 +148,5 @@ #define HYPCTX_REGS_R(x) (HYPCTX_REGS + x * 4) -/* Banked registers */ -#define SAVE_GUEST_BANKED_REG(reg) \ - mrs r2, reg; \ - str r2, [r0, #HYPCTX_##reg] -#define SAVE_GUEST_BANKED_MODE(mode) \ - SAVE_GUEST_BANKED_REG(SP_##mode); \ - SAVE_GUEST_BANKED_REG(LR_##mode); \ - SAVE_GUEST_BANKED_REG(SPSR_##mode) - -#define RESTORE_GUEST_BANKED_REG(reg) \ - ldr r2, [r0, #HYPCTX_##reg]; \ - msr reg, r2 -#define RESTORE_GUEST_BANKED_MODE(mode) \ - RESTORE_GUEST_BANKED_REG(SP_##mode); \ - RESTORE_GUEST_BANKED_REG(LR_##mode); \ - RESTORE_GUEST_BANKED_REG(SPSR_##mode) - -#define save_guest_regs \ - /* r0 - address of the hypctx */ \ - add r2, r0, #HYPCTX_REGS_R(3); \ - stm r2, {r3-r12}; \ - pop {r3-r5}; @ Get r0-r2 from the stack \ - add r2, r0, #HYPCTX_REGS_R(0); \ - stm r2, {r3-r5}; \ - \ - str lr, [r0, #HYPCTX_REGS_LR]; \ - mrs r2, SP_usr; \ - str r2, [r0, #HYPCTX_REGS_SP]; \ - \ - mrs r2, ELR_hyp; \ - str r2, [r0, #HYPCTX_REGS_PC]; \ - mrs r2, spsr; \ - str r2, [r0, #HYPCTX_REGS_CPSR]; \ - \ - SAVE_GUEST_BANKED_MODE(svc); \ - SAVE_GUEST_BANKED_MODE(abt); \ - SAVE_GUEST_BANKED_MODE(und); \ - SAVE_GUEST_BANKED_MODE(irq); \ - SAVE_GUEST_BANKED_MODE(fiq); \ - SAVE_GUEST_BANKED_REG(r8_fiq); \ - SAVE_GUEST_BANKED_REG(r9_fiq); \ - SAVE_GUEST_BANKED_REG(r10_fiq); \ - SAVE_GUEST_BANKED_REG(r11_fiq); \ - SAVE_GUEST_BANKED_REG(r12_fiq) - -#define restore_guest_regs \ - /* r0 - address of the hypctx */ \ - RESTORE_GUEST_BANKED_MODE(svc); \ - RESTORE_GUEST_BANKED_MODE(abt); \ - RESTORE_GUEST_BANKED_MODE(und); \ - RESTORE_GUEST_BANKED_MODE(irq); \ - RESTORE_GUEST_BANKED_MODE(fiq); \ - RESTORE_GUEST_BANKED_REG(r8_fiq); \ - RESTORE_GUEST_BANKED_REG(r9_fiq); \ - RESTORE_GUEST_BANKED_REG(r10_fiq); \ - RESTORE_GUEST_BANKED_REG(r11_fiq); \ - RESTORE_GUEST_BANKED_REG(r12_fiq); \ - \ - ldr r2, [r0, #HYPCTX_REGS_PC]; \ - msr ELR_hyp, r2; \ - ldr r2, [r0, #HYPCTX_REGS_CPSR]; \ - msr SPSR_cxsf, r2; \ - \ - ldr lr, [r0, #HYPCTX_REGS_LR]; \ - ldr r2, [r0, #HYPCTX_REGS_SP]; \ - msr SP_usr, r2; \ - \ - add r2, r0, #HYPCTX_REGS_R(0); \ - ldm r2, {r0-r12} - - -#define SAVE_HOST_BANKED_REG(reg) \ - mrs r2, reg; \ - push {r2} -#define SAVE_HOST_BANKED_MODE(mode) \ - SAVE_HOST_BANKED_REG(SP_##mode); \ - SAVE_HOST_BANKED_REG(LR_##mode); \ - SAVE_HOST_BANKED_REG(SPSR_##mode) - -#define RESTORE_HOST_BANKED_REG(reg) \ - pop {r2}; \ - msr reg, r2 -#define RESTORE_HOST_BANKED_MODE(mode) \ - RESTORE_HOST_BANKED_REG(SPSR_##mode); \ - RESTORE_HOST_BANKED_REG(LR_##mode); \ - RESTORE_HOST_BANKED_REG(SP_##mode) - -#define save_host_regs \ - /* SPSR was saved when entered HYP mode */ \ - mrs r2, ELR_hyp; \ - push {r2}; \ - \ - push {r4-r12}; \ - mrs r2, SP_usr; \ - push {r2}; \ - push {lr}; \ - \ - SAVE_HOST_BANKED_MODE(svc); \ - SAVE_HOST_BANKED_MODE(abt); \ - SAVE_HOST_BANKED_MODE(und); \ - SAVE_HOST_BANKED_MODE(irq); \ - SAVE_HOST_BANKED_MODE(fiq); \ - SAVE_HOST_BANKED_REG(r8_fiq); \ - SAVE_HOST_BANKED_REG(r9_fiq); \ - SAVE_HOST_BANKED_REG(r10_fiq); \ - SAVE_HOST_BANKED_REG(r11_fiq); \ - SAVE_HOST_BANKED_REG(r12_fiq) - -#define restore_host_regs \ - RESTORE_HOST_BANKED_REG(r12_fiq); \ - RESTORE_HOST_BANKED_REG(r11_fiq); \ - RESTORE_HOST_BANKED_REG(r10_fiq); \ - RESTORE_HOST_BANKED_REG(r9_fiq); \ - RESTORE_HOST_BANKED_REG(r8_fiq); \ - RESTORE_HOST_BANKED_MODE(fiq); \ - RESTORE_HOST_BANKED_MODE(irq); \ - RESTORE_HOST_BANKED_MODE(und); \ - RESTORE_HOST_BANKED_MODE(abt); \ - RESTORE_HOST_BANKED_MODE(svc); \ - \ - pop {lr}; \ - pop {r2}; \ - msr SP_usr, r2; \ - pop {r4-r12}; \ - \ - pop {r2}; \ - msr ELR_hyp, r2 - -#define load_cp15_regs_batch1 \ - mrc p15, 0, r2, c1, c0, 0; @ SCTLR \ - mrc p15, 0, r3, c1, c0, 2; @ CPACR \ - mrc p15, 0, r4, c2, c0, 2; @ TTBCR \ - mrc p15, 0, r5, c3, c0, 0; @ DACR \ - mrrc p15, 0, r6, r7, c2; @ TTBR 0 \ - mrrc p15, 1, r8, r9, c2; @ TTBR 1 \ - mrc p15, 0, r10, c10, c2, 0; @ PRRR \ - mrc p15, 0, r11, c10, c2, 1; @ NMRR \ - mrc p15, 2, r12, c0, c0, 0 @ CSSELR - -#define load_cp15_regs_batch2 \ - mrc p15, 0, r2, c13, c0, 1; @ CID \ - mrc p15, 0, r3, c13, c0, 2; @ TID_URW \ - mrc p15, 0, r4, c13, c0, 3; @ TID_URO \ - mrc p15, 0, r5, c13, c0, 4; @ TID_PRIV \ - mrc p15, 0, r6, c5, c0, 0; @ DFSR \ - mrc p15, 0, r7, c5, c0, 1; @ IFSR \ - mrc p15, 0, r8, c5, c1, 0; @ ADFSR \ - mrc p15, 0, r9, c5, c1, 1; @ AIFSR \ - mrc p15, 0, r10, c6, c0, 0; @ DFAR \ - mrc p15, 0, r11, c6, c0, 2; @ IFAR \ - mrc p15, 0, r12, c12, c0, 0 @ VBAR - -#define load_cp15_regs_batch3 \ - mrc p15, 0, r2, c14, c1, 0; @ CNTKCTL \ - mrrc p15, 0, r3, r4, c7; @ PAR \ - mrc p15, 0, r5, c10, c3, 0; @ AMAIR0 \ - mrc p15, 0, r6, c10, c3, 1 @ AMAIR1 - -#define store_cp15_regs_batch1 \ - mcr p15, 0, r2, c1, c0, 0; @ SCTLR \ - mcr p15, 0, r3, c1, c0, 2; @ CPACR \ - mcr p15, 0, r4, c2, c0, 2; @ TTBCR \ - mcr p15, 0, r5, c3, c0, 0; @ DACR \ - mcrr p15, 0, r6, r7, c2; @ TTBR 0 \ - mcrr p15, 1, r8, r9, c2; @ TTBR 1 \ - mcr p15, 0, r10, c10, c2, 0; @ PRRR \ - mcr p15, 0, r11, c10, c2, 1; @ NMRR \ - mcr p15, 2, r12, c0, c0, 0 @ CSSELR - -#define store_cp15_regs_batch2 \ - mcr p15, 0, r2, c13, c0, 1; @ CID \ - mcr p15, 0, r3, c13, c0, 2; @ TID_URW \ - mcr p15, 0, r4, c13, c0, 3; @ TID_URO \ - mcr p15, 0, r5, c13, c0, 4; @ TID_PRIV \ - mcr p15, 0, r6, c5, c0, 0; @ DFSR \ - mcr p15, 0, r7, c5, c0, 1; @ IFSR \ - mcr p15, 0, r8, c5, c1, 0; @ ADFSR \ - mcr p15, 0, r9, c5, c1, 1; @ AIFSR \ - mcr p15, 0, r10, c6, c0, 0; @ DFAR \ - mcr p15, 0, r11, c6, c0, 2; @ IFAR \ - mcr p15, 0, r12, c12, c0, 0 @ VBAR - -#define store_cp15_regs_batch3 \ - mcr p15, 0, r2, c14, c1, 0; @ CNTKCTL \ - mcrr p15, 0, r3, r4, c7; @ PAR \ - mcr p15, 0, r5, c10, c3, 0; @ AMAIR0 \ - mcr p15, 0, r6, c10, c3, 1 @ AMAIR1 - -#define store_guest_cp15_regs_batch1 \ - str r2, [r0, #HYPCTX_CP15_SCTLR]; \ - str r3, [r0, #HYPCTX_CP15_CPACR]; \ - str r4, [r0, #HYPCTX_CP15_TTBCR]; \ - str r5, [r0, #HYPCTX_CP15_DACR]; \ - add r2, r0, #HYPCTX_CP15_TTBR0; \ - strd r6, r7, [r2]; \ - add r2, r0, #HYPCTX_CP15_TTBR1; \ - strd r8, r9, [r2]; \ - str r10, [r0, #HYPCTX_CP15_PRRR]; \ - str r11, [r0, #HYPCTX_CP15_NMRR]; \ - str r12, [r0, #HYPCTX_CP15_CSSELR] - -#define store_guest_cp15_regs_batch2 \ - str r2, [r0, #HYPCTX_CP15_CID]; \ - str r3, [r0, #HYPCTX_CP15_TID_URW]; \ - str r4, [r0, #HYPCTX_CP15_TID_URO]; \ - str r5, [r0, #HYPCTX_CP15_TID_PRIV]; \ - str r6, [r0, #HYPCTX_CP15_DFSR]; \ - str r7, [r0, #HYPCTX_CP15_IFSR]; \ - str r8, [r0, #HYPCTX_CP15_ADFSR]; \ - str r9, [r0, #HYPCTX_CP15_AIFSR]; \ - str r10, [r0, #HYPCTX_CP15_DFAR]; \ - str r11, [r0, #HYPCTX_CP15_IFAR]; \ - str r12, [r0, #HYPCTX_CP15_VBAR] - -#define store_guest_cp15_regs_batch3 \ - str r2, [r0, #HYPCTX_CP15_CNTKCTL]; \ - add r2, r0, #HYPCTX_CP15_PAR; \ - strd r4, r5, [r2]; \ - str r3, [r0, #HYPCTX_CP15_AMAIR0]; \ - str r6, [r0, #HYPCTX_CP15_AMAIR1] - -#define load_guest_cp15_regs_batch1 \ - ldr r2, [r0, #HYPCTX_CP15_SCTLR]; \ - ldr r3, [r0, #HYPCTX_CP15_CPACR]; \ - ldr r4, [r0, #HYPCTX_CP15_TTBCR]; \ - ldr r5, [r0, #HYPCTX_CP15_DACR]; \ - add r2, r0, #HYPCTX_CP15_TTBR0; \ - ldrd r6, r7, [r2]; \ - add r2, r0, #HYPCTX_CP15_TTBR1; \ - ldrd r8, r9, [r2]; \ - ldr r10, [r0, #HYPCTX_CP15_PRRR]; \ - ldr r11, [r0, #HYPCTX_CP15_NMRR]; \ - ldr r12, [r0, #HYPCTX_CP15_CSSELR] - -#define load_guest_cp15_regs_batch2 \ - ldr r2, [r0, #HYPCTX_CP15_CID]; \ - ldr r3, [r0, #HYPCTX_CP15_TID_URW]; \ - ldr r4, [r0, #HYPCTX_CP15_TID_URO]; \ - ldr r5, [r0, #HYPCTX_CP15_TID_PRIV]; \ - ldr r6, [r0, #HYPCTX_CP15_DFSR]; \ - ldr r7, [r0, #HYPCTX_CP15_IFSR]; \ - ldr r8, [r0, #HYPCTX_CP15_ADFSR]; \ - ldr r9, [r0, #HYPCTX_CP15_AIFSR]; \ - ldr r10, [r0, #HYPCTX_CP15_DFAR]; \ - ldr r11, [r0, #HYPCTX_CP15_IFAR]; \ - ldr r12, [r0, #HYPCTX_CP15_VBAR] - -#define load_guest_cp15_regs_batch3 \ - ldr r2, [r0, #HYPCTX_CP15_CNTKCTL]; \ - add r2, r0, #HYPCTX_CP15_PAR; \ - ldrd r4, r5, [r2]; \ - ldr r3, [r0, #HYPCTX_CP15_AMAIR0]; \ - ldr r6, [r0, #HYPCTX_CP15_AMAIR1] - #endif + Added: soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp_helpers.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2015/mihai/bhyve-on-arm-head/sys/arm/vmm/hyp_helpers.h Wed Jul 1 15:22:01 2015 (r287815) @@ -0,0 +1,259 @@ +#ifndef _VMM_HYP_HELPERS_H_ +#define _VMM_HYP_HELPERS_H_ + + +/* Banked registers */ +#define SAVE_GUEST_BANKED_REG(reg) \ + mrs r2, reg; \ + str r2, [r0, #HYPCTX_##reg] +#define SAVE_GUEST_BANKED_MODE(mode) \ + SAVE_GUEST_BANKED_REG(SP_##mode); \ + SAVE_GUEST_BANKED_REG(LR_##mode); \ + SAVE_GUEST_BANKED_REG(SPSR_##mode) + +#define RESTORE_GUEST_BANKED_REG(reg) \ + ldr r2, [r0, #HYPCTX_##reg]; \ + msr reg, r2 +#define RESTORE_GUEST_BANKED_MODE(mode) \ + RESTORE_GUEST_BANKED_REG(SP_##mode); \ + RESTORE_GUEST_BANKED_REG(LR_##mode); \ + RESTORE_GUEST_BANKED_REG(SPSR_##mode) + +#define save_guest_regs \ + /* r0 - address of the hypctx */ \ + add r2, r0, #HYPCTX_REGS_R(3); \ + stm r2, {r3-r12}; \ + pop {r3-r5}; @ Get r0-r2 from the stack \ + add r2, r0, #HYPCTX_REGS_R(0); \ + stm r2, {r3-r5}; \ + \ + str lr, [r0, #HYPCTX_REGS_LR]; \ + mrs r2, SP_usr; \ + str r2, [r0, #HYPCTX_REGS_SP]; \ + \ + mrs r2, ELR_hyp; \ + str r2, [r0, #HYPCTX_REGS_PC]; \ + mrs r2, spsr; \ + str r2, [r0, #HYPCTX_REGS_CPSR]; \ + \ + SAVE_GUEST_BANKED_MODE(svc); \ + SAVE_GUEST_BANKED_MODE(abt); \ + SAVE_GUEST_BANKED_MODE(und); \ + SAVE_GUEST_BANKED_MODE(irq); \ + SAVE_GUEST_BANKED_MODE(fiq); \ + SAVE_GUEST_BANKED_REG(r8_fiq); \ + SAVE_GUEST_BANKED_REG(r9_fiq); \ + SAVE_GUEST_BANKED_REG(r10_fiq); \ + SAVE_GUEST_BANKED_REG(r11_fiq); \ + SAVE_GUEST_BANKED_REG(r12_fiq) + +#define restore_guest_regs \ + /* r0 - address of the hypctx */ \ + RESTORE_GUEST_BANKED_MODE(svc); \ + RESTORE_GUEST_BANKED_MODE(abt); \ + RESTORE_GUEST_BANKED_MODE(und); \ + RESTORE_GUEST_BANKED_MODE(irq); \ + RESTORE_GUEST_BANKED_MODE(fiq); \ + RESTORE_GUEST_BANKED_REG(r8_fiq); \ + RESTORE_GUEST_BANKED_REG(r9_fiq); \ + RESTORE_GUEST_BANKED_REG(r10_fiq); \ + RESTORE_GUEST_BANKED_REG(r11_fiq); \ + RESTORE_GUEST_BANKED_REG(r12_fiq); \ + \ + ldr r2, [r0, #HYPCTX_REGS_PC]; \ + msr ELR_hyp, r2; \ + ldr r2, [r0, #HYPCTX_REGS_CPSR]; \ + msr SPSR_cxsf, r2; \ + \ + ldr lr, [r0, #HYPCTX_REGS_LR]; \ + ldr r2, [r0, #HYPCTX_REGS_SP]; \ + msr SP_usr, r2; \ + \ + add r2, r0, #HYPCTX_REGS_R(0); \ + ldm r2, {r0-r12} + + +#define SAVE_HOST_BANKED_REG(reg) \ + mrs r2, reg; \ + push {r2} +#define SAVE_HOST_BANKED_MODE(mode) \ + SAVE_HOST_BANKED_REG(SP_##mode); \ + SAVE_HOST_BANKED_REG(LR_##mode); \ + SAVE_HOST_BANKED_REG(SPSR_##mode) + +#define RESTORE_HOST_BANKED_REG(reg) \ + pop {r2}; \ + msr reg, r2 +#define RESTORE_HOST_BANKED_MODE(mode) \ + RESTORE_HOST_BANKED_REG(SPSR_##mode); \ + RESTORE_HOST_BANKED_REG(LR_##mode); \ + RESTORE_HOST_BANKED_REG(SP_##mode) + +#define save_host_regs \ + /* SPSR was saved when entered HYP mode */ \ + mrs r2, ELR_hyp; \ + push {r2}; \ + \ + push {r4-r12}; \ + mrs r2, SP_usr; \ + push {r2}; \ + push {lr}; \ + \ + SAVE_HOST_BANKED_MODE(svc); \ + SAVE_HOST_BANKED_MODE(abt); \ + SAVE_HOST_BANKED_MODE(und); \ + SAVE_HOST_BANKED_MODE(irq); \ + SAVE_HOST_BANKED_MODE(fiq); \ + SAVE_HOST_BANKED_REG(r8_fiq); \ + SAVE_HOST_BANKED_REG(r9_fiq); \ + SAVE_HOST_BANKED_REG(r10_fiq); \ + SAVE_HOST_BANKED_REG(r11_fiq); \ + SAVE_HOST_BANKED_REG(r12_fiq) + +#define restore_host_regs \ + RESTORE_HOST_BANKED_REG(r12_fiq); \ + RESTORE_HOST_BANKED_REG(r11_fiq); \ + RESTORE_HOST_BANKED_REG(r10_fiq); \ + RESTORE_HOST_BANKED_REG(r9_fiq); \ + RESTORE_HOST_BANKED_REG(r8_fiq); \ + RESTORE_HOST_BANKED_MODE(fiq); \ + RESTORE_HOST_BANKED_MODE(irq); \ + RESTORE_HOST_BANKED_MODE(und); \ + RESTORE_HOST_BANKED_MODE(abt); \ + RESTORE_HOST_BANKED_MODE(svc); \ + \ + pop {lr}; \ + pop {r2}; \ + msr SP_usr, r2; \ + pop {r4-r12}; \ + \ + pop {r2}; \ + msr ELR_hyp, r2 + +#define load_cp15_regs_batch1 \ + mrc p15, 0, r2, c1, c0, 0; @ SCTLR \ + mrc p15, 0, r3, c1, c0, 2; @ CPACR \ + mrc p15, 0, r4, c2, c0, 2; @ TTBCR \ + mrc p15, 0, r5, c3, c0, 0; @ DACR \ + mrrc p15, 0, r6, r7, c2; @ TTBR 0 \ + mrrc p15, 1, r8, r9, c2; @ TTBR 1 \ + mrc p15, 0, r10, c10, c2, 0; @ PRRR \ + mrc p15, 0, r11, c10, c2, 1; @ NMRR \ + mrc p15, 2, r12, c0, c0, 0 @ CSSELR + +#define load_cp15_regs_batch2 \ + mrc p15, 0, r2, c13, c0, 1; @ CID \ + mrc p15, 0, r3, c13, c0, 2; @ TID_URW \ + mrc p15, 0, r4, c13, c0, 3; @ TID_URO \ + mrc p15, 0, r5, c13, c0, 4; @ TID_PRIV \ + mrc p15, 0, r6, c5, c0, 0; @ DFSR \ + mrc p15, 0, r7, c5, c0, 1; @ IFSR \ + mrc p15, 0, r8, c5, c1, 0; @ ADFSR \ + mrc p15, 0, r9, c5, c1, 1; @ AIFSR \ + mrc p15, 0, r10, c6, c0, 0; @ DFAR \ + mrc p15, 0, r11, c6, c0, 2; @ IFAR \ + mrc p15, 0, r12, c12, c0, 0 @ VBAR + +#define load_cp15_regs_batch3 \ + mrc p15, 0, r2, c14, c1, 0; @ CNTKCTL \ + mrrc p15, 0, r3, r4, c7; @ PAR \ + mrc p15, 0, r5, c10, c3, 0; @ AMAIR0 \ + mrc p15, 0, r6, c10, c3, 1 @ AMAIR1 + +#define store_cp15_regs_batch1 \ + mcr p15, 0, r2, c1, c0, 0; @ SCTLR \ + mcr p15, 0, r3, c1, c0, 2; @ CPACR \ + mcr p15, 0, r4, c2, c0, 2; @ TTBCR \ + mcr p15, 0, r5, c3, c0, 0; @ DACR \ + mcrr p15, 0, r6, r7, c2; @ TTBR 0 \ + mcrr p15, 1, r8, r9, c2; @ TTBR 1 \ + mcr p15, 0, r10, c10, c2, 0; @ PRRR \ + mcr p15, 0, r11, c10, c2, 1; @ NMRR \ + mcr p15, 2, r12, c0, c0, 0 @ CSSELR + +#define store_cp15_regs_batch2 \ + mcr p15, 0, r2, c13, c0, 1; @ CID \ + mcr p15, 0, r3, c13, c0, 2; @ TID_URW \ + mcr p15, 0, r4, c13, c0, 3; @ TID_URO \ + mcr p15, 0, r5, c13, c0, 4; @ TID_PRIV \ + mcr p15, 0, r6, c5, c0, 0; @ DFSR \ + mcr p15, 0, r7, c5, c0, 1; @ IFSR \ + mcr p15, 0, r8, c5, c1, 0; @ ADFSR \ + mcr p15, 0, r9, c5, c1, 1; @ AIFSR \ + mcr p15, 0, r10, c6, c0, 0; @ DFAR \ + mcr p15, 0, r11, c6, c0, 2; @ IFAR \ + mcr p15, 0, r12, c12, c0, 0 @ VBAR + +#define store_cp15_regs_batch3 \ + mcr p15, 0, r2, c14, c1, 0; @ CNTKCTL \ + mcrr p15, 0, r3, r4, c7; @ PAR \ + mcr p15, 0, r5, c10, c3, 0; @ AMAIR0 \ + mcr p15, 0, r6, c10, c3, 1 @ AMAIR1 + +#define store_guest_cp15_regs_batch1 \ + str r2, [r0, #HYPCTX_CP15_SCTLR]; \ + str r3, [r0, #HYPCTX_CP15_CPACR]; \ + str r4, [r0, #HYPCTX_CP15_TTBCR]; \ + str r5, [r0, #HYPCTX_CP15_DACR]; \ + add r2, r0, #HYPCTX_CP15_TTBR0; \ + strd r6, r7, [r2]; \ + add r2, r0, #HYPCTX_CP15_TTBR1; \ + strd r8, r9, [r2]; \ + str r10, [r0, #HYPCTX_CP15_PRRR]; \ + str r11, [r0, #HYPCTX_CP15_NMRR]; \ + str r12, [r0, #HYPCTX_CP15_CSSELR] + +#define store_guest_cp15_regs_batch2 \ + str r2, [r0, #HYPCTX_CP15_CID]; \ + str r3, [r0, #HYPCTX_CP15_TID_URW]; \ + str r4, [r0, #HYPCTX_CP15_TID_URO]; \ + str r5, [r0, #HYPCTX_CP15_TID_PRIV]; \ + str r6, [r0, #HYPCTX_CP15_DFSR]; \ + str r7, [r0, #HYPCTX_CP15_IFSR]; \ + str r8, [r0, #HYPCTX_CP15_ADFSR]; \ + str r9, [r0, #HYPCTX_CP15_AIFSR]; \ + str r10, [r0, #HYPCTX_CP15_DFAR]; \ + str r11, [r0, #HYPCTX_CP15_IFAR]; \ + str r12, [r0, #HYPCTX_CP15_VBAR] + +#define store_guest_cp15_regs_batch3 \ + str r2, [r0, #HYPCTX_CP15_CNTKCTL]; \ + add r2, r0, #HYPCTX_CP15_PAR; \ + strd r4, r5, [r2]; \ + str r3, [r0, #HYPCTX_CP15_AMAIR0]; \ + str r6, [r0, #HYPCTX_CP15_AMAIR1] + +#define load_guest_cp15_regs_batch1 \ + ldr r2, [r0, #HYPCTX_CP15_SCTLR]; \ + ldr r3, [r0, #HYPCTX_CP15_CPACR]; \ + ldr r4, [r0, #HYPCTX_CP15_TTBCR]; \ + ldr r5, [r0, #HYPCTX_CP15_DACR]; \ + add r2, r0, #HYPCTX_CP15_TTBR0; \ + ldrd r6, r7, [r2]; \ + add r2, r0, #HYPCTX_CP15_TTBR1; \ + ldrd r8, r9, [r2]; \ + ldr r10, [r0, #HYPCTX_CP15_PRRR]; \ + ldr r11, [r0, #HYPCTX_CP15_NMRR]; \ + ldr r12, [r0, #HYPCTX_CP15_CSSELR] + +#define load_guest_cp15_regs_batch2 \ + ldr r2, [r0, #HYPCTX_CP15_CID]; \ + ldr r3, [r0, #HYPCTX_CP15_TID_URW]; \ + ldr r4, [r0, #HYPCTX_CP15_TID_URO]; \ + ldr r5, [r0, #HYPCTX_CP15_TID_PRIV]; \ + ldr r6, [r0, #HYPCTX_CP15_DFSR]; \ + ldr r7, [r0, #HYPCTX_CP15_IFSR]; \ + ldr r8, [r0, #HYPCTX_CP15_ADFSR]; \ + ldr r9, [r0, #HYPCTX_CP15_AIFSR]; \ + ldr r10, [r0, #HYPCTX_CP15_DFAR]; \ + ldr r11, [r0, #HYPCTX_CP15_IFAR]; \ + ldr r12, [r0, #HYPCTX_CP15_VBAR] + +#define load_guest_cp15_regs_batch3 \ + ldr r2, [r0, #HYPCTX_CP15_CNTKCTL]; \ + add r2, r0, #HYPCTX_CP15_PAR; \ + ldrd r4, r5, [r2]; \ + ldr r3, [r0, #HYPCTX_CP15_AMAIR0]; \ + ldr r6, [r0, #HYPCTX_CP15_AMAIR1] + +#endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507011522.t61FM2MC089768>