6464
6565static_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+
85+ /*
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).
88+ */
89+ static int avic = AVIC_AUTO_MODE ;
90+ module_param_cb (avic , & avic_ops , & avic , 0444 );
91+ __MODULE_PARM_TYPE (avic , "bool" );
92+
93+ module_param (enable_ipiv , bool , 0444 );
94+
6795static bool force_avic ;
6896module_param_unsafe (force_avic , bool , 0444 );
6997
@@ -77,7 +105,58 @@ static DEFINE_HASHTABLE(svm_vm_data_hash, SVM_VM_DATA_HASH_BITS);
77105static u32 next_vm_id = 0 ;
78106static bool next_vm_id_wrapped = 0 ;
79107static DEFINE_SPINLOCK (svm_vm_data_hash_lock );
80- bool x2avic_enabled ;
108+ static bool x2avic_enabled ;
109+
110+
111+ static void avic_set_x2apic_msr_interception (struct vcpu_svm * svm ,
112+ bool intercept )
113+ {
114+ static const u32 x2avic_passthrough_msrs [] = {
115+ X2APIC_MSR (APIC_ID ),
116+ X2APIC_MSR (APIC_LVR ),
117+ X2APIC_MSR (APIC_TASKPRI ),
118+ X2APIC_MSR (APIC_ARBPRI ),
119+ X2APIC_MSR (APIC_PROCPRI ),
120+ X2APIC_MSR (APIC_EOI ),
121+ X2APIC_MSR (APIC_RRR ),
122+ X2APIC_MSR (APIC_LDR ),
123+ X2APIC_MSR (APIC_DFR ),
124+ X2APIC_MSR (APIC_SPIV ),
125+ X2APIC_MSR (APIC_ISR ),
126+ X2APIC_MSR (APIC_TMR ),
127+ X2APIC_MSR (APIC_IRR ),
128+ X2APIC_MSR (APIC_ESR ),
129+ X2APIC_MSR (APIC_ICR ),
130+ X2APIC_MSR (APIC_ICR2 ),
131+
132+ /*
133+ * Note! Always intercept LVTT, as TSC-deadline timer mode
134+ * isn't virtualized by hardware, and the CPU will generate a
135+ * #GP instead of a #VMEXIT.
136+ */
137+ X2APIC_MSR (APIC_LVTTHMR ),
138+ X2APIC_MSR (APIC_LVTPC ),
139+ X2APIC_MSR (APIC_LVT0 ),
140+ X2APIC_MSR (APIC_LVT1 ),
141+ X2APIC_MSR (APIC_LVTERR ),
142+ X2APIC_MSR (APIC_TMICT ),
143+ X2APIC_MSR (APIC_TMCCT ),
144+ X2APIC_MSR (APIC_TDCR ),
145+ };
146+ int i ;
147+
148+ if (intercept == svm -> x2avic_msrs_intercepted )
149+ return ;
150+
151+ if (!x2avic_enabled )
152+ return ;
153+
154+ for (i = 0 ; i < ARRAY_SIZE (x2avic_passthrough_msrs ); i ++ )
155+ svm_set_intercept_for_msr (& svm -> vcpu , x2avic_passthrough_msrs [i ],
156+ MSR_TYPE_RW , intercept );
157+
158+ svm -> x2avic_msrs_intercepted = intercept ;
159+ }
81160
82161static void avic_activate_vmcb (struct vcpu_svm * svm )
83162{
@@ -99,7 +178,7 @@ static void avic_activate_vmcb(struct vcpu_svm *svm)
99178 vmcb -> control .int_ctl |= X2APIC_MODE_MASK ;
100179 vmcb -> control .avic_physical_id |= X2AVIC_MAX_PHYSICAL_ID ;
101180 /* Disabling MSR intercept for x2APIC registers */
102- svm_set_x2apic_msr_interception (svm , false);
181+ avic_set_x2apic_msr_interception (svm , false);
103182 } else {
104183 /*
105184 * Flush the TLB, the guest may have inserted a non-APIC
@@ -110,7 +189,7 @@ static void avic_activate_vmcb(struct vcpu_svm *svm)
110189 /* For xAVIC and hybrid-xAVIC modes */
111190 vmcb -> control .avic_physical_id |= AVIC_MAX_PHYSICAL_ID ;
112191 /* Enabling MSR intercept for x2APIC registers */
113- svm_set_x2apic_msr_interception (svm , true);
192+ avic_set_x2apic_msr_interception (svm , true);
114193 }
115194}
116195
@@ -130,7 +209,7 @@ static void avic_deactivate_vmcb(struct vcpu_svm *svm)
130209 return ;
131210
132211 /* Enabling MSR intercept for x2APIC registers */
133- svm_set_x2apic_msr_interception (svm , true);
212+ avic_set_x2apic_msr_interception (svm , true);
134213}
135214
136215/* Note:
@@ -1090,23 +1169,27 @@ void avic_vcpu_unblocking(struct kvm_vcpu *vcpu)
10901169 avic_vcpu_load (vcpu , vcpu -> cpu );
10911170}
10921171
1093- /*
1094- * Note:
1095- * - The module param avic enable both xAPIC and x2APIC mode.
1096- * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
1097- * - The mode can be switched at run-time.
1098- */
1099- bool avic_hardware_setup (void )
1172+ static bool __init avic_want_avic_enabled (void )
11001173{
1101- if (!npt_enabled )
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+
1186+ if (!avic || !npt_enabled )
11021187 return false;
11031188
11041189 /* AVIC is a prerequisite for x2AVIC. */
11051190 if (!boot_cpu_has (X86_FEATURE_AVIC ) && !force_avic ) {
1106- if (boot_cpu_has (X86_FEATURE_X2AVIC )) {
1107- pr_warn (FW_BUG "Cannot support x2AVIC due to AVIC is disabled" );
1108- pr_warn (FW_BUG "Try enable AVIC using force_avic option" );
1109- }
1191+ if (boot_cpu_has (X86_FEATURE_X2AVIC ))
1192+ pr_warn (FW_BUG "Cannot enable x2AVIC, AVIC is unsupported\n" );
11101193 return false;
11111194 }
11121195
@@ -1116,21 +1199,37 @@ bool avic_hardware_setup(void)
11161199 return false;
11171200 }
11181201
1119- if (boot_cpu_has (X86_FEATURE_AVIC )) {
1120- pr_info ("AVIC enabled\n" );
1121- } else if (force_avic ) {
1122- /*
1123- * Some older systems does not advertise AVIC support.
1124- * See Revision Guide for specific AMD processor for more detail.
1125- */
1126- pr_warn ("AVIC is not supported in CPUID but force enabled" );
1127- pr_warn ("Your system might crash and burn" );
1128- }
1202+ /*
1203+ * Print a scary message if AVIC is force enabled to make it abundantly
1204+ * clear that ignoring CPUID could have repercussions. See Revision
1205+ * Guide for specific AMD processor for more details.
1206+ */
1207+ if (!boot_cpu_has (X86_FEATURE_AVIC ))
1208+ pr_warn ("AVIC unsupported in CPUID but force enabled, your system might crash and burn\n" );
1209+
1210+ return true;
1211+ }
1212+
1213+ /*
1214+ * Note:
1215+ * - The module param avic enable both xAPIC and x2APIC mode.
1216+ * - Hypervisor can support both xAVIC and x2AVIC in the same guest.
1217+ * - The mode can be switched at run-time.
1218+ */
1219+ bool __init avic_hardware_setup (void )
1220+ {
1221+ avic = avic_want_avic_enabled ();
1222+ if (!avic )
1223+ return false;
1224+
1225+ pr_info ("AVIC enabled\n" );
11291226
11301227 /* AVIC is a prerequisite for x2AVIC. */
11311228 x2avic_enabled = boot_cpu_has (X86_FEATURE_X2AVIC );
11321229 if (x2avic_enabled )
11331230 pr_info ("x2AVIC enabled\n" );
1231+ else
1232+ svm_x86_ops .allow_apicv_in_x2apic_without_x2apic_virtualization = true;
11341233
11351234 /*
11361235 * Disable IPI virtualization for AMD Family 17h CPUs (Zen1 and Zen2)
0 commit comments