From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A82945013A7 for ; Fri, 18 Sep 2026 13:50:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789739445; cv=none; b=ET2TP7O+5aDlUkrpE8k4n+5XLGjAv2NWZG0wxqhQ7aR3dU1R+Mpb2AVd/XTENoMntSzuid9Dse7Tqmpp7xIKLwh4N3aXXqRhD6BQCANfX3nNIWDNJpKmlkwnZJwEt/E5/CQIKl2pv6b8mmWDBzUIZtdke1I25l6tuQ3N12tXMu0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789739445; c=relaxed/simple; bh=L/pJn0jTt/iKHZnYpUOz+JK0/wt7xK+JhKzPaSSmOVU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sPXmHBhXrNNKBdxuAGuK1VnwnYsuCBpkW08yiVyrcuET1GdCf78SW5qXdctgqxQz+QsWwJDObOgYF6nnvi1XuWyxRo/Bf38PNsqEV0A69YiO0rgHds6bTn0zhIxJLG/igcA3jgp7LzfmhmhPiXtOy251CtcO82LQ0QLL7w0H/7k= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=NsJZ7emR; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="NsJZ7emR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1789739441; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Cv2Vaq9zhs1D6MKPjRR0JO1M9ONOk0fjkIDLWL2vAXE=; b=NsJZ7emRWslG8Td19a7IMC3p25lIypxMFGRFrmxq7WZBX/6tMPJsiuu/IobP5PYhAKP2Y+ l7Z+ywBDom9p8wfn6hkSI7A6H/PlSYGQ3UpcCpHYKxkO+3aBVFMbmq7U5um/XgarZsKQmp mMbKwG4ljvRzx8FapJ95UmwfPhOjeiA= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-540-i1SBNAm8Ofae4dzffxdBLw-1; Fri, 18 Sep 2026 09:50:38 -0400 X-MC-Unique: i1SBNAm8Ofae4dzffxdBLw-1 X-Mimecast-MFC-AGG-ID: i1SBNAm8Ofae4dzffxdBLw_1789739437 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4519E1955F0B; Fri, 18 Sep 2026 13:50:37 +0000 (UTC) Received: from virtlab1023.virt.eng.rdu2.dc.redhat.com (virtlab1023.virt.eng.rdu2.dc.redhat.com [10.18.48.26]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9B0781956042; Fri, 18 Sep 2026 13:50:36 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: nsaenz@amazon.com, vkuznets@redhat.com, snambakam@linux.microsoft.com Subject: [PATCH 06/31] KVM: x86: Introduce memory fault on invalid hypercalls reads/writes Date: Fri, 18 Sep 2026 09:50:05 -0400 Message-ID: <20260918135030.171564-7-pbonzini@redhat.com> In-Reply-To: <20260918135030.171564-1-pbonzini@redhat.com> References: <20260918135030.171564-1-pbonzini@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Allow userspace to perform arbitrary actions when a hypercall refers to an invalid address, by exiting with KVM_EXIT_MEMORY_FAULT. This will for example allow userspace to perform a VTL call. Co-developed-by: Nicolas Saenz Julienne Signed-off-by: Nicolas Saenz Julienne Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 19 ++++ arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/hyperv.c | 157 +++++++++++++++++++++++++------- arch/x86/kvm/x86.c | 34 +++++-- include/uapi/linux/kvm.h | 1 + 5 files changed, 173 insertions(+), 39 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 37028ce019e3..abc2ff1f8c84 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -8984,6 +8984,25 @@ enabled, cmma can't be enabled anymore and pfmfi and the storage key interpretation are disabled. If cmma has already been enabled or the hpage_2g module parameter is not set to 1, -EINVAL is returned. +7.48 KVM_CAP_HCALL_FAULT_EXIT +------------------------------------ + +:Architectures: x86 +:Parameters: args[0] is 0 to disable, 1 to enable + +When enabled, KVM checks the memory that is read or written by +hypercalls (including slow Hyper-V hypercalls and KVM_HC_CLOCK_PAIRING). +An inaccessible input page causes a KVM_EXIT_MEMORY_FAULT with +KVM_MEMORY_EXIT_FLAG_READ. An inaccessible or read-only output page causes +a KVM_EXIT_MEMORY_FAULT with KVM_MEMORY_EXIT_FLAG_WRITE. The reported +range identifies the page containing the parameter GPA. + +Hypercall parameters that are unused by the selected hypercall are not checked. + +For Hyper-V, unknown hypercalls are passed to userspace without checking their +parameter pages. The fault GPA is in the physical address space of the +VM managed by userspace, after nested GPA translation. + 8. Other capabilities. ====================== diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 683bb8bf43a9..c08781bb0327 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1169,6 +1169,7 @@ struct kvm_arch { bool has_protected_eoi; bool has_protected_pmu; bool pre_fault_allowed; + bool hcall_fault_exit; struct hlist_head *mmu_page_hash; struct list_head active_mmu_pages; struct kvm_possible_nx_huge_pages possible_nx_huge_pages[KVM_NR_MMU_TYPES]; diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index d2921d443fde..e3a8e8236230 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2033,7 +2033,68 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) return -ENOSPC; } -static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) +static int kvm_hv_hypercall_check_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, + bool write) +{ + bool writable = true; + gfn_t gfn = gpa_to_gfn(gpa); + unsigned long addr; + + addr = kvm_vcpu_gfn_to_hva_prot(vcpu, gfn, &writable); + if (!kvm_is_error_hva(addr) && (!write || writable)) + return 0; + + kvm_prepare_memory_fault_exit(vcpu, gfn_to_gpa(gfn), PAGE_SIZE, + write, false, false); + return -EFAULT; +} + +static unsigned int kvm_hv_hypercall_mem_access(u16 code) +{ + switch (code) { + case HVCALL_SIGNAL_EVENT: + case HVCALL_POST_MESSAGE: + case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST: + case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX: + case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE: + case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX: + case HVCALL_SEND_IPI: + case HVCALL_SEND_IPI_EX: + return KVM_MEMORY_EXIT_FLAG_READ; + case HVCALL_POST_DEBUG_DATA: + case HVCALL_RETRIEVE_DEBUG_DATA: + return KVM_MEMORY_EXIT_FLAG_READ | KVM_MEMORY_EXIT_FLAG_WRITE; + case HVCALL_RESET_DEBUG_SESSION: + case HV_EXT_CALL_QUERY_CAPABILITIES: + return KVM_MEMORY_EXIT_FLAG_WRITE; + } + + return 0; +} + +static int kvm_hv_hypercall_check_params(struct kvm_vcpu *vcpu, + struct kvm_hv_hcall *hc) +{ + unsigned access; + int r; + + if (hc->fast || !vcpu->kvm->arch.hcall_fault_exit) + return 0; + + access = kvm_hv_hypercall_mem_access(hc->code); + if (access & KVM_MEMORY_EXIT_FLAG_READ) { + r = kvm_hv_hypercall_check_gpa(vcpu, hc->ingpa, false); + if (r) + return r; + } + + if (access & KVM_MEMORY_EXIT_FLAG_WRITE) + return kvm_hv_hypercall_check_gpa(vcpu, hc->outgpa, true); + + return 0; +} + +static s64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) { struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); unsigned long *vcpu_mask = hv_vcpu->vcpu_mask; @@ -2053,6 +2114,19 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) struct kvm_vcpu *v; unsigned long i; bool all_cpus; + int r; + + /* Slow direct hypercalls from L2 provide a nested GPA. */ + if (!hc->fast) { + hc->ingpa = kvm_translate_gpa(vcpu, &vcpu->arch.gva_walk, hc->ingpa, + PFERR_GUEST_FINAL_MASK, NULL, 0); + if (unlikely(hc->ingpa == INVALID_GPA)) + return HV_STATUS_INVALID_HYPERCALL_INPUT; + } + + r = kvm_hv_hypercall_check_params(vcpu, hc); + if (r) + return r; /* * The Hyper-V TLFS doesn't allow more than HV_MAX_SPARSE_VCPU_BANKS @@ -2061,20 +2135,6 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) */ BUILD_BUG_ON(KVM_HV_MAX_SPARSE_VCPU_SET_BITS > HV_MAX_SPARSE_VCPU_BANKS); - /* - * 'Slow' hypercall's first parameter is the address in guest's memory - * where hypercall parameters are placed. This is either a GPA or a - * nested GPA when KVM is handling the call from L2 ('direct' TLB - * flush). Translate the address here so the memory can be uniformly - * read with kvm_read_guest(). - */ - if (!hc->fast) { - hc->ingpa = kvm_translate_gpa(vcpu, &vcpu->arch.gva_walk, hc->ingpa, - PFERR_GUEST_FINAL_MASK, NULL, 0); - if (unlikely(hc->ingpa == INVALID_GPA)) - return HV_STATUS_INVALID_HYPERCALL_INPUT; - } - if (hc->code == HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST || hc->code == HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE) { if (hc->fast) { @@ -2242,7 +2302,7 @@ static void kvm_hv_send_ipi_to_many(struct kvm *kvm, u32 vector, } } -static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) +static int kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) { struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); u64 *sparse_banks = hv_vcpu->sparse_banks; @@ -2252,6 +2312,11 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) u64 valid_bank_mask; u32 vector; bool all_cpus; + int r; + + r = kvm_hv_hypercall_check_params(vcpu, hc); + if (r) + return r; if (!lapic_in_kernel(vcpu)) return HV_STATUS_INVALID_HYPERCALL_INPUT; @@ -2432,11 +2497,16 @@ static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu) return kvm_hv_hypercall_complete(vcpu, vcpu->run->hyperv.u.hcall.result); } -static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) +static int kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) { struct kvm_hv *hv = to_kvm_hv(vcpu->kvm); struct eventfd_ctx *eventfd; u64 conn_id; + int ret; + + ret = kvm_hv_hypercall_check_params(vcpu, hc); + if (ret) + return ret; if (unlikely(!hc->fast)) { int ret; @@ -2550,11 +2620,30 @@ static bool hv_check_hypercall_access(struct kvm_vcpu_hv *hv_vcpu, u16 code) return true; } +static int kvm_hv_hypercall_userspace_exit(struct kvm_vcpu *vcpu, + struct kvm_hv_hcall *hc) +{ + int r; + + r = kvm_hv_hypercall_check_params(vcpu, hc); + if (r) + return r; + + vcpu->run->exit_reason = KVM_EXIT_HYPERV; + vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL; + vcpu->run->hyperv.u.hcall.input = hc->param; + vcpu->run->hyperv.u.hcall.params[0] = hc->ingpa; + vcpu->run->hyperv.u.hcall.params[1] = hc->outgpa; + vcpu->arch.complete_userspace_io = kvm_hv_hypercall_complete_userspace; + return 0; +} + int kvm_hv_hypercall(struct kvm_vcpu *vcpu) { struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); struct kvm_hv_hcall hc; u64 ret = HV_STATUS_SUCCESS; + s64 r; /* * hypercall generates UD from non zero cpl and real mode @@ -2622,7 +2711,10 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) ret = HV_STATUS_INVALID_HYPERCALL_INPUT; break; } - ret = kvm_hvcall_signal_event(vcpu, &hc); + r = kvm_hvcall_signal_event(vcpu, &hc); + if (r < 0) + return r; + ret = r; if (ret != HV_STATUS_INVALID_PORT_ID) break; fallthrough; /* maybe userspace knows this conn_id */ @@ -2632,7 +2724,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) ret = HV_STATUS_INVALID_HYPERCALL_INPUT; break; } - goto hypercall_userspace_exit; + return kvm_hv_hypercall_userspace_exit(vcpu, &hc); case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST: if (unlikely(hc.var_cnt)) { ret = HV_STATUS_INVALID_HYPERCALL_INPUT; @@ -2644,7 +2736,10 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) ret = HV_STATUS_INVALID_HYPERCALL_INPUT; break; } - ret = kvm_hv_flush_tlb(vcpu, &hc); + r = kvm_hv_flush_tlb(vcpu, &hc); + if (r < 0) + return r; + ret = r; break; case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE: if (unlikely(hc.var_cnt)) { @@ -2657,7 +2752,10 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) ret = HV_STATUS_INVALID_HYPERCALL_INPUT; break; } - ret = kvm_hv_flush_tlb(vcpu, &hc); + r = kvm_hv_flush_tlb(vcpu, &hc); + if (r < 0) + return r; + ret = r; break; case HVCALL_SEND_IPI: if (unlikely(hc.var_cnt)) { @@ -2670,7 +2768,10 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) ret = HV_STATUS_INVALID_HYPERCALL_INPUT; break; } - ret = kvm_hv_send_ipi(vcpu, &hc); + r = kvm_hv_send_ipi(vcpu, &hc); + if (r < 0) + return r; + ret = r; break; case HVCALL_POST_DEBUG_DATA: case HVCALL_RETRIEVE_DEBUG_DATA: @@ -2691,14 +2792,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) ret = HV_STATUS_OPERATION_DENIED; break; } - goto hypercall_userspace_exit; + return kvm_hv_hypercall_userspace_exit(vcpu, &hc); } case HV_EXT_CALL_QUERY_CAPABILITIES ... HV_EXT_CALL_MAX: if (unlikely(hc.fast)) { ret = HV_STATUS_INVALID_PARAMETER; break; } - goto hypercall_userspace_exit; + return kvm_hv_hypercall_userspace_exit(vcpu, &hc); default: ret = HV_STATUS_INVALID_HYPERCALL_CODE; break; @@ -2707,14 +2808,6 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) hypercall_complete: return kvm_hv_hypercall_complete(vcpu, ret); -hypercall_userspace_exit: - vcpu->run->exit_reason = KVM_EXIT_HYPERV; - vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL; - vcpu->run->hyperv.u.hcall.input = hc.param; - vcpu->run->hyperv.u.hcall.params[0] = hc.ingpa; - vcpu->run->hyperv.u.hcall.params[1] = hc.outgpa; - vcpu->arch.complete_userspace_io = kvm_hv_hypercall_complete_userspace; - return 0; } void kvm_hv_init_vm(struct kvm *kvm) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0fbe2d4e685f..3338d85c721f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2242,6 +2242,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_HYPERV_ENFORCE_CPUID: case KVM_CAP_SYS_HYPERV_CPUID: #endif + case KVM_CAP_HCALL_FAULT_EXIT: case KVM_CAP_PCI_SEGMENT: case KVM_CAP_DEBUGREGS: case KVM_CAP_X86_ROBUST_SINGLESTEP: @@ -4210,6 +4211,10 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, mutex_unlock(&kvm->lock); break; } + case KVM_CAP_HCALL_FAULT_EXIT: + kvm->arch.hcall_fault_exit = cap->args[0]; + r = 0; + break; default: r = -EINVAL; break; @@ -7191,25 +7196,28 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_x86_vendor_exit); #ifdef CONFIG_X86_64 static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, - unsigned long clock_type) + unsigned long clock_type, unsigned long *ret) { struct kvm_clock_pairing clock_pairing; struct timespec64 ts; size_t offset = 0; + bool writable; + unsigned long hva; u64 cycle; + *ret = -KVM_EOPNOTSUPP; if (clock_type != KVM_CLOCK_PAIRING_WALLCLOCK) - return -KVM_EOPNOTSUPP; + return 0; /* * When tsc is in permanent catchup mode guests won't be able to use * pvclock_read_retry loop to get consistent view of pvclock */ if (vcpu->arch.tsc_always_catchup) - return -KVM_EOPNOTSUPP; + return 0; if (!kvm_get_walltime_and_clockread(&ts, &cycle)) - return -KVM_EOPNOTSUPP; + return 0; clock_pairing.sec = ts.tv_sec; clock_pairing.nsec = ts.tv_nsec; @@ -7217,6 +7225,7 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, clock_pairing.flags = 0; memset(&clock_pairing.pad, 0, sizeof(clock_pairing.pad)); + *ret = -KVM_EFAULT; while (offset < sizeof(clock_pairing)) { gpa_t gpa = kvm_translate_gpa(vcpu, &vcpu->arch.gva_walk, paddr + offset, PFERR_WRITE_MASK | PFERR_GUEST_FINAL_MASK, NULL, 0); @@ -7224,12 +7233,22 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, PAGE_SIZE - offset_in_page(gpa)); if (gpa == INVALID_GPA) - return -KVM_EFAULT; + return 0; + if (vcpu->kvm->arch.hcall_fault_exit) { + hva = kvm_vcpu_gfn_to_hva_prot(vcpu, gpa_to_gfn(gpa), &writable); + if (kvm_is_error_hva(hva) || !writable) { + kvm_prepare_memory_fault_exit(vcpu, gpa & PAGE_MASK, PAGE_SIZE, + true, false, false); + return -EFAULT; + } + } if (kvm_write_guest(vcpu->kvm, gpa, (u8 *)&clock_pairing + offset, len)) - return -KVM_EFAULT; + return 0; offset += len; } + + *ret = 0; return 0; } #endif @@ -7388,7 +7407,8 @@ int ____kvm_emulate_hypercall(struct kvm_vcpu *vcpu, int cpl, break; #ifdef CONFIG_X86_64 case KVM_HC_CLOCK_PAIRING: - ret = kvm_pv_clock_pairing(vcpu, a0, a1); + if (kvm_pv_clock_pairing(vcpu, a0, a1, &ret)) + return -EFAULT; break; #endif case KVM_HC_SEND_IPI: diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 15a3090f067e..c23f1ea62eaf 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1002,6 +1002,7 @@ struct kvm_enable_cap { #define KVM_CAP_S390_HPAGE_2G 249 #define KVM_CAP_PPC_COMPAT_CAPS 250 #define KVM_CAP_ARM_PMU_V3_STRICT 251 +#define KVM_CAP_HCALL_FAULT_EXIT 252 struct kvm_irq_routing_irqchip { __u32 irqchip; -- 2.52.0