svn commit: r222795 - head/sys/dev/atkbdc

Jung-uk Kim jkim at FreeBSD.org
Tue Jun 7 15:39:50 UTC 2011


On Tuesday 07 June 2011 09:52 am, John Baldwin wrote:
> On Monday, June 06, 2011 7:03:38 pm Jung-uk Kim wrote:
> > Author: jkim
> > Date: Mon Jun  6 23:03:37 2011
> > New Revision: 222795
> > URL: http://svn.freebsd.org/changeset/base/222795
> >
> > Log:
> >   Validate INT 15h and 16h vectors more strictly.  Traditionally
> > these entry points are fixed addresses and (U)EFI CSM
> > specification also mandated that. Unfortunately, (U)EFI CSM
> > specification does not specifically mention this is to call
> > service routine via interrupt vector table or to jump directly to
> > the entry point.  As a result, some CSM seems to install two
> > routines and acts differently, depending on how it was executed,
> > unfortunately. When INT 15h is used, it calls a function pointer
> > (which is probably a UEFI service function).  When it jumps
> > directly to the entry point, it executes a simple and traditional
> > INT 15h service routine.  Therefore, actually there are two
> > possible fixes, i. e., this fix or jumping directly to the fixed
> > entry point.  However, we chose this fix because a) keyboard
> > typematic support via BIOS is becoming extremely rarer and b) we
> > cannot support random service routine installed by a firmware or
> > a boot loader.  This should fix Lenovo X220 laptop, specifically.
>
> So we really think that all valid BIOSes ever produced for x86 use
> these exact entry points for these two interrupts?

In fact, I didn't think so.  I tried to explain the rationale as much 
as possible but I guess I failed.  Sigh...  Please see below.

> Actually, my desktop here at work (a modern i5 system) fails this 
test:
> > sudo dd if=/dev/mem bs=4 iseek=0x15 count=2 | hd
>
> 00000000  9a e9 00 f0 2e e8 00 f0                          
> |........|
>
> Here INT 15 uses the (perfectly valid and not from an option ROM)
> entry point of 0xf000:e99a.
>
> Note that EFI is not a spec for all BIOSen, just a limited subset
> of very recent BIOS implementations.
>
> I have another machine (1U server from a few years ago):
>
> CPU: Intel(R) Xeon(R) CPU            5160  @ 3.00GHz (2992.51-MHz
> K8-class CPU) Origin = "GenuineIntel"  Id = 0x6f6  Family = 6 
> Model = f  Stepping = 6
> Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTR
>R,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,T
>M,PBE>
> Features2=0x4e3bd<SSE3,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,CX16,xTP
>R,PDCM,DCA> AMD Features=0x20100800<SYSCALL,NX,LM>
>   AMD Features2=0x1<LAHF>
>   TSC: P-state invariant
>   Cores per package: 2
>
> And it has these entry points:
> > sudo dd if=/dev/mem bs=4 iseek=0x15 count=2 | hd
>
> 00000000  59 f8 00 f0 09 3f fb e5                          
> |Y....?..|
>
> Note that INT 16 is 0xfbe5:3f09.  This is also in the valid BIOS
> ROM range (0xf0000 - 0xfffff).

The whole point of this commit is to blacklist *recent* BIOS (or CSM) 
from probing keyboard typematic information, more specifically, 
recent Intel chipset platforms.  They don't support many INT 15h/16h 
functions but only cause trouble at best.  OTOH, I haven't seen such 
problems with AMD chipset systems and they all seem to have 
traditional entry points at the interrupt vector table, for example.

> You might as well just turn the check off on all machines at this
> point rather than using completely arbitrary tests that are only
> valid on a small fraction of the x86 universe.

I don't think it is "completely" arbitrary.  If it doesn't have the 
traditional entry points, it is very unlikely to support keyboard 
typematic in the first place.  Please let me know if you have any 
counter example.

> I would favor adding logic to the loader to query these values and
> pass them into the kernel as metadata instead as we do for SMAP.

Actually, I thought about that, too.  However, I didn't implement it 
because I thought it is too much trouble for such tiny feature.  
Shrug...

Jung-uk Kim


More information about the svn-src-head mailing list