Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Aug 2023 14:53:56 GMT
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 676386b5563f - main - Support dynamically sized register sets
Message-ID:  <202308231453.37NErugD056233@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=676386b5563f60739d5ea2244cd0d770b390a1d7

commit 676386b5563f60739d5ea2244cd0d770b390a1d7
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2023-08-23 14:32:56 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2023-08-23 14:32:56 +0000

    Support dynamically sized register sets
    
    We don't always know the size of the register set at compile time,
    e.g. on arm64 the size of the SVE registers need to be queried on boot.
    To support register sets that needs to be calculated at run time
    query the correct size when it is zero.
    
    Reviewed by:    markj, kib (earlier version)
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D41302
---
 sys/kern/sys_process.c | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 86b9ec532c11..647487f86b02 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -190,8 +190,21 @@ proc_read_regset(struct thread *td, int note, struct iovec *iov)
 	if (regset == NULL)
 		return (EINVAL);
 
+	if (regset->get == NULL)
+		return (EINVAL);
+
+	size = regset->size;
+	/*
+	 * The regset is dynamically sized, e.g. the size could change
+	 * depending on the hardware, or may have a per-thread size.
+	 */
+	if (size == 0) {
+		if (!regset->get(regset, td, NULL, &size))
+			return (EINVAL);
+	}
+
 	if (iov->iov_base == NULL) {
-		iov->iov_len = regset->size;
+		iov->iov_len = size;
 		if (iov->iov_len == 0)
 			return (EINVAL);
 
@@ -199,14 +212,10 @@ proc_read_regset(struct thread *td, int note, struct iovec *iov)
 	}
 
 	/* The length is wrong, return an error */
-	if (iov->iov_len != regset->size)
-		return (EINVAL);
-
-	if (regset->get == NULL)
+	if (iov->iov_len != size)
 		return (EINVAL);
 
 	error = 0;
-	size = regset->size;
 	p = td->td_proc;
 
 	/* Drop the proc lock while allocating the temp buffer */
@@ -218,7 +227,7 @@ proc_read_regset(struct thread *td, int note, struct iovec *iov)
 	if (!regset->get(regset, td, buf, &size)) {
 		error = EINVAL;
 	} else {
-		KASSERT(size == regset->size,
+		KASSERT(size == regset->size || regset->size == 0,
 		    ("%s: Getter function changed the size", __func__));
 
 		iov->iov_len = size;
@@ -245,14 +254,23 @@ proc_write_regset(struct thread *td, int note, struct iovec *iov)
 	if (regset == NULL)
 		return (EINVAL);
 
+	size = regset->size;
+	/*
+	 * The regset is dynamically sized, e.g. the size could change
+	 * depending on the hardware, or may have a per-thread size.
+	 */
+	if (size == 0) {
+		if (!regset->get(regset, td, NULL, &size))
+			return (EINVAL);
+	}
+
 	/* The length is wrong, return an error */
-	if (iov->iov_len != regset->size)
+	if (iov->iov_len != size)
 		return (EINVAL);
 
 	if (regset->set == NULL)
 		return (EINVAL);
 
-	size = regset->size;
 	p = td->td_proc;
 
 	/* Drop the proc lock while allocating the temp buffer */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202308231453.37NErugD056233>