On 10/15/2024 11:19 PM, Sean Christopherson wrote:
> On Fri, Oct 04, 2024, Manali Shukla wrote:
...
>>  
>> +static int bus_lock_exit(struct kvm_vcpu *vcpu)
>> +{
>> +    struct vcpu_svm *svm = to_svm(vcpu);
>> +
>> +    vcpu->run->exit_reason = KVM_EXIT_X86_BUS_LOCK;
>> +    vcpu->run->flags |= KVM_RUN_X86_BUS_LOCK;
>> +
>> +    /*
>> +     * Reload the counter with value greater than '0'.
> 
> The value quite obviously must be exactly '1', not simply greater than '0.  I 
> also
> think this is the wrong place to set the counter.  Rather than set the 
> counter at
> the time of exit, KVM should implement a vcpu->arch.complete_userspace_io 
> callback
> and set the counter to '1' if and only if RIP (or LIP, but I have no 
> objection to
> keeping things simple) is unchanged.  It's a bit of extra complexity, but it 
> will
> make it super obvious why KVM is setting the counter to '1'.  And, if 
> userspace
> wants to stuff state and move past the instruction, e.g. by emulating the 
> guilty
> instruction, then KVM won't unnecessarily allow a bus lock in the guest.
> 
> And then the comment can be:
> 
>       /*
>        * If userspace has NOT change RIP, then KVM's ABI is to let the guest
>        * execute the bus-locking instruction.  Set the bus lock counter to '1'
>        * to effectively step past the bus lock.
>        */
> 

The bus lock threshold intercept feature is available for SEV-ES and SEV-SNP
guests too. The rip where the bus lock exit occurred, is not available in
bus_lock_exit handler for SEV-ES and SEV-SNP guests, so the above-mentioned
solution won't work with SEV-ES and SEV-SNP guests.

I would propose to add the above-mentioned solution only for normal and SEV 
guests
and unconditionally reloading of bus_lock_counter to 1 in complete_userspace_io
for SEV-ES and SEV-SNP guests.

Any thoughts ?


>> +     * The bus lock exit on SVM happens with RIP pointing to the guilty
>> +     * instruction. So, reloading the value of bus_lock_counter to '0'
>> +     * results into generating continuous bus lock exits.
>> +     */
>> +    svm->vmcb->control.bus_lock_counter = 1;
>> +
>> +    return 0;
>> +}
>> +
>>  static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
>>      [SVM_EXIT_READ_CR0]                     = cr_interception,
>>      [SVM_EXIT_READ_CR3]                     = cr_interception,
>> @@ -3353,6 +3374,7 @@ static int (*const svm_exit_handlers[])(struct 
>> kvm_vcpu *vcpu) = {
>>      [SVM_EXIT_CR4_WRITE_TRAP]               = cr_trap,
>>      [SVM_EXIT_CR8_WRITE_TRAP]               = cr_trap,
>>      [SVM_EXIT_INVPCID]                      = invpcid_interception,
>> +    [SVM_EXIT_BUS_LOCK]                     = bus_lock_exit,
>>      [SVM_EXIT_NPF]                          = npf_interception,
>>      [SVM_EXIT_RSM]                          = rsm_interception,
>>      [SVM_EXIT_AVIC_INCOMPLETE_IPI]          = 
>> avic_incomplete_ipi_interception,
>> @@ -5227,6 +5249,11 @@ static __init void svm_set_cpu_caps(void)
>>              kvm_cpu_cap_set(X86_FEATURE_SVME_ADDR_CHK);
>>      }
>>  
>> +    if (cpu_feature_enabled(X86_FEATURE_BUS_LOCK_THRESHOLD)) {
>> +            pr_info("Bus Lock Threashold supported\n");
>> +            kvm_caps.has_bus_lock_exit = true;
>> +    }
>> +
>>      /* CPUID 0x80000008 */
>>      if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD) ||
>>          boot_cpu_has(X86_FEATURE_AMD_SSBD))
>> -- 
>> 2.34.1
>>
 -Manali

Reply via email to