DF-5537 / fix.diff
--- a/sys/platform/vkernel64/platform/console.c +++ b/sys/platform/vkernel64/platform/console.c @@ -272,20 +272,29 @@ vconswinch_intr(void *arg __unused, void *frame __unused) { struct winsize newsize; + struct consdev *cp; + struct tty *tp; - if (vconsole != NULL && vconsole->cn_dev->si_tty != NULL) { - ioctl(0, TIOCGWINSZ, &newsize); - /* - * ttioctl(vconsole->cn_dev->si_tty, TIOCSWINSZ, &newsize, 0); - * I wished. Unfortunately this needs a curproc, so do it - * manually. - */ - if (bcmp(&newsize, &vconsole->cn_dev->si_tty->t_winsize, - sizeof(newsize)) != 0) { - vconsole->cn_dev->si_tty->t_winsize = newsize; - pgsignal(vconsole->cn_dev->si_tty->t_pgrp, SIGWINCH, 1); - } + if ((cp = vconsole) == NULL) + return; + if ((tp = cp->cn_dev->si_tty) == NULL) + return; + /* + * ttioctl(tp, TIOCSWINSZ, &newsize, 0); I wished. Unfortunately + * this needs a curproc, so do it manually -- but under the tty + * token, like every other t_winsize / t_pgrp consumer (see + * vconsvirt_intr below and ttioctl()'s TIOCSWINSZ handling). + * + * Caching cp/tp in locals also closes the double-load race of + * vconsole against vconsterm(). + */ + lwkt_gettoken(&tp->t_token); + ioctl(0, TIOCGWINSZ, &newsize); + if (bcmp(&newsize, &tp->t_winsize, sizeof(newsize)) != 0) { + tp->t_winsize = newsize; + pgsignal(tp->t_pgrp, SIGWINCH, 1); } + lwkt_reltoken(&tp->t_token); } /* |