All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ammar Faizi <ammarfaizi2@gnuweeb.org>
To: Willy Tarreau <w@1wt.eu>, Shuah Khan <shuah@kernel.org>,
	"Paul E. McKenney" <paulmck@kernel.org>
Cc: Ammar Faizi <ammarfaizi2@gnuweeb.org>,
	Gilang Fachrezy <gilang4321@gmail.com>,
	VNLX Kernel Department <kernel@vnlx.org>,
	Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>,
	Kanna Scarlet <knscarlet@gnuweeb.org>,
	Muhammad Rizki <kiizuha@gnuweeb.org>,
	GNU/Weeb Mailing List <gwml@vger.gnuweeb.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Linux Kselftest Mailing List  <linux-kselftest@vger.kernel.org>
Subject: [RFC PATCH v1 3/8] nolibc/sys: Implement `getpagesize(2)` function
Date: Thu, 22 Dec 2022 10:51:29 +0700	[thread overview]
Message-ID: <20221222035134.3467659-4-ammar.faizi@intel.com> (raw)
In-Reply-To: <20221222035134.3467659-1-ammar.faizi@intel.com>

From: Ammar Faizi <ammarfaizi2@gnuweeb.org>

This commit adds getpagesize() function implementation.

The getpagesize() syscall doesn't always exist on the Linux syscall
table. Only specific architectures have this syscall.

Implementation detail:
Some architectures use a fixed page size, like x86. We can hard-code
the page size value on such architectures.

Some other architectures may use different page sizes. For example,
Linux aarch64 supports three values of page size: 4K, 16K, and 64K
which are selected at kernel compilation time. The kernel stores the
used page size in the auxiliary vector. The auxiliary vector can be
obtained from /proc/self/auxv at AT_PAGESZ key-value-pair.
/proc/self/auxv is available on all architectures.

Once we obtain the page size info, cache the value in a static
variable to avoid traversing the auxiliary vector again in the next
getpagesize() call. The page size should never change during kernel
uptime.

Link: https://lwn.net/Articles/519085
Link: https://github.com/torvalds/linux/blob/v6.1/fs/binfmt_elf.c#L260
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
---
 tools/include/nolibc/sys.h | 114 +++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index ca348939eb50..e9e3640c36e1 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/loop.h>
 #include <linux/time.h>
+#include <linux/auxvec.h>
 
 #include "arch.h"
 #include "errno.h"
@@ -407,6 +408,119 @@ int getdents64(int fd, struct linux_dirent64 *dirp, int count)
 	return ret;
 }
 
+/*
+ * The getpagesize() syscall doesn't always exist on the Linux syscall
+ * table. Only specific architectures have this syscall.
+ *
+ * Implementation detail:
+ * Some architectures use a fixed page size, like x86. We can hard-code
+ * the page size value on such architectures.
+ *
+ * Some other architectures may use different page sizes. For example,
+ * Linux aarch64 supports three values of page size: 4K, 16K, and 64K
+ * which are selected at kernel compilation time. The kernel stores the
+ * used page size in the auxiliary vector. The auxiliary vector can be
+ * obtained from /proc/self/auxv at AT_PAGESZ key-val-pair.
+ * /proc/self/auxv is available on all architectures.
+ *
+ * Once we obtain the page size info, cache the value in a static
+ * variable to avoid traversing the auxiliary vector again in the next
+ * getpagesize() call. The page size should never change during kernel
+ * uptime.
+ *
+ * Link: https://lwn.net/Articles/519085
+ * Link: https://github.com/torvalds/linux/blob/v6.1/fs/binfmt_elf.c#L260
+ *
+ *
+ * long getpagesize(void);
+ *
+ */
+
+#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
+__attribute__((unused))
+static inline long getpagesize(void)
+{
+	/*
+	 * x86 family is always 4K page. Don't bother
+	 * reading the auxiliary vector.
+	 */
+	return 4096;
+}
+#else
+static int sys_open(const char *path, int flags, mode_t mode);
+static ssize_t sys_read(int fd, void *buf, size_t count);
+
+/*
+ * This function works for all architectures.
+ */
+static long sys_getpagesize(void)
+{
+	uint64_t buf[2] = {0, 0};
+	long ret;
+	int fd;
+
+
+	fd = sys_open("/proc/self/auxv", O_RDONLY, 0);
+	if (fd < 0)
+		return fd;
+
+	while (1) {
+		ssize_t x;
+
+		x = sys_read(fd, buf, sizeof(buf));
+		if (x < 0) {
+			ret = x;
+			break;
+		}
+
+		if (__builtin_expect(x == 0, 0)) {
+			/*
+			 * We've reached the end of the auxiliary
+			 * vector, but can't find the AT_PAGESZ
+			 * entry.
+			 */
+			ret = -ENOENT;
+			break;
+		}
+
+		/*
+		 * buf[0] is the key.
+		 * buf[1] is the value.
+		 */
+		if (buf[0] == AT_PAGESZ) {
+			ret = buf[1];
+			break;
+		}
+	}
+
+	sys_close(fd);
+	return ret;
+}
+
+__attribute__((unused))
+static long getpagesize(void)
+{
+	static long cached;
+	long ret;
+
+	/*
+	 * No need to read the auxv for the second
+	 * getpagesize() call.
+	 */
+	if (__builtin_expect(cached != 0, 1))
+		return cached;
+
+	ret = sys_getpagesize();
+	if (ret < 0) {
+		SET_ERRNO(-ret);
+		ret = -1;
+	} else {
+		cached = ret;
+	}
+	return ret;
+}
+#endif
+
 
 /*
  * pid_t getpgid(pid_t pid);
-- 
Ammar Faizi


  parent reply	other threads:[~2022-12-22  3:52 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-22  3:51 [RFC PATCH v1 0/8] nolibc signal handling support Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 1/8] nolibc/sys: Implement `sigaction(2)` function Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 2/8] nolibc/sys: Implement `signal(2)` function Ammar Faizi
2022-12-22  3:51 ` Ammar Faizi [this message]
2022-12-22  3:51 ` [RFC PATCH v1 4/8] selftests/nolibc: Add `-Wall` and `-Wno-unsed-function` to the CFLAGS Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 5/8] selftests/nolibc: Add `fork(2)` selftest Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 6/8] selftests/nolibc: Add `sigaction(2)` selftest Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 7/8] selftests/nolibc: Add `signal(2)` selftest Ammar Faizi
2022-12-22  3:51 ` [RFC PATCH v1 8/8] selftests/nolibc: Add `getpagesize(2)` selftest Ammar Faizi
2022-12-22  4:34 ` [RFC PATCH v1 0/8] nolibc signal handling support Willy Tarreau
2022-12-22 13:46   ` Ammar Faizi
2022-12-27  6:26     ` Willy Tarreau
2022-12-27 13:32       ` Ammar Faizi
2022-12-27 13:36         ` Ammar Faizi
2022-12-27 18:58           ` Willy Tarreau
2022-12-28 12:23             ` Ammar Faizi
2022-12-27 18:49         ` Willy Tarreau
2022-12-28 12:01           ` Ammar Faizi
2022-12-28 13:35             ` Willy Tarreau
2022-12-29 11:41               ` Ammar Faizi
2023-01-03  3:51                 ` Alviro Iskandar Setiawan
2023-01-03  3:54                   ` Willy Tarreau
2023-01-03  3:59                     ` Ammar Faizi
2023-01-08 13:08                       ` [PATCH v1 0/3] nolibc auxiliary vector retrieval support Ammar Faizi
2023-01-08 13:08                         ` [PATCH v1 1/3] nolibc/stdlib: Implement `getauxval(3)` function Ammar Faizi
2023-01-08 13:08                         ` [PATCH v1 2/3] nolibc/sys: Implement `getpagesize(2)` function Ammar Faizi
2023-01-08 13:08                         ` [PATCH v1 3/3] selftests/nolibc: Add `getpagesize(2)` selftest Ammar Faizi
2023-01-08 13:10                       ` [PATCH v2 0/4] nolibc signal handling support Ammar Faizi
2023-01-08 13:10                         ` [PATCH v2 1/4] nolibc/sys: Implement `sigaction(2)` function Ammar Faizi
2023-01-08 13:10                         ` [PATCH v2 2/4] nolibc/sys: Implement `signal(2)` function Ammar Faizi
2023-01-08 13:10                         ` [PATCH v2 3/4] selftests/nolibc: Add `fork(2)` selftest Ammar Faizi
2023-01-08 13:10                         ` [PATCH v2 4/4] selftests/nolibc: Add `sigaction(2)` selftest Ammar Faizi
2023-01-08 13:28                         ` [PATCH v2 0/4] nolibc signal handling support Alviro Iskandar Setiawan
2023-01-08 13:31                           ` Ammar Faizi
2023-01-08 13:39                             ` Ammar Faizi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221222035134.3467659-4-ammar.faizi@intel.com \
    --to=ammarfaizi2@gnuweeb.org \
    --cc=alviro.iskandar@gnuweeb.org \
    --cc=gilang4321@gmail.com \
    --cc=gwml@vger.gnuweeb.org \
    --cc=kernel@vnlx.org \
    --cc=kiizuha@gnuweeb.org \
    --cc=knscarlet@gnuweeb.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=paulmck@kernel.org \
    --cc=shuah@kernel.org \
    --cc=w@1wt.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.