KVM: VMX: fix memory order between loading vmcs and clearing vmcs
vmcs->cpu indicates whether it exists on the target cpu, -1 means the vmcs does not exist on any vcpu If vcpu load vmcs with vmcs.cpu = -1, it can be directly added to cpu's percpu list. The list can be corrupted if the cpu prefetch the vmcs's list before reading vmcs->cpu. Meanwhile, we should remove vmcs from the list before making vmcs->vcpu == -1 be visible Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
e6c7d32172
commit
5a560f8b5e
1 changed files with 17 additions and 0 deletions
|
@ -1002,6 +1002,15 @@ static void __loaded_vmcs_clear(void *arg)
|
|||
if (per_cpu(current_vmcs, cpu) == loaded_vmcs->vmcs)
|
||||
per_cpu(current_vmcs, cpu) = NULL;
|
||||
list_del(&loaded_vmcs->loaded_vmcss_on_cpu_link);
|
||||
|
||||
/*
|
||||
* we should ensure updating loaded_vmcs->loaded_vmcss_on_cpu_link
|
||||
* is before setting loaded_vmcs->vcpu to -1 which is done in
|
||||
* loaded_vmcs_init. Otherwise, other cpu can see vcpu = -1 fist
|
||||
* then adds the vmcs into percpu list before it is deleted.
|
||||
*/
|
||||
smp_wmb();
|
||||
|
||||
loaded_vmcs_init(loaded_vmcs);
|
||||
}
|
||||
|
||||
|
@ -1537,6 +1546,14 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
|||
|
||||
kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
|
||||
local_irq_disable();
|
||||
|
||||
/*
|
||||
* Read loaded_vmcs->cpu should be before fetching
|
||||
* loaded_vmcs->loaded_vmcss_on_cpu_link.
|
||||
* See the comments in __loaded_vmcs_clear().
|
||||
*/
|
||||
smp_rmb();
|
||||
|
||||
list_add(&vmx->loaded_vmcs->loaded_vmcss_on_cpu_link,
|
||||
&per_cpu(loaded_vmcss_on_cpu, cpu));
|
||||
local_irq_enable();
|
||||
|
|
Loading…
Reference in a new issue