diff mbox series

arch: arm64: always set EL=1 when injecting undefined exception

Message ID 20250212144950.2818089-1-volodymyr_babchuk@epam.com (mailing list archive)
State New
Headers show
Series arch: arm64: always set EL=1 when injecting undefined exception | expand

Commit Message

Volodymyr Babchuk Feb. 12, 2025, 2:50 p.m. UTC
ARM Architecture Reference Manual states that EL field of ESR_EL1
register should be 1 when EC is 0b000000 aka HSR_EC_UNKNOWN.

Section D24.2.40, page D24-7337 of ARM DDI 0487L:

  IL, bit [25]
  Instruction Length for synchronous exceptions. Possible values of this bit are:

  [...]

  0b1 - 32-bit instruction trapped.
  This value is also used when the exception is one of the following:
  [...]
   - An exception reported using EC value 0b000000.

To align code with the specification, set .len field to 1 in
inject_undef64_exception() and remove unneeded second parameter.

Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
---
 xen/arch/arm/arm64/vsysreg.c           |  8 ++++----
 xen/arch/arm/include/asm/arm64/traps.h |  2 +-
 xen/arch/arm/include/asm/traps.h       |  2 +-
 xen/arch/arm/p2m.c                     |  2 +-
 xen/arch/arm/traps.c                   | 24 ++++++++++++------------
 xen/arch/arm/vcpreg.c                  | 24 ++++++++++++------------
 xen/arch/arm/vsmc.c                    |  6 ++----
 7 files changed, 33 insertions(+), 35 deletions(-)

Comments

Stefano Stabellini Feb. 12, 2025, 10:03 p.m. UTC | #1
On Wed, 12 Feb 2025, Volodymyr Babchuk wrote:
> ARM Architecture Reference Manual states that EL field of ESR_EL1
> register should be 1 when EC is 0b000000 aka HSR_EC_UNKNOWN.
> 
> Section D24.2.40, page D24-7337 of ARM DDI 0487L:
> 
>   IL, bit [25]
>   Instruction Length for synchronous exceptions. Possible values of this bit are:
> 
>   [...]
> 
>   0b1 - 32-bit instruction trapped.
>   This value is also used when the exception is one of the following:
>   [...]
>    - An exception reported using EC value 0b000000.
> 
> To align code with the specification, set .len field to 1 in
> inject_undef64_exception() and remove unneeded second parameter.
> 
> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>


> ---
>  xen/arch/arm/arm64/vsysreg.c           |  8 ++++----
>  xen/arch/arm/include/asm/arm64/traps.h |  2 +-
>  xen/arch/arm/include/asm/traps.h       |  2 +-
>  xen/arch/arm/p2m.c                     |  2 +-
>  xen/arch/arm/traps.c                   | 24 ++++++++++++------------
>  xen/arch/arm/vcpreg.c                  | 24 ++++++++++++------------
>  xen/arch/arm/vsmc.c                    |  6 ++----
>  7 files changed, 33 insertions(+), 35 deletions(-)
> 
> diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c
> index c73b2c95ce..29622a8593 100644
> --- a/xen/arch/arm/arm64/vsysreg.c
> +++ b/xen/arch/arm/arm64/vsysreg.c
> @@ -95,7 +95,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>       */
>      case HSR_SYSREG_ACTLR_EL1:
>          if ( regs_mode_is_user(regs) )
> -            return inject_undef_exception(regs, hsr);
> +            return inject_undef_exception(regs);
>          if ( hsr.sysreg.read )
>              set_user_reg(regs, regidx, v->arch.actlr);
>          break;
> @@ -267,7 +267,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>      case HSR_SYSREG_CNTP_TVAL_EL0:
>      case HSR_SYSREG_CNTP_CVAL_EL0:
>          if ( !vtimer_emulate(regs, hsr) )
> -            return inject_undef_exception(regs, hsr);
> +            return inject_undef_exception(regs);
>          break;
>  
>      /*
> @@ -280,7 +280,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>      case HSR_SYSREG_ICC_SGI0R_EL1:
>  
>          if ( !vgic_emulate(regs, hsr) )
> -            return inject_undef64_exception(regs, hsr.len);
> +            return inject_undef64_exception(regs);
>          break;
>  
>      /*
> @@ -440,7 +440,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>      gdprintk(XENLOG_ERR,
>               "unhandled 64-bit sysreg access %#"PRIregister"\n",
>               hsr.bits & HSR_SYSREG_REGS_MASK);
> -    inject_undef_exception(regs, hsr);
> +    inject_undef_exception(regs);
>  }
>  
>  /*
> diff --git a/xen/arch/arm/include/asm/arm64/traps.h b/xen/arch/arm/include/asm/arm64/traps.h
> index a347cb13d6..3be2fa69ee 100644
> --- a/xen/arch/arm/include/asm/arm64/traps.h
> +++ b/xen/arch/arm/include/asm/arm64/traps.h
> @@ -1,7 +1,7 @@
>  #ifndef __ASM_ARM64_TRAPS__
>  #define __ASM_ARM64_TRAPS__
>  
> -void inject_undef64_exception(struct cpu_user_regs *regs, int instr_len);
> +void inject_undef64_exception(struct cpu_user_regs *regs);
>  
>  void do_sysreg(struct cpu_user_regs *regs,
>                 const union hsr hsr);
> diff --git a/xen/arch/arm/include/asm/traps.h b/xen/arch/arm/include/asm/traps.h
> index 9a60dbf70e..3b40afe262 100644
> --- a/xen/arch/arm/include/asm/traps.h
> +++ b/xen/arch/arm/include/asm/traps.h
> @@ -44,7 +44,7 @@ int check_conditional_instr(struct cpu_user_regs *regs, const union hsr hsr);
>  
>  void advance_pc(struct cpu_user_regs *regs, const union hsr hsr);
>  
> -void inject_undef_exception(struct cpu_user_regs *regs, const union hsr hsr);
> +void inject_undef_exception(struct cpu_user_regs *regs);
>  
>  /* read as zero and write ignore */
>  void handle_raz_wi(struct cpu_user_regs *regs, int regidx, bool read,
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 65b70955e3..6196cad0d4 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -438,7 +438,7 @@ void p2m_set_way_flush(struct vcpu *v, struct cpu_user_regs *regs,
>      {
>          gprintk(XENLOG_ERR,
>                  "The cache should be flushed by VA rather than by set/way.\n");
> -        inject_undef_exception(regs, hsr);
> +        inject_undef_exception(regs);
>          return;
>      }
>  
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index 737f4d65e3..5338d5c033 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -533,12 +533,12 @@ static vaddr_t exception_handler64(struct cpu_user_regs *regs, vaddr_t offset)
>  }
>  
>  /* Inject an undefined exception into a 64 bit guest */
> -void inject_undef64_exception(struct cpu_user_regs *regs, int instr_len)
> +void inject_undef64_exception(struct cpu_user_regs *regs)
>  {
>      vaddr_t handler;
>      const union hsr esr = {
>          .iss = 0,
> -        .len = instr_len,
> +        .len = 1,
>          .ec = HSR_EC_UNKNOWN,
>      };
>  
> @@ -606,13 +606,13 @@ static void inject_iabt64_exception(struct cpu_user_regs *regs,
>  
>  #endif
>  
> -void inject_undef_exception(struct cpu_user_regs *regs, const union hsr hsr)
> +void inject_undef_exception(struct cpu_user_regs *regs)
>  {
>          if ( is_32bit_domain(current->domain) )
>              inject_undef32_exception(regs);
>  #ifdef CONFIG_ARM_64
>          else
> -            inject_undef64_exception(regs, hsr.len);
> +            inject_undef64_exception(regs);
>  #endif
>  }
>  
> @@ -1418,7 +1418,7 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
>      if ( hsr.iss != XEN_HYPERCALL_TAG )
>      {
>          gprintk(XENLOG_WARNING, "Invalid HVC imm 0x%x\n", hsr.iss);
> -        return inject_undef_exception(regs, hsr);
> +        return inject_undef_exception(regs);
>      }
>  
>      curr->hcall_preempted = false;
> @@ -1655,7 +1655,7 @@ void handle_raz_wi(struct cpu_user_regs *regs,
>      ASSERT((min_el == 0) || (min_el == 1));
>  
>      if ( min_el > 0 && regs_mode_is_user(regs) )
> -        return inject_undef_exception(regs, hsr);
> +        return inject_undef_exception(regs);
>  
>      if ( read )
>          set_user_reg(regs, regidx, 0);
> @@ -1674,10 +1674,10 @@ void handle_wo_wi(struct cpu_user_regs *regs,
>      ASSERT((min_el == 0) || (min_el == 1));
>  
>      if ( min_el > 0 && regs_mode_is_user(regs) )
> -        return inject_undef_exception(regs, hsr);
> +        return inject_undef_exception(regs);
>  
>      if ( read )
> -        return inject_undef_exception(regs, hsr);
> +        return inject_undef_exception(regs);
>      /* else: ignore */
>  
>      advance_pc(regs, hsr);
> @@ -1694,10 +1694,10 @@ void handle_ro_read_val(struct cpu_user_regs *regs,
>      ASSERT((min_el == 0) || (min_el == 1));
>  
>      if ( min_el > 0 && regs_mode_is_user(regs) )
> -        return inject_undef_exception(regs, hsr);
> +        return inject_undef_exception(regs);
>  
>      if ( !read )
> -        return inject_undef_exception(regs, hsr);
> +        return inject_undef_exception(regs);
>  
>      set_user_reg(regs, regidx, val);
>  
> @@ -2147,7 +2147,7 @@ void asmlinkage do_trap_guest_sync(struct cpu_user_regs *regs)
>      case HSR_EC_SVE:
>          GUEST_BUG_ON(regs_mode_is_32bit(regs));
>          gprintk(XENLOG_WARNING, "Domain tried to use SVE while not allowed\n");
> -        inject_undef_exception(regs, hsr);
> +        inject_undef_exception(regs);
>          break;
>  #endif
>  
> @@ -2164,7 +2164,7 @@ void asmlinkage do_trap_guest_sync(struct cpu_user_regs *regs)
>          gprintk(XENLOG_WARNING,
>                  "Unknown Guest Trap. HSR=%#"PRIregister" EC=0x%x IL=%x Syndrome=0x%"PRIx32"\n",
>                  hsr.bits, hsr.ec, hsr.len, hsr.iss);
> -        inject_undef_exception(regs, hsr);
> +        inject_undef_exception(regs);
>          break;
>      }
>  }
> diff --git a/xen/arch/arm/vcpreg.c b/xen/arch/arm/vcpreg.c
> index 0b336875a4..a7f627bfe0 100644
> --- a/xen/arch/arm/vcpreg.c
> +++ b/xen/arch/arm/vcpreg.c
> @@ -206,7 +206,7 @@ void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr)
>      case HSR_CPREG32(CNTP_CTL):
>      case HSR_CPREG32(CNTP_TVAL):
>          if ( !vtimer_emulate(regs, hsr) )
> -            return inject_undef_exception(regs, hsr);
> +            return inject_undef_exception(regs);
>          break;
>  
>      /*
> @@ -217,7 +217,7 @@ void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr)
>       */
>      case HSR_CPREG32(ACTLR):
>          if ( regs_mode_is_user(regs) )
> -            return inject_undef_exception(regs, hsr);
> +            return inject_undef_exception(regs);
>          if ( cp32.read )
>              set_user_reg(regs, regidx, v->arch.actlr);
>          break;
> @@ -397,7 +397,7 @@ void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr)
>                   cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
>          gdprintk(XENLOG_ERR, "unhandled 32-bit CP15 access %#"PRIregister"\n",
>                   hsr.bits & HSR_CP32_REGS_MASK);
> -        inject_undef_exception(regs, hsr);
> +        inject_undef_exception(regs);
>          return;
>      }
>      advance_pc(regs, hsr);
> @@ -421,7 +421,7 @@ void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr)
>       */
>      case HSR_CPREG64(CNTP_CVAL):
>          if ( !vtimer_emulate(regs, hsr) )
> -            return inject_undef_exception(regs, hsr);
> +            return inject_undef_exception(regs);
>          break;
>  
>      /*
> @@ -433,7 +433,7 @@ void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr)
>      case HSR_CPREG64(ICC_ASGI1R):
>      case HSR_CPREG64(ICC_SGI0R):
>          if ( !vgic_emulate(regs, hsr) )
> -            return inject_undef_exception(regs, hsr);
> +            return inject_undef_exception(regs);
>          break;
>  
>      GENERATE_CASE(TTBR0, 64)
> @@ -467,7 +467,7 @@ void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr)
>              gdprintk(XENLOG_ERR,
>                       "unhandled 64-bit CP15 access %#"PRIregister"\n",
>                       hsr.bits & HSR_CP64_REGS_MASK);
> -            inject_undef_exception(regs, hsr);
> +            inject_undef_exception(regs);
>              return;
>          }
>      }
> @@ -532,7 +532,7 @@ void do_cp14_32(struct cpu_user_regs *regs, const union hsr hsr)
>           * is set to 0, which we emulated below.
>           */
>          if ( !cp32.read )
> -            return inject_undef_exception(regs, hsr);
> +            return inject_undef_exception(regs);
>  
>          /* Implement the minimum requirements:
>           *  - Number of watchpoints: 1
> @@ -631,7 +631,7 @@ void do_cp14_32(struct cpu_user_regs *regs, const union hsr hsr)
>               cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
>      gdprintk(XENLOG_ERR, "unhandled 32-bit cp14 access %#"PRIregister"\n",
>               hsr.bits & HSR_CP32_REGS_MASK);
> -    inject_undef_exception(regs, hsr);
> +    inject_undef_exception(regs);
>  }
>  
>  void do_cp14_64(struct cpu_user_regs *regs, const union hsr hsr)
> @@ -669,7 +669,7 @@ void do_cp14_64(struct cpu_user_regs *regs, const union hsr hsr)
>               cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
>      gdprintk(XENLOG_ERR, "unhandled 64-bit CP14 access %#"PRIregister"\n",
>               hsr.bits & HSR_CP64_REGS_MASK);
> -    inject_undef_exception(regs, hsr);
> +    inject_undef_exception(regs);
>  }
>  
>  void do_cp14_dbg(struct cpu_user_regs *regs, const union hsr hsr)
> @@ -698,7 +698,7 @@ void do_cp14_dbg(struct cpu_user_regs *regs, const union hsr hsr)
>      gdprintk(XENLOG_ERR, "unhandled 64-bit CP14 DBG access %#"PRIregister"\n",
>               hsr.bits & HSR_CP64_REGS_MASK);
>  
> -    inject_undef_exception(regs, hsr);
> +    inject_undef_exception(regs);
>  }
>  
>  void do_cp10(struct cpu_user_regs *regs, const union hsr hsr)
> @@ -731,7 +731,7 @@ void do_cp10(struct cpu_user_regs *regs, const union hsr hsr)
>                   cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
>          gdprintk(XENLOG_ERR, "unhandled 32-bit CP10 access %#"PRIregister"\n",
>                   hsr.bits & HSR_CP32_REGS_MASK);
> -        inject_undef_exception(regs, hsr);
> +        inject_undef_exception(regs);
>          return;
>      }
>      
> @@ -756,7 +756,7 @@ void do_cp(struct cpu_user_regs *regs, const union hsr hsr)
>  
>      ASSERT(!cp.tas); /* We don't trap SIMD instruction */
>      gdprintk(XENLOG_ERR, "unhandled CP%d access\n", cp.coproc);
> -    inject_undef_exception(regs, hsr);
> +    inject_undef_exception(regs);
>  }
>  
>  /*
> diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c
> index 62d8117a12..e253865b6c 100644
> --- a/xen/arch/arm/vsmc.c
> +++ b/xen/arch/arm/vsmc.c
> @@ -346,13 +346,11 @@ void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr)
>      if ( vsmccc_handle_call(regs) )
>          advance_pc(regs, hsr);
>      else
> -        inject_undef_exception(regs, hsr);
> +        inject_undef_exception(regs);
>  }
>  
>  void do_trap_hvc_smccc(struct cpu_user_regs *regs)
>  {
> -    const union hsr hsr = { .bits = regs->hsr };
> -
>      /*
>       * vsmccc_handle_call() will return false if this call is not
>       * SMCCC compatible (e.g. immediate value != 0). As it is not
> @@ -360,7 +358,7 @@ void do_trap_hvc_smccc(struct cpu_user_regs *regs)
>       * ARM_SMCCC_ERR_UNKNOWN_FUNCTION.
>       */
>      if ( !vsmccc_handle_call(regs) )
> -        inject_undef_exception(regs, hsr);
> +        inject_undef_exception(regs);
>  }
>  
>  /*
> -- 
> 2.47.1
>
Michal Orzel Feb. 13, 2025, 8:29 a.m. UTC | #2
Hi Volodymyr,

NIT: s/EL/IL/ in commit title

One remark below.

On 12/02/2025 23:03, Stefano Stabellini wrote:
> 
> 
> On Wed, 12 Feb 2025, Volodymyr Babchuk wrote:
>> ARM Architecture Reference Manual states that EL field of ESR_EL1
>> register should be 1 when EC is 0b000000 aka HSR_EC_UNKNOWN.
>>
>> Section D24.2.40, page D24-7337 of ARM DDI 0487L:
>>
>>   IL, bit [25]
>>   Instruction Length for synchronous exceptions. Possible values of this bit are:
>>
>>   [...]
>>
>>   0b1 - 32-bit instruction trapped.
>>   This value is also used when the exception is one of the following:
>>   [...]
>>    - An exception reported using EC value 0b000000.
>>
>> To align code with the specification, set .len field to 1 in
>> inject_undef64_exception() and remove unneeded second parameter.
>>
>> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
> 
> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
> 
> 
>> ---
>>  xen/arch/arm/arm64/vsysreg.c           |  8 ++++----
>>  xen/arch/arm/include/asm/arm64/traps.h |  2 +-
>>  xen/arch/arm/include/asm/traps.h       |  2 +-
>>  xen/arch/arm/p2m.c                     |  2 +-
>>  xen/arch/arm/traps.c                   | 24 ++++++++++++------------
>>  xen/arch/arm/vcpreg.c                  | 24 ++++++++++++------------
>>  xen/arch/arm/vsmc.c                    |  6 ++----
>>  7 files changed, 33 insertions(+), 35 deletions(-)
>>
>> diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c
>> index c73b2c95ce..29622a8593 100644
>> --- a/xen/arch/arm/arm64/vsysreg.c
>> +++ b/xen/arch/arm/arm64/vsysreg.c
>> @@ -95,7 +95,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>>       */
>>      case HSR_SYSREG_ACTLR_EL1:
>>          if ( regs_mode_is_user(regs) )
>> -            return inject_undef_exception(regs, hsr);
>> +            return inject_undef_exception(regs);
>>          if ( hsr.sysreg.read )
>>              set_user_reg(regs, regidx, v->arch.actlr);
>>          break;
>> @@ -267,7 +267,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>>      case HSR_SYSREG_CNTP_TVAL_EL0:
>>      case HSR_SYSREG_CNTP_CVAL_EL0:
>>          if ( !vtimer_emulate(regs, hsr) )
>> -            return inject_undef_exception(regs, hsr);
>> +            return inject_undef_exception(regs);
>>          break;
>>
>>      /*
>> @@ -280,7 +280,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>>      case HSR_SYSREG_ICC_SGI0R_EL1:
>>
>>          if ( !vgic_emulate(regs, hsr) )
>> -            return inject_undef64_exception(regs, hsr.len);
>> +            return inject_undef64_exception(regs);
>>          break;
>>
>>      /*
>> @@ -440,7 +440,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>>      gdprintk(XENLOG_ERR,
>>               "unhandled 64-bit sysreg access %#"PRIregister"\n",
>>               hsr.bits & HSR_SYSREG_REGS_MASK);
>> -    inject_undef_exception(regs, hsr);
>> +    inject_undef_exception(regs);
>>  }
>>
>>  /*
>> diff --git a/xen/arch/arm/include/asm/arm64/traps.h b/xen/arch/arm/include/asm/arm64/traps.h
>> index a347cb13d6..3be2fa69ee 100644
>> --- a/xen/arch/arm/include/asm/arm64/traps.h
>> +++ b/xen/arch/arm/include/asm/arm64/traps.h
>> @@ -1,7 +1,7 @@
>>  #ifndef __ASM_ARM64_TRAPS__
>>  #define __ASM_ARM64_TRAPS__
>>
>> -void inject_undef64_exception(struct cpu_user_regs *regs, int instr_len);
>> +void inject_undef64_exception(struct cpu_user_regs *regs);
>>
>>  void do_sysreg(struct cpu_user_regs *regs,
>>                 const union hsr hsr);
>> diff --git a/xen/arch/arm/include/asm/traps.h b/xen/arch/arm/include/asm/traps.h
>> index 9a60dbf70e..3b40afe262 100644
>> --- a/xen/arch/arm/include/asm/traps.h
>> +++ b/xen/arch/arm/include/asm/traps.h
>> @@ -44,7 +44,7 @@ int check_conditional_instr(struct cpu_user_regs *regs, const union hsr hsr);
>>
>>  void advance_pc(struct cpu_user_regs *regs, const union hsr hsr);
>>
>> -void inject_undef_exception(struct cpu_user_regs *regs, const union hsr hsr);
>> +void inject_undef_exception(struct cpu_user_regs *regs);
>>
>>  /* read as zero and write ignore */
>>  void handle_raz_wi(struct cpu_user_regs *regs, int regidx, bool read,
>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>> index 65b70955e3..6196cad0d4 100644
>> --- a/xen/arch/arm/p2m.c
>> +++ b/xen/arch/arm/p2m.c
>> @@ -438,7 +438,7 @@ void p2m_set_way_flush(struct vcpu *v, struct cpu_user_regs *regs,
>>      {
>>          gprintk(XENLOG_ERR,
>>                  "The cache should be flushed by VA rather than by set/way.\n");
>> -        inject_undef_exception(regs, hsr);
>> +        inject_undef_exception(regs);
There's nothing using hsr anymore, so you should drop hsr parameter from
p2m_set_way_flush()

BTW. Are you going to also look at simplifying e.g. inject_iabt_exception() for
which IL is also 1?

~Michal
Michal Orzel Feb. 13, 2025, 11:13 a.m. UTC | #3
You seem to have accidentally dropped xen-devel. Re-adding.

On 13/02/2025 12:04, Volodymyr Babchuk wrote:
> 
> 
> Hi Michal,
> 
> "Orzel, Michal" <michal.orzel@amd.com> writes:
> 
>> Hi Volodymyr,
>>
>> NIT: s/EL/IL/ in commit title
> 
> Sure, thanks.
> 
>> One remark below.
>>
>> On 12/02/2025 23:03, Stefano Stabellini wrote:
>>>
>>>
>>> On Wed, 12 Feb 2025, Volodymyr Babchuk wrote:
>>>> ARM Architecture Reference Manual states that EL field of ESR_EL1
>>>> register should be 1 when EC is 0b000000 aka HSR_EC_UNKNOWN.
>>>>
>>>> Section D24.2.40, page D24-7337 of ARM DDI 0487L:
>>>>
>>>>   IL, bit [25]
>>>>   Instruction Length for synchronous exceptions. Possible values of this bit are:
>>>>
>>>>   [...]
>>>>
>>>>   0b1 - 32-bit instruction trapped.
>>>>   This value is also used when the exception is one of the following:
>>>>   [...]
>>>>    - An exception reported using EC value 0b000000.
>>>>
>>>> To align code with the specification, set .len field to 1 in
>>>> inject_undef64_exception() and remove unneeded second parameter.
>>>>
>>>> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
>>>
>>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>>>
>>>
>>>> ---
>>>>  xen/arch/arm/arm64/vsysreg.c           |  8 ++++----
>>>>  xen/arch/arm/include/asm/arm64/traps.h |  2 +-
>>>>  xen/arch/arm/include/asm/traps.h       |  2 +-
>>>>  xen/arch/arm/p2m.c                     |  2 +-
>>>>  xen/arch/arm/traps.c                   | 24 ++++++++++++------------
>>>>  xen/arch/arm/vcpreg.c                  | 24 ++++++++++++------------
>>>>  xen/arch/arm/vsmc.c                    |  6 ++----
>>>>  7 files changed, 33 insertions(+), 35 deletions(-)
>>>>
>>>> diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c
>>>> index c73b2c95ce..29622a8593 100644
>>>> --- a/xen/arch/arm/arm64/vsysreg.c
>>>> +++ b/xen/arch/arm/arm64/vsysreg.c
>>>> @@ -95,7 +95,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>>>>       */
>>>>      case HSR_SYSREG_ACTLR_EL1:
>>>>          if ( regs_mode_is_user(regs) )
>>>> -            return inject_undef_exception(regs, hsr);
>>>> +            return inject_undef_exception(regs);
>>>>          if ( hsr.sysreg.read )
>>>>              set_user_reg(regs, regidx, v->arch.actlr);
>>>>          break;
>>>> @@ -267,7 +267,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>>>>      case HSR_SYSREG_CNTP_TVAL_EL0:
>>>>      case HSR_SYSREG_CNTP_CVAL_EL0:
>>>>          if ( !vtimer_emulate(regs, hsr) )
>>>> -            return inject_undef_exception(regs, hsr);
>>>> +            return inject_undef_exception(regs);
>>>>          break;
>>>>
>>>>      /*
>>>> @@ -280,7 +280,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>>>>      case HSR_SYSREG_ICC_SGI0R_EL1:
>>>>
>>>>          if ( !vgic_emulate(regs, hsr) )
>>>> -            return inject_undef64_exception(regs, hsr.len);
>>>> +            return inject_undef64_exception(regs);
>>>>          break;
>>>>
>>>>      /*
>>>> @@ -440,7 +440,7 @@ void do_sysreg(struct cpu_user_regs *regs,
>>>>      gdprintk(XENLOG_ERR,
>>>>               "unhandled 64-bit sysreg access %#"PRIregister"\n",
>>>>               hsr.bits & HSR_SYSREG_REGS_MASK);
>>>> -    inject_undef_exception(regs, hsr);
>>>> +    inject_undef_exception(regs);
>>>>  }
>>>>
>>>>  /*
>>>> diff --git a/xen/arch/arm/include/asm/arm64/traps.h b/xen/arch/arm/include/asm/arm64/traps.h
>>>> index a347cb13d6..3be2fa69ee 100644
>>>> --- a/xen/arch/arm/include/asm/arm64/traps.h
>>>> +++ b/xen/arch/arm/include/asm/arm64/traps.h
>>>> @@ -1,7 +1,7 @@
>>>>  #ifndef __ASM_ARM64_TRAPS__
>>>>  #define __ASM_ARM64_TRAPS__
>>>>
>>>> -void inject_undef64_exception(struct cpu_user_regs *regs, int instr_len);
>>>> +void inject_undef64_exception(struct cpu_user_regs *regs);
>>>>
>>>>  void do_sysreg(struct cpu_user_regs *regs,
>>>>                 const union hsr hsr);
>>>> diff --git a/xen/arch/arm/include/asm/traps.h b/xen/arch/arm/include/asm/traps.h
>>>> index 9a60dbf70e..3b40afe262 100644
>>>> --- a/xen/arch/arm/include/asm/traps.h
>>>> +++ b/xen/arch/arm/include/asm/traps.h
>>>> @@ -44,7 +44,7 @@ int check_conditional_instr(struct cpu_user_regs *regs, const union hsr hsr);
>>>>
>>>>  void advance_pc(struct cpu_user_regs *regs, const union hsr hsr);
>>>>
>>>> -void inject_undef_exception(struct cpu_user_regs *regs, const union hsr hsr);
>>>> +void inject_undef_exception(struct cpu_user_regs *regs);
>>>>
>>>>  /* read as zero and write ignore */
>>>>  void handle_raz_wi(struct cpu_user_regs *regs, int regidx, bool read,
>>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>>> index 65b70955e3..6196cad0d4 100644
>>>> --- a/xen/arch/arm/p2m.c
>>>> +++ b/xen/arch/arm/p2m.c
>>>> @@ -438,7 +438,7 @@ void p2m_set_way_flush(struct vcpu *v, struct cpu_user_regs *regs,
>>>>      {
>>>>          gprintk(XENLOG_ERR,
>>>>                  "The cache should be flushed by VA rather than by set/way.\n");
>>>> -        inject_undef_exception(regs, hsr);
>>>> +        inject_undef_exception(regs);
>> There's nothing using hsr anymore, so you should drop hsr parameter from
>> p2m_set_way_flush()
> 
> You are right, I'll do this in the second version. It is strange that
> compiler didn't warn me about unused parameter, though...
You would need to explicitly set -Wunused-parameter in EXTRA_CFLAGS_XEN_CORE.
There are other issues there though.

> 
>> BTW. Are you going to also look at simplifying e.g. inject_iabt_exception() for
>> which IL is also 1?
> 
> Yes, I'll add a separate patch in the next version.
> 
> --
> WBR, Volodymyr

~Michal
diff mbox series

Patch

diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c
index c73b2c95ce..29622a8593 100644
--- a/xen/arch/arm/arm64/vsysreg.c
+++ b/xen/arch/arm/arm64/vsysreg.c
@@ -95,7 +95,7 @@  void do_sysreg(struct cpu_user_regs *regs,
      */
     case HSR_SYSREG_ACTLR_EL1:
         if ( regs_mode_is_user(regs) )
-            return inject_undef_exception(regs, hsr);
+            return inject_undef_exception(regs);
         if ( hsr.sysreg.read )
             set_user_reg(regs, regidx, v->arch.actlr);
         break;
@@ -267,7 +267,7 @@  void do_sysreg(struct cpu_user_regs *regs,
     case HSR_SYSREG_CNTP_TVAL_EL0:
     case HSR_SYSREG_CNTP_CVAL_EL0:
         if ( !vtimer_emulate(regs, hsr) )
-            return inject_undef_exception(regs, hsr);
+            return inject_undef_exception(regs);
         break;
 
     /*
@@ -280,7 +280,7 @@  void do_sysreg(struct cpu_user_regs *regs,
     case HSR_SYSREG_ICC_SGI0R_EL1:
 
         if ( !vgic_emulate(regs, hsr) )
-            return inject_undef64_exception(regs, hsr.len);
+            return inject_undef64_exception(regs);
         break;
 
     /*
@@ -440,7 +440,7 @@  void do_sysreg(struct cpu_user_regs *regs,
     gdprintk(XENLOG_ERR,
              "unhandled 64-bit sysreg access %#"PRIregister"\n",
              hsr.bits & HSR_SYSREG_REGS_MASK);
-    inject_undef_exception(regs, hsr);
+    inject_undef_exception(regs);
 }
 
 /*
diff --git a/xen/arch/arm/include/asm/arm64/traps.h b/xen/arch/arm/include/asm/arm64/traps.h
index a347cb13d6..3be2fa69ee 100644
--- a/xen/arch/arm/include/asm/arm64/traps.h
+++ b/xen/arch/arm/include/asm/arm64/traps.h
@@ -1,7 +1,7 @@ 
 #ifndef __ASM_ARM64_TRAPS__
 #define __ASM_ARM64_TRAPS__
 
-void inject_undef64_exception(struct cpu_user_regs *regs, int instr_len);
+void inject_undef64_exception(struct cpu_user_regs *regs);
 
 void do_sysreg(struct cpu_user_regs *regs,
                const union hsr hsr);
diff --git a/xen/arch/arm/include/asm/traps.h b/xen/arch/arm/include/asm/traps.h
index 9a60dbf70e..3b40afe262 100644
--- a/xen/arch/arm/include/asm/traps.h
+++ b/xen/arch/arm/include/asm/traps.h
@@ -44,7 +44,7 @@  int check_conditional_instr(struct cpu_user_regs *regs, const union hsr hsr);
 
 void advance_pc(struct cpu_user_regs *regs, const union hsr hsr);
 
-void inject_undef_exception(struct cpu_user_regs *regs, const union hsr hsr);
+void inject_undef_exception(struct cpu_user_regs *regs);
 
 /* read as zero and write ignore */
 void handle_raz_wi(struct cpu_user_regs *regs, int regidx, bool read,
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 65b70955e3..6196cad0d4 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -438,7 +438,7 @@  void p2m_set_way_flush(struct vcpu *v, struct cpu_user_regs *regs,
     {
         gprintk(XENLOG_ERR,
                 "The cache should be flushed by VA rather than by set/way.\n");
-        inject_undef_exception(regs, hsr);
+        inject_undef_exception(regs);
         return;
     }
 
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 737f4d65e3..5338d5c033 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -533,12 +533,12 @@  static vaddr_t exception_handler64(struct cpu_user_regs *regs, vaddr_t offset)
 }
 
 /* Inject an undefined exception into a 64 bit guest */
-void inject_undef64_exception(struct cpu_user_regs *regs, int instr_len)
+void inject_undef64_exception(struct cpu_user_regs *regs)
 {
     vaddr_t handler;
     const union hsr esr = {
         .iss = 0,
-        .len = instr_len,
+        .len = 1,
         .ec = HSR_EC_UNKNOWN,
     };
 
@@ -606,13 +606,13 @@  static void inject_iabt64_exception(struct cpu_user_regs *regs,
 
 #endif
 
-void inject_undef_exception(struct cpu_user_regs *regs, const union hsr hsr)
+void inject_undef_exception(struct cpu_user_regs *regs)
 {
         if ( is_32bit_domain(current->domain) )
             inject_undef32_exception(regs);
 #ifdef CONFIG_ARM_64
         else
-            inject_undef64_exception(regs, hsr.len);
+            inject_undef64_exception(regs);
 #endif
 }
 
@@ -1418,7 +1418,7 @@  static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
     if ( hsr.iss != XEN_HYPERCALL_TAG )
     {
         gprintk(XENLOG_WARNING, "Invalid HVC imm 0x%x\n", hsr.iss);
-        return inject_undef_exception(regs, hsr);
+        return inject_undef_exception(regs);
     }
 
     curr->hcall_preempted = false;
@@ -1655,7 +1655,7 @@  void handle_raz_wi(struct cpu_user_regs *regs,
     ASSERT((min_el == 0) || (min_el == 1));
 
     if ( min_el > 0 && regs_mode_is_user(regs) )
-        return inject_undef_exception(regs, hsr);
+        return inject_undef_exception(regs);
 
     if ( read )
         set_user_reg(regs, regidx, 0);
@@ -1674,10 +1674,10 @@  void handle_wo_wi(struct cpu_user_regs *regs,
     ASSERT((min_el == 0) || (min_el == 1));
 
     if ( min_el > 0 && regs_mode_is_user(regs) )
-        return inject_undef_exception(regs, hsr);
+        return inject_undef_exception(regs);
 
     if ( read )
-        return inject_undef_exception(regs, hsr);
+        return inject_undef_exception(regs);
     /* else: ignore */
 
     advance_pc(regs, hsr);
@@ -1694,10 +1694,10 @@  void handle_ro_read_val(struct cpu_user_regs *regs,
     ASSERT((min_el == 0) || (min_el == 1));
 
     if ( min_el > 0 && regs_mode_is_user(regs) )
-        return inject_undef_exception(regs, hsr);
+        return inject_undef_exception(regs);
 
     if ( !read )
-        return inject_undef_exception(regs, hsr);
+        return inject_undef_exception(regs);
 
     set_user_reg(regs, regidx, val);
 
@@ -2147,7 +2147,7 @@  void asmlinkage do_trap_guest_sync(struct cpu_user_regs *regs)
     case HSR_EC_SVE:
         GUEST_BUG_ON(regs_mode_is_32bit(regs));
         gprintk(XENLOG_WARNING, "Domain tried to use SVE while not allowed\n");
-        inject_undef_exception(regs, hsr);
+        inject_undef_exception(regs);
         break;
 #endif
 
@@ -2164,7 +2164,7 @@  void asmlinkage do_trap_guest_sync(struct cpu_user_regs *regs)
         gprintk(XENLOG_WARNING,
                 "Unknown Guest Trap. HSR=%#"PRIregister" EC=0x%x IL=%x Syndrome=0x%"PRIx32"\n",
                 hsr.bits, hsr.ec, hsr.len, hsr.iss);
-        inject_undef_exception(regs, hsr);
+        inject_undef_exception(regs);
         break;
     }
 }
diff --git a/xen/arch/arm/vcpreg.c b/xen/arch/arm/vcpreg.c
index 0b336875a4..a7f627bfe0 100644
--- a/xen/arch/arm/vcpreg.c
+++ b/xen/arch/arm/vcpreg.c
@@ -206,7 +206,7 @@  void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr)
     case HSR_CPREG32(CNTP_CTL):
     case HSR_CPREG32(CNTP_TVAL):
         if ( !vtimer_emulate(regs, hsr) )
-            return inject_undef_exception(regs, hsr);
+            return inject_undef_exception(regs);
         break;
 
     /*
@@ -217,7 +217,7 @@  void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr)
      */
     case HSR_CPREG32(ACTLR):
         if ( regs_mode_is_user(regs) )
-            return inject_undef_exception(regs, hsr);
+            return inject_undef_exception(regs);
         if ( cp32.read )
             set_user_reg(regs, regidx, v->arch.actlr);
         break;
@@ -397,7 +397,7 @@  void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr)
                  cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
         gdprintk(XENLOG_ERR, "unhandled 32-bit CP15 access %#"PRIregister"\n",
                  hsr.bits & HSR_CP32_REGS_MASK);
-        inject_undef_exception(regs, hsr);
+        inject_undef_exception(regs);
         return;
     }
     advance_pc(regs, hsr);
@@ -421,7 +421,7 @@  void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr)
      */
     case HSR_CPREG64(CNTP_CVAL):
         if ( !vtimer_emulate(regs, hsr) )
-            return inject_undef_exception(regs, hsr);
+            return inject_undef_exception(regs);
         break;
 
     /*
@@ -433,7 +433,7 @@  void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr)
     case HSR_CPREG64(ICC_ASGI1R):
     case HSR_CPREG64(ICC_SGI0R):
         if ( !vgic_emulate(regs, hsr) )
-            return inject_undef_exception(regs, hsr);
+            return inject_undef_exception(regs);
         break;
 
     GENERATE_CASE(TTBR0, 64)
@@ -467,7 +467,7 @@  void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr)
             gdprintk(XENLOG_ERR,
                      "unhandled 64-bit CP15 access %#"PRIregister"\n",
                      hsr.bits & HSR_CP64_REGS_MASK);
-            inject_undef_exception(regs, hsr);
+            inject_undef_exception(regs);
             return;
         }
     }
@@ -532,7 +532,7 @@  void do_cp14_32(struct cpu_user_regs *regs, const union hsr hsr)
          * is set to 0, which we emulated below.
          */
         if ( !cp32.read )
-            return inject_undef_exception(regs, hsr);
+            return inject_undef_exception(regs);
 
         /* Implement the minimum requirements:
          *  - Number of watchpoints: 1
@@ -631,7 +631,7 @@  void do_cp14_32(struct cpu_user_regs *regs, const union hsr hsr)
              cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
     gdprintk(XENLOG_ERR, "unhandled 32-bit cp14 access %#"PRIregister"\n",
              hsr.bits & HSR_CP32_REGS_MASK);
-    inject_undef_exception(regs, hsr);
+    inject_undef_exception(regs);
 }
 
 void do_cp14_64(struct cpu_user_regs *regs, const union hsr hsr)
@@ -669,7 +669,7 @@  void do_cp14_64(struct cpu_user_regs *regs, const union hsr hsr)
              cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
     gdprintk(XENLOG_ERR, "unhandled 64-bit CP14 access %#"PRIregister"\n",
              hsr.bits & HSR_CP64_REGS_MASK);
-    inject_undef_exception(regs, hsr);
+    inject_undef_exception(regs);
 }
 
 void do_cp14_dbg(struct cpu_user_regs *regs, const union hsr hsr)
@@ -698,7 +698,7 @@  void do_cp14_dbg(struct cpu_user_regs *regs, const union hsr hsr)
     gdprintk(XENLOG_ERR, "unhandled 64-bit CP14 DBG access %#"PRIregister"\n",
              hsr.bits & HSR_CP64_REGS_MASK);
 
-    inject_undef_exception(regs, hsr);
+    inject_undef_exception(regs);
 }
 
 void do_cp10(struct cpu_user_regs *regs, const union hsr hsr)
@@ -731,7 +731,7 @@  void do_cp10(struct cpu_user_regs *regs, const union hsr hsr)
                  cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
         gdprintk(XENLOG_ERR, "unhandled 32-bit CP10 access %#"PRIregister"\n",
                  hsr.bits & HSR_CP32_REGS_MASK);
-        inject_undef_exception(regs, hsr);
+        inject_undef_exception(regs);
         return;
     }
     
@@ -756,7 +756,7 @@  void do_cp(struct cpu_user_regs *regs, const union hsr hsr)
 
     ASSERT(!cp.tas); /* We don't trap SIMD instruction */
     gdprintk(XENLOG_ERR, "unhandled CP%d access\n", cp.coproc);
-    inject_undef_exception(regs, hsr);
+    inject_undef_exception(regs);
 }
 
 /*
diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c
index 62d8117a12..e253865b6c 100644
--- a/xen/arch/arm/vsmc.c
+++ b/xen/arch/arm/vsmc.c
@@ -346,13 +346,11 @@  void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr)
     if ( vsmccc_handle_call(regs) )
         advance_pc(regs, hsr);
     else
-        inject_undef_exception(regs, hsr);
+        inject_undef_exception(regs);
 }
 
 void do_trap_hvc_smccc(struct cpu_user_regs *regs)
 {
-    const union hsr hsr = { .bits = regs->hsr };
-
     /*
      * vsmccc_handle_call() will return false if this call is not
      * SMCCC compatible (e.g. immediate value != 0). As it is not
@@ -360,7 +358,7 @@  void do_trap_hvc_smccc(struct cpu_user_regs *regs)
      * ARM_SMCCC_ERR_UNKNOWN_FUNCTION.
      */
     if ( !vsmccc_handle_call(regs) )
-        inject_undef_exception(regs, hsr);
+        inject_undef_exception(regs);
 }
 
 /*