Floating point instructions (e.g. cvtsi2sd) incorrect result

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi everyone,

I am using KVM to run a virtual machine (x86) without having a guest
OS. So the machine state is set for long mode before calling KVM_RUN
and I am trapping out of KVM on every syscall  to emulate the syscall
in the program that uses KVM. Also I am trapping out of KVM on
pagefaults to deal with stack growth.

This has been working great for integer workloads, however I have
encoutered some workloads which are using floating point instructions,
for example cvtsi2sd to cast an integer to a double, and their result
is incorrect.

Recently I have discovered that KVM does FPU context save on-demand,
meaning when the virtual machine actually uses the FPU [1]. I am
wondering if this machanism has some baked in assumptions about
running a virtual machine with a guest OS and if a guest OS is not
present the FPU state might be altered? Also I have not seen any #NM
exceptions, these usually trap out of KVM.

The FPU state that I am using [2] seems valid and it does not change
when trapping out of KVM for syscalls and pagefaults. In addition, I
have tried running with multiple linux versions 2.6.29, 3.13 and 4.0.4
and all of them give incorrect floating point instructions result,
however for different instructions.

Thank you,
-- 
Alex

[1] http://www.linux-kvm.org/images/e/ea/2010-forum-mtosatti_walkthrough_entry_exit.pdf
[2] FPU related machine state before calling KVM_RUN:
 Efer efer = 0;
 efer.sce = 1; // Enable system call extensions.
 efer.lme = 1; // Enable long mode.
 efer.lma = 1; // Activate long mode.
 efer.nxe = 0; // Enable nx support.
 efer.svme = 1; // Enable svm support for now.
 efer.ffxsr = 0; // Turn on fast fxsave and fxrstor.

 //Set up the registers that describe the operating mode.
 CR0 cr0 = 0;
 cr0.pg = 1; // Turn on paging.
 cr0.cd = 0; // Don't disable caching.
 cr0.nw = 0; // This is bit is defined to be ignored.
 cr0.am = 1; // No alignment checking
 cr0.wp = 1; // Supervisor mode can write read only pages
 cr0.ne = 1;
 cr0.et = 1; // This should always be 1
 cr0.ts = 0; // We don't do task switching, so causing fp exceptions
             // would be pointless.
 cr0.em = 0; // Allow x87 instructions to execute natively.
 cr0.mp = 1; // This doesn't really matter, but the manual suggests
             // setting it to one.
 cr0.pe = 1; // We're definitely in protected mode.

 CR4 cr4 = 0;
 //Turn on pae.
 cr4.osxsave = 1; // Enable XSAVE and Proc Extended States
 cr4.osxmmexcpt = 1; // Operating System Unmasked Exception
 cr4.osfxsr = 1; // Operating System FXSave/FSRSTOR Support
 cr4.pce = 0; // Performance-Monitoring Counter Enable
 cr4.pge = 0; // Page-Global Enable
 cr4.mce = 0; // Machine Check Enable
 cr4.pae = 1; // Physical-Address Extension
 cr4.pse = 0; // Page Size Extensions
 cr4.de = 0; // Debugging Extensions
 cr4.tsd = 0; // Time Stamp Disable
 cr4.pvi = 0; // Protected-Mode Virtual Interrupts
 cr4.vme = 0; // Virtual-8086 Mode Extensions
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux