Re: [PATCH 3/7] KVM: SVM: Emulate guest accesses to LBR v2 MSRs

Shivansh Dhiman <[email protected]>
Newsgroups dev.linux.lists.sashiko-reviews,org.kernel.vger.kvm
Message-ID <[email protected]>

On 25-07-26 01:43, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> - [High] LBRv2 emulation ignores the `lbrv` module parameter, allowing guest LBRv2 usage even when LBR Virtualization is globally disabled.
> - [High] The newly added LBR v2 MSRs are missing from KVM's list of saveable MSRs, causing them to be silently dropped during live migration.
> - [High] Missing nested SVM state synchronization for LBRv2 fields causes state corruption and cross-tenant information leaks between L2 guests.
> --
> 
> --- Patch [3]: [PATCH 3/7] KVM: SVM: Emulate guest accesses to LBR v2 MSRs ---
> commit ea17366da9bcd5ccfa5c4c9307a6f68cda7d1255
> Author: Shivansh Dhiman <[email protected]>
> 
> KVM: SVM: Emulate guest accesses to LBR v2 MSRs
>     
> Back the LBR v2 MSRs with their VMCB save-area fields in
> svm_{get,set}_msr(). This is required when guest accesses to these
> MSRs are intercepted. This allows the guest to retain the values
> of these MSRs on VMRUN/#VMEXIT cycle when vLBR is disabled.
> 
>> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
>> index ef69a51ab27f9..13ac62604ca05 100644
>> --- a/arch/x86/kvm/svm/svm.c
>> +++ b/arch/x86/kvm/svm/svm.c
> 
> [ ... ]
> 
>> @@ -744,6 +744,12 @@ static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu)
>>  	svm->lbr_msrs_intercepted = intercept;
>>  }
>>  
>> +static bool svm_lbrv2_supported(struct kvm_vcpu *vcpu)
>> +{
>> +	return guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2) &&
>> +	       kvm_vcpu_has_mediated_pmu(vcpu);
>> +}
> 
> [Severity: High]
> Does this capability check need to respect the global lbrv module parameter?
> 
> Unlike the legacy LBR logic which explicitly checks lbrv, this function only
> checks the X86_FEATURE_AMD_LBR_V2 capability. 
> 
> Could this allow a local guest to bypass the host administrator's explicit
> disablement of LBR Virtualization (when loaded with lbrv=0) by directly
> accessing LBRv2 MSRs?

The lbrv check is not needed here because that capability is already gated
on lbrv in svm_set_cpu_caps(), and the guest cannot have LBRv2 if kvm
capability is clear.

	if (!lbrv || !enable_mediated_pmu ||
	    !kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2))
		kvm_cpu_cap_clear(X86_FEATURE_AMD_LBR_V2);


> 
> [ ... ]
> 
>> @@ -2882,6 +2901,21 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>  	case MSR_IA32_LASTINTTOIP:
>>  		msr_info->data = lbrv ? *svm_vmcb_lbr(svm, msr_info->index) : 0;
>>  		break;
>> +	case MSR_AMD_DBG_EXTN_CFG:
>> +		if (!svm_lbrv2_supported(vcpu))
>> +			return KVM_MSR_RET_UNSUPPORTED;
>> +		msr_info->data = svm->vmcb->save.dbg_extn_cfg;
>> +		break;
> 
> [Severity: High]
> Are these new LBR v2 MSRs missing from KVM's list of saveable MSRs?
> 
> Because the new LBRv2 MSRs (MSR_AMD_DBG_EXTN_CFG, MSR_AMD64_LBR_SELECT, and
> the MSR_AMD_SAMP_BR_FROM array) are omitted from msrs_to_save_base in
> arch/x86/kvm/msrs.c, they won't be returned to the VMM by
> KVM_GET_MSR_INDEX_LIST.
> 
> Will this cause the LBRv2 state to be silently dropped during live migration?

Good catch. I missed adding the MSRs here. Will do that in v2.

> 
> [ ... ]
> 
>> @@ -3181,6 +3215,40 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
>>  		*svm_vmcb_lbr(svm, ecx) = data;
>>  		vmcb_mark_dirty(svm->vmcb, VMCB_LBR);
>>  		break;
>> +	case MSR_AMD_DBG_EXTN_CFG:
>> +		if (!svm_lbrv2_supported(vcpu))
>> +			return KVM_MSR_RET_UNSUPPORTED;
>> +
>> +		if (data & DBG_EXTN_CFG_RESERVED_BITS)
>> +			return 1;
>> +
>> +		if (svm->vmcb->save.dbg_extn_cfg == data)
>> +			break;
>> +
>> +		svm->vmcb->save.dbg_extn_cfg = data;
>> +		vmcb_mark_dirty(svm->vmcb, VMCB_LBR);
>> +		svm_update_lbrv(vcpu);
>> +		break;
> 
> [Severity: High]
> Does nested SVM state synchronization need to be updated for these new LBRv2
> fields?
> 
> Looking at nested virtualization, L2 guest state is synchronized using
> svm_copy_lbrs() in arch/x86/kvm/svm/svm.h, which is called during
> nested_vmcb02_prepare_save().
> 
> Because svm_copy_lbrs() was not updated to copy the new dbg_extn_cfg,
> lbr_select, and lbr array fields, vmcb02 can retain a previous L2 guest's
> branch records. When a new L2 guest reads its MSRs, it could observe the prior
> L2 guest's execution trace.
> 
> Additionally, upon nested_svm_vmexit(), wouldn't L2 modifications be dropped
> because they aren't copied back to L1's vmcb12?

Nested support isn't part of v1. Will implement it in upcoming versions.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.