On Wed, Nov 08, 2017 at 05:14:33PM +0100, Denys Vlasenko wrote: > On 11/08/2017 12:00 PM, tip-bot for Ricardo Neri wrote: > >Commit-ID: 1e5db223696afa55e6a038fac638f759e1fdcc01 > >Gitweb: https://git.kernel.org/tip/1e5db223696afa55e6a038fac638f759e1fdcc01 > >Author: Ricardo Neri <ricardo.neri-calderon@xxxxxxxxxxxxxxx> > >AuthorDate: Sun, 5 Nov 2017 18:27:52 -0800 > >Committer: Ingo Molnar <mingo@xxxxxxxxxx> > >CommitDate: Wed, 8 Nov 2017 11:16:22 +0100 > > > >x86/umip: Add emulation code for UMIP instructions > > > >The feature User-Mode Instruction Prevention present in recent Intel > >processor prevents a group of instructions (sgdt, sidt, sldt, smsw, and > >str) from being executed with CPL > 0. Otherwise, a general protection > >fault is issued. > > This was arguably an oversight on Intel's part - these insns should have been > protected from the start, as they leak a tiny bit of kernel data. > > >Rather than relaying to the user space the general protection fault caused > >by the UMIP-protected instructions (in the form of a SIGSEGV signal), it > >can be trapped and the instruction emulated to provide a dummy result. > >This allows to both conserve the current kernel behavior and not reveal the > >system resources that UMIP intends to protect (i.e., the locations of the > >global descriptor and interrupt descriptor tables, the segment selectors of > >the local descriptor table, the value of the task state register and the > >contents of the CR0 register). > > > >This emulation is needed because certain applications (e.g., WineHQ and > >DOSEMU2) rely on this subset of instructions to function. > > I'm surprised. What in the world they need those insns for? > > Wine uses sidt like this, to emulate "mov from r/m to reg" insns: > > static LDT_ENTRY idt[256]; > ... > case 0x8a: /* mov Eb, Gb */ > case 0x8b: /* mov Ev, Gv */ > { > BYTE *data = INSTR_GetOperandAddr(context, instr + 1, long_addr, > segprefix, &len); > unsigned int data_size = (*instr == 0x8b) ? (long_op ? 4 : 2) : 1; > struct idtr idtr = get_idtr(); <=============================== HERE > unsigned int offset = data - idtr.base; > > if (offset <= idtr.limit + 1 - data_size) > { > idt[1].LimitLow = 0x100; /* FIXME */ > idt[2].LimitLow = 0x11E; /* FIXME */ > idt[3].LimitLow = 0x500; /* FIXME */ > > switch (*instr) > { > case 0x8a: store_reg_byte( context, instr[1], (BYTE *)idt + offset ); break; > case 0x8b: store_reg_word( context, instr[1], (BYTE *)idt + offset, long_op ); break; > } > context->Eip += prefixlen + len + 1; > return ExceptionContinueExecution; > } > break; /* Unable to emulate it */ > } > > Looks baffling, to say the least... this supports someone who reads > IDT bytes via those insns, and they need to ensure that the values read > from idt[1/2/3].LimitLow are as expected. That's it? Pity git history > doesn't go far enough in the past, and comments are not informative as well... > > I did not find smsw or sgdt in Wine git tree. > > I did not find smsw, sidt or sgdt in dosemu2-devel git tree. Stas Sergeev investigated what applications use smsw when running dosemu2 in virtual-8086 mode. He found that Windows 3.1 and dos4gw use it [1], [2]. Thanks and BR, Ricardo [1]. https://www.winehq.org/pipermail/wine-devel/2017-April/117159.html [2]. https://marc.info/?l=linux-kernel&m=147876798717927&w=2 -- To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html