Linux-RISC-V Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Updates for asm/ptrace/insn code
@ 2024-12-01 10:27 Ben Dooks
  2024-12-01 10:27 ` [PATCH v2 1/3] riscv: ptrace: add regs_set_register() Ben Dooks
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Ben Dooks @ 2024-12-01 10:27 UTC (permalink / raw)
  To: linux-riscv; +Cc: ajones, palmer

This is a re-send of the series that was setting up for the RDCYCLE
emulation in kernel space. I think these are still useful so am
re-sending this series with comments and fixups.

Even if we don't emulate RDCYCLE, we may still want to check for it
in the trap handler and possibly allow for it to be emulated later
if people feel that would be good (or at least some sort of warning
printed)

Thanks for the reviews. Hopefully this isn't too late for inclusion.



_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/3] riscv: ptrace: add regs_set_register()
  2024-12-01 10:27 Updates for asm/ptrace/insn code Ben Dooks
@ 2024-12-01 10:27 ` Ben Dooks
  2024-12-02  9:02   ` Andrew Jones
  2024-12-02 17:09   ` Björn Töpel
  2024-12-01 10:27 ` [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction Ben Dooks
  2024-12-01 10:27 ` [PATCH v2 3/3] riscv: insn: add RV_EXTRACT_FUNCT3() Ben Dooks
  2 siblings, 2 replies; 9+ messages in thread
From: Ben Dooks @ 2024-12-01 10:27 UTC (permalink / raw)
  To: linux-riscv; +Cc: ajones, palmer, Ben Dooks

Since we have regs_get_register() and we could use the set counterpart
for things like fixing up traps, add regs_set_register() to set a pt_regs
value from offset.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
v2:
  - fixed Andrew Jones' suggestions for comments
---
 arch/riscv/include/asm/ptrace.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index b5b0adcc85c1..45c503b592c8 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -143,6 +143,26 @@ static inline unsigned long regs_get_register(struct pt_regs *regs,
 	return *(unsigned long *)((unsigned long)regs + offset);
 }
 
+/**
+ * regs_set_register() - set register value at its offset
+ * @regs:	pt_regs to which register value is set
+ * @offset:	offset of the register.
+ * @value:	value to set register to
+ *
+ * regs_set_register sets the value @to to a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this will ignore the write.
+ */
+static inline void regs_set_register(struct pt_regs *regs,
+				     unsigned int offset,
+				     unsigned long value)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return;
+
+	*(unsigned long *)((unsigned long)regs + offset) = value;
+}
+
 /**
  * regs_get_kernel_argument() - get Nth function argument in kernel
  * @regs:       pt_regs of that context
-- 
2.37.2.352.g3c44437643


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction
  2024-12-01 10:27 Updates for asm/ptrace/insn code Ben Dooks
  2024-12-01 10:27 ` [PATCH v2 1/3] riscv: ptrace: add regs_set_register() Ben Dooks
@ 2024-12-01 10:27 ` Ben Dooks
  2024-12-02  9:16   ` Andrew Jones
  2024-12-02 17:30   ` Björn Töpel
  2024-12-01 10:27 ` [PATCH v2 3/3] riscv: insn: add RV_EXTRACT_FUNCT3() Ben Dooks
  2 siblings, 2 replies; 9+ messages in thread
From: Ben Dooks @ 2024-12-01 10:27 UTC (permalink / raw)
  To: linux-riscv; +Cc: ajones, palmer, Ben Dooks

Add the trapped instruction (insn) as the second argument to
riscv_v_first_use_handler() from the trap handler so when we
add more handlers we can do the fetch of the instruction just
once.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
- fixed wording of patch from rfc
v2:
  - fixed todo by going to illegal instruction error if get_user fails
  - added pointer print for failed read
  - fixed issues with rebasing onto main branch
---
 arch/riscv/include/asm/vector.h |  4 ++--
 arch/riscv/kernel/traps.c       | 14 +++++++++++++-
 arch/riscv/kernel/vector.c      | 11 +----------
 3 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index c7c023afbacd..9ec2473c1b73 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -22,7 +22,7 @@
 extern unsigned long riscv_v_vsize;
 int riscv_v_setup_vsize(void);
 bool insn_is_vector(u32 insn_buf);
-bool riscv_v_first_use_handler(struct pt_regs *regs);
+bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn);
 void kernel_vector_begin(void);
 void kernel_vector_end(void);
 void get_cpu_vector_context(void);
@@ -270,7 +270,7 @@ struct pt_regs;
 static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
 static __always_inline bool has_vector(void) { return false; }
 static __always_inline bool insn_is_vector(u32 insn_buf) { return false; }
-static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return false; }
+static inline bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn) { return false; }
 static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; }
 static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
 #define riscv_v_vsize (0)
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 51ebfd23e007..9662138ba45c 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -172,11 +172,23 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
 	bool handled;
 
 	if (user_mode(regs)) {
+		u32 __user *epc = (u32 __user *)regs->epc;
+		u32 insn = (u32)regs->badaddr;
+
 		irqentry_enter_from_user_mode(regs);
 
 		local_irq_enable();
 
-		handled = riscv_v_first_use_handler(regs);
+		if (!insn) {
+			if (__get_user(insn, epc)) {
+				printk_ratelimited(KERN_ERR "traps: failed to read instruction at user %px\n", epc);
+				handled = false;
+				insn = 0;
+			}
+		}
+
+		if (insn)
+			handled = riscv_v_first_use_handler(regs, insn);
 
 		local_irq_disable();
 
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 821818886fab..08164a9121fe 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -168,11 +168,8 @@ bool riscv_v_vstate_ctrl_user_allowed(void)
 }
 EXPORT_SYMBOL_GPL(riscv_v_vstate_ctrl_user_allowed);
 
-bool riscv_v_first_use_handler(struct pt_regs *regs)
+bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn)
 {
-	u32 __user *epc = (u32 __user *)regs->epc;
-	u32 insn = (u32)regs->badaddr;
-
 	if (!has_vector())
 		return false;
 
@@ -184,12 +181,6 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
 	if (riscv_v_vstate_query(regs))
 		return false;
 
-	/* Get the instruction */
-	if (!insn) {
-		if (__get_user(insn, epc))
-			return false;
-	}
-
 	/* Filter out non-V instructions */
 	if (!insn_is_vector(insn))
 		return false;
-- 
2.37.2.352.g3c44437643


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/3] riscv: insn: add RV_EXTRACT_FUNCT3()
  2024-12-01 10:27 Updates for asm/ptrace/insn code Ben Dooks
  2024-12-01 10:27 ` [PATCH v2 1/3] riscv: ptrace: add regs_set_register() Ben Dooks
  2024-12-01 10:27 ` [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction Ben Dooks
@ 2024-12-01 10:27 ` Ben Dooks
  2 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2024-12-01 10:27 UTC (permalink / raw)
  To: linux-riscv; +Cc: ajones, palmer, Ben Dooks

Add extraction for the func3 field of most instructions
for use with anyone who needs it.

Note, added this for decoding of CSR accesses for
work we did looking at the RDCYCLE v RDTIME calls.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 arch/riscv/include/asm/insn.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h
index 09fde95a5e8f..c67f44ff2066 100644
--- a/arch/riscv/include/asm/insn.h
+++ b/arch/riscv/include/asm/insn.h
@@ -299,6 +299,10 @@ static __always_inline bool riscv_insn_is_c_jalr(u32 code)
 	({typeof(x) x_ = (x); \
 	(RV_X(x_, RVG_RD_OPOFF, RVG_RD_MASK)); })
 
+#define RV_EXTRACT_FUNCT3(x) \
+	({typeof(x) x_ = (x); \
+	(RV_X(x_, RV_INSN_FUNCT3_OPOFF, RV_INSN_FUNCT3_MASK)); })
+
 #define RV_EXTRACT_UTYPE_IMM(x) \
 	({typeof(x) x_ = (x); \
 	(RV_X(x_, RV_U_IMM_31_12_OPOFF, RV_U_IMM_31_12_MASK)); })
-- 
2.37.2.352.g3c44437643


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] riscv: ptrace: add regs_set_register()
  2024-12-01 10:27 ` [PATCH v2 1/3] riscv: ptrace: add regs_set_register() Ben Dooks
@ 2024-12-02  9:02   ` Andrew Jones
  2024-12-02 17:09   ` Björn Töpel
  1 sibling, 0 replies; 9+ messages in thread
From: Andrew Jones @ 2024-12-02  9:02 UTC (permalink / raw)
  To: Ben Dooks; +Cc: linux-riscv, palmer

On Sun, Dec 01, 2024 at 10:27:57AM +0000, Ben Dooks wrote:
> Since we have regs_get_register() and we could use the set counterpart
> for things like fixing up traps, add regs_set_register() to set a pt_regs
> value from offset.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
> v2:
>   - fixed Andrew Jones' suggestions for comments
> ---
>  arch/riscv/include/asm/ptrace.h | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
> index b5b0adcc85c1..45c503b592c8 100644
> --- a/arch/riscv/include/asm/ptrace.h
> +++ b/arch/riscv/include/asm/ptrace.h
> @@ -143,6 +143,26 @@ static inline unsigned long regs_get_register(struct pt_regs *regs,
>  	return *(unsigned long *)((unsigned long)regs + offset);
>  }
>  
> +/**
> + * regs_set_register() - set register value at its offset
> + * @regs:	pt_regs to which register value is set
> + * @offset:	offset of the register.

drop the '.'

> + * @value:	value to set register to
> + *
> + * regs_set_register sets the value @to to a register whose offset from @regs.
                                       ^ @value

but just write regs_set_register sets @value...

also

s/whose/which is/

> + * The @offset is the offset of the register in struct pt_regs.
> + * If @offset is bigger than MAX_REG_OFFSET, this will ignore the write.
> + */
> +static inline void regs_set_register(struct pt_regs *regs,
> +				     unsigned int offset,
> +				     unsigned long value)
> +{
> +	if (unlikely(offset > MAX_REG_OFFSET))
> +		return;
> +
> +	*(unsigned long *)((unsigned long)regs + offset) = value;
> +}
> +
>  /**
>   * regs_get_kernel_argument() - get Nth function argument in kernel
>   * @regs:       pt_regs of that context
> -- 
> 2.37.2.352.g3c44437643
>

Otherwise,

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction
  2024-12-01 10:27 ` [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction Ben Dooks
@ 2024-12-02  9:16   ` Andrew Jones
  2024-12-02  9:23     ` Ben Dooks
  2024-12-02 17:30   ` Björn Töpel
  1 sibling, 1 reply; 9+ messages in thread
From: Andrew Jones @ 2024-12-02  9:16 UTC (permalink / raw)
  To: Ben Dooks; +Cc: linux-riscv, palmer

On Sun, Dec 01, 2024 at 10:27:58AM +0000, Ben Dooks wrote:
> Add the trapped instruction (insn) as the second argument to
> riscv_v_first_use_handler() from the trap handler so when we
> add more handlers we can do the fetch of the instruction just
> once.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
> - fixed wording of patch from rfc
> v2:
>   - fixed todo by going to illegal instruction error if get_user fails
>   - added pointer print for failed read
>   - fixed issues with rebasing onto main branch
> ---
>  arch/riscv/include/asm/vector.h |  4 ++--
>  arch/riscv/kernel/traps.c       | 14 +++++++++++++-
>  arch/riscv/kernel/vector.c      | 11 +----------
>  3 files changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
> index c7c023afbacd..9ec2473c1b73 100644
> --- a/arch/riscv/include/asm/vector.h
> +++ b/arch/riscv/include/asm/vector.h
> @@ -22,7 +22,7 @@
>  extern unsigned long riscv_v_vsize;
>  int riscv_v_setup_vsize(void);
>  bool insn_is_vector(u32 insn_buf);
> -bool riscv_v_first_use_handler(struct pt_regs *regs);
> +bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn);
>  void kernel_vector_begin(void);
>  void kernel_vector_end(void);
>  void get_cpu_vector_context(void);
> @@ -270,7 +270,7 @@ struct pt_regs;
>  static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
>  static __always_inline bool has_vector(void) { return false; }
>  static __always_inline bool insn_is_vector(u32 insn_buf) { return false; }
> -static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return false; }
> +static inline bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn) { return false; }
>  static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; }
>  static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
>  #define riscv_v_vsize (0)
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 51ebfd23e007..9662138ba45c 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -172,11 +172,23 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
>  	bool handled;
>  
>  	if (user_mode(regs)) {
> +		u32 __user *epc = (u32 __user *)regs->epc;
> +		u32 insn = (u32)regs->badaddr;
> +
>  		irqentry_enter_from_user_mode(regs);
>  
>  		local_irq_enable();
>  
> -		handled = riscv_v_first_use_handler(regs);
> +		if (!insn) {
> +			if (__get_user(insn, epc)) {
> +				printk_ratelimited(KERN_ERR "traps: failed to read instruction at user %px\n", epc);

I don't think we want this, even ratelimited.

> +				handled = false;
> +				insn = 0;
> +			}
> +		}
> +
> +		if (insn)
> +			handled = riscv_v_first_use_handler(regs, insn);
>  
>  		local_irq_disable();
>  
> diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
> index 821818886fab..08164a9121fe 100644
> --- a/arch/riscv/kernel/vector.c
> +++ b/arch/riscv/kernel/vector.c
> @@ -168,11 +168,8 @@ bool riscv_v_vstate_ctrl_user_allowed(void)
>  }
>  EXPORT_SYMBOL_GPL(riscv_v_vstate_ctrl_user_allowed);
>  
> -bool riscv_v_first_use_handler(struct pt_regs *regs)
> +bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn)
>  {
> -	u32 __user *epc = (u32 __user *)regs->epc;
> -	u32 insn = (u32)regs->badaddr;
> -
>  	if (!has_vector())
>  		return false;
>  
> @@ -184,12 +181,6 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
>  	if (riscv_v_vstate_query(regs))
>  		return false;
>  
> -	/* Get the instruction */
> -	if (!insn) {
> -		if (__get_user(insn, epc))
> -			return false;
> -	}
> -
>  	/* Filter out non-V instructions */
>  	if (!insn_is_vector(insn))
>  		return false;
> -- 
> 2.37.2.352.g3c44437643
>

Thanks,
drew

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction
  2024-12-02  9:16   ` Andrew Jones
@ 2024-12-02  9:23     ` Ben Dooks
  0 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2024-12-02  9:23 UTC (permalink / raw)
  To: Andrew Jones; +Cc: linux-riscv, palmer

On 02/12/2024 09:16, Andrew Jones wrote:
> On Sun, Dec 01, 2024 at 10:27:58AM +0000, Ben Dooks wrote:
>> Add the trapped instruction (insn) as the second argument to
>> riscv_v_first_use_handler() from the trap handler so when we
>> add more handlers we can do the fetch of the instruction just
>> once.
>>
>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>> ---
>> - fixed wording of patch from rfc
>> v2:
>>    - fixed todo by going to illegal instruction error if get_user fails
>>    - added pointer print for failed read
>>    - fixed issues with rebasing onto main branch
>> ---
>>   arch/riscv/include/asm/vector.h |  4 ++--
>>   arch/riscv/kernel/traps.c       | 14 +++++++++++++-
>>   arch/riscv/kernel/vector.c      | 11 +----------
>>   3 files changed, 16 insertions(+), 13 deletions(-)
>>
>> diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
>> index c7c023afbacd..9ec2473c1b73 100644
>> --- a/arch/riscv/include/asm/vector.h
>> +++ b/arch/riscv/include/asm/vector.h
>> @@ -22,7 +22,7 @@
>>   extern unsigned long riscv_v_vsize;
>>   int riscv_v_setup_vsize(void);
>>   bool insn_is_vector(u32 insn_buf);
>> -bool riscv_v_first_use_handler(struct pt_regs *regs);
>> +bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn);
>>   void kernel_vector_begin(void);
>>   void kernel_vector_end(void);
>>   void get_cpu_vector_context(void);
>> @@ -270,7 +270,7 @@ struct pt_regs;
>>   static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
>>   static __always_inline bool has_vector(void) { return false; }
>>   static __always_inline bool insn_is_vector(u32 insn_buf) { return false; }
>> -static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return false; }
>> +static inline bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn) { return false; }
>>   static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; }
>>   static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
>>   #define riscv_v_vsize (0)
>> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
>> index 51ebfd23e007..9662138ba45c 100644
>> --- a/arch/riscv/kernel/traps.c
>> +++ b/arch/riscv/kernel/traps.c
>> @@ -172,11 +172,23 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
>>   	bool handled;
>>   
>>   	if (user_mode(regs)) {
>> +		u32 __user *epc = (u32 __user *)regs->epc;
>> +		u32 insn = (u32)regs->badaddr;
>> +
>>   		irqentry_enter_from_user_mode(regs);
>>   
>>   		local_irq_enable();
>>   
>> -		handled = riscv_v_first_use_handler(regs);
>> +		if (!insn) {
>> +			if (__get_user(insn, epc)) {
>> +				printk_ratelimited(KERN_ERR "traps: failed to read instruction at user %px\n", epc);
> 
> I don't think we want this, even ratelimited.
> 

Ok, it is a bit weird but I suppose it will end up generating a fault.



-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] riscv: ptrace: add regs_set_register()
  2024-12-01 10:27 ` [PATCH v2 1/3] riscv: ptrace: add regs_set_register() Ben Dooks
  2024-12-02  9:02   ` Andrew Jones
@ 2024-12-02 17:09   ` Björn Töpel
  1 sibling, 0 replies; 9+ messages in thread
From: Björn Töpel @ 2024-12-02 17:09 UTC (permalink / raw)
  To: Ben Dooks, linux-riscv; +Cc: ajones, palmer, Ben Dooks

Ben Dooks <ben.dooks@codethink.co.uk> writes:

> Since we have regs_get_register() and we could use the set counterpart
> for things like fixing up traps, add regs_set_register() to set a pt_regs
> value from offset.
>
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
> v2:
>   - fixed Andrew Jones' suggestions for comments
> ---
>  arch/riscv/include/asm/ptrace.h | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
> index b5b0adcc85c1..45c503b592c8 100644
> --- a/arch/riscv/include/asm/ptrace.h
> +++ b/arch/riscv/include/asm/ptrace.h
> @@ -143,6 +143,26 @@ static inline unsigned long regs_get_register(struct pt_regs *regs,
>  	return *(unsigned long *)((unsigned long)regs + offset);
>  }
>  
> +/**
> + * regs_set_register() - set register value at its offset
> + * @regs:	pt_regs to which register value is set
> + * @offset:	offset of the register.
> + * @value:	value to set register to
> + *
> + * regs_set_register sets the value @to to a register whose offset from @regs.
> + * The @offset is the offset of the register in struct pt_regs.
> + * If @offset is bigger than MAX_REG_OFFSET, this will ignore the write.
> + */
> +static inline void regs_set_register(struct pt_regs *regs,
> +				     unsigned int offset,
> +				     unsigned long value)

Hobby horse warning! If you're resending for drew's comments, please use
the full 100 chars!

Björn

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction
  2024-12-01 10:27 ` [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction Ben Dooks
  2024-12-02  9:16   ` Andrew Jones
@ 2024-12-02 17:30   ` Björn Töpel
  1 sibling, 0 replies; 9+ messages in thread
From: Björn Töpel @ 2024-12-02 17:30 UTC (permalink / raw)
  To: Ben Dooks, linux-riscv; +Cc: ajones, palmer, Ben Dooks

Ben Dooks <ben.dooks@codethink.co.uk> writes:

> Add the trapped instruction (insn) as the second argument to
> riscv_v_first_use_handler() from the trap handler so when we
> add more handlers we can do the fetch of the instruction just
> once.
>
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
> - fixed wording of patch from rfc
> v2:
>   - fixed todo by going to illegal instruction error if get_user fails
>   - added pointer print for failed read
>   - fixed issues with rebasing onto main branch
> ---
>  arch/riscv/include/asm/vector.h |  4 ++--
>  arch/riscv/kernel/traps.c       | 14 +++++++++++++-
>  arch/riscv/kernel/vector.c      | 11 +----------
>  3 files changed, 16 insertions(+), 13 deletions(-)
>
> diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
> index c7c023afbacd..9ec2473c1b73 100644
> --- a/arch/riscv/include/asm/vector.h
> +++ b/arch/riscv/include/asm/vector.h
> @@ -22,7 +22,7 @@
>  extern unsigned long riscv_v_vsize;
>  int riscv_v_setup_vsize(void);
>  bool insn_is_vector(u32 insn_buf);
> -bool riscv_v_first_use_handler(struct pt_regs *regs);
> +bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn);
>  void kernel_vector_begin(void);
>  void kernel_vector_end(void);
>  void get_cpu_vector_context(void);
> @@ -270,7 +270,7 @@ struct pt_regs;
>  static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
>  static __always_inline bool has_vector(void) { return false; }
>  static __always_inline bool insn_is_vector(u32 insn_buf) { return false; }
> -static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return false; }
> +static inline bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn) { return false; }
>  static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; }
>  static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
>  #define riscv_v_vsize (0)
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 51ebfd23e007..9662138ba45c 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -172,11 +172,23 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
>  	bool handled;
>  
>  	if (user_mode(regs)) {
> +		u32 __user *epc = (u32 __user *)regs->epc;
> +		u32 insn = (u32)regs->badaddr;
> +
>  		irqentry_enter_from_user_mode(regs);
>  
>  		local_irq_enable();
>  
> -		handled = riscv_v_first_use_handler(regs);
> +		if (!insn) {
> +			if (__get_user(insn, epc)) {
> +				printk_ratelimited(KERN_ERR "traps: failed to read instruction at user %px\n", epc);
> +				handled = false;
> +				insn = 0;
> +			}
> +		}
> +
> +		if (insn)
> +			handled = riscv_v_first_use_handler(regs, insn);

Maybe it's just me, but this addition makes it a bit hard (harder!) to
read.

Maybe replace the chunk something in the lines of:

	if (!insn && __get_user(insn, epc))
		goto out;
	
	handled = riscv_v_first_use_handler(regs, insn);
out:


Björn

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-12-02 17:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-01 10:27 Updates for asm/ptrace/insn code Ben Dooks
2024-12-01 10:27 ` [PATCH v2 1/3] riscv: ptrace: add regs_set_register() Ben Dooks
2024-12-02  9:02   ` Andrew Jones
2024-12-02 17:09   ` Björn Töpel
2024-12-01 10:27 ` [PATCH v2 2/3] riscv: traps: make insn fetch common in unknown instruction Ben Dooks
2024-12-02  9:16   ` Andrew Jones
2024-12-02  9:23     ` Ben Dooks
2024-12-02 17:30   ` Björn Töpel
2024-12-01 10:27 ` [PATCH v2 3/3] riscv: insn: add RV_EXTRACT_FUNCT3() Ben Dooks

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox