This applies after my recent series, but is easy to apply to any tree. Peter Maydell points out: We could reasonably also use HCR.TIDCP to trap the L2CTLR/L2ECTLR (on the A15 the ranges trapped by TIDCP cover just those two registers), rather than using HSTR.9. (For trapping the perf regs we should be using HDCR.TPM and HDCR.TPMCR). Notes: 1) Shouldn't we trap the rest of CP14? 2) Why do we trap c11 accesses in HSTR? AFAICT there's nothing there... Signed-off-by: Rusty Russell <rusty.russell at linaro.org> diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index c812368..38a0c55 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -62,6 +62,7 @@ * TSC: Trap SMC * TSW: Trap cache operations by set/way * TWI: Trap WFI + * TIDCP: Trap L2CTLR/L2ECTLR. * BSU_IS: Upgrade barriers to the inner shareable domain * FB: Force broadcast of all maintainance operations * AMO: Override CPSR.A and enable signaling with VA @@ -71,7 +72,7 @@ */ #define HCR_GUEST_MASK (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM | HCR_BSU_IS | \ HCR_FB | HCR_TAC | HCR_AMO | HCR_IMO | HCR_FMO | \ - HCR_SWIO) + HCR_SWIO | HCR_TIDCP) #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) /* System Control Register (SCTLR) bits */ @@ -119,6 +120,16 @@ #define HCPTR_TTA (1 << 20) #define HCPTR_TCPAC (1 << 31) +/* Hyp Debug Configuration Register bits */ +#define HDCR_TDRA (1 << 11) +#define HDCR_TDOSA (1 << 10) +#define HDCR_TDA (1 << 9) +#define HDCR_TDE (1 << 8) +#define HDCR_HPME (1 << 7) +#define HDCR_TPM (1 << 6) +#define HDCR_TPMCR (1 << 5) +#define HDCR_HPMN_MASK (0x1F) + /* Virtualization Translation Control Register (VTCR) bits */ #define VTCR_SH0 (3 << 12) #define VTCR_ORGN0 (3 << 10) diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index c7aa96a..dbeb514 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S @@ -409,9 +409,9 @@ ENDPROC(__kvm_flush_vm_context) * (hardware reset value is 0) */ .macro set_hstr entry mrc p15, 4, r2, c1, c1, 3 - ldr r3, =(HSTR_T(9) | HSTR_T(11) | HSTR_T(15)) + ldr r3, =(HSTR_T(11) | HSTR_T(15)) .if \entry == 1 - orr r2, r2, r3 @ Trap CR{9,11,15} + orr r2, r2, r3 @ Trap CR{11,15} .else bic r2, r2, r3 @ Don't trap any CRx accesses .endif @@ -431,6 +431,19 @@ ENDPROC(__kvm_flush_vm_context) mcr p15, 4, r2, c1, c1, 2 .endm +/* Configures the HDCR (Hyp Debug Configuration Register) on entry/return + * (hardware reset value is 0) */ +.macro set_hdcr entry + mrc p15, 4, r2, c1, c1, 1 + ldr r3, =(HDCR_TPM|HDCR_TPMCR) + .if \entry == 1 + orr r2, r2, r3 @ Trap some perfmon accesses + .else + bic r2, r2, r3 @ Don't trap any perfmon accesses + .endif + mcr p15, 4, r2, c1, c1, 1 +.endm + /* Enable/Disable: stage-2 trans., trap interrupts, trap wfi, trap smc */ .macro configure_hyp_role entry, vcpu_ptr mrc p15, 4, r2, c1, c1, 0 @ HCR @@ -477,6 +490,7 @@ ENTRY(__kvm_vcpu_run) @ Trap coprocessor CRx accesses set_hstr 1 set_hcptr 1 + set_hdcr 1 @ Write configured ID register into MIDR alias ldr r1, [r0, #VCPU_MIDR] @@ -537,6 +551,7 @@ __kvm_vcpu_return: @ Don't trap coprocessor accesses for host kernel set_hstr 0 set_hcptr 0 + set_hdcr 0 @ Reset Hyp-role configure_hyp_role 0, r1