* [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 related [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 related [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 related [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 related [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