|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [RFC PATCH] xen/arm: Replace vreg_emulate_{sysreg/cp}32 with vreg_emulate_{sysreg/cp}
Hi Michal,
> On 27 Jul 2021, at 10:50 am, Michal Orzel <Michal.Orzel@xxxxxxx> wrote:
>
> According to ARMv8A architecture, AArch64 registers
> are 64bit wide even though in many cases the upper
> 32bit is reserved. Therefore there is no need for
> function vreg_emulate_sysreg32 on arm64.
>
> Ideally on arm64 there should be only one function
> vreg_emulate_sysreg(using register_t) or
> vreg_emulate_sysreg64(using uint64_t) but in the Xen code
> there is a lot of functions passed both to the
> vreg_emulate_cp* and vreg_emulate_sysreg*.
> This would require to duplicate them which is not
> a good solution.
>
> The easiest/minimal solution to fix this issue is
> to replace vreg_emulate_{sysreg/cp}32 with
> vreg_emulate_{sysreg/cp}. The modifed functions
> are now taking function pointer:
> -typedef bool (*vreg_reg_fn_t)(struct cpu_user_regs *regs,
> register_t *r, bool read);
> instead of:
> -typedef bool (*vreg_reg32_fn_t)(struct cpu_user_regs *regs,
> uint32_t *r, bool read);
>
> This change allows to properly use 64bit registers on arm64
> and in case of 32bit guest the cast is done by the hardware
> due to the 32bit registers being the lower part of 64bit ones.
>
> Signed-off-by: Michal Orzel <michal.orzel@xxxxxxx>
Reviewed-by: Rahul Singh <rahul.singh@xxxxxxx>
Regards,
Rahul
> ---
> The reason for this change is to clean up the mess related to types.
> This patch achieves that but it does not reduce the code size.
> I'm not sure whether we want such change hence it is pushed as RFC.
> ---
> xen/arch/arm/vcpreg.c | 16 +++++++++++-----
> xen/arch/arm/vtimer.c | 18 +++++++++---------
> xen/include/asm-arm/vreg.h | 14 +++++++-------
> 3 files changed, 27 insertions(+), 21 deletions(-)
>
> diff --git a/xen/arch/arm/vcpreg.c b/xen/arch/arm/vcpreg.c
> index e3ce56d875..376a1ceee2 100644
> --- a/xen/arch/arm/vcpreg.c
> +++ b/xen/arch/arm/vcpreg.c
> @@ -57,9 +57,12 @@
> #define WRITE_SYSREG_SZ(sz, val, sysreg...) WRITE_SYSREG##sz(val, sysreg)
> #endif
>
> +#define type32_t register_t
> +#define type64_t uint64_t
> +
> /* The name is passed from the upper macro to workaround macro expansion. */
> #define TVM_REG(sz, func, reg...) \
> -static bool func(struct cpu_user_regs *regs, uint##sz##_t *r, bool read) \
> +static bool func(struct cpu_user_regs *regs, type##sz##_t *r, bool read) \
> { \
> struct vcpu *v = current; \
> bool cache_enabled = vcpu_has_cache_enabled(v); \
> @@ -83,7 +86,7 @@ static bool func(struct cpu_user_regs *regs, uint##sz##_t
> *r, bool read) \
>
> #else /* CONFIG_ARM_64 */
> #define TVM_REG32_COMBINED(lowreg, hireg, xreg) \
> -static bool vreg_emulate_##xreg(struct cpu_user_regs *regs, uint32_t *r, \
> +static bool vreg_emulate_##xreg(struct cpu_user_regs *regs, register_t *r, \
> bool read, bool hi) \
> { \
> struct vcpu *v = current; \
> @@ -108,13 +111,13 @@ static bool vreg_emulate_##xreg(struct cpu_user_regs
> *regs, uint32_t *r, \
> return true; \
> } \
> \
> -static bool vreg_emulate_##lowreg(struct cpu_user_regs *regs, uint32_t *r, \
> +static bool vreg_emulate_##lowreg(struct cpu_user_regs *regs, register_t *r,\
> bool read) \
> { \
> return vreg_emulate_##xreg(regs, r, read, false); \
> } \
> \
> -static bool vreg_emulate_##hireg(struct cpu_user_regs *regs, uint32_t *r, \
> +static bool vreg_emulate_##hireg(struct cpu_user_regs *regs, register_t *r, \
> bool read) \
> { \
> return vreg_emulate_##xreg(regs, r, read, true); \
> @@ -154,13 +157,16 @@ TVM_REG32_COMBINED(MAIR0, MAIR1, MAIR_EL1)
> TVM_REG32_COMBINED(AMAIR0, AMAIR1, AMAIR_EL1)
> TVM_REG32(CONTEXTIDR, CONTEXTIDR_EL1)
>
> +#define VREG_EMULATE_CP32(regs, hsr, fn) vreg_emulate_cp(regs, hsr, fn)
> +#define VREG_EMULATE_CP64(regs, hsr, fn) vreg_emulate_cp64(regs, hsr, fn)
> +
> /* Macro to generate easily case for co-processor emulation. */
> #define GENERATE_CASE(reg, sz) \
> case HSR_CPREG##sz(reg): \
> { \
> bool res; \
> \
> - res = vreg_emulate_cp##sz(regs, hsr, vreg_emulate_##reg); \
> + res = VREG_EMULATE_CP##sz(regs, hsr, vreg_emulate_##reg); \
> ASSERT(res); \
> break; \
> }
> diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
> index 167fc6127a..17b5649a05 100644
> --- a/xen/arch/arm/vtimer.c
> +++ b/xen/arch/arm/vtimer.c
> @@ -162,7 +162,7 @@ void virt_timer_restore(struct vcpu *v)
> WRITE_SYSREG(v->arch.virt_timer.ctl, CNTV_CTL_EL0);
> }
>
> -static bool vtimer_cntp_ctl(struct cpu_user_regs *regs, uint32_t *r, bool
> read)
> +static bool vtimer_cntp_ctl(struct cpu_user_regs *regs, register_t *r, bool
> read)
> {
> struct vcpu *v = current;
> s_time_t expires;
> @@ -176,7 +176,7 @@ static bool vtimer_cntp_ctl(struct cpu_user_regs *regs,
> uint32_t *r, bool read)
> }
> else
> {
> - uint32_t ctl = *r & ~CNTx_CTL_PENDING;
> + register_t ctl = *r & ~CNTx_CTL_PENDING;
> if ( ctl & CNTx_CTL_ENABLE )
> ctl |= v->arch.phys_timer.ctl & CNTx_CTL_PENDING;
> v->arch.phys_timer.ctl = ctl;
> @@ -197,7 +197,7 @@ static bool vtimer_cntp_ctl(struct cpu_user_regs *regs,
> uint32_t *r, bool read)
> return true;
> }
>
> -static bool vtimer_cntp_tval(struct cpu_user_regs *regs, uint32_t *r,
> +static bool vtimer_cntp_tval(struct cpu_user_regs *regs, register_t *r,
> bool read)
> {
> struct vcpu *v = current;
> @@ -211,11 +211,11 @@ static bool vtimer_cntp_tval(struct cpu_user_regs
> *regs, uint32_t *r,
>
> if ( read )
> {
> - *r = (uint32_t)((v->arch.phys_timer.cval - cntpct) & 0xffffffffull);
> + *r = (register_t)((v->arch.phys_timer.cval - cntpct) &
> 0xffffffffull);
> }
> else
> {
> - v->arch.phys_timer.cval = cntpct + (uint64_t)(int32_t)*r;
> + v->arch.phys_timer.cval = cntpct + (uint64_t)(register_t)*r;
> if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
> {
> v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING;
> @@ -274,10 +274,10 @@ static bool vtimer_emulate_cp32(struct cpu_user_regs
> *regs, union hsr hsr)
> switch ( hsr.bits & HSR_CP32_REGS_MASK )
> {
> case HSR_CPREG32(CNTP_CTL):
> - return vreg_emulate_cp32(regs, hsr, vtimer_cntp_ctl);
> + return vreg_emulate_cp(regs, hsr, vtimer_cntp_ctl);
>
> case HSR_CPREG32(CNTP_TVAL):
> - return vreg_emulate_cp32(regs, hsr, vtimer_cntp_tval);
> + return vreg_emulate_cp(regs, hsr, vtimer_cntp_tval);
>
> default:
> return false;
> @@ -316,9 +316,9 @@ static bool vtimer_emulate_sysreg(struct cpu_user_regs
> *regs, union hsr hsr)
> switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
> {
> case HSR_SYSREG_CNTP_CTL_EL0:
> - return vreg_emulate_sysreg32(regs, hsr, vtimer_cntp_ctl);
> + return vreg_emulate_sysreg(regs, hsr, vtimer_cntp_ctl);
> case HSR_SYSREG_CNTP_TVAL_EL0:
> - return vreg_emulate_sysreg32(regs, hsr, vtimer_cntp_tval);
> + return vreg_emulate_sysreg(regs, hsr, vtimer_cntp_tval);
> case HSR_SYSREG_CNTP_CVAL_EL0:
> return vreg_emulate_sysreg64(regs, hsr, vtimer_cntp_cval);
>
> diff --git a/xen/include/asm-arm/vreg.h b/xen/include/asm-arm/vreg.h
> index 1253753833..cef55aabea 100644
> --- a/xen/include/asm-arm/vreg.h
> +++ b/xen/include/asm-arm/vreg.h
> @@ -4,13 +4,13 @@
> #ifndef __ASM_ARM_VREG__
> #define __ASM_ARM_VREG__
>
> -typedef bool (*vreg_reg32_fn_t)(struct cpu_user_regs *regs, uint32_t *r,
> +typedef bool (*vreg_reg_fn_t)(struct cpu_user_regs *regs, register_t *r,
> bool read);
> typedef bool (*vreg_reg64_fn_t)(struct cpu_user_regs *regs, uint64_t *r,
> bool read);
>
> -static inline bool vreg_emulate_cp32(struct cpu_user_regs *regs, union hsr
> hsr,
> - vreg_reg32_fn_t fn)
> +static inline bool vreg_emulate_cp(struct cpu_user_regs *regs, union hsr hsr,
> + vreg_reg_fn_t fn)
> {
> struct hsr_cp32 cp32 = hsr.cp32;
> /*
> @@ -18,7 +18,7 @@ static inline bool vreg_emulate_cp32(struct cpu_user_regs
> *regs, union hsr hsr,
> * implementation error in the emulation (such as not correctly
> * setting r).
> */
> - uint32_t r = 0;
> + register_t r = 0;
> bool ret;
>
> if ( !cp32.read )
> @@ -64,11 +64,11 @@ static inline bool vreg_emulate_cp64(struct cpu_user_regs
> *regs, union hsr hsr,
> }
>
> #ifdef CONFIG_ARM_64
> -static inline bool vreg_emulate_sysreg32(struct cpu_user_regs *regs, union
> hsr hsr,
> - vreg_reg32_fn_t fn)
> +static inline bool vreg_emulate_sysreg(struct cpu_user_regs *regs, union hsr
> hsr,
> + vreg_reg_fn_t fn)
> {
> struct hsr_sysreg sysreg = hsr.sysreg;
> - uint32_t r = 0;
> + register_t r = 0;
> bool ret;
>
> if ( !sysreg.read )
> --
> 2.29.0
>
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |