@@ -2624,6 +2624,21 @@ static void kvm_hv_hypercall_read_xmm(struct kvm_hv_hcall *hc)
26242624 kvm_fpu_put ();
26252625}
26262626
2627+ static u64 kvm_hv_ext_query_capabilities (struct kvm_vcpu * vcpu , struct kvm_hv_hcall * hc )
2628+ {
2629+ u64 caps = 0 ; /* No caps */
2630+
2631+ if (!hc -> fast ) {
2632+ if (unlikely (kvm_write_guest (vcpu -> kvm , hc -> outgpa , & caps , sizeof (caps )) != 0 ))
2633+ return HV_STATUS_INVALID_HYPERCALL_INPUT ;
2634+ } else {
2635+ kvm_rdx_write (vcpu , caps );
2636+ }
2637+
2638+ trace_kvm_hv_ext_query_capabilities (caps );
2639+ return HV_STATUS_SUCCESS ;
2640+ }
2641+
26272642static bool kvm_hv_xlate_va_validate_input (struct kvm_vcpu * vcpu ,
26282643 struct hv_xlate_va_input * in ,
26292644 u8 * vtl , u8 * flags )
@@ -2803,6 +2818,10 @@ static bool is_hypercall_advertised(struct kvm_vcpu *vcpu, u16 code)
28032818 feature_mask = HV_ACCESS_VSM ;
28042819 reg = VCPU_REGS_RBX ;
28052820 break ;
2821+ case HV_EXT_CALL_QUERY_CAPABILITIES :
2822+ feature_mask = HV_ENABLE_EXTENDED_HYPERCALLS ;
2823+ reg = VCPU_REGS_RBX ;
2824+ break ;
28062825 default :
28072826 /* everything else is advertised by default */
28082827 return true;
@@ -2960,7 +2979,16 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
29602979 }
29612980 goto hypercall_userspace_exit ;
29622981 }
2963- case HV_EXT_CALL_QUERY_CAPABILITIES ... HV_EXT_CALL_MAX :
2982+ case HV_EXT_CALL_QUERY_CAPABILITIES : {
2983+ if (unlikely (hc .rep_cnt )) {
2984+ ret = HV_STATUS_INVALID_HYPERCALL_INPUT ;
2985+ break ;
2986+ }
2987+
2988+ ret = kvm_hv_ext_query_capabilities (vcpu , & hc );
2989+ break ;
2990+ }
2991+ case HV_EXT_CALL_GET_BOOT_ZEROED_MEMORY ... HV_EXT_CALL_MAX :
29642992 if (unlikely (hc .fast )) {
29652993 ret = HV_STATUS_INVALID_PARAMETER ;
29662994 break ;
0 commit comments