Cc Radim, Nadav, 2017-10-24 19:10 GMT+08:00 Pedro Fonseca <pfonseca@xxxxxxxxxxxxxxxxx>: > Hi, > > During tests that we conducted on KVM, we noticed that executing a "PUSH > %ES" instruction under KVM produces different results on both memory and the > SP register depending on whether EPT support is enabled. With EPT the SP is > reduced by 4 bytes (and the written value is 0-padded) but without EPT > support it is only reduced by 2 bytes. The difference can be observed when > the CS.DB field is 1 (32-bit) but not when it's 0 (16-bit). > > The test case initializes the VM with EIP=0, CS.DB=1, ES=0x10, and SP=0xFFE. > Memory is initialized with 0x06 (PUSH %ES) and 0xF4 (HLT). The testing > system was running Linux 4.12.5 and Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz. > > The test case (https://pastebin.com/ZejdtGEk) produces the output bellow. > Note that 0x10 is written to 0xFFA on EPT=1 but it's written to 0xFFC on > EPT=0. >> >> $ insmod kvm-intel.ko >> $ sudo ./reproduce-push_es >> Executing KVM_RUN >> KVM_RUN exited (exit_reason: 5, KVM_EXIT_HLT) >> 0000: 06 f4 00 00 00 00 00 00 >> 0008: 00 00 00 00 00 00 00 00 >> 0ff8: 00 00 10 00 00 00 00 00 >> 1000: 00 00 00 00 00 00 00 00 > > >> $ insmod kvm-intel.ko ept=0 >> $ sudo ./reproduce-push_es >> Executing KVM_RUN >> KVM_RUN exited (exit_reason: 5, KVM_EXIT_HLT) >> 0000: 06 f4 00 00 00 00 00 00 >> 0008: 00 00 00 00 00 00 00 00 >> 0ff8: 00 00 00 00 10 00 00 00 >> 1000: 00 00 00 00 00 00 00 00 The cause of your two reports are the same. I think it has associated with EPT+unrestricted_guest and vm8086 instead of EPT itself. vm8086 emulates a real mode environment, so it will not respect CS.D=1 which you give since there is no segment descriptors support. However, big real mode is different, they still load the segment descriptors which hand over from protect mode before the mode switch. Your testcase just start a real mode guest in all its life time w/o switch to protect mode or vice versa. And KVM(EPT=Y, unrestricted_guest=Y) can't distinguish between a real mode guest w/ segment descriptors given by userspace and big real mode which occurs when protect mode switch to real mode. Regards, Wanpeng Li