Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'kvm-updates/3.3' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Fixing a regression with the PMU MSRs when PMU virtualization is
disabled, a guest-internal DoS with the SYSCALL instruction, and a dirty
memory logging race that may cause live migration to fail.

* 'kvm-updates/3.3' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: do not #GP on perf MSR writes when vPMU is disabled
KVM: x86: fix missing checks in syscall emulation
KVM: x86: extend "struct x86_emulate_ops" with "get_cpuid"
KVM: Fix __set_bit() race in mark_page_dirty() during dirty logging

+113 -1
+16
arch/x86/include/asm/kvm_emulate.h
··· 190 190 int (*intercept)(struct x86_emulate_ctxt *ctxt, 191 191 struct x86_instruction_info *info, 192 192 enum x86_intercept_stage stage); 193 + 194 + bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, 195 + u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); 193 196 }; 194 197 195 198 typedef u32 __attribute__((vector_size(16))) sse128_t; ··· 300 297 /* any protected mode */ 301 298 #define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \ 302 299 X86EMUL_MODE_PROT64) 300 + 301 + /* CPUID vendors */ 302 + #define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541 303 + #define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163 304 + #define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65 305 + 306 + #define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41 307 + #define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574 308 + #define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273 309 + 310 + #define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547 311 + #define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e 312 + #define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69 303 313 304 314 enum x86_intercept_stage { 305 315 X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */
+51
arch/x86/kvm/emulate.c
··· 1891 1891 ss->p = 1; 1892 1892 } 1893 1893 1894 + static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt) 1895 + { 1896 + struct x86_emulate_ops *ops = ctxt->ops; 1897 + u32 eax, ebx, ecx, edx; 1898 + 1899 + /* 1900 + * syscall should always be enabled in longmode - so only become 1901 + * vendor specific (cpuid) if other modes are active... 1902 + */ 1903 + if (ctxt->mode == X86EMUL_MODE_PROT64) 1904 + return true; 1905 + 1906 + eax = 0x00000000; 1907 + ecx = 0x00000000; 1908 + if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) { 1909 + /* 1910 + * Intel ("GenuineIntel") 1911 + * remark: Intel CPUs only support "syscall" in 64bit 1912 + * longmode. Also an 64bit guest with a 1913 + * 32bit compat-app running will #UD !! While this 1914 + * behaviour can be fixed (by emulating) into AMD 1915 + * response - CPUs of AMD can't behave like Intel. 1916 + */ 1917 + if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx && 1918 + ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx && 1919 + edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx) 1920 + return false; 1921 + 1922 + /* AMD ("AuthenticAMD") */ 1923 + if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx && 1924 + ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx && 1925 + edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx) 1926 + return true; 1927 + 1928 + /* AMD ("AMDisbetter!") */ 1929 + if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx && 1930 + ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx && 1931 + edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx) 1932 + return true; 1933 + } 1934 + 1935 + /* default: (not Intel, not AMD), apply Intel's stricter rules... */ 1936 + return false; 1937 + } 1938 + 1894 1939 static int em_syscall(struct x86_emulate_ctxt *ctxt) 1895 1940 { 1896 1941 struct x86_emulate_ops *ops = ctxt->ops; ··· 1949 1904 ctxt->mode == X86EMUL_MODE_VM86) 1950 1905 return emulate_ud(ctxt); 1951 1906 1907 + if (!(em_syscall_is_enabled(ctxt))) 1908 + return emulate_ud(ctxt); 1909 + 1952 1910 ops->get_msr(ctxt, MSR_EFER, &efer); 1953 1911 setup_syscalls_segments(ctxt, &cs, &ss); 1912 + 1913 + if (!(efer & EFER_SCE)) 1914 + return emulate_ud(ctxt); 1954 1915 1955 1916 ops->get_msr(ctxt, MSR_STAR, &msr_data); 1956 1917 msr_data >>= 32;
+45
arch/x86/kvm/x86.c
··· 1495 1495 1496 1496 int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) 1497 1497 { 1498 + bool pr = false; 1499 + 1498 1500 switch (msr) { 1499 1501 case MSR_EFER: 1500 1502 return set_efer(vcpu, data); ··· 1636 1634 case MSR_K7_PERFCTR3: 1637 1635 pr_unimpl(vcpu, "unimplemented perfctr wrmsr: " 1638 1636 "0x%x data 0x%llx\n", msr, data); 1637 + break; 1638 + case MSR_P6_PERFCTR0: 1639 + case MSR_P6_PERFCTR1: 1640 + pr = true; 1641 + case MSR_P6_EVNTSEL0: 1642 + case MSR_P6_EVNTSEL1: 1643 + if (kvm_pmu_msr(vcpu, msr)) 1644 + return kvm_pmu_set_msr(vcpu, msr, data); 1645 + 1646 + if (pr || data != 0) 1647 + pr_unimpl(vcpu, "disabled perfctr wrmsr: " 1648 + "0x%x data 0x%llx\n", msr, data); 1639 1649 break; 1640 1650 case MSR_K7_CLK_CTL: 1641 1651 /* ··· 1847 1833 case MSR_K8_INT_PENDING_MSG: 1848 1834 case MSR_AMD64_NB_CFG: 1849 1835 case MSR_FAM10H_MMIO_CONF_BASE: 1836 + data = 0; 1837 + break; 1838 + case MSR_P6_PERFCTR0: 1839 + case MSR_P6_PERFCTR1: 1840 + case MSR_P6_EVNTSEL0: 1841 + case MSR_P6_EVNTSEL1: 1842 + if (kvm_pmu_msr(vcpu, msr)) 1843 + return kvm_pmu_get_msr(vcpu, msr, pdata); 1850 1844 data = 0; 1851 1845 break; 1852 1846 case MSR_IA32_UCODE_REV: ··· 4202 4180 return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage); 4203 4181 } 4204 4182 4183 + static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt, 4184 + u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) 4185 + { 4186 + struct kvm_cpuid_entry2 *cpuid = NULL; 4187 + 4188 + if (eax && ecx) 4189 + cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt), 4190 + *eax, *ecx); 4191 + 4192 + if (cpuid) { 4193 + *eax = cpuid->eax; 4194 + *ecx = cpuid->ecx; 4195 + if (ebx) 4196 + *ebx = cpuid->ebx; 4197 + if (edx) 4198 + *edx = cpuid->edx; 4199 + return true; 4200 + } 4201 + 4202 + return false; 4203 + } 4204 + 4205 4205 static struct x86_emulate_ops emulate_ops = { 4206 4206 .read_std = kvm_read_guest_virt_system, 4207 4207 .write_std = kvm_write_guest_virt_system, ··· 4255 4211 .get_fpu = emulator_get_fpu, 4256 4212 .put_fpu = emulator_put_fpu, 4257 4213 .intercept = emulator_intercept, 4214 + .get_cpuid = emulator_get_cpuid, 4258 4215 }; 4259 4216 4260 4217 static void cache_all_regs(struct kvm_vcpu *vcpu)
+1 -1
virt/kvm/kvm_main.c
··· 1543 1543 if (memslot && memslot->dirty_bitmap) { 1544 1544 unsigned long rel_gfn = gfn - memslot->base_gfn; 1545 1545 1546 - if (!__test_and_set_bit_le(rel_gfn, memslot->dirty_bitmap)) 1546 + if (!test_and_set_bit_le(rel_gfn, memslot->dirty_bitmap)) 1547 1547 memslot->nr_dirty_pages++; 1548 1548 } 1549 1549 }