Re: autoloading compat43 on tty ioctls
On Sat, Oct 10, 2020 at 03:54:32PM -, Christos Zoulas wrote: > Aside for the TIOCGSID bug which I am about to fix (it is in tty_43.c > and is used in libc tcgetsid(), all the compat tty ioctls are defined > in /usr/src/sys/sys/ioctl_compat.h... We can empty that file and try > to build the tree :-), but I am guessing things will break. Also a lot > of pkgsrc will break too. It is not 4.3 applications that break it is > applications that still use the 4.3 terminal api's. I _think_ I killed off the last sgtty.h user in pkgsrc a few years ago, but that's only the really old interface. There are probably still things using the ioctls. rooting them out would probably be a good exercise but not exactly a high priority... -- David A. Holland dholl...@netbsd.org
Re: [PATCH 0/2] Delete CIRCLEQ
On Mon, Oct 12, 2020 at 01:23:15PM +1100, matthew green wrote: > > Switch the last user (ypserv) from CIRCLEQ to TAILQ. > > This is inspired by analogous refactoring from OpenBSD: > > https://github.com/openbsd/src/commit/d53c0cf4d32fdbd8b42debfba068f1b0efa423dc#diff-8d0a4fbb89658213ebf314ff188581d7 > > > > Remove the CIRCLEQ API completely from the system headers and document > > this fact in the QUEUE(3) man-page. > > why? queue.h may be used by more than src. > > i don't see any benefit except forcing working code to > be changed, possibly introducing bugs. > > please leave it alone. It's been deprecated since -7, we can remove it for -10. Anyway, please at least do fix ypserv. -- David A. Holland dholl...@netbsd.org
re: [PATCH 0/2] Delete CIRCLEQ
Kamil Rytarowski writes: > Switch the last user (ypserv) from CIRCLEQ to TAILQ. > This is inspired by analogous refactoring from OpenBSD: > https://github.com/openbsd/src/commit/d53c0cf4d32fdbd8b42debfba068f1b0efa423dc#diff-8d0a4fbb89658213ebf314ff188581d7 > > Remove the CIRCLEQ API completely from the system headers and document > this fact in the QUEUE(3) man-page. why? queue.h may be used by more than src. i don't see any benefit except forcing working code to be changed, possibly introducing bugs. please leave it alone. .mrg.
Re: [PATCH 2/2] Remove the CIRCLEQ API
On Sun, 11 Oct 2020, Kamil Rytarowski wrote: It was marked deprecated in NetBSD 7 and already removed from FreeBSD in 2000 and OpenBSD in 2015. --- share/man/man3/queue.3 | 10 +++ sys/sys/queue.h| 196 - 2 files changed, 10 insertions(+), 196 deletions(-) diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3 index 4293090986d4..359c772e5439 100644 --- a/share/man/man3/queue.3 +++ b/share/man/man3/queue.3 @@ -1091,3 +1091,13 @@ and .Nm STAILQ functions first appeared in .Fx 2.1.5 . +.Pp +The +.Nm CIRCLEQ +functions first appeared in +.Bx 4.4 +and were deprecated in +.Nx 7 +and removed in +.Nx 10 +due to the pointer aliasing violations. Please reword this slightly. Instead of and and use , , and . diff --git a/sys/sys/queue.h b/sys/sys/queue.h index 5764c7a98a53..ec686364126b 100644 --- a/sys/sys/queue.h +++ b/sys/sys/queue.h @@ -69,14 +69,6 @@ * after an existing element, at the head of the list, or at the end of * the list. A tail queue may be traversed in either direction. * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * * For details on the use of these macros, see the queue(3) manual page. */ @@ -663,192 +655,4 @@ struct { \ ((struct type *)(void *)\ ((char *)((head)->stqh_last) - offsetof(struct type, field - -#ifndef _KERNEL -/* - * Circular queue definitions. Do not use. We still keep the macros - * for compatibility but because of pointer aliasing issues their use - * is discouraged! - */ - -/* - * __launder_type(): We use this ugly hack to work around the compiler - * noticing that two types may not alias each other and elide tests in code. - * We hit this in the CIRCLEQ macros when comparing 'struct name *' and - * 'struct type *' (see CIRCLEQ_HEAD()). Modern compilers (such as GCC - * 4.8) declare these comparisons as always false, causing the code to - * not run as designed. - * - * This hack is only to be used for comparisons and thus can be fully const. - * Do not use for assignment. - * - * If we ever choose to change the ABI of the CIRCLEQ macros, we could fix - * this by changing the head/tail sentinal values, but see the note above - * this one. - */ -static __inline const void * __launder_type(const void *); -static __inline const void * -__launder_type(const void *__x) -{ - __asm __volatile("" : "+r" (__x)); - return __x; -} - -#if defined(QUEUEDEBUG) -#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \ - if ((head)->cqh_first != CIRCLEQ_ENDC(head) && \ - (head)->cqh_first->field.cqe_prev != CIRCLEQ_ENDC(head)) \ - QUEUEDEBUG_ABORT("CIRCLEQ head forw %p %s:%d", (head),\ - __FILE__, __LINE__); \ - if ((head)->cqh_last != CIRCLEQ_ENDC(head) &&\ - (head)->cqh_last->field.cqe_next != CIRCLEQ_ENDC(head)) \ - QUEUEDEBUG_ABORT("CIRCLEQ head back %p %s:%d", (head),\ - __FILE__, __LINE__); -#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \ - if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) { \ - if ((head)->cqh_last != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm last %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } else {\ - if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm forw %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } \ - if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) { \ - if ((head)->cqh_first != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm first %p %s:%d",\ - (elm), __FILE__, __LINE__); \ - } else {\ - if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm prev %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - }
[PATCH 2/2] Remove the CIRCLEQ API
It was marked deprecated in NetBSD 7 and already removed from FreeBSD in 2000 and OpenBSD in 2015. --- share/man/man3/queue.3 | 10 +++ sys/sys/queue.h| 196 - 2 files changed, 10 insertions(+), 196 deletions(-) diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3 index 4293090986d4..359c772e5439 100644 --- a/share/man/man3/queue.3 +++ b/share/man/man3/queue.3 @@ -1091,3 +1091,13 @@ and .Nm STAILQ functions first appeared in .Fx 2.1.5 . +.Pp +The +.Nm CIRCLEQ +functions first appeared in +.Bx 4.4 +and were deprecated in +.Nx 7 +and removed in +.Nx 10 +due to the pointer aliasing violations. diff --git a/sys/sys/queue.h b/sys/sys/queue.h index 5764c7a98a53..ec686364126b 100644 --- a/sys/sys/queue.h +++ b/sys/sys/queue.h @@ -69,14 +69,6 @@ * after an existing element, at the head of the list, or at the end of * the list. A tail queue may be traversed in either direction. * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * * For details on the use of these macros, see the queue(3) manual page. */ @@ -663,192 +655,4 @@ struct { \ ((struct type *)(void *)\ ((char *)((head)->stqh_last) - offsetof(struct type, field - -#ifndef _KERNEL -/* - * Circular queue definitions. Do not use. We still keep the macros - * for compatibility but because of pointer aliasing issues their use - * is discouraged! - */ - -/* - * __launder_type(): We use this ugly hack to work around the compiler - * noticing that two types may not alias each other and elide tests in code. - * We hit this in the CIRCLEQ macros when comparing 'struct name *' and - * 'struct type *' (see CIRCLEQ_HEAD()). Modern compilers (such as GCC - * 4.8) declare these comparisons as always false, causing the code to - * not run as designed. - * - * This hack is only to be used for comparisons and thus can be fully const. - * Do not use for assignment. - * - * If we ever choose to change the ABI of the CIRCLEQ macros, we could fix - * this by changing the head/tail sentinal values, but see the note above - * this one. - */ -static __inline const void * __launder_type(const void *); -static __inline const void * -__launder_type(const void *__x) -{ - __asm __volatile("" : "+r" (__x)); - return __x; -} - -#if defined(QUEUEDEBUG) -#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \ - if ((head)->cqh_first != CIRCLEQ_ENDC(head) && \ - (head)->cqh_first->field.cqe_prev != CIRCLEQ_ENDC(head))\ - QUEUEDEBUG_ABORT("CIRCLEQ head forw %p %s:%d", (head), \ - __FILE__, __LINE__); \ - if ((head)->cqh_last != CIRCLEQ_ENDC(head) && \ - (head)->cqh_last->field.cqe_next != CIRCLEQ_ENDC(head)) \ - QUEUEDEBUG_ABORT("CIRCLEQ head back %p %s:%d", (head), \ - __FILE__, __LINE__); -#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \ - if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) { \ - if ((head)->cqh_last != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm last %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } else {\ - if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm forw %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } \ - if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) { \ - if ((head)->cqh_first != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm first %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } else {\ - if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm prev %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } -#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) \ - (elm)->field.cqe_next = (void *)1L; \ -
[PATCH 1/2] Convert the CIRCLEQ (from sys/queue.h) usage to TAILQ
The CIRCLEQ API from sys/queue.h is deprecated since NetBSD 7 and it will be removed soon. The CIRCLEQ API implementation is prone to a miscompilation due to the pointer aliasing and is discouraged. --- usr.sbin/ypserv/ypserv/ypserv_db.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/usr.sbin/ypserv/ypserv/ypserv_db.c b/usr.sbin/ypserv/ypserv/ypserv_db.c index d6f9eda39eaa..9edfabc4f675 100644 --- a/usr.sbin/ypserv/ypserv/ypserv_db.c +++ b/usr.sbin/ypserv/ypserv/ypserv_db.c @@ -65,7 +65,7 @@ __RCSID("$NetBSD: ypserv_db.c,v 1.22 2011/02/01 21:00:25 chuck Exp $"); LIST_HEAD(domainlist, opt_domain); /* LIST of domains */ LIST_HEAD(maplist, opt_map); /* LIST of maps (in a domain) */ -CIRCLEQ_HEAD(mapq, opt_map); /* CIRCLEQ of maps (LRU) */ +TAILQ_HEAD(mapq, opt_map); /* TAILQ of maps (LRU) */ struct opt_map { char*map; /* map name (malloc'd) */ @@ -76,7 +76,7 @@ struct opt_map { dev_t dbdev; /* device db is on */ ino_t dbino; /* inode of db */ time_t dbmtime;/* time of last db modification */ - CIRCLEQ_ENTRY(opt_map) mapsq; /* map queue pointers */ + TAILQ_ENTRY(opt_map) mapsq; /* map queue pointers */ LIST_ENTRY(opt_map) mapsl; /* map list pointers */ }; @@ -106,7 +106,7 @@ ypdb_init(void) { LIST_INIT(); - CIRCLEQ_INIT(); + TAILQ_INIT(); } /* @@ -161,7 +161,7 @@ yp_private(datum key, int ypprivate) void ypdb_close_map(struct opt_map *map) { - CIRCLEQ_REMOVE(, map, mapsq); /* remove from LRU circleq */ + TAILQ_REMOVE(, map, mapsq);/* remove from LRU tailq */ LIST_REMOVE(map, mapsl);/* remove from domain list */ #ifdef DEBUG @@ -326,8 +326,8 @@ ypdb_open_db(const char *domain, const char *map, u_int *status, */ if (finfo.st_dev == m->dbdev && finfo.st_ino == m->dbino && finfo.st_mtime == m->dbmtime) { - CIRCLEQ_REMOVE(, m, mapsq); /* adjust LRU queue */ - CIRCLEQ_INSERT_HEAD(, m, mapsq); + TAILQ_REMOVE(, m, mapsq); /* adjust LRU queue */ + TAILQ_INSERT_HEAD(, m, mapsq); if (map_info) *map_info = m; return (m->db); @@ -423,7 +423,7 @@ retryopen: m->dbdev = finfo.st_dev; m->dbino = finfo.st_ino; m->dbmtime = finfo.st_mtime; - CIRCLEQ_INSERT_HEAD(, m, mapsq); + TAILQ_INSERT_HEAD(, m, mapsq); LIST_INSERT_HEAD(>dmaps, m, mapsl); if (strcmp(map, YP_HOSTNAME) == 0 || strcmp(map, YP_HOSTADDR) == 0) { if (!usedns) { -- 2.28.0
[PATCH 0/2] Delete CIRCLEQ
Switch the last user (ypserv) from CIRCLEQ to TAILQ. This is inspired by analogous refactoring from OpenBSD: https://github.com/openbsd/src/commit/d53c0cf4d32fdbd8b42debfba068f1b0efa423dc#diff-8d0a4fbb89658213ebf314ff188581d7 Remove the CIRCLEQ API completely from the system headers and document this fact in the QUEUE(3) man-page. Kamil Rytarowski (2): Convert the CIRCLEQ (from sys/queue.h) usage to TAILQ Remove the CIRCLEQ API share/man/man3/queue.3 | 10 ++ sys/sys/queue.h| 196 - usr.sbin/ypserv/ypserv/ypserv_db.c | 14 +-- 3 files changed, 17 insertions(+), 203 deletions(-) -- 2.28.0
[PATCH] Fix s87_tw reconstruction to correctly indicate register states
Fix the code reconstructing s87_tw (full tag word) from fx_sw (abridged tag word) to correctly represent all register states. The previous code only distinguished between empty/non-empty registers, and assigned 'regular value' to all non-empty registers. The new code explicitly distinguishes the two other tag word values: empty and special. --- sys/arch/x86/x86/fpu.c | 28 -- tests/lib/libc/sys/t_ptrace_x86_wait.h | 2 -- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/sys/arch/x86/x86/fpu.c b/sys/arch/x86/x86/fpu.c index d89c78dcef47..c580f34b0615 100644 --- a/sys/arch/x86/x86/fpu.c +++ b/sys/arch/x86/x86/fpu.c @@ -668,7 +668,7 @@ fpu_sigreset(struct lwp *l) static void process_xmm_to_s87(const struct fxsave *sxmm, struct save87 *s87) { - unsigned int tag, ab_tag; + unsigned int tag, ab_tag, st; const struct fpaccfx *fx_reg; struct fpacc87 *s87_reg; int i; @@ -723,12 +723,28 @@ process_xmm_to_s87(const struct fxsave *sxmm, struct save87 *s87) return; } + /* For ST(i), i = fpu_reg - top, we start with fpu_reg=7. */ + st = 7 - ((sxmm->fx_sw >> 11) & 7); tag = 0; - /* Separate bits of abridged tag word with zeros */ - for (i = 0x80; i != 0; tag <<= 1, i >>= 1) - tag |= ab_tag & i; - /* Replicate and invert so that 0 => 0b11 and 1 => 0b00 */ - s87->s87_tw = (tag | tag >> 1) ^ 0x; + for (i = 0x80; i != 0; i >>= 1) { + tag <<= 2; + if (ab_tag & i) { + unsigned int exp; + /* Non-empty - we need to check ST(i) */ + fx_reg = >fx_87_ac[st]; + exp = fx_reg->r.f87_exp_sign & 0x7fff; + if (exp == 0) { + if (fx_reg->r.f87_mantissa == 0) + tag |= 1; /* Zero */ + else + tag |= 2; /* Denormal */ + } else if (exp == 0x7fff) + tag |= 2; /* Infinity or NaN */ + } else + tag |= 3; /* Empty */ + st = (st - 1) & 7; + } + s87->s87_tw = tag; } static void diff --git a/tests/lib/libc/sys/t_ptrace_x86_wait.h b/tests/lib/libc/sys/t_ptrace_x86_wait.h index d7e93fde55a3..6067066a36c1 100644 --- a/tests/lib/libc/sys/t_ptrace_x86_wait.h +++ b/tests/lib/libc/sys/t_ptrace_x86_wait.h @@ -3367,10 +3367,8 @@ x86_register_test(enum x86_test_regset regset, enum x86_test_registers regs, expected_fpu.cw); ATF_CHECK_EQ(fpr.fstate.s87_sw, expected_fpu.sw); -#if 0 /* TODO: translation from FXSAVE is broken */ ATF_CHECK_EQ(fpr.fstate.s87_tw, expected_fpu.tw); -#endif ATF_CHECK_EQ(fpr.fstate.s87_opcode, expected_fpu.opcode); ATF_CHECK_EQ(fpr.fstate.s87_ip.fa_32.fa_off, -- 2.28.0
Re: Trying to write a kernel module for (un)mounting tmpfs
Hi, When I call the namei_simple_user function it always return errno 14. It calls the nameiat_simple_user who calls the pathbuf_copyin function. I set a bp in pathbuf_copyin and i compare what happens when I use mount command vs my module. basically it calls the pathbuf_create_raw() who does all the magic, when use the mount command it sets pb->pb_path to "/tmp" and when i load my module it sets to the "./mount.kmod" (my module's name), that's why namei always returns a bad address errno. The pathbuf_create_raw() calls the PNBUF_GET() who is a macro for pool_cache_get(pnbuf_cache, PR_WAITOK). My question is how can I pass "/tmp" string to pnbuf_cache argument? Will I need to reimplement all these functions inside my code? Thanks for the help. Sent from [ProtonMail](https://protonmail.com), Swiss-based encrypted email. ‐‐‐ Original Message ‐‐‐ Em domingo, 13 de setembro de 2020 às 23:57, Maciej escreveu: > Hi Bruno, > > The reason why it is hard to map VFS operations inside the kernel is due to > the way how POSIX filesystems are designed. > Most of the operations are made to run in the context of some process where > we have information about things such mount point, > some file structures or path. This information is later translated to > concrete kernel structures. > > From the other side kernel module code when executed would need to get > somehow such information like mount point and mount options. > If you take a look on the man-page of mount(2) you will notice that there are > couple arguments like flags > (Filesystem independent - or at least meant to be independent), and mount > data which is filesystem-specific. > > The first design question that should ask yourself is how this information > would be provided to the kernel module? > Probably they can be hardcoded in the module; however, if you decide to > trigger this operation from userspace > (by using any US to kernel interface), you can provide some structure that > contains more information about current filesystem to make things easier. > > A good starting point to understand how things are working would be > implementation in VFS layer of mount system call: > > `do_sys_mount()` inside: kern/vfs_syscalls.c > > You can notice that in order to get vnode (structure needed for mount: the > mount point) > you need to translate file path to find a vnode using `namei` operation > > Next thing is mount operation itself, as you realized each filesystem has its > own `struct vfsops` that contains filesystem operations. > Kernel contains the global list `struct vfs_list_head vfs_list ` build inside > `kern/vfs_init.c` > this list contains all filesystems availavble on NetBSD with their operations. > To get filesystem specific structure you can use `mount_get_vfsops()`. > > When finished with the preparation (probably you will need to prepare > arguments according to man page mentioned before), > you can call your favourite FS mount operation by `mount_domount()`. > > Hope that quick walkthrough will help you understand how mount operation > works inside the kernel. > Maciej > > ‐‐‐ Original Message ‐‐‐ > On Thursday, September 10, 2020 12:51 PM, Bruno Melo > wrote: > >> Hi, >> >> I'm trying to write a kernel module as example for mounting and unmounting >> tmpfs. For that, I read the mount_tmpfs code and in line 247 I found the >> call for mount() syscall here: >> https://nxr.netbsd.org/xref/src/sbin/mount_tmpfs/mount_tmpfs.c#247 >> >> Then I looked for how the kernel mounts file systems and found there are >> _mount() function for every file system: >> https://nxr.netbsd.org/xref/src/sys/sys/mount.h#254 >> >> Now, I just needed to know how to use tmpfs_mount() and find it here: >> https://nxr.netbsd.org/xref/src/sys/fs/tmpfs/tmpfs_vfsops.c#86 >> but I still don't know how to use it. I created the struct >> [tmpfs_args](https://nxr.netbsd.org/source/s?defs=tmpfs_args=src) >> [args](https://nxr.netbsd.org/source/s?refs=args=src) and size_t >> args_len = sizeof args variables to pass to data and data_len arguments in >> tmpfs_mount(). And the directory I'm mounting is "/tmp". So, I have 3 of 4 >> arguments needed to tmpfs_mount(), the last one is the struct mount *mp. >> >> I know the mount() syscall takes >> [MOUNT_TMPFS](https://nxr.netbsd.org/source/s?defs=MOUNT_TMPFS=src) >> as first argument, but I'm not understanding the magic behind struct mount >> mp and what I need to assign to the struct mount variable to pass it to that >> argument. Any hint? >> >> Thanks for the help, >> >> Bruno Melo.