]>
Commit | Line | Data |
---|---|---|
18d0a261 DM |
1 | From 29282fde80d44e587f8c152b10049a56e61659f0 Mon Sep 17 00:00:00 2001 |
2 | From: Takashi Iwai <tiwai@suse.de> | |
3 | Date: Fri, 09 Nov 2012 14:20:17 +0000 | |
4 | Subject: KVM: x86: Fix invalid secondary exec controls in vmx_cpuid_update() | |
5 | ||
6 | The commit [ad756a16: KVM: VMX: Implement PCID/INVPCID for guests with | |
7 | EPT] introduced the unconditional access to SECONDARY_VM_EXEC_CONTROL, | |
8 | and this triggers kernel warnings like below on old CPUs: | |
9 | ||
10 | vmwrite error: reg 401e value a0568000 (err 12) | |
11 | Pid: 13649, comm: qemu-kvm Not tainted 3.7.0-rc4-test2+ #154 | |
12 | Call Trace: | |
13 | [<ffffffffa0558d86>] vmwrite_error+0x27/0x29 [kvm_intel] | |
14 | [<ffffffffa054e8cb>] vmcs_writel+0x1b/0x20 [kvm_intel] | |
15 | [<ffffffffa054f114>] vmx_cpuid_update+0x74/0x170 [kvm_intel] | |
16 | [<ffffffffa03629b6>] kvm_vcpu_ioctl_set_cpuid2+0x76/0x90 [kvm] | |
17 | [<ffffffffa0341c67>] kvm_arch_vcpu_ioctl+0xc37/0xed0 [kvm] | |
18 | [<ffffffff81143f7c>] ? __vunmap+0x9c/0x110 | |
19 | [<ffffffffa0551489>] ? vmx_vcpu_load+0x39/0x1a0 [kvm_intel] | |
20 | [<ffffffffa0340ee2>] ? kvm_arch_vcpu_load+0x52/0x1a0 [kvm] | |
21 | [<ffffffffa032dcd4>] ? vcpu_load+0x74/0xd0 [kvm] | |
22 | [<ffffffffa032deb0>] kvm_vcpu_ioctl+0x110/0x5e0 [kvm] | |
23 | [<ffffffffa032e93d>] ? kvm_dev_ioctl+0x4d/0x4a0 [kvm] | |
24 | [<ffffffff8117dc6f>] do_vfs_ioctl+0x8f/0x530 | |
25 | [<ffffffff81139d76>] ? remove_vma+0x56/0x60 | |
26 | [<ffffffff8113b708>] ? do_munmap+0x328/0x400 | |
27 | [<ffffffff81187c8c>] ? fget_light+0x4c/0x100 | |
28 | [<ffffffff8117e1a1>] sys_ioctl+0x91/0xb0 | |
29 | [<ffffffff815a942d>] system_call_fastpath+0x1a/0x1f | |
30 | ||
31 | This patch adds a check for the availability of secondary exec | |
32 | control to avoid these warnings. | |
33 | ||
34 | Cc: <stable@vger.kernel.org> [v3.6+] | |
35 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
36 | Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> | |
37 | --- | |
38 | diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c | |
39 | index ad6b1dd..f858159 100644 | |
40 | --- a/arch/x86/kvm/vmx.c | |
41 | +++ b/arch/x86/kvm/vmx.c | |
42 | @@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) | |
43 | } | |
44 | } | |
45 | ||
46 | - exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
47 | /* Exposing INVPCID only when PCID is exposed */ | |
48 | best = kvm_find_cpuid_entry(vcpu, 0x7, 0); | |
49 | if (vmx_invpcid_supported() && | |
50 | best && (best->ebx & bit(X86_FEATURE_INVPCID)) && | |
51 | guest_cpuid_has_pcid(vcpu)) { | |
52 | + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
53 | exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; | |
54 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | |
55 | exec_control); | |
56 | } else { | |
57 | - exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; | |
58 | - vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | |
59 | - exec_control); | |
60 | + if (cpu_has_secondary_exec_ctrls()) { | |
61 | + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
62 | + exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; | |
63 | + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | |
64 | + exec_control); | |
65 | + } | |
66 | if (best) | |
67 | best->ebx &= ~bit(X86_FEATURE_INVPCID); | |
68 | } | |
69 | -- | |
70 | cgit v0.9.2 |