>@@ -1870,6 +1873,37 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data, > > data = (u32)data; > break; >+ case MSR_IA32_FRED_STKLVLS: >+ if (!guest_cpu_cap_has(vcpu, X86_FEATURE_FRED)) >+ return 1; Return KVM_MSR_RET_UNSUPPORTED instead of 1. KVM's uAPI allows userspace to read MSRs and write 0 to MSRs even if an MSR isn't supported according to guest CPUIDs. Returning KVM_MSR_RET_UNSUPPORTED allows kvm_do_msr_access() to suppress the failure when needed to comply with the uAPI. For more details, see kvm_do_msr_access(). >+ break; >+ case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_RSP3: >+ case MSR_IA32_FRED_SSP1 ... MSR_IA32_FRED_CONFIG: >+ u64 reserved_bits = 0; >+ >+ if (!guest_cpu_cap_has(vcpu, X86_FEATURE_FRED)) >+ return 1; Ditto here and for __kvm_get_msr() below. >+ >+ if (is_noncanonical_msr_address(data, vcpu)) >+ return 1; >+ >+ switch (index) { >+ case MSR_IA32_FRED_CONFIG: >+ reserved_bits = BIT_ULL(11) | GENMASK_ULL(5, 4) | BIT_ULL(2); >+ break; >+ case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_RSP3: >+ reserved_bits = GENMASK_ULL(5, 0); >+ break; >+ case MSR_IA32_FRED_SSP1 ... MSR_IA32_FRED_SSP3: >+ reserved_bits = GENMASK_ULL(2, 0); >+ break; >+ default: >+ WARN_ON_ONCE(1); >+ return 1; >+ } >+ if (data & reserved_bits) >+ return 1; >+ break; > } > > msr.data = data; >@@ -1914,6 +1948,10 @@ int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, > !guest_cpu_cap_has(vcpu, X86_FEATURE_RDPID)) > return 1; > break; >+ case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_CONFIG: >+ if (!guest_cpu_cap_has(vcpu, X86_FEATURE_FRED)) >+ return 1; >+ break; > } > > msr.index = index; >@@ -7365,6 +7403,10 @@ static void kvm_probe_msr_to_save(u32 msr_index) > if (!(kvm_get_arch_capabilities() & ARCH_CAP_TSX_CTRL_MSR)) > return; > break; >+ case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_CONFIG: >+ if (!kvm_cpu_cap_has(X86_FEATURE_FRED)) >+ return; >+ break; > default: > break; > } >-- >2.50.1 >