(skip the discussion section for a description of the attached patch.) * Davide Libenzi wrote: > > > + /* > > > + * Perform the lazy TSS's I/O bitmap copy. If the TSS has an > > > + * invalid offset set (the LAZY one) and the faulting thread has > > > + * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS > > > + * and we set the offset field correctly. Then we let the CPU to > > > + * restart the faulting instruction. > > > + */ > > > > I don't like it very much that most GPFs will be executed twice now > > when the process has ioperm enabled. > > This will confuse debuggers and could have other bad side effects. > > Checking the EIP would be better. > > The eventually double GPF would happen only on TSS-IObmp-lazy tasks, ie > tasks using the I/O bitmap. The check for the I/O opcode can certainly be > done though, even if it'd make the code a little bit more complex. another issue is that this code doesnt solve the 64K ports issue: even with a perfect decoder ioperm() apps still see a ~80 usecs copying latency (plus related cache trash effects) upon the first GPF - either IO related or not. I dont think coupling this into the GPF handler is all that good. since 100% of Linux ioperm() apps currently use 1024 ports or less, i'd prefer the 128 bytes (one cacheline on a P4) copy over any asynchronous solution. (if someone wants more ports the price goes up. It should be rare. I dont think X will ever go above 1024 ports.) We've already had one security exploit in the lazy IO bitmap code, which further underlies how dangerous such asynchronity is. there's yet another danger: apps that _do_ use IO ports frequently will see the most serious overhead via the GPF solution. They will most likely switch to iopl(3) - which is an even less safe API than ioperm() - so robustness suffers. So i think it's wrong policy too. Sorry :-| but there's one additional step we can do ontop of the ports-max code to get rid of copying in X.org's case: cache the last task that set up the IO bitmap. This means we can set the offset to invalid and keep the IO bitmap of that task, and switch back to a valid offset (without any copying) when switching back to that task. (or do a copy if there is another ioperm task we switch to.) I've attached ioport-cache-2.6.8.1.patch that implements this. When there's a single active ioperm() using task in the system then the context-switch overhead is very low and constant: # ./ioperm-latency default no ioperm: scheduling latency: 2478 cycles turning on port 80 ioperm: scheduling latency: 2499 cycles turning on port 65535 ioperm: scheduling latency: 2481 cycles (updated ioperm-latency.c attached) This single-ioperm-user situation matches 99% of the actual ioperm() usage scenarios and gets rid of any copying whatsoever - without relying on any fault mechanism. I can see no advantage of the GPF approach over this patch. the patch is against the most recent BK tree, i've tested it on x86 SMP and UP. Ingo