~ubuntu-branches/ubuntu/lucid/linux-lts-backport-maverick/lucid-updates

« back to all changes in this revision

Viewing changes to arch/x86/kvm/emulate.c

  • Committer: Package Import Robot
  • Author(s): Luis Henriques, Luis Henriques, Andy Whitcroft, Upstream Kernel Changes
  • Date: 2012-03-28 16:24:53 UTC
  • Revision ID: package-import@ubuntu.com-20120328162453-gqffsvlqm36x1jqc
Tags: 2.6.35-32.68~lucid1
[ Luis Henriques ]

* Release Tracking Bug
  - LP: #967068

[ Andy Whitcroft ]

* [Config] restore build-% shortcut

[ Upstream Kernel Changes ]

* bsg: fix sysfs link remove warning
  - LP: #946928
* regset: Prevent null pointer reference on readonly regsets
  - LP: #949905
  - CVE-2012-1097
* regset: Return -EFAULT, not -EIO, on host-side memory fault
  - LP: #949905
  - CVE-2012-1097
* mm: memcg: Correct unregistring of events attached to the same eventfd
  - LP: #952828
  - CVE-2012-1146
* KVM: Remove ability to assign a device without iommu support
  - LP: #897812
  - CVE-2011-4347
* KVM: x86: extend "struct x86_emulate_ops" with "get_cpuid"
  - LP: #917842
  - CVE-2012-0045
* KVM: x86: fix missing checks in syscall emulation
  - LP: #917842
  - CVE-2012-0045
* eCryptfs: Clear ECRYPTFS_NEW_FILE flag during truncate
  - LP: #745836

Show diffs side-by-side

added added

removed removed

Lines of Context:
1842
1842
        ss->present = 1;
1843
1843
}
1844
1844
 
 
1845
static bool syscall_is_enabled(struct x86_emulate_ctxt *ctxt,
 
1846
                               struct x86_emulate_ops *ops)
 
1847
{
 
1848
        u32 eax, ebx, ecx, edx;
 
1849
 
 
1850
        /*
 
1851
         * syscall should always be enabled in longmode - so only become
 
1852
         * vendor specific (cpuid) if other modes are active...
 
1853
         */
 
1854
        if (ctxt->mode == X86EMUL_MODE_PROT64)
 
1855
                return true;
 
1856
 
 
1857
        eax = 0x00000000;
 
1858
        ecx = 0x00000000;
 
1859
        if (ops->get_cpuid(ctxt->vcpu, &eax, &ebx, &ecx, &edx)) {
 
1860
                /*
 
1861
                 * Intel ("GenuineIntel")
 
1862
                 * remark: Intel CPUs only support "syscall" in 64bit
 
1863
                 * longmode. Also an 64bit guest with a
 
1864
                 * 32bit compat-app running will #UD !! While this
 
1865
                 * behaviour can be fixed (by emulating) into AMD
 
1866
                 * response - CPUs of AMD can't behave like Intel.
 
1867
                 */
 
1868
                if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
 
1869
                    ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
 
1870
                    edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
 
1871
                        return false;
 
1872
 
 
1873
                /* AMD ("AuthenticAMD") */
 
1874
                if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
 
1875
                    ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
 
1876
                    edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
 
1877
                        return true;
 
1878
 
 
1879
                /* AMD ("AMDisbetter!") */
 
1880
                if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
 
1881
                    ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
 
1882
                    edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
 
1883
                        return true;
 
1884
        }
 
1885
 
 
1886
        /* default: (not Intel, not AMD), apply Intel's stricter rules... */
 
1887
        return false;
 
1888
}
 
1889
 
1845
1890
static int
1846
 
emulate_syscall(struct x86_emulate_ctxt *ctxt)
 
1891
emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1847
1892
{
1848
1893
        struct decode_cache *c = &ctxt->decode;
1849
1894
        struct kvm_segment cs, ss;
1850
1895
        u64 msr_data;
 
1896
        u64 efer = 0;
1851
1897
 
1852
1898
        /* syscall is not available in real mode */
1853
1899
        if (ctxt->mode == X86EMUL_MODE_REAL ||
1856
1902
                return X86EMUL_PROPAGATE_FAULT;
1857
1903
        }
1858
1904
 
 
1905
        if (!(syscall_is_enabled(ctxt, ops))) {
 
1906
                kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
 
1907
                return X86EMUL_PROPAGATE_FAULT;
 
1908
        }
 
1909
 
 
1910
        kvm_x86_ops->get_msr(ctxt->vcpu, MSR_EFER, &efer);
1859
1911
        setup_syscalls_segments(ctxt, &cs, &ss);
1860
1912
 
 
1913
        if (!(efer & EFER_SCE)) {
 
1914
                kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
 
1915
                return X86EMUL_PROPAGATE_FAULT;
 
1916
        }
 
1917
 
1861
1918
        kvm_x86_ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data);
1862
1919
        msr_data >>= 32;
1863
1920
        cs.selector = (u16)(msr_data & 0xfffc);
3062
3119
                }
3063
3120
                break;
3064
3121
        case 0x05:              /* syscall */
3065
 
                rc = emulate_syscall(ctxt);
 
3122
                rc = emulate_syscall(ctxt, ops);
3066
3123
                if (rc != X86EMUL_CONTINUE)
3067
3124
                        goto done;
3068
3125
                else