[PATCH v14 03/22] KVM: x86: Check XSS validity against guest CPUIDs

Chao Gao posted 22 patches 3 weeks, 2 days ago
[PATCH v14 03/22] KVM: x86: Check XSS validity against guest CPUIDs
Posted by Chao Gao 3 weeks, 2 days ago
Maintain per-guest valid XSS bits and check XSS validity against them
rather than against KVM capabilities. This is to prevent bits that are
supported by KVM but not supported for a guest from being set.

Opportunistically return KVM_MSR_RET_UNSUPPORTED on IA32_XSS MSR accesses
if guest CPUID doesn't enumerate X86_FEATURE_XSAVES. Since
KVM_MSR_RET_UNSUPPORTED takes care of host_initiated cases, drop the
host_initiated check.

Signed-off-by: Chao Gao <chao.gao@intel.com>
---
v14 - new, introduce guest_supported_xss in a separate patch (Xiaoyao)
---
 arch/x86/include/asm/kvm_host.h |  3 ++-
 arch/x86/kvm/cpuid.c            | 12 ++++++++++++
 arch/x86/kvm/x86.c              |  7 +++----
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 0d3cc0fc27af..b2983c830247 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -815,7 +815,6 @@ struct kvm_vcpu_arch {
 	bool at_instruction_boundary;
 	bool tpr_access_reporting;
 	bool xfd_no_write_intercept;
-	u64 ia32_xss;
 	u64 microcode_version;
 	u64 arch_capabilities;
 	u64 perf_capabilities;
@@ -876,6 +875,8 @@ struct kvm_vcpu_arch {
 
 	u64 xcr0;
 	u64 guest_supported_xcr0;
+	u64 ia32_xss;
+	u64 guest_supported_xss;
 
 	struct kvm_pio_request pio;
 	void *pio_data;
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index ad6cadf09930..46cf616663e6 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -263,6 +263,17 @@ static u64 cpuid_get_supported_xcr0(struct kvm_vcpu *vcpu)
 	return (best->eax | ((u64)best->edx << 32)) & kvm_caps.supported_xcr0;
 }
 
+static u64 cpuid_get_supported_xss(struct kvm_vcpu *vcpu)
+{
+	struct kvm_cpuid_entry2 *best;
+
+	best = kvm_find_cpuid_entry_index(vcpu, 0xd, 1);
+	if (!best)
+		return 0;
+
+	return (best->ecx | ((u64)best->edx << 32)) & kvm_caps.supported_xss;
+}
+
 static __always_inline void kvm_update_feature_runtime(struct kvm_vcpu *vcpu,
 						       struct kvm_cpuid_entry2 *entry,
 						       unsigned int x86_feature,
@@ -424,6 +435,7 @@ void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 	}
 
 	vcpu->arch.guest_supported_xcr0 = cpuid_get_supported_xcr0(vcpu);
+	vcpu->arch.guest_supported_xss = cpuid_get_supported_xss(vcpu);
 
 	vcpu->arch.pv_cpuid.features = kvm_apply_cpuid_pv_features_quirk(vcpu);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 47b60f275fd7..6c167117018c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4011,15 +4011,14 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		}
 		break;
 	case MSR_IA32_XSS:
-		if (!msr_info->host_initiated &&
-		    !guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
-			return 1;
+		if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
+			return KVM_MSR_RET_UNSUPPORTED;
 		/*
 		 * KVM supports exposing PT to the guest, but does not support
 		 * IA32_XSS[bit 8]. Guests have to use RDMSR/WRMSR rather than
 		 * XSAVES/XRSTORS to save/restore PT MSRs.
 		 */
-		if (data & ~kvm_caps.supported_xss)
+		if (data & ~vcpu->arch.guest_supported_xss)
 			return 1;
 		vcpu->arch.ia32_xss = data;
 		vcpu->arch.cpuid_dynamic_bits_dirty = true;
-- 
2.47.3
Re: [PATCH v14 03/22] KVM: x86: Check XSS validity against guest CPUIDs
Posted by Xiaoyao Li 3 weeks, 1 day ago
On 9/9/2025 5:39 PM, Chao Gao wrote:
> Maintain per-guest valid XSS bits and check XSS validity against them
> rather than against KVM capabilities. This is to prevent bits that are
> supported by KVM but not supported for a guest from being set.
> 
> Opportunistically return KVM_MSR_RET_UNSUPPORTED on IA32_XSS MSR accesses
> if guest CPUID doesn't enumerate X86_FEATURE_XSAVES. Since
> KVM_MSR_RET_UNSUPPORTED takes care of host_initiated cases, drop the
> host_initiated check.
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>

Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>

<snip>
> @@ -4011,15 +4011,14 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>   		}
>   		break;
>   	case MSR_IA32_XSS:
> -		if (!msr_info->host_initiated &&
> -		    !guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
> -			return 1;
> +		if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
> +			return KVM_MSR_RET_UNSUPPORTED;
>   		/*
>   		 * KVM supports exposing PT to the guest, but does not support
>   		 * IA32_XSS[bit 8]. Guests have to use RDMSR/WRMSR rather than
>   		 * XSAVES/XRSTORS to save/restore PT MSRs.
>   		 */

Not an issue of this patch, there seems not the proper place to put 
above comment.
> -		if (data & ~kvm_caps.supported_xss)
> +		if (data & ~vcpu->arch.guest_supported_xss)
>   			return 1;
>   		vcpu->arch.ia32_xss = data;
>   		vcpu->arch.cpuid_dynamic_bits_dirty = true;
Re: [PATCH v14 03/22] KVM: x86: Check XSS validity against guest CPUIDs
Posted by Chao Gao 3 weeks, 1 day ago
On Wed, Sep 10, 2025 at 05:22:15PM +0800, Xiaoyao Li wrote:
>On 9/9/2025 5:39 PM, Chao Gao wrote:
>> Maintain per-guest valid XSS bits and check XSS validity against them
>> rather than against KVM capabilities. This is to prevent bits that are
>> supported by KVM but not supported for a guest from being set.
>> 
>> Opportunistically return KVM_MSR_RET_UNSUPPORTED on IA32_XSS MSR accesses
>> if guest CPUID doesn't enumerate X86_FEATURE_XSAVES. Since
>> KVM_MSR_RET_UNSUPPORTED takes care of host_initiated cases, drop the
>> host_initiated check.
>> 
>> Signed-off-by: Chao Gao <chao.gao@intel.com>
>
>Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
>
><snip>
>> @@ -4011,15 +4011,14 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>   		}
>>   		break;
>>   	case MSR_IA32_XSS:
>> -		if (!msr_info->host_initiated &&
>> -		    !guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
>> -			return 1;
>> +		if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
>> +			return KVM_MSR_RET_UNSUPPORTED;
>>   		/*
>>   		 * KVM supports exposing PT to the guest, but does not support
>>   		 * IA32_XSS[bit 8]. Guests have to use RDMSR/WRMSR rather than
>>   		 * XSAVES/XRSTORS to save/restore PT MSRs.
>>   		 */
>
>Not an issue of this patch, there seems not the proper place to put above
>comment.

Agreed.

I am curious why PT state isn't supported, which is apparently missing from
the comment. If it is due to lack of host FPU support, I think the recent
guest-only xfeatures we built for CET can help.

Anyway, PT is only visible on BROKEN kernels. so we won't do anything for
now besides documenting the reason.
Re: [PATCH v14 03/22] KVM: x86: Check XSS validity against guest CPUIDs
Posted by Sean Christopherson 3 weeks, 1 day ago
On Wed, Sep 10, 2025, Chao Gao wrote:
> On Wed, Sep 10, 2025 at 05:22:15PM +0800, Xiaoyao Li wrote:
> >On 9/9/2025 5:39 PM, Chao Gao wrote:
> >> Maintain per-guest valid XSS bits and check XSS validity against them
> >> rather than against KVM capabilities. This is to prevent bits that are
> >> supported by KVM but not supported for a guest from being set.
> >> 
> >> Opportunistically return KVM_MSR_RET_UNSUPPORTED on IA32_XSS MSR accesses
> >> if guest CPUID doesn't enumerate X86_FEATURE_XSAVES. Since
> >> KVM_MSR_RET_UNSUPPORTED takes care of host_initiated cases, drop the
> >> host_initiated check.
> >> 
> >> Signed-off-by: Chao Gao <chao.gao@intel.com>
> >
> >Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> >
> ><snip>
> >> @@ -4011,15 +4011,14 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> >>   		}
> >>   		break;
> >>   	case MSR_IA32_XSS:
> >> -		if (!msr_info->host_initiated &&
> >> -		    !guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
> >> -			return 1;
> >> +		if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
> >> +			return KVM_MSR_RET_UNSUPPORTED;
> >>   		/*
> >>   		 * KVM supports exposing PT to the guest, but does not support
> >>   		 * IA32_XSS[bit 8]. Guests have to use RDMSR/WRMSR rather than
> >>   		 * XSAVES/XRSTORS to save/restore PT MSRs.
> >>   		 */
> >
> >Not an issue of this patch, there seems not the proper place to put above
> >comment.
> 
> Agreed.

It was there to call out that KVM doesn't support any XSS bits even though KVM
supports a feature that architecturally can be context switched via XSS+XSTATE.
I'll find a better home for the comment (probably move it in patch 5 as
Xiaoyao suggested).

> I am curious why PT state isn't supported, which is apparently missing from
> the comment. If it is due to lack of host FPU support, I think the recent
> guest-only xfeatures we built for CET can help.

Presumably, perf uses PT across multiple tasks, i.e. doesn't want to context
switch PT state along with everything else.  For KVM, PT virtualization is
intertwined with perf, and so wholesale swapping guest PT state simply won't
work.
 
> Anyway, PT is only visible on BROKEN kernels. so we won't do anything for
> now besides documenting the reason.

Yeah, PT virtualization is riddled with problems, just ignore it.