diff mbox series

[RFC,v4,01/13] ptrace: Use regset_size() for dynamic regset size.

Message ID 3700190a602a6d30fcbf76e1eea667e29a65c4c9.1590474856.git.greentime.hu@sifive.com (mailing list archive)
State New, archived
Headers show
Series riscv: Add vector ISA support | expand

Commit Message

Greentime Hu May 26, 2020, 7:02 a.m. UTC
It uses regset_size() instead of using regset->n and regset->size directly.
In this case, it will call the get_size() ported by arch dynamically to
support dynamic regset size case.

Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
---
 kernel/ptrace.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Comments

Oleg Nesterov May 26, 2020, 2 p.m. UTC | #1
On 05/26, Greentime Hu wrote:
>
> @@ -882,13 +882,18 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
>  	const struct user_regset_view *view = task_user_regset_view(task);
>  	const struct user_regset *regset = find_regset(view, type);
>  	int regset_no;
> +	unsigned int size;
>
> -	if (!regset || (kiov->iov_len % regset->size) != 0)
> +	if (!regset)
>  		return -EINVAL;
>
>  	regset_no = regset - view->regsets;
> -	kiov->iov_len = min(kiov->iov_len,
> -			    (__kernel_size_t) (regset->n * regset->size));
> +	size = regset_size(task, regset);
> +
> +	if ((kiov->iov_len % size) != 0)
> +		return -EINVAL;

Hmm. this doesn't look right.

Before this patch we check "iov_len % regset->size", this is not the same
as "iov_len % regset_size()".

IOW, currently you can read/write, say, only the 1st register, you patch
breaks this?

Oleg.
Greentime Hu May 27, 2020, 6:34 a.m. UTC | #2
Oleg Nesterov <oleg@redhat.com> 於 2020年5月26日 週二 下午10:00寫道:
>
> On 05/26, Greentime Hu wrote:
> >
> > @@ -882,13 +882,18 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
> >       const struct user_regset_view *view = task_user_regset_view(task);
> >       const struct user_regset *regset = find_regset(view, type);
> >       int regset_no;
> > +     unsigned int size;
> >
> > -     if (!regset || (kiov->iov_len % regset->size) != 0)
> > +     if (!regset)
> >               return -EINVAL;
> >
> >       regset_no = regset - view->regsets;
> > -     kiov->iov_len = min(kiov->iov_len,
> > -                         (__kernel_size_t) (regset->n * regset->size));
> > +     size = regset_size(task, regset);
> > +
> > +     if ((kiov->iov_len % size) != 0)
> > +             return -EINVAL;
>
> Hmm. this doesn't look right.
>
> Before this patch we check "iov_len % regset->size", this is not the same
> as "iov_len % regset_size()".
>
> IOW, currently you can read/write, say, only the 1st register, you patch
> breaks this?
>

Hi Oleg,

Thank you. I misunderstood the meaning of regset->size
It seems I only needs to update this line, right?
- kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t) (regset->n *
regset->size));
+ kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t)
regset_size(task, regset));
Oleg Nesterov May 27, 2020, 11:31 a.m. UTC | #3
On 05/27, Greentime Hu wrote:
>
> It seems I only needs to update this line, right?
> - kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t) (regset->n *
> regset->size));
> + kiov->iov_len = min(kiov->iov_len,  (__kernel_size_t)
> regset_size(task, regset));

Yes, agreed.

Oleg.
diff mbox series

Patch

diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 43d6179508d6..6877105e1b1e 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -882,13 +882,18 @@  static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
 	const struct user_regset_view *view = task_user_regset_view(task);
 	const struct user_regset *regset = find_regset(view, type);
 	int regset_no;
+	unsigned int size;
 
-	if (!regset || (kiov->iov_len % regset->size) != 0)
+	if (!regset)
 		return -EINVAL;
 
 	regset_no = regset - view->regsets;
-	kiov->iov_len = min(kiov->iov_len,
-			    (__kernel_size_t) (regset->n * regset->size));
+	size = regset_size(task, regset);
+
+	if ((kiov->iov_len % size) != 0)
+		return -EINVAL;
+
+	kiov->iov_len = min(kiov->iov_len, (__kernel_size_t) size);
 
 	if (req == PTRACE_GETREGSET)
 		return copy_regset_to_user(task, view, regset_no, 0,