Hyper-V partition must possess 'HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED'
privilege ('recommended' is rather a misnomer) to issue
HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST/SPACE hypercalls. '_EX' versions of these
hypercalls also require HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED.

Signed-off-by: Vitaly Kuznetsov <vkuzn...@redhat.com>
---
 arch/x86/kvm/hyperv.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 7cb1dd1a9fc1..3e8a34c08aef 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2155,6 +2155,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
                                kvm_hv_hypercall_complete_userspace;
                return 0;
        case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
+               if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+                              HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))) {
+                       ret = HV_STATUS_ACCESS_DENIED;
+                       break;
+               }
+
                if (unlikely(fast || !rep_cnt || rep_idx)) {
                        ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
                        break;
@@ -2162,6 +2168,12 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
                ret = kvm_hv_flush_tlb(vcpu, ingpa, rep_cnt, false);
                break;
        case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
+               if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+                              HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))) {
+                       ret = HV_STATUS_ACCESS_DENIED;
+                       break;
+               }
+
                if (unlikely(fast || rep)) {
                        ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
                        break;
@@ -2169,6 +2181,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
                ret = kvm_hv_flush_tlb(vcpu, ingpa, rep_cnt, false);
                break;
        case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
+               if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+                              HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED) ||
+                            !(hv_vcpu->cpuid_cache.enlightenments_eax &
+                              HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))) {
+                       ret = HV_STATUS_ACCESS_DENIED;
+                       break;
+               }
+
                if (unlikely(fast || !rep_cnt || rep_idx)) {
                        ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
                        break;
@@ -2176,6 +2196,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
                ret = kvm_hv_flush_tlb(vcpu, ingpa, rep_cnt, true);
                break;
        case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
+               if (unlikely(!(hv_vcpu->cpuid_cache.enlightenments_eax &
+                              HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED) ||
+                            !(hv_vcpu->cpuid_cache.enlightenments_eax &
+                              HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))) {
+                       ret = HV_STATUS_ACCESS_DENIED;
+                       break;
+               }
+
                if (unlikely(fast || rep)) {
                        ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
                        break;
-- 
2.30.2

Reply via email to