[PATCH v3 5/6] KVM: SVM: Move global "avic" variable to avic.c

Sean Christopherson posted 6 patches 1 week, 6 days ago
There is a newer version of this series
[PATCH v3 5/6] KVM: SVM: Move global "avic" variable to avic.c
Posted by Sean Christopherson 1 week, 6 days ago
Move "avic" to avic.c so that it's colocated with the other AVIC specific
globals and module params, and so that avic_hardware_setup() is a bit more
self-contained, e.g. similar to sev_hardware_setup().

Deliberately set enable_apicv in svm.c as it's already globally visible
(defined by kvm.ko, not by kvm-amd.ko), and to clearly capture the
dependency on enable_apicv being initialized (svm_hardware_setup() clears
several AVIC-specific hooks when enable_apicv is disabled).

Alternatively, clearing of the hooks (and enable_ipiv) could be moved to
avic_hardware_setup(), but that's not obviously better, e.g. it's helpful
to isolate the setting of enable_apicv when reading code from the generic
x86 side of the world.

No functional change intended.

Cc: Naveen N Rao (AMD) <naveen@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/svm/avic.c | 32 ++++++++++++++++++++++++--------
 arch/x86/kvm/svm/svm.c  | 11 +----------
 2 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 497d755c206f..e059dcae6945 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -64,6 +64,14 @@
 
 static_assert(__AVIC_GATAG(AVIC_VM_ID_MASK, AVIC_VCPU_IDX_MASK) == -1u);
 
+/*
+ * enable / disable AVIC.  Because the defaults differ for APICv
+ * support between VMX and SVM we cannot use module_param_named.
+ */
+static bool avic;
+module_param(avic, bool, 0444);
+module_param(enable_ipiv, bool, 0444);
+
 static bool force_avic;
 module_param_unsafe(force_avic, bool, 0444);
 
@@ -1141,15 +1149,9 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
 	avic_vcpu_load(vcpu, vcpu->cpu);
 }
 
-/*
- * Note:
- * - The module param avic enable both xAPIC and x2APIC mode.
- * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
- * - The mode can be switched at run-time.
- */
-bool __init avic_hardware_setup(struct kvm_x86_ops *svm_ops)
+static bool __init avic_want_avic_enable(void)
 {
-	if (!npt_enabled)
+	if (!avic || !npt_enabled)
 		return false;
 
 	/* AVIC is a prerequisite for x2AVIC. */
@@ -1174,6 +1176,20 @@ bool __init avic_hardware_setup(struct kvm_x86_ops *svm_ops)
 		pr_warn("AVIC unsupported in CPUID but force enabled, your system might crash and burn\n");
 
 	pr_info("AVIC enabled\n");
+	return true;
+}
+
+/*
+ * Note:
+ * - The module param avic enable both xAPIC and x2APIC mode.
+ * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
+ * - The mode can be switched at run-time.
+ */
+bool __init avic_hardware_setup(struct kvm_x86_ops *svm_ops)
+{
+	avic = avic_want_avic_enable();
+	if (!avic)
+		return false;
 
 	/* AVIC is a prerequisite for x2AVIC. */
 	x2avic_enabled = boot_cpu_has(X86_FEATURE_X2AVIC);
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index d4643dce7c91..c473246f8881 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -158,14 +158,6 @@ module_param(lbrv, int, 0444);
 static int tsc_scaling = true;
 module_param(tsc_scaling, int, 0444);
 
-/*
- * enable / disable AVIC.  Because the defaults differ for APICv
- * support between VMX and SVM we cannot use module_param_named.
- */
-static bool avic;
-module_param(avic, bool, 0444);
-module_param(enable_ipiv, bool, 0444);
-
 module_param(enable_device_posted_irqs, bool, 0444);
 
 bool __read_mostly dump_invalid_vmcb;
@@ -5354,8 +5346,7 @@ static __init int svm_hardware_setup(void)
 			goto err;
 	}
 
-	enable_apicv = avic = avic && avic_hardware_setup(&svm_x86_ops);
-
+	enable_apicv = avic_hardware_setup(&svm_x86_ops);
 	if (!enable_apicv) {
 		enable_ipiv = false;
 		svm_x86_ops.vcpu_blocking = NULL;
-- 
2.51.0.470.ga7dc726c21-goog
Re: [PATCH v3 5/6] KVM: SVM: Move global "avic" variable to avic.c
Posted by Naveen N Rao 1 week, 5 days ago
On Thu, Sep 18, 2025 at 05:21:35PM -0700, Sean Christopherson wrote:
> Move "avic" to avic.c so that it's colocated with the other AVIC specific
> globals and module params, and so that avic_hardware_setup() is a bit more
> self-contained, e.g. similar to sev_hardware_setup().
> 
> Deliberately set enable_apicv in svm.c as it's already globally visible
> (defined by kvm.ko, not by kvm-amd.ko), and to clearly capture the
> dependency on enable_apicv being initialized (svm_hardware_setup() clears
> several AVIC-specific hooks when enable_apicv is disabled).
> 
> Alternatively, clearing of the hooks (and enable_ipiv) could be moved to
> avic_hardware_setup(), but that's not obviously better, e.g. it's helpful
> to isolate the setting of enable_apicv when reading code from the generic
> x86 side of the world.
> 
> No functional change intended.
> 
> Cc: Naveen N Rao (AMD) <naveen@kernel.org>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
>  arch/x86/kvm/svm/avic.c | 32 ++++++++++++++++++++++++--------
>  arch/x86/kvm/svm/svm.c  | 11 +----------
>  2 files changed, 25 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index 497d755c206f..e059dcae6945 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -64,6 +64,14 @@
>  
>  static_assert(__AVIC_GATAG(AVIC_VM_ID_MASK, AVIC_VCPU_IDX_MASK) == -1u);
>  
> +/*
> + * enable / disable AVIC.  Because the defaults differ for APICv
> + * support between VMX and SVM we cannot use module_param_named.
> + */
> +static bool avic;
> +module_param(avic, bool, 0444);
> +module_param(enable_ipiv, bool, 0444);
> +
>  static bool force_avic;
>  module_param_unsafe(force_avic, bool, 0444);
>  
> @@ -1141,15 +1149,9 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
>  	avic_vcpu_load(vcpu, vcpu->cpu);
>  }
>  
> -/*
> - * Note:
> - * - The module param avic enable both xAPIC and x2APIC mode.
> - * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
> - * - The mode can be switched at run-time.
> - */
> -bool __init avic_hardware_setup(struct kvm_x86_ops *svm_ops)
> +static bool __init avic_want_avic_enable(void)

Maybe avic_can_enable()?

>  {
> -	if (!npt_enabled)
> +	if (!avic || !npt_enabled)
>  		return false;
>  
>  	/* AVIC is a prerequisite for x2AVIC. */
> @@ -1174,6 +1176,20 @@ bool __init avic_hardware_setup(struct kvm_x86_ops *svm_ops)
>  		pr_warn("AVIC unsupported in CPUID but force enabled, your system might crash and burn\n");
>  
>  	pr_info("AVIC enabled\n");

I think it would be good to keep this in avic_hardware_setup() alongside 
the message printing "x2AVIC enabled".

Otherwise:
Acked-by: Naveen N Rao (AMD) <naveen@kernel.org>


- Naveen
Re: [PATCH v3 5/6] KVM: SVM: Move global "avic" variable to avic.c
Posted by Sean Christopherson 1 week, 5 days ago
On Fri, Sep 19, 2025, Naveen N Rao wrote:
> On Thu, Sep 18, 2025 at 05:21:35PM -0700, Sean Christopherson wrote:
> > @@ -1141,15 +1149,9 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
> >  	avic_vcpu_load(vcpu, vcpu->cpu);
> >  }
> >  
> > -/*
> > - * Note:
> > - * - The module param avic enable both xAPIC and x2APIC mode.
> > - * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
> > - * - The mode can be switched at run-time.
> > - */
> > -bool __init avic_hardware_setup(struct kvm_x86_ops *svm_ops)
> > +static bool __init avic_want_avic_enable(void)
> 
> Maybe avic_can_enable()?

That was actualy one of my first names, but I didn't want to use "can" because
(to me at least) that doesn't capture that the helper is incorporating input from
the user, i.e. that it's also checking what the user "wants".

I agree the name isn't great.  Does avic_want_avic_enabled() read any better?

> >  {
> > -	if (!npt_enabled)
> > +	if (!avic || !npt_enabled)
> >  		return false;
> >  
> >  	/* AVIC is a prerequisite for x2AVIC. */
> > @@ -1174,6 +1176,20 @@ bool __init avic_hardware_setup(struct kvm_x86_ops *svm_ops)
> >  		pr_warn("AVIC unsupported in CPUID but force enabled, your system might crash and burn\n");
> >  
> >  	pr_info("AVIC enabled\n");
> 
> I think it would be good to keep this in avic_hardware_setup() alongside 
> the message printing "x2AVIC enabled".

+1, looks waaay better that way.
Re: [PATCH v3 5/6] KVM: SVM: Move global "avic" variable to avic.c
Posted by Naveen N Rao 1 week, 5 days ago
On Fri, Sep 19, 2025 at 07:44:29AM -0700, Sean Christopherson wrote:
> On Fri, Sep 19, 2025, Naveen N Rao wrote:
> > On Thu, Sep 18, 2025 at 05:21:35PM -0700, Sean Christopherson wrote:
> > > @@ -1141,15 +1149,9 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
> > >  	avic_vcpu_load(vcpu, vcpu->cpu);
> > >  }
> > >  
> > > -/*
> > > - * Note:
> > > - * - The module param avic enable both xAPIC and x2APIC mode.
> > > - * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
> > > - * - The mode can be switched at run-time.
> > > - */
> > > -bool __init avic_hardware_setup(struct kvm_x86_ops *svm_ops)
> > > +static bool __init avic_want_avic_enable(void)
> > 
> > Maybe avic_can_enable()?
> 
> That was actualy one of my first names, but I didn't want to use "can" because
> (to me at least) that doesn't capture that the helper is incorporating input from
> the user, i.e. that it's also checking what the user "wants".

Makes sense.

> 
> I agree the name isn't great.  Does avic_want_avic_enabled() read any better?

Yes, though I think avic_want_enabled() suffices. But, I'm ok if you 
want it to be explicit.


- Naveen