|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 4/7] xen/arm: Move sysreg emulation outside of traps.c
On Tue, 12 Sep 2017, Julien Grall wrote:
> The sysreg emulation is 64-bit specific and surrounded by #ifdef. Move
> them in a separate file arm/arm64/vsysreg.c to shrink down a bit traps.c
>
> No functional change.
>
> Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> ---
> xen/arch/arm/arm64/Makefile | 1 +
> xen/arch/arm/arm64/vsysreg.c | 229
> ++++++++++++++++++++++++++++++++++++++
> xen/arch/arm/traps.c | 198 --------------------------------
> xen/include/asm-arm/arm64/traps.h | 3 +
> 4 files changed, 233 insertions(+), 198 deletions(-)
> create mode 100644 xen/arch/arm/arm64/vsysreg.c
>
> diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile
> index 149b6b3901..718fe44455 100644
> --- a/xen/arch/arm/arm64/Makefile
> +++ b/xen/arch/arm/arm64/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_LIVEPATCH) += livepatch.o
> obj-y += smpboot.o
> obj-y += traps.o
> obj-y += vfp.o
> +obj-y += vsysreg.o
> diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c
> new file mode 100644
> index 0000000000..c57ac12503
> --- /dev/null
> +++ b/xen/arch/arm/arm64/vsysreg.c
> @@ -0,0 +1,229 @@
> +/*
> + * xen/arch/arm/arm64/sysreg.c
> + *
> + * Emulate system registers trapped.
> + *
> + * Copyright (c) 2011 Citrix Systems.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <xen/sched.h>
> +
> +#include <asm/current.h>
> +#include <asm/regs.h>
> +#include <asm/traps.h>
> +#include <asm/vtimer.h>
> +
> +void do_sysreg(struct cpu_user_regs *regs,
> + const union hsr hsr)
> +{
> + int regidx = hsr.sysreg.reg;
> + struct vcpu *v = current;
> +
> + switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
> + {
> + /*
> + * HCR_EL2.TACR
> + *
> + * ARMv8 (DDI 0487A.d): D7.2.1
> + */
> + case HSR_SYSREG_ACTLR_EL1:
> + if ( psr_mode_is_user(regs) )
> + return inject_undef_exception(regs, hsr);
> + if ( hsr.sysreg.read )
> + set_user_reg(regs, regidx, v->arch.actlr);
> + break;
> +
> + /*
> + * MDCR_EL2.TDRA
> + *
> + * ARMv8 (DDI 0487A.d): D1-1508 Table D1-57
> + */
> + case HSR_SYSREG_MDRAR_EL1:
> + return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 1);
> +
> + /*
> + * MDCR_EL2.TDOSA
> + *
> + * ARMv8 (DDI 0487A.d): D1-1509 Table D1-58
> + *
> + * Unhandled:
> + * OSLSR_EL1
> + * DBGPRCR_EL1
> + */
> + case HSR_SYSREG_OSLAR_EL1:
> + return handle_wo_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> + case HSR_SYSREG_OSDLR_EL1:
> + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> +
> + /*
> + * MDCR_EL2.TDA
> + *
> + * ARMv8 (DDI 0487A.d): D1-1510 Table D1-59
> + *
> + * Unhandled:
> + * MDCCINT_EL1
> + * DBGDTR_EL0
> + * DBGDTRRX_EL0
> + * DBGDTRTX_EL0
> + * OSDTRRX_EL1
> + * OSDTRTX_EL1
> + * OSECCR_EL1
> + * DBGCLAIMSET_EL1
> + * DBGCLAIMCLR_EL1
> + * DBGAUTHSTATUS_EL1
> + */
> + case HSR_SYSREG_MDSCR_EL1:
> + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> + case HSR_SYSREG_MDCCSR_EL0:
> + /*
> + * Accessible at EL0 only if MDSCR_EL1.TDCC is set to 0. We emulate
> that
> + * register as RAZ/WI above. So RO at both EL0 and EL1.
> + */
> + return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 0);
> + HSR_SYSREG_DBG_CASES(DBGBVR):
> + HSR_SYSREG_DBG_CASES(DBGBCR):
> + HSR_SYSREG_DBG_CASES(DBGWVR):
> + HSR_SYSREG_DBG_CASES(DBGWCR):
> + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> +
> + /*
> + * MDCR_EL2.TPM
> + *
> + * ARMv8 (DDI 0487A.d): D1-1511 Table D1-61
> + *
> + * Unhandled:
> + * PMEVCNTR<n>_EL0
> + * PMEVTYPER<n>_EL0
> + * PMCCFILTR_EL0
> + * MDCR_EL2.TPMCR
> + *
> + * ARMv7 (DDI 0406C.b): B1.14.17
> + * ARMv8 (DDI 0487A.d): D1-1511 Table D1-62
> + *
> + * NB: Both MDCR_EL2.TPM and MDCR_EL2.TPMCR cause trapping of PMCR.
> + */
> + case HSR_SYSREG_PMINTENSET_EL1:
> + case HSR_SYSREG_PMINTENCLR_EL1:
> + /*
> + * Accessible from EL1 only, but if EL0 trap happens handle as
> + * undef.
> + */
> + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> + case HSR_SYSREG_PMUSERENR_EL0:
> + /* RO at EL0. RAZ/WI at EL1 */
> + if ( psr_mode_is_user(regs) )
> + return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 0);
> + else
> + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> + case HSR_SYSREG_PMCR_EL0:
> + case HSR_SYSREG_PMCNTENSET_EL0:
> + case HSR_SYSREG_PMCNTENCLR_EL0:
> + case HSR_SYSREG_PMOVSCLR_EL0:
> + case HSR_SYSREG_PMSWINC_EL0:
> + case HSR_SYSREG_PMSELR_EL0:
> + case HSR_SYSREG_PMCEID0_EL0:
> + case HSR_SYSREG_PMCEID1_EL0:
> + case HSR_SYSREG_PMCCNTR_EL0:
> + case HSR_SYSREG_PMXEVTYPER_EL0:
> + case HSR_SYSREG_PMXEVCNTR_EL0:
> + case HSR_SYSREG_PMOVSSET_EL0:
> + /*
> + * Accessible at EL0 only if PMUSERENR_EL0.EN is set. We
> + * emulate that register as 0 above.
> + */
> + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> +
> + /*
> + * !CNTHCTL_EL2.EL1PCEN
> + *
> + * ARMv8 (DDI 0487A.d): D1-1510 Table D1-60
> + */
> + case HSR_SYSREG_CNTP_CTL_EL0:
> + case HSR_SYSREG_CNTP_TVAL_EL0:
> + case HSR_SYSREG_CNTP_CVAL_EL0:
> + if ( !vtimer_emulate(regs, hsr) )
> + return inject_undef_exception(regs, hsr);
> + break;
> +
> + /*
> + * HCR_EL2.FMO or HCR_EL2.IMO
> + *
> + * GIC Architecture Specification (IHI 0069C): Section 4.6.3
> + */
> + case HSR_SYSREG_ICC_SGI1R_EL1:
> + case HSR_SYSREG_ICC_ASGI1R_EL1:
> + case HSR_SYSREG_ICC_SGI0R_EL1:
> +
> + if ( !vgic_emulate(regs, hsr) )
> + return inject_undef64_exception(regs, hsr.len);
> + break;
> +
> + /*
> + * ICC_SRE_EL2.Enable = 0
> + *
> + * GIC Architecture Specification (IHI 0069C): Section 8.1.9
> + */
> + case HSR_SYSREG_ICC_SRE_EL1:
> + /*
> + * Trapped when the guest is using GICv2 whilst the platform
> + * interrupt controller is GICv3. In this case, the register
> + * should be emulate as RAZ/WI to tell the guest to use the GIC
> + * memory mapped interface (i.e GICv2 compatibility).
> + */
> + return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> +
> + /*
> + * HCR_EL2.TIDCP
> + *
> + * ARMv8 (DDI 0487A.d): D1-1501 Table D1-43
> + *
> + * - Reserved control space for IMPLEMENTATION DEFINED functionality.
> + *
> + * CPTR_EL2.TTA
> + *
> + * ARMv8 (DDI 0487A.d): D1-1507 Table D1-54
> + *
> + * - All implemented trace registers.
> + *
> + * And all other unknown registers.
> + */
> + default:
> + {
> + const struct hsr_sysreg sysreg = hsr.sysreg;
> +
> + gdprintk(XENLOG_ERR,
> + "%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
> + sysreg.read ? "mrs" : "msr",
> + sysreg.op0, sysreg.op1,
> + sysreg.crn, sysreg.crm,
> + sysreg.op2,
> + sysreg.read ? "=>" : "<=",
> + sysreg.reg, regs->pc);
> + gdprintk(XENLOG_ERR, "unhandled 64-bit sysreg access %#x\n",
> + hsr.bits & HSR_SYSREG_REGS_MASK);
> + inject_undef_exception(regs, hsr);
> + return;
> + }
> + }
> +
> + regs->pc += 4;
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index 1c334a7b99..f00aa48892 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -2295,204 +2295,6 @@ static void do_cp(struct cpu_user_regs *regs, const
> union hsr hsr)
> inject_undef_exception(regs, hsr);
> }
>
> -#ifdef CONFIG_ARM_64
> -static void do_sysreg(struct cpu_user_regs *regs,
> - const union hsr hsr)
> -{
> - int regidx = hsr.sysreg.reg;
> - struct vcpu *v = current;
> -
> - switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
> - {
> - /*
> - * HCR_EL2.TACR
> - *
> - * ARMv8 (DDI 0487A.d): D7.2.1
> - */
> - case HSR_SYSREG_ACTLR_EL1:
> - if ( psr_mode_is_user(regs) )
> - return inject_undef_exception(regs, hsr);
> - if ( hsr.sysreg.read )
> - set_user_reg(regs, regidx, v->arch.actlr);
> - break;
> -
> - /*
> - * MDCR_EL2.TDRA
> - *
> - * ARMv8 (DDI 0487A.d): D1-1508 Table D1-57
> - */
> - case HSR_SYSREG_MDRAR_EL1:
> - return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 1);
> -
> - /*
> - * MDCR_EL2.TDOSA
> - *
> - * ARMv8 (DDI 0487A.d): D1-1509 Table D1-58
> - *
> - * Unhandled:
> - * OSLSR_EL1
> - * DBGPRCR_EL1
> - */
> - case HSR_SYSREG_OSLAR_EL1:
> - return handle_wo_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> - case HSR_SYSREG_OSDLR_EL1:
> - return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> -
> - /*
> - * MDCR_EL2.TDA
> - *
> - * ARMv8 (DDI 0487A.d): D1-1510 Table D1-59
> - *
> - * Unhandled:
> - * MDCCINT_EL1
> - * DBGDTR_EL0
> - * DBGDTRRX_EL0
> - * DBGDTRTX_EL0
> - * OSDTRRX_EL1
> - * OSDTRTX_EL1
> - * OSECCR_EL1
> - * DBGCLAIMSET_EL1
> - * DBGCLAIMCLR_EL1
> - * DBGAUTHSTATUS_EL1
> - */
> - case HSR_SYSREG_MDSCR_EL1:
> - return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> - case HSR_SYSREG_MDCCSR_EL0:
> - /*
> - * Accessible at EL0 only if MDSCR_EL1.TDCC is set to 0. We emulate
> that
> - * register as RAZ/WI above. So RO at both EL0 and EL1.
> - */
> - return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 0);
> - HSR_SYSREG_DBG_CASES(DBGBVR):
> - HSR_SYSREG_DBG_CASES(DBGBCR):
> - HSR_SYSREG_DBG_CASES(DBGWVR):
> - HSR_SYSREG_DBG_CASES(DBGWCR):
> - return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> -
> - /*
> - * MDCR_EL2.TPM
> - *
> - * ARMv8 (DDI 0487A.d): D1-1511 Table D1-61
> - *
> - * Unhandled:
> - * PMEVCNTR<n>_EL0
> - * PMEVTYPER<n>_EL0
> - * PMCCFILTR_EL0
> - * MDCR_EL2.TPMCR
> - *
> - * ARMv7 (DDI 0406C.b): B1.14.17
> - * ARMv8 (DDI 0487A.d): D1-1511 Table D1-62
> - *
> - * NB: Both MDCR_EL2.TPM and MDCR_EL2.TPMCR cause trapping of PMCR.
> - */
> - case HSR_SYSREG_PMINTENSET_EL1:
> - case HSR_SYSREG_PMINTENCLR_EL1:
> - /*
> - * Accessible from EL1 only, but if EL0 trap happens handle as
> - * undef.
> - */
> - return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> - case HSR_SYSREG_PMUSERENR_EL0:
> - /* RO at EL0. RAZ/WI at EL1 */
> - if ( psr_mode_is_user(regs) )
> - return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 0);
> - else
> - return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> - case HSR_SYSREG_PMCR_EL0:
> - case HSR_SYSREG_PMCNTENSET_EL0:
> - case HSR_SYSREG_PMCNTENCLR_EL0:
> - case HSR_SYSREG_PMOVSCLR_EL0:
> - case HSR_SYSREG_PMSWINC_EL0:
> - case HSR_SYSREG_PMSELR_EL0:
> - case HSR_SYSREG_PMCEID0_EL0:
> - case HSR_SYSREG_PMCEID1_EL0:
> - case HSR_SYSREG_PMCCNTR_EL0:
> - case HSR_SYSREG_PMXEVTYPER_EL0:
> - case HSR_SYSREG_PMXEVCNTR_EL0:
> - case HSR_SYSREG_PMOVSSET_EL0:
> - /*
> - * Accessible at EL0 only if PMUSERENR_EL0.EN is set. We
> - * emulate that register as 0 above.
> - */
> - return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> -
> - /*
> - * !CNTHCTL_EL2.EL1PCEN
> - *
> - * ARMv8 (DDI 0487A.d): D1-1510 Table D1-60
> - */
> - case HSR_SYSREG_CNTP_CTL_EL0:
> - case HSR_SYSREG_CNTP_TVAL_EL0:
> - case HSR_SYSREG_CNTP_CVAL_EL0:
> - if ( !vtimer_emulate(regs, hsr) )
> - return inject_undef_exception(regs, hsr);
> - break;
> -
> - /*
> - * HCR_EL2.FMO or HCR_EL2.IMO
> - *
> - * GIC Architecture Specification (IHI 0069C): Section 4.6.3
> - */
> - case HSR_SYSREG_ICC_SGI1R_EL1:
> - case HSR_SYSREG_ICC_ASGI1R_EL1:
> - case HSR_SYSREG_ICC_SGI0R_EL1:
> -
> - if ( !vgic_emulate(regs, hsr) )
> - return inject_undef64_exception(regs, hsr.len);
> - break;
> -
> - /*
> - * ICC_SRE_EL2.Enable = 0
> - *
> - * GIC Architecture Specification (IHI 0069C): Section 8.1.9
> - */
> - case HSR_SYSREG_ICC_SRE_EL1:
> - /*
> - * Trapped when the guest is using GICv2 whilst the platform
> - * interrupt controller is GICv3. In this case, the register
> - * should be emulate as RAZ/WI to tell the guest to use the GIC
> - * memory mapped interface (i.e GICv2 compatibility).
> - */
> - return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
> -
> - /*
> - * HCR_EL2.TIDCP
> - *
> - * ARMv8 (DDI 0487A.d): D1-1501 Table D1-43
> - *
> - * - Reserved control space for IMPLEMENTATION DEFINED functionality.
> - *
> - * CPTR_EL2.TTA
> - *
> - * ARMv8 (DDI 0487A.d): D1-1507 Table D1-54
> - *
> - * - All implemented trace registers.
> - *
> - * And all other unknown registers.
> - */
> - default:
> - {
> - const struct hsr_sysreg sysreg = hsr.sysreg;
> -
> - gdprintk(XENLOG_ERR,
> - "%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
> - sysreg.read ? "mrs" : "msr",
> - sysreg.op0, sysreg.op1,
> - sysreg.crn, sysreg.crm,
> - sysreg.op2,
> - sysreg.read ? "=>" : "<=",
> - sysreg.reg, regs->pc);
> - gdprintk(XENLOG_ERR, "unhandled 64-bit sysreg access %#x\n",
> - hsr.bits & HSR_SYSREG_REGS_MASK);
> - inject_undef_exception(regs, hsr);
> - return;
> - }
> - }
> -
> - regs->pc += 4;
> -}
> -#endif
> -
> void dump_guest_s1_walk(struct domain *d, vaddr_t addr)
> {
> register_t ttbcr = READ_SYSREG(TCR_EL1);
> diff --git a/xen/include/asm-arm/arm64/traps.h
> b/xen/include/asm-arm/arm64/traps.h
> index e5e5a4a036..2379b578cb 100644
> --- a/xen/include/asm-arm/arm64/traps.h
> +++ b/xen/include/asm-arm/arm64/traps.h
> @@ -3,6 +3,9 @@
>
> void inject_undef64_exception(struct cpu_user_regs *regs, int instr_len);
>
> +void do_sysreg(struct cpu_user_regs *regs,
> + const union hsr hsr);
> +
> #endif /* __ASM_ARM64_TRAPS__ */
> /*
> * Local variables:
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |