i386/86380: i386_set_ioperm doesn't take effect immediately
Trevor Blackwell
tlb at anybots.com
Tue Sep 20 12:10:03 PDT 2005
>Number: 86380
>Category: i386
>Synopsis: i386_set_ioperm doesn't take effect immediately
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-i386
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Sep 20 19:10:02 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Trevor Blackwell
>Release: FreeBSD 5.4-RELEASE-p6 i386
>Organization:
Anybots Inc
>Environment:
System: FreeBSD lab.anybots.com 5.4-RELEASE-p6 FreeBSD 5.4-RELEASE-p6 #0: Thu Sep 15 12:26:46 PDT 2005 root at tlb.anybots.com:/usr/obj/usr/src/sys/LAB i386
>Description:
Calling i386_set_ioperm immediately followed by an inb or outb causes a bus error. Inserting a context switch delay between the two
avoids the problem
>How-To-Repeat:
cat >t_ioperm.c <<EOF
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <machine/sysarch.h>
#include <machine/cpufunc.h>
void
test_ioperm(int base, int len, int wr, int delay)
{
if (i386_set_ioperm(base, len, 1)<0) {
fprintf(stderr, "Can't set ioperm on %d %d\n", base, len);
exit(1);
}
if (delay) {
usleep(2000); // FreeBSD 5.4 seems to sometimes get a bus error if we do IO too soon after set_ioperm
}
if (wr) {
outb(base, 0x00);
} else {
inb(base);
}
}
int
main(int argc, char **argv)
{
test_ioperm(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
return 0;
}
EOF
gcc -o t_ioperm t_ioperm.c
sudo ./t_ioperm 1018 8 0 0 # expect bus error
sudo ./t_ioperm 1018 8 0 1 # no bus error
(the port number is byte 2 of COM1, a fairly harmless thing to read from)
>Fix:
Inserting a usleep after i386_set_ioperm seems to work around it.
I assume there's some fancy lazy updating going on in the TLB management.
This happens for me on multiple machines, including a dual Xeon, a P4, and an old Pentium-MMX
--
Trevor Blackwell tlb at tlb.org (650) 776-7870
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-i386
mailing list