Date: Fri, 28 Nov 1997 11:54:01 +1000 (EST) From: Stephen McKay <syssgm@dtir.qld.gov.au> To: freebsd-hackers@freebsd.org Cc: syssgm@dtir.qld.gov.au Subject: Re: Updated f00f workaround Message-ID: <199711280154.LAA05490@troll.dtir.qld.gov.au> In-Reply-To: <199711270743.XAA08912@kithrup.com> from Sean Eric Fagan at "Thu, 27 Nov 1997 07:43:19 %2B0000" References: <199711270743.XAA08912@kithrup.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[Yesterday hub.freebsd.org rejected this with '550 Access denied' so let's see how it goes today!] On Thursday, 27th November 1997, Sean Eric Fagan wrote: >Well, I was waiting for someone else to do anything about this, but >everybody is apparantly busy :). Yeah, even though this is fun (in a sicko way) and highly technical (Homer: Hmmmm, processor erratum!) it still has to compete for time with the dramas of Real Life(tm). Pity. >This isn't quite right -- I think there should be a less obviously-i386 >method of making the page in question non-writable; there should be a better >way to allocate two page-aligned pages of memory You don't want to do that nasty stuff. I would allocate 2 pages with addr = kmem_alloc(kernel_map, 2*PAGE_SIZE); and unmap the first page with vm_map_protect(kernel_map, addr, addr+PAGE_SIZE, VM_PROT_NONE, FALSE); though it is unclear to me how this relates to vm_page_protect() which would have played with PG_WRITEABLE. Oh well, more reading to be done. Um, having just re-read your code, you are expecting the F00F instruction to write to the IDT? [Quick trot over to www.intel.com] Well, that's an odd thing, eh? It will page fault on a non-writable IDT when thinking about delivering an Invalid Opcode Exception! Hopefully it's just because of the lock prefix, or these Intel processors are weird! So, if you are using that workaround, I think you only have to allocate one page, put the goodies in it, and make it read-only with vm_map_protect(). You have to read between the lines, but Intel is implying that there is no split-over-a-page-boundary requirement for this one, and that only exception 6 will cause a page fault. They claim that you only have to do the split trick if you want to update the exception handlers for 7 and up on the fly. Even if we wanted to do that, we could just turn it on, frob, and turn it off. No user code would run in that interval. >and the check for the >fault address should be done lower, but I don't know the code well enough to >decide where. The IDT is in kernel memory and the fault will come from ring 0, so you want to move your test down a bit (to before line 642 of my 2.2.5-stable trap.c after the comment "...kernel virtual address addresses always have pte pages mapped...") to avoid triggering from user mode accesses. Also the Intel notes imply that an explicit equality test of the faulting address against the exception 6 address is sufficient, so you should be able to convert your test to: if (eva == (int)&t_idt[6] && has_f00f_bug) { frame->tf_trapno = T_PRIVINFLT; return -2; } Final warning: I only look like I know what I'm doing. I've never actually done any of this! :-) Stephen.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711280154.LAA05490>