AVIC and x2AVIC are fully functional since Zen 4, with no known hardware errata. Enable it by default on those processors, but allow users to continue passing 'avic' module parameter to explicitly enable/disable AVIC. Convert 'avic' to an integer to be able to identify if the user has asked to explicitly enable or disable AVIC. By default, 'avic' is initialized to -1 and AVIC is enabled if Zen 4+ processor is detected (and other dependencies are satisfied). So as not to break existing usage of 'avic' which was a boolean, switch to using module_param_cb() and use existing callbacks which expose this field as a boolean (so users can still continue to pass 'avic=on' or 'avic=off') but sets an integer value. Finally, stop warning about missing HvInUseWrAllowed on SNP-enabled systems if trying to enable AVIC by default so as not to spam the kernel log. Users who specifically care about AVIC can explicitly pass 'avic=on' in which case the error is still printed. Signed-off-by: Naveen N Rao (AMD) --- arch/x86/kvm/svm/svm.h | 2 +- arch/x86/kvm/svm/avic.c | 8 +++++++- arch/x86/kvm/svm/svm.c | 17 +++++++++++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index d332930b3dae..0e87e2768a1f 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -48,7 +48,7 @@ extern bool npt_enabled; extern int nrips; extern int vgif; extern bool intercept_smi; -extern bool avic; +extern int avic; extern bool x2avic_enabled; extern bool vnmi; extern int lbrv; diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index 9fe1fd709458..6bd5079a01f1 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -1095,8 +1095,13 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu) */ void avic_hardware_setup(bool force_avic) { + bool default_avic = (avic == -1); bool enable = false; + /* Enable AVIC by default from Zen 4 */ + if (default_avic) + avic = boot_cpu_data.x86 > 0x19 || cpu_feature_enabled(X86_FEATURE_ZEN4); + if (!avic || !npt_enabled) goto out; @@ -1105,7 +1110,8 @@ void avic_hardware_setup(bool force_avic) if (cc_platform_has(CC_ATTR_HOST_SEV_SNP) && !boot_cpu_has(X86_FEATURE_HV_INUSE_WR_ALLOWED)) { - pr_warn("AVIC disabled: missing HvInUseWrAllowed on SNP-enabled system\n"); + if (!default_avic) + pr_warn("AVIC disabled: missing HvInUseWrAllowed on SNP-enabled system\n"); goto out; } diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index b66fbfd47d4c..3d4f1ef2ff76 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -158,12 +158,17 @@ 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. - */ -bool avic; -module_param(avic, bool, 0444); +static const struct kernel_param_ops avic_ops = { + .flags = KERNEL_PARAM_OPS_FL_NOARG, + .set = param_set_bint, + .get = param_get_bool, +}; + +/* enable/disable AVIC (-1 = auto) */ +int avic = -1; +module_param_cb(avic, &avic_ops, &avic, 0444); +__MODULE_PARM_TYPE(avic, "bool"); + module_param(enable_ipiv, bool, 0444); static bool force_avic; -- 2.50.1