KVM Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking
@ 2021-04-06 17:18 Sean Christopherson
  2021-04-06 17:18 ` [PATCH 1/4] KVM: SVM: Don't set current_vmcb->cpu when switching vmcb Sean Christopherson
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Sean Christopherson @ 2021-04-06 17:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Cathy Avery, Maxim Levitsky

Belated code review for the vmcb changes that are queued for 5.13.

Sean Christopherson (4):
  KVM: SVM: Don't set current_vmcb->cpu when switching vmcb
  KVM: SVM: Drop vcpu_svm.vmcb_pa
  KVM: SVM: Add a comment to clarify what vcpu_svm.vmcb points at
  KVM: SVM: Enhance and clean up the vmcb tracking comment in
    pre_svm_run()

 arch/x86/kvm/svm/svm.c | 29 +++++++++++++----------------
 arch/x86/kvm/svm/svm.h |  2 +-
 2 files changed, 14 insertions(+), 17 deletions(-)

-- 
2.31.0.208.g409f899ff0-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] KVM: SVM: Don't set current_vmcb->cpu when switching vmcb
  2021-04-06 17:18 [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Sean Christopherson
@ 2021-04-06 17:18 ` Sean Christopherson
  2021-04-06 17:18 ` [PATCH 2/4] KVM: SVM: Drop vcpu_svm.vmcb_pa Sean Christopherson
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sean Christopherson @ 2021-04-06 17:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Cathy Avery, Maxim Levitsky

Do not update the new vmcb's last-run cpu when switching to a different
vmcb.  If the vCPU is migrated between its last run and a vmcb switch,
e.g. for nested VM-Exit, then setting the cpu without marking the vmcb
dirty will lead to KVM running the vCPU on a different physical cpu with
stale clean bit settings.

                          vcpu->cpu    current_vmcb->cpu    hardware
  pre_svm_run()           cpu0         cpu0                 cpu0,clean
  kvm_arch_vcpu_load()    cpu1         cpu0                 cpu0,clean
  svm_switch_vmcb()       cpu1         cpu1                 cpu0,clean
  pre_svm_run()           cpu1         cpu1                 kaboom

Simply delete the offending code; unlike VMX, which needs to update the
cpu at switch time due to the need to do VMPTRLD, SVM only cares about
which cpu last ran the vCPU.

Fixes: af18fa775d07 ("KVM: nSVM: Track the physical cpu of the vmcb vmrun through the vmcb")
Cc: Cathy Avery <cavery@redhat.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/svm/svm.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 48b396f33bee..89619cc52cf4 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1311,14 +1311,6 @@ void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb)
 	svm->current_vmcb = target_vmcb;
 	svm->vmcb = target_vmcb->ptr;
 	svm->vmcb_pa = target_vmcb->pa;
-
-	/*
-	* Track the physical CPU the target_vmcb is running on
-	* in order to mark the VMCB dirty if the cpu changes at
-	* its next vmrun.
-	*/
-
-	svm->current_vmcb->cpu = svm->vcpu.cpu;
 }
 
 static int svm_create_vcpu(struct kvm_vcpu *vcpu)
-- 
2.31.0.208.g409f899ff0-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/4] KVM: SVM: Drop vcpu_svm.vmcb_pa
  2021-04-06 17:18 [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Sean Christopherson
  2021-04-06 17:18 ` [PATCH 1/4] KVM: SVM: Don't set current_vmcb->cpu when switching vmcb Sean Christopherson
@ 2021-04-06 17:18 ` Sean Christopherson
  2021-04-06 17:18 ` [PATCH 3/4] KVM: SVM: Add a comment to clarify what vcpu_svm.vmcb points at Sean Christopherson
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sean Christopherson @ 2021-04-06 17:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Cathy Avery, Maxim Levitsky

Remove vmcb_pa from vcpu_svm and simply read current_vmcb->pa directly in
the one path where it is consumed.  Unlike svm->vmcb, use of the current
vmcb's address is very limited, as evidenced by the fact that its use
can be trimmed to a single dereference.

Opportunistically add a comment about using vmcb01 for VMLOAD/VMSAVE, at
first glance using vmcb01 instead of vmcb_pa looks wrong.

No functional change intended.

Cc: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/svm/svm.c | 12 +++++++++---
 arch/x86/kvm/svm/svm.h |  1 -
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 89619cc52cf4..f62c56adf7c9 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1310,7 +1310,6 @@ void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb)
 {
 	svm->current_vmcb = target_vmcb;
 	svm->vmcb = target_vmcb->ptr;
-	svm->vmcb_pa = target_vmcb->pa;
 }
 
 static int svm_create_vcpu(struct kvm_vcpu *vcpu)
@@ -3704,6 +3703,7 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
 static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
+	unsigned long vmcb_pa = svm->current_vmcb->pa;
 
 	/*
 	 * VMENTER enables interrupts (host state), but the kernel state is
@@ -3726,12 +3726,18 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
 	lockdep_hardirqs_on(CALLER_ADDR0);
 
 	if (sev_es_guest(vcpu->kvm)) {
-		__svm_sev_es_vcpu_run(svm->vmcb_pa);
+		__svm_sev_es_vcpu_run(vmcb_pa);
 	} else {
 		struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
 
+		/*
+		 * Use a single vmcb (vmcb01 because it's always valid) for
+		 * context switching guest state via VMLOAD/VMSAVE, that way
+		 * the state doesn't need to be copied between vmcb01 and
+		 * vmcb02 when switching vmcbs for nested virtualization.
+		 */
 		vmload(svm->vmcb01.pa);
-		__svm_vcpu_run(svm->vmcb_pa, (unsigned long *)&vcpu->arch.regs);
+		__svm_vcpu_run(vmcb_pa, (unsigned long *)&vcpu->arch.regs);
 		vmsave(svm->vmcb01.pa);
 
 		vmload(__sme_page_pa(sd->save_area));
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 02f8ece8c741..2173fe985104 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -112,7 +112,6 @@ struct svm_nested_state {
 struct vcpu_svm {
 	struct kvm_vcpu vcpu;
 	struct vmcb *vmcb;
-	unsigned long vmcb_pa;
 	struct kvm_vmcb_info vmcb01;
 	struct kvm_vmcb_info *current_vmcb;
 	struct svm_cpu_data *svm_data;
-- 
2.31.0.208.g409f899ff0-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/4] KVM: SVM: Add a comment to clarify what vcpu_svm.vmcb points at
  2021-04-06 17:18 [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Sean Christopherson
  2021-04-06 17:18 ` [PATCH 1/4] KVM: SVM: Don't set current_vmcb->cpu when switching vmcb Sean Christopherson
  2021-04-06 17:18 ` [PATCH 2/4] KVM: SVM: Drop vcpu_svm.vmcb_pa Sean Christopherson
@ 2021-04-06 17:18 ` Sean Christopherson
  2021-04-06 17:18 ` [PATCH 4/4] KVM: SVM: Enhance and clean up the vmcb tracking comment in pre_svm_run() Sean Christopherson
  2021-04-17 12:50 ` [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Paolo Bonzini
  4 siblings, 0 replies; 6+ messages in thread
From: Sean Christopherson @ 2021-04-06 17:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Cathy Avery, Maxim Levitsky

Add a comment above the declaration of vcpu_svm.vmcb to call out that it
is simply a shorthand for current_vmcb->ptr.  The myriad accesses to
svm->vmcb are quite confusing without this crucial detail.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/svm/svm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 2173fe985104..b230950c1aa6 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -111,6 +111,7 @@ struct svm_nested_state {
 
 struct vcpu_svm {
 	struct kvm_vcpu vcpu;
+	/* vmcb always points at current_vmcb->ptr, it's purely a shorthand. */
 	struct vmcb *vmcb;
 	struct kvm_vmcb_info vmcb01;
 	struct kvm_vmcb_info *current_vmcb;
-- 
2.31.0.208.g409f899ff0-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/4] KVM: SVM: Enhance and clean up the vmcb tracking comment in pre_svm_run()
  2021-04-06 17:18 [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Sean Christopherson
                   ` (2 preceding siblings ...)
  2021-04-06 17:18 ` [PATCH 3/4] KVM: SVM: Add a comment to clarify what vcpu_svm.vmcb points at Sean Christopherson
@ 2021-04-06 17:18 ` Sean Christopherson
  2021-04-17 12:50 ` [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Paolo Bonzini
  4 siblings, 0 replies; 6+ messages in thread
From: Sean Christopherson @ 2021-04-06 17:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
	Joerg Roedel, kvm, linux-kernel, Cathy Avery, Maxim Levitsky

Explicitly document why a vmcb must be marked dirty and assigned a new
asid when it will be run on a different cpu.  The "what" is relatively
obvious, whereas the "why" requires reading the APM and/or KVM code.

Opportunistically remove a spurious period and several unnecessary
newlines in the comment.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/svm/svm.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index f62c56adf7c9..afc275ba5d59 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3336,11 +3336,10 @@ static void pre_svm_run(struct kvm_vcpu *vcpu)
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 	/*
-	 * If the previous vmrun of the vmcb occurred on
-	 * a different physical cpu then we must mark the vmcb dirty.
-	 * and assign a new asid.
-	*/
-
+	 * If the previous vmrun of the vmcb occurred on a different physical
+	 * cpu, then mark the vmcb dirty and assign a new asid.  Hardware's
+	 * vmcb clean bits are per logical CPU, as are KVM's asid assignments.
+	 */
 	if (unlikely(svm->current_vmcb->cpu != vcpu->cpu)) {
 		svm->current_vmcb->asid_generation = 0;
 		vmcb_mark_all_dirty(svm->vmcb);
-- 
2.31.0.208.g409f899ff0-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking
  2021-04-06 17:18 [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Sean Christopherson
                   ` (3 preceding siblings ...)
  2021-04-06 17:18 ` [PATCH 4/4] KVM: SVM: Enhance and clean up the vmcb tracking comment in pre_svm_run() Sean Christopherson
@ 2021-04-17 12:50 ` Paolo Bonzini
  4 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2021-04-17 12:50 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Vitaly Kuznetsov, Wanpeng Li, Jim Mattson, Joerg Roedel, kvm,
	linux-kernel, Cathy Avery, Maxim Levitsky

On 06/04/21 19:18, Sean Christopherson wrote:
> Belated code review for the vmcb changes that are queued for 5.13.
> 
> Sean Christopherson (4):
>    KVM: SVM: Don't set current_vmcb->cpu when switching vmcb
>    KVM: SVM: Drop vcpu_svm.vmcb_pa
>    KVM: SVM: Add a comment to clarify what vcpu_svm.vmcb points at
>    KVM: SVM: Enhance and clean up the vmcb tracking comment in
>      pre_svm_run()
> 
>   arch/x86/kvm/svm/svm.c | 29 +++++++++++++----------------
>   arch/x86/kvm/svm/svm.h |  2 +-
>   2 files changed, 14 insertions(+), 17 deletions(-)
> 

Queued, thanks -- especially for the bug in patch 1, which avoided review.

Paolo


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-06 17:18 [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Sean Christopherson
2021-04-06 17:18 ` [PATCH 1/4] KVM: SVM: Don't set current_vmcb->cpu when switching vmcb Sean Christopherson
2021-04-06 17:18 ` [PATCH 2/4] KVM: SVM: Drop vcpu_svm.vmcb_pa Sean Christopherson
2021-04-06 17:18 ` [PATCH 3/4] KVM: SVM: Add a comment to clarify what vcpu_svm.vmcb points at Sean Christopherson
2021-04-06 17:18 ` [PATCH 4/4] KVM: SVM: Enhance and clean up the vmcb tracking comment in pre_svm_run() Sean Christopherson
2021-04-17 12:50 ` [PATCH 0/4] KVM: SVM: A fix and cleanups for vmcb tracking Paolo Bonzini

KVM Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/kvm/0 kvm/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 kvm kvm/ https://lore.kernel.org/kvm \
		kvm@vger.kernel.org
	public-inbox-index kvm

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.kvm


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git