Skip site navigation (1)Skip section navigation (2)
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>