diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-11-09 09:20:17 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2012-11-16 17:25:18 -0500 |
commit | 29282fde80d44e587f8c152b10049a56e61659f0 (patch) | |
tree | 397f6fbfedad13d676a8817ad99b35149e557199 | |
parent | d3fb695576fc7f9d045da9e1ef001d94b0eea3cb (diff) |
KVM: x86: Fix invalid secondary exec controls in vmx_cpuid_update()
The commit [ad756a16: KVM: VMX: Implement PCID/INVPCID for guests with
EPT] introduced the unconditional access to SECONDARY_VM_EXEC_CONTROL,
and this triggers kernel warnings like below on old CPUs:
vmwrite error: reg 401e value a0568000 (err 12)
Pid: 13649, comm: qemu-kvm Not tainted 3.7.0-rc4-test2+ #154
Call Trace:
[<ffffffffa0558d86>] vmwrite_error+0x27/0x29 [kvm_intel]
[<ffffffffa054e8cb>] vmcs_writel+0x1b/0x20 [kvm_intel]
[<ffffffffa054f114>] vmx_cpuid_update+0x74/0x170 [kvm_intel]
[<ffffffffa03629b6>] kvm_vcpu_ioctl_set_cpuid2+0x76/0x90 [kvm]
[<ffffffffa0341c67>] kvm_arch_vcpu_ioctl+0xc37/0xed0 [kvm]
[<ffffffff81143f7c>] ? __vunmap+0x9c/0x110
[<ffffffffa0551489>] ? vmx_vcpu_load+0x39/0x1a0 [kvm_intel]
[<ffffffffa0340ee2>] ? kvm_arch_vcpu_load+0x52/0x1a0 [kvm]
[<ffffffffa032dcd4>] ? vcpu_load+0x74/0xd0 [kvm]
[<ffffffffa032deb0>] kvm_vcpu_ioctl+0x110/0x5e0 [kvm]
[<ffffffffa032e93d>] ? kvm_dev_ioctl+0x4d/0x4a0 [kvm]
[<ffffffff8117dc6f>] do_vfs_ioctl+0x8f/0x530
[<ffffffff81139d76>] ? remove_vma+0x56/0x60
[<ffffffff8113b708>] ? do_munmap+0x328/0x400
[<ffffffff81187c8c>] ? fget_light+0x4c/0x100
[<ffffffff8117e1a1>] sys_ioctl+0x91/0xb0
[<ffffffff815a942d>] system_call_fastpath+0x1a/0x1f
This patch adds a check for the availability of secondary exec
control to avoid these warnings.
Cc: <stable@vger.kernel.org> [v3.6+]
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | arch/x86/kvm/vmx.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad6b1dd06f8b..f85815945fc6 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) | |||
6549 | } | 6549 | } |
6550 | } | 6550 | } |
6551 | 6551 | ||
6552 | exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | ||
6553 | /* Exposing INVPCID only when PCID is exposed */ | 6552 | /* Exposing INVPCID only when PCID is exposed */ |
6554 | best = kvm_find_cpuid_entry(vcpu, 0x7, 0); | 6553 | best = kvm_find_cpuid_entry(vcpu, 0x7, 0); |
6555 | if (vmx_invpcid_supported() && | 6554 | if (vmx_invpcid_supported() && |
6556 | best && (best->ebx & bit(X86_FEATURE_INVPCID)) && | 6555 | best && (best->ebx & bit(X86_FEATURE_INVPCID)) && |
6557 | guest_cpuid_has_pcid(vcpu)) { | 6556 | guest_cpuid_has_pcid(vcpu)) { |
6557 | exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | ||
6558 | exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; | 6558 | exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; |
6559 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | 6559 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, |
6560 | exec_control); | 6560 | exec_control); |
6561 | } else { | 6561 | } else { |
6562 | exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; | 6562 | if (cpu_has_secondary_exec_ctrls()) { |
6563 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | 6563 | exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); |
6564 | exec_control); | 6564 | exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; |
6565 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | ||
6566 | exec_control); | ||
6567 | } | ||
6565 | if (best) | 6568 | if (best) |
6566 | best->ebx &= ~bit(X86_FEATURE_INVPCID); | 6569 | best->ebx &= ~bit(X86_FEATURE_INVPCID); |
6567 | } | 6570 | } |