[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [XEN v2 03/12] xen/Arm: vreg: Support vreg_reg64_* helpers on Aarch32


  • To: Ayan Kumar Halder <ayankuma@xxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Michal Orzel <michal.orzel@xxxxxxx>
  • Date: Wed, 2 Nov 2022 09:52:18 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=X/jLUbXTFMMm9MS2oC3GDrF/cplqLRXe+DAHKVZ9w/U=; b=jyeMIiFCWBSEcwFJLgvn6gx+AXI41IiweB2TDDMaznPDs00JsgM3lTIR2JJn54Y5nSZECOGMu0EnrNNLF4awEd2jbyrknW/i2heAoCdJUXWF48F3Sb8dkYRS1C1tbDAVRN+xt9luXtClEGwVJDgbnM4GC7b6yEfcH3bhiq+jeYprit8pZQ7rUK5PaCO5wle7t/rDs2kaVqho8eeeQZlJfGsP8mhaaGr59224JiiA3evvSqKcuETp90eVQQWEZ2VbeGNi7+0dZD54ejKVuwejseuEqBUAK3pTTObtP/KaIKcX5VJEpwIBoxDe3znLh2H9mZ7ZVHKvwkzpukdrhmdbSQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=esEuTEJp4PkZS3hUvY/RaaVcaUGd3OZJHgebkNeJVqj715FUQHDvyhsB9l8NMj4BXi1ikWlJTsYfCZVHjuUBnfhTb2ealo3GkP6mZvsKjwhI5rDfIlThi7UnPWPh2WoRScHGScePfOIrdi+0UvZ+0/2L/u1gRRSyVdW5C/U163df7rZRX23oExVg9DcA8K6LldEDuVJOvxc8QdTrAYzvvm49Q6akdopuo2JTznV8mE8NELGevQRBSqxVrsxl5Gmb0897lVIO5gG0pc+SvZ/IEsJ737VkpL1sfG2H/vhDhoaddtXcVTgNCTqzS/ORD9nFjO+N5kfHZiP0MkLbY6C2kA==
  • Cc: <sstabellini@xxxxxxxxxx>, <stefanos@xxxxxxxxxx>, <julien@xxxxxxx>, <Volodymyr_Babchuk@xxxxxxxx>, <bertrand.marquis@xxxxxxx>, <burzalodowa@xxxxxxxxx>
  • Delivery-date: Wed, 02 Nov 2022 08:52:32 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hi Ayan,

On 31/10/2022 16:13, Ayan Kumar Halder wrote:
> 
> 
> In some situations (eg GICR_TYPER), the hypervior may need to emulate
> 64bit registers in aarch32 mode. In such situations, the hypervisor may
> need to read/modify the lower or upper 32 bits of the 64 bit register.
> 
> In aarch32, 'unsigned long' is 32 bits. Thus, we cannot use it for 64 bit
> registers.
> 
> The correct approach is to typecast 'mask' based on the size of register 
> access
> (ie uint32_t or uint64_t) instead of using 'unsigned long' as it will not
> generate the correct mask for the upper 32 bits of a 64 bit register.
> Also, 'val' needs to be typecasted so that it can correctly update the upper/
> lower 32 bits of a 64 bit register.
> 
> Signed-off-by: Ayan Kumar Halder <ayankuma@xxxxxxx>
> ---
> 
> Changes from :-
> v1 - 1. Remove vreg_reg_extract(), vreg_reg_update(), vreg_reg_setbits() and
> vreg_reg_clearbits(). Moved the implementation to  vreg_reg##sz##_*.
> 'mask' and 'val' is now using uint##sz##_t.
> 
>  xen/arch/arm/include/asm/vreg.h | 88 ++++++++-------------------------
>  1 file changed, 20 insertions(+), 68 deletions(-)
> 
> diff --git a/xen/arch/arm/include/asm/vreg.h b/xen/arch/arm/include/asm/vreg.h
> index f26a70d024..122ea79b65 100644
> --- a/xen/arch/arm/include/asm/vreg.h
> +++ b/xen/arch/arm/include/asm/vreg.h
> @@ -89,107 +89,59 @@ static inline bool vreg_emulate_sysreg(struct 
> cpu_user_regs *regs, union hsr hsr
>   * The check on the size supported by the register has to be done by
>   * the caller of vreg_regN_*.
>   *
> - * vreg_reg_* should never be called directly. Instead use the vreg_regN_*
> - * according to size of the emulated register
> - *
>   * Note that the alignment fault will always be taken in the guest
>   * (see B3.12.7 DDI0406.b).
>   */
> -static inline register_t vreg_reg_extract(unsigned long reg,
> -                                          unsigned int offset,
> -                                          enum dabt_size size)
> -{
> -    reg >>= 8 * offset;
> -    reg &= VREG_REG_MASK(size);
> -
> -    return reg;
> -}
> -
> -static inline void vreg_reg_update(unsigned long *reg, register_t val,
> -                                   unsigned int offset,
> -                                   enum dabt_size size)
> -{
> -    unsigned long mask = VREG_REG_MASK(size);
> -    int shift = offset * 8;
> -
> -    *reg &= ~(mask << shift);
> -    *reg |= ((unsigned long)val & mask) << shift;
> -}
> -
> -static inline void vreg_reg_setbits(unsigned long *reg, register_t bits,
> -                                    unsigned int offset,
> -                                    enum dabt_size size)
> -{
> -    unsigned long mask = VREG_REG_MASK(size);
> -    int shift = offset * 8;
> -
> -    *reg |= ((unsigned long)bits & mask) << shift;
> -}
> -
> -static inline void vreg_reg_clearbits(unsigned long *reg, register_t bits,
> -                                      unsigned int offset,
> -                                      enum dabt_size size)
> -{
> -    unsigned long mask = VREG_REG_MASK(size);
> -    int shift = offset * 8;
> -
> -    *reg &= ~(((unsigned long)bits & mask) << shift);
> -}
> 
>  /* N-bit register helpers */
>  #define VREG_REG_HELPERS(sz, offmask)                                   \
>  static inline register_t vreg_reg##sz##_extract(uint##sz##_t reg,       \
>                                                  const mmio_info_t *info)\
>  {                                                                       \
> -    return vreg_reg_extract(reg, info->gpa & (offmask),                 \
> -                            info->dabt.size);                           \
> +    unsigned int offset = info->gpa & (offmask);                        \
In all the other helpers you are also defining the variables to store shift and 
mask,
no matter the number of uses. I know that this is a left over from the removed 
helpers,
but since you are modifying the file you could improve consistency and define 
them
here as well.

> +                                                                        \
> +    reg >>= 8 * offset;                                                 \
> +    reg &= VREG_REG_MASK(info->dabt.size);                              \
> +                                                                        \
> +    return reg;                                                         \
>  }                                                                       \
>                                                                          \
>  static inline void vreg_reg##sz##_update(uint##sz##_t *reg,             \
>                                           register_t val,                \
>                                           const mmio_info_t *info)       \
>  {                                                                       \
> -    unsigned long tmp = *reg;                                           \
> -                                                                        \
> -    vreg_reg_update(&tmp, val, info->gpa & (offmask),                   \
> -                    info->dabt.size);                                   \
> +    unsigned int offset = info->gpa & (offmask);                        \
> +    uint##sz##_t mask = VREG_REG_MASK(info->dabt.size);                 \
> +    int shift = offset * 8;                                             \
>                                                                          \
> -    *reg = tmp;                                                         \
> +    *reg &= ~(mask << shift);                                           \
> +    *reg |= ((uint##sz##_t)val & mask) << shift;                        \
>  }                                                                       \
>                                                                          \
>  static inline void vreg_reg##sz##_setbits(uint##sz##_t *reg,            \
>                                            register_t bits,              \
>                                            const mmio_info_t *info)      \
>  {                                                                       \
> -    unsigned long tmp = *reg;                                           \
> -                                                                        \
> -    vreg_reg_setbits(&tmp, bits, info->gpa & (offmask),                 \
> -                     info->dabt.size);                                  \
> +    unsigned int offset = info->gpa & (offmask);                        \
> +    uint##sz##_t mask = VREG_REG_MASK(info->dabt.size);                 \
> +    int shift = offset * 8;                                             \
>                                                                          \
> -    *reg = tmp;                                                         \
> +    *reg |= ((uint##sz##_t)bits & mask) << shift;                       \
>  }                                                                       \
>                                                                          \
>  static inline void vreg_reg##sz##_clearbits(uint##sz##_t *reg,          \
>                                              register_t bits,            \
>                                              const mmio_info_t *info)    \
>  {                                                                       \
> -    unsigned long tmp = *reg;                                           \
> +    unsigned int offset = info->gpa & (offmask);                        \
> +    uint##sz##_t mask = VREG_REG_MASK(info->dabt.size);                 \
> +    int shift = offset * 8;                                             \
>                                                                          \
> -    vreg_reg_clearbits(&tmp, bits, info->gpa & (offmask),               \
> -                       info->dabt.size);                                \
> -                                                                        \
> -    *reg = tmp;                                                         \
> +    *reg &= ~(((uint##sz##_t)bits & mask) << shift);                    \
>  }
> 
> -/*
> - * 64 bits registers are only supported on platform with 64-bit long.
> - * This is also allow us to optimize the 32 bit case by using
> - * unsigned long rather than uint64_t
> - */
> -#if BITS_PER_LONG == 64
> -VREG_REG_HELPERS(64, 0x7);
> -#endif
>  VREG_REG_HELPERS(32, 0x3);
> +VREG_REG_HELPERS(64, 0x7);
No need for the movement. 64 should stay as it was before 32 and you should only
remove the guards.

> 
>  #undef VREG_REG_HELPERS
> 
> --
> 2.17.1
> 
> 
Apart from that, the change looks good.

~Michal



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.