Skip to content

Commit ca2967d

Browse files
rnavsean-jc
authored andcommitted
KVM: SVM: Enable AVIC by default for Zen4+ if x2AVIC is support
AVIC and x2AVIC are fully functional since Zen 4, with no known hardware errata. Enable AVIC and x2AVIC by default on Zen4+ so long as x2AVIC is supported (to avoid enabling partial support for APIC virtualization by default). Internally, convert "avic" to an integer so that KVM can identify if the user has asked to explicitly enable or disable AVIC, i.e. so that KVM doesn't override an explicit 'y' from the user. Arbitrarily use -1 to denote auto-mode, and accept the string "auto" for the module param in addition to standard boolean values, i.e. continue to allow the user to configure the "avic" module parameter to explicitly enable/disable AVIC. To again maintain backward compatibility with a standard boolean param, set KERNEL_PARAM_OPS_FL_NOARG, which tells the params infrastructure to allow empty values for %true, i.e. to interpret a bare "avic" as "avic=y". Take care to check for a NULL @Val when looking for "auto"! Lastly, always print "avic" as a boolean, since auto-mode is resolved during module initialization, i.e. the user should never see "auto" in sysfs. Signed-off-by: Naveen N Rao (AMD) <[email protected]> Tested-by: Naveen N Rao (AMD) <[email protected]> Co-developed-by: Sean Christopherson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]>
1 parent b146653 commit ca2967d

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

arch/x86/kvm/svm/avic.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,32 @@
6464

6565
static_assert(__AVIC_GATAG(AVIC_VM_ID_MASK, AVIC_VCPU_IDX_MASK) == -1u);
6666

67+
#define AVIC_AUTO_MODE -1
68+
69+
static int avic_param_set(const char *val, const struct kernel_param *kp)
70+
{
71+
if (val && sysfs_streq(val, "auto")) {
72+
*(int *)kp->arg = AVIC_AUTO_MODE;
73+
return 0;
74+
}
75+
76+
return param_set_bint(val, kp);
77+
}
78+
79+
static const struct kernel_param_ops avic_ops = {
80+
.flags = KERNEL_PARAM_OPS_FL_NOARG,
81+
.set = avic_param_set,
82+
.get = param_get_bool,
83+
};
84+
6785
/*
68-
* enable / disable AVIC. Because the defaults differ for APICv
69-
* support between VMX and SVM we cannot use module_param_named.
86+
* Enable / disable AVIC. In "auto" mode (default behavior), AVIC is enabled
87+
* for Zen4+ CPUs with x2AVIC (and all other criteria for enablement are met).
7088
*/
71-
static bool avic;
72-
module_param(avic, bool, 0444);
89+
static int avic = AVIC_AUTO_MODE;
90+
module_param_cb(avic, &avic_ops, &avic, 0444);
91+
__MODULE_PARM_TYPE(avic, "bool");
92+
7393
module_param(enable_ipiv, bool, 0444);
7494

7595
static bool force_avic;
@@ -1151,6 +1171,18 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
11511171

11521172
static bool __init avic_want_avic_enabled(void)
11531173
{
1174+
/*
1175+
* In "auto" mode, enable AVIC by default for Zen4+ if x2AVIC is
1176+
* supported (to avoid enabling partial support by default, and because
1177+
* x2AVIC should be supported by all Zen4+ CPUs). Explicitly check for
1178+
* family 0x19 and later (Zen5+), as the kernel's synthetic ZenX flags
1179+
* aren't inclusive of previous generations, i.e. the kernel will set
1180+
* at most one ZenX feature flag.
1181+
*/
1182+
if (avic == AVIC_AUTO_MODE)
1183+
avic = boot_cpu_has(X86_FEATURE_X2AVIC) &&
1184+
(boot_cpu_data.x86 > 0x19 || cpu_feature_enabled(X86_FEATURE_ZEN4));
1185+
11541186
if (!avic || !npt_enabled)
11551187
return false;
11561188

0 commit comments

Comments
 (0)