[PATCH 22/33] riscv: signal: abstract header saving for setup_sigcontext

Deepak Gupta posted 33 patches 1 month, 3 weeks ago
There is a newer version of this series
[PATCH 22/33] riscv: signal: abstract header saving for setup_sigcontext
Posted by Deepak Gupta 1 month, 3 weeks ago
From: Andy Chiu <andy.chiu@sifive.com>

The function save_v_state() served two purposes. First, it saved
extension context into the signal stack. Then, it constructed the
extension header if there was no fault. The second part is independent
of the extension itself. As a result, we can pull that part out, so
future extensions may reuse it. This patch adds arch_ext_list and makes
setup_sigcontext() go through all possible extensions' save() callback.
The callback returns a positive value indicating the size of the
successfully saved extension. Then the kernel proceeds to construct the
header for that extension. The kernel skips an extension if it does
not exist, or if the saving fails for some reasons. The error code is
propagated out on the later case.

This patch does not introduce any functional changes.

Signed-off-by: Andy Chiu <andy.chiu@sifive.com>
---
 arch/riscv/kernel/signal.c | 60 ++++++++++++++++++++++++++++++----------------
 1 file changed, 39 insertions(+), 21 deletions(-)

diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index dcd282419456..014ac1024b85 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -68,18 +68,18 @@ static long save_fp_state(struct pt_regs *regs,
 #define restore_fp_state(task, regs) (0)
 #endif
 
-#ifdef CONFIG_RISCV_ISA_V
-
-static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
+static long save_v_state(struct pt_regs *regs, void __user *sc_vec)
 {
-	struct __riscv_ctx_hdr __user *hdr;
 	struct __sc_riscv_v_state __user *state;
 	void __user *datap;
 	long err;
 
-	hdr = *sc_vec;
-	/* Place state to the user's signal context space after the hdr */
-	state = (struct __sc_riscv_v_state __user *)(hdr + 1);
+	if (!IS_ENABLED(CONFIG_RISCV_ISA_V) ||
+		!(has_vector() && riscv_v_vstate_query(regs)))
+		return 0;
+
+	/* Place state to the user's signal context spac */
+	state = (struct __sc_riscv_v_state __user *)sc_vec;
 	/* Point datap right after the end of __sc_riscv_v_state */
 	datap = state + 1;
 
@@ -97,15 +97,11 @@ static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
 	err |= __put_user((__force void *)datap, &state->v_state.datap);
 	/* Copy the whole vector content to user space datap. */
 	err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize);
-	/* Copy magic to the user space after saving  all vector conetext */
-	err |= __put_user(RISCV_V_MAGIC, &hdr->magic);
-	err |= __put_user(riscv_v_sc_size, &hdr->size);
 	if (unlikely(err))
-		return err;
+		return -EFAULT;
 
-	/* Only progress the sv_vec if everything has done successfully  */
-	*sc_vec += riscv_v_sc_size;
-	return 0;
+	/* Only return the size if everything has done successfully  */
+	return riscv_v_sc_size;
 }
 
 /*
@@ -142,10 +138,19 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
 	 */
 	return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
 }
-#else
-#define save_v_state(task, regs) (0)
-#define __restore_v_state(task, regs) (0)
-#endif
+
+struct arch_ext_priv {
+	__u32 magic;
+	long (*save)(struct pt_regs *regs, void __user *sc_vec);
+};
+
+struct arch_ext_priv arch_ext_list[] = {
+	{
+		.magic = RISCV_V_MAGIC,
+		.save = &save_v_state,
+	},
+};
+const size_t nr_arch_exts = ARRAY_SIZE(arch_ext_list);
 
 static long restore_sigcontext(struct pt_regs *regs,
 	struct sigcontext __user *sc)
@@ -276,7 +281,8 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
 {
 	struct sigcontext __user *sc = &frame->uc.uc_mcontext;
 	struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
-	long err;
+	struct arch_ext_priv *arch_ext;
+	long err, i, ext_size;
 
 	/* sc_regs is structured the same as the start of pt_regs */
 	err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
@@ -284,8 +290,20 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
 	if (has_fpu())
 		err |= save_fp_state(regs, &sc->sc_fpregs);
 	/* Save the vector state. */
-	if (has_vector() && riscv_v_vstate_query(regs))
-		err |= save_v_state(regs, (void __user **)&sc_ext_ptr);
+	for (i = 0; i < nr_arch_exts; i++) {
+		arch_ext = &arch_ext_list[i];
+		if (!arch_ext->save)
+			continue;
+
+		ext_size = arch_ext->save(regs, sc_ext_ptr + 1);
+		if (ext_size <= 0) {
+			err |= ext_size;
+		} else {
+			err |= __put_user(arch_ext->magic, &sc_ext_ptr->magic);
+			err |= __put_user(ext_size, &sc_ext_ptr->size);
+			sc_ext_ptr = (void *)sc_ext_ptr + ext_size;
+		}
+	}
 	/* Write zero to fp-reserved space and check it on restore_sigcontext */
 	err |= __put_user(0, &sc->sc_extdesc.reserved);
 	/* And put END __riscv_ctx_hdr at the end. */

-- 
2.45.0
Re: [PATCH 22/33] riscv: signal: abstract header saving for setup_sigcontext
Posted by kernel test robot 1 month, 3 weeks ago
Hi Deepak,

kernel test robot noticed the following build errors:

[auto build test ERROR on 9852d85ec9d492ebef56dc5f229416c925758edc]

url:    https://github.com/intel-lab-lkp/linux/commits/Deepak-Gupta/mm-Introduce-ARCH_HAS_USER_SHADOW_STACK/20241002-000937
base:   9852d85ec9d492ebef56dc5f229416c925758edc
patch link:    https://lore.kernel.org/r/20241001-v5_user_cfi_series-v1-22-3ba65b6e550f%40rivosinc.com
patch subject: [PATCH 22/33] riscv: signal: abstract header saving for setup_sigcontext
config: riscv-allnoconfig (https://download.01.org/0day-ci/archive/20241004/202410040912.4TpCD7iU-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241004/202410040912.4TpCD7iU-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410040912.4TpCD7iU-lkp@intel.com/

All errors (new ones prefixed by >>):

   arch/riscv/kernel/signal.c: In function 'save_v_state':
>> arch/riscv/kernel/signal.c:89:9: error: implicit declaration of function 'get_cpu_vector_context' [-Wimplicit-function-declaration]
      89 |         get_cpu_vector_context();
         |         ^~~~~~~~~~~~~~~~~~~~~~
>> arch/riscv/kernel/signal.c:91:9: error: implicit declaration of function 'put_cpu_vector_context' [-Wimplicit-function-declaration]
      91 |         put_cpu_vector_context();
         |         ^~~~~~~~~~~~~~~~~~~~~~
   arch/riscv/kernel/signal.c: In function '__restore_v_state':
>> arch/riscv/kernel/signal.c:123:9: error: implicit declaration of function 'riscv_v_vstate_set_restore'; did you mean 'riscv_v_vstate_restore'? [-Wimplicit-function-declaration]
     123 |         riscv_v_vstate_set_restore(current, regs);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
         |         riscv_v_vstate_restore


vim +/get_cpu_vector_context +89 arch/riscv/kernel/signal.c

e2c0cdfba7f699 Palmer Dabbelt 2017-07-10   70  
3fad3080e143f7 Andy Chiu      2024-10-01   71  static long save_v_state(struct pt_regs *regs, void __user *sc_vec)
8ee0b41898fa26 Greentime Hu   2023-06-05   72  {
8ee0b41898fa26 Greentime Hu   2023-06-05   73  	struct __sc_riscv_v_state __user *state;
8ee0b41898fa26 Greentime Hu   2023-06-05   74  	void __user *datap;
8ee0b41898fa26 Greentime Hu   2023-06-05   75  	long err;
8ee0b41898fa26 Greentime Hu   2023-06-05   76  
3fad3080e143f7 Andy Chiu      2024-10-01   77  	if (!IS_ENABLED(CONFIG_RISCV_ISA_V) ||
3fad3080e143f7 Andy Chiu      2024-10-01   78  		!(has_vector() && riscv_v_vstate_query(regs)))
3fad3080e143f7 Andy Chiu      2024-10-01   79  		return 0;
3fad3080e143f7 Andy Chiu      2024-10-01   80  
3fad3080e143f7 Andy Chiu      2024-10-01   81  	/* Place state to the user's signal context spac */
3fad3080e143f7 Andy Chiu      2024-10-01   82  	state = (struct __sc_riscv_v_state __user *)sc_vec;
8ee0b41898fa26 Greentime Hu   2023-06-05   83  	/* Point datap right after the end of __sc_riscv_v_state */
8ee0b41898fa26 Greentime Hu   2023-06-05   84  	datap = state + 1;
8ee0b41898fa26 Greentime Hu   2023-06-05   85  
8ee0b41898fa26 Greentime Hu   2023-06-05   86  	/* datap is designed to be 16 byte aligned for better performance */
1d20e5d437cfeb Zhongqiu Han   2024-06-20   87  	WARN_ON(!IS_ALIGNED((unsigned long)datap, 16));
8ee0b41898fa26 Greentime Hu   2023-06-05   88  
7df56cbc27e423 Andy Chiu      2024-01-15  @89  	get_cpu_vector_context();
d6c78f1ca3e8ec Andy Chiu      2024-01-15   90  	riscv_v_vstate_save(&current->thread.vstate, regs);
7df56cbc27e423 Andy Chiu      2024-01-15  @91  	put_cpu_vector_context();
7df56cbc27e423 Andy Chiu      2024-01-15   92  
8ee0b41898fa26 Greentime Hu   2023-06-05   93  	/* Copy everything of vstate but datap. */
8ee0b41898fa26 Greentime Hu   2023-06-05   94  	err = __copy_to_user(&state->v_state, &current->thread.vstate,
8ee0b41898fa26 Greentime Hu   2023-06-05   95  			     offsetof(struct __riscv_v_ext_state, datap));
8ee0b41898fa26 Greentime Hu   2023-06-05   96  	/* Copy the pointer datap itself. */
869436dae72acf Ben Dooks      2023-11-23   97  	err |= __put_user((__force void *)datap, &state->v_state.datap);
8ee0b41898fa26 Greentime Hu   2023-06-05   98  	/* Copy the whole vector content to user space datap. */
8ee0b41898fa26 Greentime Hu   2023-06-05   99  	err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize);
8ee0b41898fa26 Greentime Hu   2023-06-05  100  	if (unlikely(err))
3fad3080e143f7 Andy Chiu      2024-10-01  101  		return -EFAULT;
8ee0b41898fa26 Greentime Hu   2023-06-05  102  
3fad3080e143f7 Andy Chiu      2024-10-01  103  	/* Only return the size if everything has done successfully  */
3fad3080e143f7 Andy Chiu      2024-10-01  104  	return riscv_v_sc_size;
8ee0b41898fa26 Greentime Hu   2023-06-05  105  }
8ee0b41898fa26 Greentime Hu   2023-06-05  106  
8ee0b41898fa26 Greentime Hu   2023-06-05  107  /*
8ee0b41898fa26 Greentime Hu   2023-06-05  108   * Restore Vector extension context from the user's signal frame. This function
8ee0b41898fa26 Greentime Hu   2023-06-05  109   * assumes a valid extension header. So magic and size checking must be done by
8ee0b41898fa26 Greentime Hu   2023-06-05  110   * the caller.
8ee0b41898fa26 Greentime Hu   2023-06-05  111   */
8ee0b41898fa26 Greentime Hu   2023-06-05  112  static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
8ee0b41898fa26 Greentime Hu   2023-06-05  113  {
8ee0b41898fa26 Greentime Hu   2023-06-05  114  	long err;
8ee0b41898fa26 Greentime Hu   2023-06-05  115  	struct __sc_riscv_v_state __user *state = sc_vec;
8ee0b41898fa26 Greentime Hu   2023-06-05  116  	void __user *datap;
8ee0b41898fa26 Greentime Hu   2023-06-05  117  
c27fa53b858b4e Björn Töpel    2024-04-03  118  	/*
c27fa53b858b4e Björn Töpel    2024-04-03  119  	 * Mark the vstate as clean prior performing the actual copy,
c27fa53b858b4e Björn Töpel    2024-04-03  120  	 * to avoid getting the vstate incorrectly clobbered by the
c27fa53b858b4e Björn Töpel    2024-04-03  121  	 *  discarded vector state.
c27fa53b858b4e Björn Töpel    2024-04-03  122  	 */
c27fa53b858b4e Björn Töpel    2024-04-03 @123  	riscv_v_vstate_set_restore(current, regs);
c27fa53b858b4e Björn Töpel    2024-04-03  124  
8ee0b41898fa26 Greentime Hu   2023-06-05  125  	/* Copy everything of __sc_riscv_v_state except datap. */
8ee0b41898fa26 Greentime Hu   2023-06-05  126  	err = __copy_from_user(&current->thread.vstate, &state->v_state,
8ee0b41898fa26 Greentime Hu   2023-06-05  127  			       offsetof(struct __riscv_v_ext_state, datap));
8ee0b41898fa26 Greentime Hu   2023-06-05  128  	if (unlikely(err))
8ee0b41898fa26 Greentime Hu   2023-06-05  129  		return err;
8ee0b41898fa26 Greentime Hu   2023-06-05  130  
8ee0b41898fa26 Greentime Hu   2023-06-05  131  	/* Copy the pointer datap itself. */
8ee0b41898fa26 Greentime Hu   2023-06-05  132  	err = __get_user(datap, &state->v_state.datap);
8ee0b41898fa26 Greentime Hu   2023-06-05  133  	if (unlikely(err))
8ee0b41898fa26 Greentime Hu   2023-06-05  134  		return err;
8ee0b41898fa26 Greentime Hu   2023-06-05  135  	/*
8ee0b41898fa26 Greentime Hu   2023-06-05  136  	 * Copy the whole vector content from user space datap. Use
8ee0b41898fa26 Greentime Hu   2023-06-05  137  	 * copy_from_user to prevent information leak.
8ee0b41898fa26 Greentime Hu   2023-06-05  138  	 */
c27fa53b858b4e Björn Töpel    2024-04-03  139  	return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
8ee0b41898fa26 Greentime Hu   2023-06-05  140  }
3fad3080e143f7 Andy Chiu      2024-10-01  141  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki