From patchwork Fri Oct 4 14:08:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13822436 Received: from smtp-fw-80007.amazon.com (smtp-fw-80007.amazon.com [99.78.197.218]) (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 9E80715B0EC; Fri, 4 Oct 2024 14:08:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=99.78.197.218 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050919; cv=none; b=J5wG5YqdZFy50Jd/YTPOexC2FhVzzkhcZYrFQcHysMYVa19d5seuVnGYi3gZVE+2Wi3W1/gQlfn0arzVme8wwBTbmcCefbkOAAHymB7jBQC5mQtQAZmz7nhacPZRcKWYoVMQxQ0P5hupFqbhw+N5bmy7KIyHypvlZGHXAGipcNk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050919; c=relaxed/simple; bh=uDS66yWU/o+mC6Ph2xwQoCR3wmyAWrHGhVUeB3qamNk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=n3imtLw/la48mruEiEiTgZ4CvTAy8OtJN93BfSARILPH28PtUb83IQ24MVUU2TwI1ix435GK7C0rFeNtwjCO0YtZ8VCE6GPPWcJ4vuLqUGTVA4urJRhUl1O3m2pTFObcEjlJU1FO49qKBfZbxXClMU+KFGMd5ht+lZCpkLip8Yk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=XVyxGRyL; arc=none smtp.client-ip=99.78.197.218 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="XVyxGRyL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1728050917; x=1759586917; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wYFKE2E4waTHClkNCyjDT6IPnkP81VWl5E6BczCRIVg=; b=XVyxGRyL+2NzObCmDwtvkHo6CQgA+eVM1AXS2sXZMuwGWXeGDqNAbPhi 8QCAbnXbLIhTg1HWJfbudYoXGL02KfI8s+JiElMDq1DwFF0unFgEFwR4Z MNnTBzgqv13Ui7evu37Um2dBrJJUe3XGTRBOtoaTMpSovxv1JiEFrM/p7 U=; X-IronPort-AV: E=Sophos;i="6.11,177,1725321600"; d="scan'208";a="339710549" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-80007.pdx80.corp.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2024 14:08:33 +0000 Received: from EX19MTAUWC002.ant.amazon.com [10.0.21.151:16033] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.6.41:2525] with esmtp (Farcaster) id 8a3d9a7d-a200-4716-80e4-178ca71dcd05; Fri, 4 Oct 2024 14:08:32 +0000 (UTC) X-Farcaster-Flow-ID: 8a3d9a7d-a200-4716-80e4-178ca71dcd05 Received: from EX19D020UWA004.ant.amazon.com (10.13.138.231) by EX19MTAUWC002.ant.amazon.com (10.250.64.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:08:31 +0000 Received: from EX19MTAUEC002.ant.amazon.com (10.252.135.146) by EX19D020UWA004.ant.amazon.com (10.13.138.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:08:31 +0000 Received: from email-imr-corp-prod-iad-all-1b-af42e9ba.us-east-1.amazon.com (10.43.8.6) by mail-relay.amazon.com (10.252.135.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Fri, 4 Oct 2024 14:08:31 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com [10.253.74.52]) by email-imr-corp-prod-iad-all-1b-af42e9ba.us-east-1.amazon.com (Postfix) with ESMTPS id C781B443FC; Fri, 4 Oct 2024 14:08:29 +0000 (UTC) From: Nikolas Wipper To: Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Sean Christopherson , "Paolo Bonzini" , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , Nikolas Wipper , , , , , , "Nikolas Wipper" Subject: [PATCH 1/7] KVM: Add API documentation for KVM_HYPERV_SET_TLB_FLUSH_INHIBIT Date: Fri, 4 Oct 2024 14:08:04 +0000 Message-ID: <20241004140810.34231-2-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20241004140810.34231-1-nikwip@amazon.de> References: <20241004140810.34231-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add API documentation for the new KVM_HYPERV_SET_TLB_FLUSH_INHIBIT ioctl. Signed-off-by: Nikolas Wipper --- Documentation/virt/kvm/api.rst | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index a4b7dc4a9dda..9c11a8af336b 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -6443,6 +6443,47 @@ the capability to be present. `flags` must currently be zero. +4.144 KVM_HYPERV_SET_TLB_FLUSH_INHIBIT +-------------------------------------- + +:Capability: KVM_CAP_HYPERV_TLB_FLUSH_INHIBIT +:Architectures: x86 +:Type: vcpu ioctl +:Parameters: struct kvm_hyperv_tlb_flush_inhibit +:returnReturns: 0 on success, this ioctl can't fail + +KVM_HYPERV_SET_TLB_FLUSH_INHIBIT allows userspace to prevent Hyper-V hyper-calls +that remotely flush a vCPU's TLB, i.e. HvFlushVirtualAddressSpace(Ex)/ +HvFlushVirtualAddressList(Ex). When the flag is set, a vCPU attempting to flush +an inhibited vCPU will be suspended and will only resume once the flag is +cleared again using this ioctl. During suspension, the vCPU will not finish the +hyper-call, but may enter the guest to retry it. Because it is caused by a +hyper-call, the suspension naturally happens on a guest instruction boundary. +This behaviour and the suspend state itself are specified in Microsoft's +"Hypervisor Top Level Functional Specification" (TLFS). + +:: + + /* for KVM_HYPERV_SET_TLB_FLUSH_INHIBIT */ + struct kvm_hyperv_tlb_flush_inhibit { + /* in */ + __u16 flags; + #define KVM_HYPERV_UNINHIBIT_TLB_FLUSH 0 + #define KVM_HYPERV_INHIBIT_TLB_FLUSH 1 + __u8 inhibit; + __u8 padding[5]; + }; + +No flags are specified so far, the corresponding field must be set to zero, +otherwise the ioctl will fail with exit code -EINVAL. + +The suspension is transparent to userspace. It won't cause KVM_RUN to return or +the MP state to be changed. The suspension cannot be manually induced or exited +apart from changing the TLB flush inhibit flag of a targeted processor. + +There is no way for userspace to query the state of the flush inhibit flag. +Userspace must keep track of the required state itself. + 5. The kvm_run structure ======================== From patchwork Fri Oct 4 14:08:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13822437 Received: from smtp-fw-52003.amazon.com (smtp-fw-52003.amazon.com [52.119.213.152]) (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 DC389215F47; Fri, 4 Oct 2024 14:08:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.119.213.152 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050940; cv=none; b=R8lrs+8Vux19mfrjvfUBycSy1nSxGJ4Wl/1kSPmCHgsIAB25RQ7zz3/Nmv2YSIwfVUTnHVLzeucD5OuYVfBq1y07jOFe3bJrMSjlsj9ZXPrjoWXWSpGwSjJqRlvm68+3p+3rbSJ7Sir3J8nTcGJXvxK67k6MYeGkMQN6MnI5zOY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050940; c=relaxed/simple; bh=0yy+9WKCZgOVTzh2AGRwHIFkSwFDeipRd0/EhmXF6DE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KBCOltfwtv0p5qDfZlFyERcp8wqFnOP6QK8llGFkR4rYnNSxM8vctY3+5JIH8rBRhao70+rMjxGwGJGF7RUJ4bj/Ex2fvIayhiVtqm4zdQ9uKEwfKgCN6ndgdH/+DPwBL4G1oMUUeZh0gYZF2mFJakeWgcSHPhpIjvQ5DGRl3x8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=vr2lVGgj; arc=none smtp.client-ip=52.119.213.152 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="vr2lVGgj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1728050938; x=1759586938; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MWh2kibeZpG7HQf/g1yy13nxNTc1d8CAKEDX7gkW48c=; b=vr2lVGgjdkPMA3jvRWBufm+kYv0sPzKdsEiGuMgV0HkKa+MpPUuIEYiH ImDmbpxaP7O+elkMRAtEwOQykqiTYPg9D7qa+lTdz3Na8PZTcZBkFWsFQ hI93rOGMbAIyD3LpFp04qW4etDDRHokTCWvUn2H4CHt7nz4+EL6YiwvSz M=; X-IronPort-AV: E=Sophos;i="6.11,177,1725321600"; d="scan'208";a="30652709" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-52003.iad7.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2024 14:08:53 +0000 Received: from EX19MTAEUA001.ant.amazon.com [10.0.43.254:37485] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.16.194:2525] with esmtp (Farcaster) id 9c0e9e1b-774d-4cee-a407-e978806281b0; Fri, 4 Oct 2024 14:08:51 +0000 (UTC) X-Farcaster-Flow-ID: 9c0e9e1b-774d-4cee-a407-e978806281b0 Received: from EX19D004EUA001.ant.amazon.com (10.252.50.27) by EX19MTAEUA001.ant.amazon.com (10.252.50.192) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:08:51 +0000 Received: from EX19MTAUEC001.ant.amazon.com (10.252.135.222) by EX19D004EUA001.ant.amazon.com (10.252.50.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:08:50 +0000 Received: from email-imr-corp-prod-pdx-all-2c-619df93b.us-west-2.amazon.com (10.43.8.6) by mail-relay.amazon.com (10.252.135.200) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Fri, 4 Oct 2024 14:08:50 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com [10.253.74.52]) by email-imr-corp-prod-pdx-all-2c-619df93b.us-west-2.amazon.com (Postfix) with ESMTPS id 6B70340508; Fri, 4 Oct 2024 14:08:47 +0000 (UTC) From: Nikolas Wipper To: Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Sean Christopherson , "Paolo Bonzini" , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , Nikolas Wipper , , , , , , "Nikolas Wipper" Subject: [PATCH 2/7] KVM: x86: Implement Hyper-V's vCPU suspended state Date: Fri, 4 Oct 2024 14:08:05 +0000 Message-ID: <20241004140810.34231-3-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20241004140810.34231-1-nikwip@amazon.de> References: <20241004140810.34231-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce a suspension state for Hyper-V enlightened vCPUs. Microsoft's "Hypervisor Top Level Functional Specification" (TLFS) introduces this state as a "vCPU that is stopped on a instruction guest boundary, either explicitly or implicitly due to an intercept". The only documented explicit suspension is caused in response to a TLB Flush hypercall, which will use the state switching API in subsequent patches. Each Hyper-V vCPU now has a 'suspended' boolean field, which is checked before entering the guest. When set, it forces the vCPU to block. Once in that state, the vCPU ignores any events. The vCPU is unsuspended by clearing 'suspend' and issuing a request to force the vCPU out of sleep. Suspensions are issued as a mechanism to halt execution until state change is observed on a remote vCPU. Hyper-V vCPUs track this with 'waiting_on', which holds the 'vcpu_id' of the remote vCPU that forced the vCPU to enter the suspended state. It's the remote vCPU's responsibility to wake up the suspended vCPUs when ready. 'waiting_on' ensures the remote vCPU can selectively unsuspend vCPUs that blocked on its behalf while leaving other suspended vCPUs undisturbed. One vCPU can only be suspended due to a single remote vCPU, but different vCPUs can be suspended on behalf of different or the same remote vCPU(s). The guest is responsible for avoiding circular dependencies between suspended vCPUs. Callers of the suspend API are responsible for ensuring that suspend and unsuspend aren't called in parallel while targeting the same pair of vCPUs. Otherwise kvm_hv_vcpu_{un}suspend_tlb_flush() ensure 'waiting_on' and 'suspended' are updated and accessed in the correct order. This, for example, avoids races where the unsuspended vCPU re-suspends before kvm_hv_vcpu_unsuspend_tlb_flush() is done updating 'waiting_on'. Signed-off-by: Nikolas Wipper --- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/hyperv.c | 30 ++++++++++++++++++++++++++++++ arch/x86/kvm/hyperv.h | 17 +++++++++++++++++ arch/x86/kvm/x86.c | 4 +++- 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 46e0a466d7fb..7571ac578884 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -695,6 +695,9 @@ struct kvm_vcpu_hv { u64 vm_id; u32 vp_id; } nested; + + bool suspended; + int waiting_on; }; struct kvm_hypervisor_cpuid { diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 4f0a94346d00..6e7941ed25ae 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -971,6 +971,7 @@ int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu) vcpu->arch.hyperv = hv_vcpu; hv_vcpu->vcpu = vcpu; + hv_vcpu->waiting_on = -1; synic_init(&hv_vcpu->synic); @@ -2915,3 +2916,32 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, return 0; } + +void kvm_hv_vcpu_suspend_tlb_flush(struct kvm_vcpu *vcpu, int vcpu_id) +{ + /* waiting_on's store should happen before suspended's */ + WRITE_ONCE(vcpu->arch.hyperv->waiting_on, vcpu_id); + WRITE_ONCE(vcpu->arch.hyperv->suspended, true); +} + +void kvm_hv_vcpu_unsuspend_tlb_flush(struct kvm_vcpu *vcpu) +{ + DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS); + struct kvm_vcpu_hv *vcpu_hv; + struct kvm_vcpu *v; + unsigned long i; + + kvm_for_each_vcpu(i, v, vcpu->kvm) { + vcpu_hv = to_hv_vcpu(v); + + if (kvm_hv_vcpu_suspended(v) && + READ_ONCE(vcpu_hv->waiting_on) == vcpu->vcpu_id) { + /* waiting_on's store should happen before suspended's */ + WRITE_ONCE(v->arch.hyperv->waiting_on, -1); + WRITE_ONCE(v->arch.hyperv->suspended, false); + __set_bit(i, vcpu_mask); + } + } + + kvm_make_vcpus_request_mask(vcpu->kvm, KVM_REQ_EVENT, vcpu_mask); +} diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h index 913bfc96959c..a55832cea221 100644 --- a/arch/x86/kvm/hyperv.h +++ b/arch/x86/kvm/hyperv.h @@ -265,6 +265,15 @@ static inline void kvm_hv_nested_transtion_tlb_flush(struct kvm_vcpu *vcpu, } int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu); + +static inline bool kvm_hv_vcpu_suspended(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.hyperv_enabled && + READ_ONCE(vcpu->arch.hyperv->suspended); +} + +void kvm_hv_vcpu_suspend_tlb_flush(struct kvm_vcpu *vcpu, int vcpu_id); +void kvm_hv_vcpu_unsuspend_tlb_flush(struct kvm_vcpu *vcpu); #else /* CONFIG_KVM_HYPERV */ static inline void kvm_hv_setup_tsc_page(struct kvm *kvm, struct pvclock_vcpu_time_info *hv_clock) {} @@ -321,6 +330,14 @@ static inline u32 kvm_hv_get_vpindex(struct kvm_vcpu *vcpu) return vcpu->vcpu_idx; } static inline void kvm_hv_nested_transtion_tlb_flush(struct kvm_vcpu *vcpu, bool tdp_enabled) {} + +static inline bool kvm_hv_vcpu_suspended(struct kvm_vcpu *vcpu) +{ + return false; +} + +static inline void kvm_hv_vcpu_suspend_tlb_flush(struct kvm_vcpu *vcpu, int vcpu_id) {} +static inline void kvm_hv_vcpu_unsuspend_tlb_flush(struct kvm_vcpu *vcpu) {} #endif /* CONFIG_KVM_HYPERV */ #endif /* __ARCH_X86_KVM_HYPERV_H__ */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 15080385b8fe..18d0a300e79a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -135,6 +135,8 @@ static void store_regs(struct kvm_vcpu *vcpu); static int sync_regs(struct kvm_vcpu *vcpu); static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu); +static inline bool kvm_hv_vcpu_suspended(struct kvm_vcpu *vcpu); + static int __set_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2); static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2); @@ -11107,7 +11109,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) static bool kvm_vcpu_running(struct kvm_vcpu *vcpu) { return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE && - !vcpu->arch.apf.halted); + !vcpu->arch.apf.halted && !kvm_hv_vcpu_suspended(vcpu)); } static bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu) From patchwork Fri Oct 4 14:08:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13822438 Received: from smtp-fw-80007.amazon.com (smtp-fw-80007.amazon.com [99.78.197.218]) (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 1BE70215F5A; Fri, 4 Oct 2024 14:09:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=99.78.197.218 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050951; cv=none; b=hL2RMvV41osUibkKOet3JGG9jq6piijqsYm8KeGlp6Rd9kimHG8Irbrn3Uf4/kI6kYoZ3aEsoerCsm0jiyv3tclFRgrR8csQgrBnOEGIjlQ2/NbdXAQgGTYmzFWI2EyY5iCP0jy116l7CG+ec9xS65XoOvDRM0D8x6CIfvGEpfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050951; c=relaxed/simple; bh=d5e3re3bKYhsCTezzJ6vHBEGbT/gEBMfZwqxRw4jXj0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jbFJP1ZrBpJ39IZzK+KsvZ5476B3i7O2NUvSToIhjwcXBBGgE+YVfdkFsZFsXCL9WOwHvmJVJBvkx8Hxqq5N0s2OEEBhvMvuQdcrkRNAiXpR+4GlDNFmdiHad1/2C8KUUkEjKaGBPlHZ/s6ZvPnXvnpgm+qX8ZPcXCjyJcxaTRk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=ZaJBfKXk; arc=none smtp.client-ip=99.78.197.218 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="ZaJBfKXk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1728050951; x=1759586951; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=H0Of6mnihpmPtExDP0xT26xF0R3YjWEN9KFRfWKloXQ=; b=ZaJBfKXkQsgJvyAx03v2yOqYJ4WNw/exbFyk3N4DcKEisgHakV9JK6JK kQjXQb7+X9FurUVsI7r408ZLlTfDI07WP/LWMofFMNpLQFZGmdb1QsaoR oYiyCXFPQ4pI4Xu6WxoHGfbdbYYioBK9gnOu+KsaYh1hPPmGIcTco9X/Q Y=; X-IronPort-AV: E=Sophos;i="6.11,177,1725321600"; d="scan'208";a="339710839" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-80007.pdx80.corp.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2024 14:09:10 +0000 Received: from EX19MTAEUA002.ant.amazon.com [10.0.17.79:48210] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.16.194:2525] with esmtp (Farcaster) id 4e6ccfcf-09ca-4d48-a91d-b8dd0cd98837; Fri, 4 Oct 2024 14:09:08 +0000 (UTC) X-Farcaster-Flow-ID: 4e6ccfcf-09ca-4d48-a91d-b8dd0cd98837 Received: from EX19D004EUA001.ant.amazon.com (10.252.50.27) by EX19MTAEUA002.ant.amazon.com (10.252.50.124) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:09:07 +0000 Received: from EX19MTAUEA001.ant.amazon.com (10.252.134.203) by EX19D004EUA001.ant.amazon.com (10.252.50.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:09:07 +0000 Received: from email-imr-corp-prod-iad-all-1b-85daddd1.us-east-1.amazon.com (10.43.8.2) by mail-relay.amazon.com (10.252.134.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Fri, 4 Oct 2024 14:09:07 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com [10.253.74.52]) by email-imr-corp-prod-iad-all-1b-85daddd1.us-east-1.amazon.com (Postfix) with ESMTPS id C101D40600; Fri, 4 Oct 2024 14:09:05 +0000 (UTC) From: Nikolas Wipper To: Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Sean Christopherson , "Paolo Bonzini" , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , Nikolas Wipper , , , , , , "Nikolas Wipper" Subject: [PATCH 3/7] KVM: x86: Check vCPUs before enqueuing TLB flushes in kvm_hv_flush_tlb() Date: Fri, 4 Oct 2024 14:08:06 +0000 Message-ID: <20241004140810.34231-4-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20241004140810.34231-1-nikwip@amazon.de> References: <20241004140810.34231-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 In Hyper-V's kvm_hv_flush_tlb(), check targeted vCPUs and store them in a bitmap before flushing their TLBs. In a subsequent commit, remote TLB flushes may need to be aborted, so allow checking for that before starting to enque the flushes. No functional change intended. Signed-off-by: Nikolas Wipper --- arch/x86/kvm/hyperv.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 6e7941ed25ae..e68fbc0c7fc1 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2134,26 +2134,21 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) * analyze it here, flush TLB regardless of the specified address space. */ if (all_cpus && !is_guest_mode(vcpu)) { + bitmap_zero(vcpu_mask, KVM_MAX_VCPUS); + kvm_for_each_vcpu(i, v, kvm) { - tlb_flush_fifo = kvm_hv_get_tlb_flush_fifo(v, false); - hv_tlb_flush_enqueue(v, tlb_flush_fifo, - tlb_flush_entries, hc->rep_cnt); + __set_bit(i, vcpu_mask); } - - kvm_make_all_cpus_request(kvm, KVM_REQ_HV_TLB_FLUSH); } else if (!is_guest_mode(vcpu)) { sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask, vcpu_mask); for_each_set_bit(i, vcpu_mask, KVM_MAX_VCPUS) { v = kvm_get_vcpu(kvm, i); - if (!v) + if (!v) { + __clear_bit(i, vcpu_mask); continue; - tlb_flush_fifo = kvm_hv_get_tlb_flush_fifo(v, false); - hv_tlb_flush_enqueue(v, tlb_flush_fifo, - tlb_flush_entries, hc->rep_cnt); + } } - - kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH, vcpu_mask); } else { struct kvm_vcpu_hv *hv_v; @@ -2181,14 +2176,19 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) continue; __set_bit(i, vcpu_mask); - tlb_flush_fifo = kvm_hv_get_tlb_flush_fifo(v, true); - hv_tlb_flush_enqueue(v, tlb_flush_fifo, - tlb_flush_entries, hc->rep_cnt); } + } - kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH, vcpu_mask); + for_each_set_bit(i, vcpu_mask, KVM_MAX_VCPUS) { + v = kvm_get_vcpu(kvm, i); + + tlb_flush_fifo = kvm_hv_get_tlb_flush_fifo(v, is_guest_mode(vcpu)); + hv_tlb_flush_enqueue(v, tlb_flush_fifo, + tlb_flush_entries, hc->rep_cnt); } + kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH, vcpu_mask); + ret_success: /* We always do full TLB flush, set 'Reps completed' = 'Rep Count' */ return (u64)HV_STATUS_SUCCESS | From patchwork Fri Oct 4 14:08:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13822439 Received: from smtp-fw-80007.amazon.com (smtp-fw-80007.amazon.com [99.78.197.218]) (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 6F80D215F58; Fri, 4 Oct 2024 14:09:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=99.78.197.218 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050967; cv=none; b=PKoeYdw05tus2FAfCFZrhJoL0JMKBTEijvOFTh3tdkXaK12irGAgXAjkqgKDH/Sh+kJ9TLnhT7l/N1ZDiszZo10o100eYZ7a/MFyiqsTMjuEWKWvQLW37iTTq9+U8+U/7Jkwk9deddTlcbCSQdtJbz5Q5v/gFQWbctgtquwEsMg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050967; c=relaxed/simple; bh=ijdUR2tr23wvuK2BDcqM5eeebMA0pBaquvBvJve5Y+c=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=I4oaaI3TkMjmbRtU3Ove2ro5K6EIEs58pTJ2B8PXdLpewOyZMa8ClgPzKxjRDswx+dasDzVSxlvVoIGyo6qx+dqW+LBM81sv8ae/+2OiRnDHpgf7EgQA4BUxqryLDvAiUbIEE+S9esXASqDgeOSOGU0drrisA5uqeB9FTyWsGAo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=Rg72AFB1; arc=none smtp.client-ip=99.78.197.218 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="Rg72AFB1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1728050967; x=1759586967; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=AG/ptwPUku9Mc+u82giaMkWtyLl7RVKvof7I4SY5+cM=; b=Rg72AFB1DJwqqtnE6Bujeiv6CJ7CoLEXSiU1PKMQu7bxISb6Riq01VlJ M4w9XKa6hURXKfw6a5SFrP6Z936wE91fEAGJgg4kyIX11FKV+RFXA7jLS cKIPk5eGvnNrEhELFdKdivp4yWErM/GLhJ3d8DmX4e6qpb5YK/DVnyRZb 4=; X-IronPort-AV: E=Sophos;i="6.11,177,1725321600"; d="scan'208";a="339710977" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-80007.pdx80.corp.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2024 14:09:26 +0000 Received: from EX19MTAUWA001.ant.amazon.com [10.0.7.35:49576] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.4.107:2525] with esmtp (Farcaster) id eb11cd6e-058f-40b7-9473-d65ea63f28a6; Fri, 4 Oct 2024 14:09:25 +0000 (UTC) X-Farcaster-Flow-ID: eb11cd6e-058f-40b7-9473-d65ea63f28a6 Received: from EX19D020UWA001.ant.amazon.com (10.13.138.249) by EX19MTAUWA001.ant.amazon.com (10.250.64.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:09:25 +0000 Received: from EX19MTAUEC001.ant.amazon.com (10.252.135.222) by EX19D020UWA001.ant.amazon.com (10.13.138.249) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:09:24 +0000 Received: from email-imr-corp-prod-iad-all-1b-8410187a.us-east-1.amazon.com (10.43.8.6) by mail-relay.amazon.com (10.252.135.200) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Fri, 4 Oct 2024 14:09:24 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com [10.253.74.52]) by email-imr-corp-prod-iad-all-1b-8410187a.us-east-1.amazon.com (Postfix) with ESMTPS id E6810405B1; Fri, 4 Oct 2024 14:09:22 +0000 (UTC) From: Nikolas Wipper To: Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Sean Christopherson , "Paolo Bonzini" , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , Nikolas Wipper , , , , , , "Nikolas Wipper" Subject: [PATCH 4/7] KVM: Introduce KVM_HYPERV_SET_TLB_FLUSH_INHIBIT Date: Fri, 4 Oct 2024 14:08:07 +0000 Message-ID: <20241004140810.34231-5-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20241004140810.34231-1-nikwip@amazon.de> References: <20241004140810.34231-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce a new ioctl to control whether remote flushing via Hyper-V hyper-calls should be allowed on a vCPU. When the tlb_flush_inhibit bit is set, vCPUs attempting to flush the TLB of the inhibitied vCPU will be suspended until the bit is clearded. Signed-off-by: Nikolas Wipper --- include/uapi/linux/kvm.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 637efc055145..3bc43fdcab88 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -933,6 +933,7 @@ struct kvm_enable_cap { #define KVM_CAP_PRE_FAULT_MEMORY 236 #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 #define KVM_CAP_X86_GUEST_MODE 238 +#define KVM_CAP_HYPERV_TLB_FLUSH_INHIBIT 239 struct kvm_irq_routing_irqchip { __u32 irqchip; @@ -1573,4 +1574,18 @@ struct kvm_pre_fault_memory { __u64 padding[5]; }; +/* Available with KVM_CAP_HYPERV_TLBFLUSH */ +#define KVM_HYPERV_SET_TLB_FLUSH_INHIBIT \ + _IOW(KVMIO, 0xd6, struct kvm_hyperv_tlb_flush_inhibit) + +/* for KVM_HYPERV_SET_TLB_FLUSH_INHIBIT */ +struct kvm_hyperv_tlb_flush_inhibit { + /* in */ + __u16 flags; +#define KVM_HYPERV_UNINHIBIT_TLB_FLUSH 0 +#define KVM_HYPERV_INHIBIT_TLB_FLUSH 1 + __u8 inhibit; + __u8 reserved[5]; +}; + #endif /* __LINUX_KVM_H */ From patchwork Fri Oct 4 14:08:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13822440 Received: from smtp-fw-2101.amazon.com (smtp-fw-2101.amazon.com [72.21.196.25]) (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 8B4592141D3; Fri, 4 Oct 2024 14:09:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=72.21.196.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050995; cv=none; b=jkWagYe6/sS7VtucU0sHGfzq1d9CUue53dL1f8EoYteYL0XFJ0ls4Tw+OoFmviuL+bnw4JJYOh/mIE8tfitknUlduOVAAvKPDOycrIz+xCbgVqv/FTAyPcOVwvZrGuXmrSPLeI026KFvk4KLbmYOQ5KFnf6RKtM6pEyeGmGAtSc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728050995; c=relaxed/simple; bh=PBWunUlE2HKldlDCMDHY1HsP3G0Nm9kXB9Qg70SWmiw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ppjqe5fCtd9y0vUApOQE+PJ46vajBPx6ozoWmSIEs5KIg7o5yxfRIon4SpFCxicnyTs2NX1MhHRUBnfoNxtl3is4EFYAFKfOpOCuKdM7Ju8uJAkZAgMxcslQpUjZj2hQncEtLQxyzoQxQr2J5D8D0orAVG/5n1ZhmeaEM1Ny4rE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=Q9lrNkYg; arc=none smtp.client-ip=72.21.196.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="Q9lrNkYg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1728050995; x=1759586995; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bTyTxdXDkqtaFKJhoIWU6tpWvAMHM4NmS0qwKkyNGls=; b=Q9lrNkYgqb2HS1b9w21sDR8js9VVYjUR5e0VKezcG22lfDpq6FH4Mqlo xiCapZHVTeNbOESPvYFmuY4k8nsTURLkTW1Na60blD2MUIfeJKy2lHpNx oHK1jOJZs5B5M7NLKPn6RhhSMoZGLcBkRUm6Dv5tFVvbsjItlbZ60UHj0 I=; X-IronPort-AV: E=Sophos;i="6.11,177,1725321600"; d="scan'208";a="432592906" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-2101.iad2.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2024 14:09:49 +0000 Received: from EX19MTAUWA001.ant.amazon.com [10.0.7.35:27215] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.57.100:2525] with esmtp (Farcaster) id 837820b9-f6bd-4e90-a60f-14a0c3cb0afb; Fri, 4 Oct 2024 14:09:47 +0000 (UTC) X-Farcaster-Flow-ID: 837820b9-f6bd-4e90-a60f-14a0c3cb0afb Received: from EX19D020UWC003.ant.amazon.com (10.13.138.187) by EX19MTAUWA001.ant.amazon.com (10.250.64.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:09:43 +0000 Received: from EX19MTAUWC001.ant.amazon.com (10.250.64.145) by EX19D020UWC003.ant.amazon.com (10.13.138.187) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:09:43 +0000 Received: from email-imr-corp-prod-pdx-all-2b-22fa938e.us-west-2.amazon.com (10.25.36.210) by mail-relay.amazon.com (10.250.64.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Fri, 4 Oct 2024 14:09:43 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com [10.253.74.52]) by email-imr-corp-prod-pdx-all-2b-22fa938e.us-west-2.amazon.com (Postfix) with ESMTPS id 87583C0504; Fri, 4 Oct 2024 14:09:40 +0000 (UTC) From: Nikolas Wipper To: Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Sean Christopherson , "Paolo Bonzini" , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , Nikolas Wipper , , , , , , "Nikolas Wipper" Subject: [PATCH 5/7] KVM: x86: Implement KVM_HYPERV_SET_TLB_FLUSH_INHIBIT Date: Fri, 4 Oct 2024 14:08:08 +0000 Message-ID: <20241004140810.34231-6-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20241004140810.34231-1-nikwip@amazon.de> References: <20241004140810.34231-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement KVM_HYPERV_SET_TLB_FLUSH_INHIBIT for x86. Apart from setting/ clearing the internal TLB flush inhibit flag this ioctl also wakes up vCPUs suspended and waiting on this vCPU. When the flag is set, a vCPU trying to flush the inhibited vCPUs TLB with a Hyper-V hyper-call suspendeds until the bit is cleared again. The hyper- call finishes internally, but the instruction isn't skipped, and execution doesn't return to the guest. This behaviour and the suspended state itself are specified in Microsoft's "Hypervisor Top Level Functional Specification" (TLFS). To maintain thread safety during suspension and unsuspension, the IOCTL uses the KVM SRCU. After flipping the flush inhibit flag, it synchronizes SRCU to ensure that all running TLB flush attempts that saw the old state, finish before the IOCTL exits. If the flag was changed to inhibit new TLB flushes, this guarantees that no TLB flushes happen once the ioctl exits. If the flag was changed to no longer inhibit TLB flushes, the synchronization ensures that all suspended CPUs finished entering the suspended state properly, so they can be unsuspended again. Once TLB flushes are no longer inhibited, all suspended vCPUs are unsuspended. Signed-off-by: Nikolas Wipper --- arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/hyperv.c | 22 ++++++++++++++++++++ arch/x86/kvm/x86.c | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 7571ac578884..ab3a9beb61a2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -698,6 +698,8 @@ struct kvm_vcpu_hv { bool suspended; int waiting_on; + + int tlb_flush_inhibit; }; struct kvm_hypervisor_cpuid { diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index e68fbc0c7fc1..40ea8340838f 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2137,6 +2137,9 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) bitmap_zero(vcpu_mask, KVM_MAX_VCPUS); kvm_for_each_vcpu(i, v, kvm) { + if (READ_ONCE(v->arch.hyperv->tlb_flush_inhibit)) + goto ret_suspend; + __set_bit(i, vcpu_mask); } } else if (!is_guest_mode(vcpu)) { @@ -2148,6 +2151,9 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) __clear_bit(i, vcpu_mask); continue; } + + if (READ_ONCE(v->arch.hyperv->tlb_flush_inhibit)) + goto ret_suspend; } } else { struct kvm_vcpu_hv *hv_v; @@ -2175,6 +2181,9 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) sparse_banks)) continue; + if (READ_ONCE(v->arch.hyperv->tlb_flush_inhibit)) + goto ret_suspend; + __set_bit(i, vcpu_mask); } } @@ -2193,6 +2202,9 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) /* We always do full TLB flush, set 'Reps completed' = 'Rep Count' */ return (u64)HV_STATUS_SUCCESS | ((u64)hc->rep_cnt << HV_HYPERCALL_REP_COMP_OFFSET); +ret_suspend: + kvm_hv_vcpu_suspend_tlb_flush(vcpu, v->vcpu_id); + return -EBUSY; } static void kvm_hv_send_ipi_to_many(struct kvm *kvm, u32 vector, @@ -2380,6 +2392,13 @@ static int kvm_hv_hypercall_complete(struct kvm_vcpu *vcpu, u64 result) u32 tlb_lock_count = 0; int ret; + /* + * Reached when the hyper-call resulted in a suspension of the vCPU. + * The instruction will be re-tried once the vCPU is unsuspended. + */ + if (kvm_hv_vcpu_suspended(vcpu)) + return 1; + if (hv_result_success(result) && is_guest_mode(vcpu) && kvm_hv_is_tlb_flush_hcall(vcpu) && kvm_read_guest(vcpu->kvm, to_hv_vcpu(vcpu)->nested.pa_page_gpa, @@ -2919,6 +2938,9 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, void kvm_hv_vcpu_suspend_tlb_flush(struct kvm_vcpu *vcpu, int vcpu_id) { + RCU_LOCKDEP_WARN(!srcu_read_lock_held(&vcpu->kvm->srcu), + "Suspicious Hyper-V TLB flush inhibit usage\n"); + /* waiting_on's store should happen before suspended's */ WRITE_ONCE(vcpu->arch.hyperv->waiting_on, vcpu_id); WRITE_ONCE(vcpu->arch.hyperv->suspended, true); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 18d0a300e79a..1f925e32a927 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4642,6 +4642,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_HYPERV_CPUID: case KVM_CAP_HYPERV_ENFORCE_CPUID: case KVM_CAP_SYS_HYPERV_CPUID: + case KVM_CAP_HYPERV_TLB_FLUSH_INHIBIT: #endif case KVM_CAP_PCI_SEGMENT: case KVM_CAP_DEBUGREGS: @@ -5853,6 +5854,31 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, } } +static int kvm_vcpu_ioctl_set_tlb_flush_inhibit(struct kvm_vcpu *vcpu, + struct kvm_hyperv_tlb_flush_inhibit *set) +{ + if (set->inhibit == READ_ONCE(vcpu->arch.hyperv->tlb_flush_inhibit)) + return 0; + + WRITE_ONCE(vcpu->arch.hyperv->tlb_flush_inhibit, set->inhibit); + + /* + * synchronize_srcu() ensures that: + * - On inhibit, all concurrent TLB flushes finished before this ioctl + * exits. + * - On uninhibit, there are no longer vCPUs being suspended due to this + * inhibit. + * This function can't race with itself, because vCPU IOCTLs are + * serialized, so if the inhibit bit is already the desired value this + * synchronization has already happened. + */ + synchronize_srcu(&vcpu->kvm->srcu); + if (!set->inhibit) + kvm_hv_vcpu_unsuspend_tlb_flush(vcpu); + + return 0; +} + long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -6306,6 +6332,17 @@ long kvm_arch_vcpu_ioctl(struct file *filp, case KVM_SET_DEVICE_ATTR: r = kvm_vcpu_ioctl_device_attr(vcpu, ioctl, argp); break; +#ifdef CONFIG_KVM_HYPERV + case KVM_HYPERV_SET_TLB_FLUSH_INHIBIT: { + struct kvm_hyperv_tlb_flush_inhibit set; + + r = -EFAULT; + if (copy_from_user(&set, argp, sizeof(set))) + goto out; + r = kvm_vcpu_ioctl_set_tlb_flush_inhibit(vcpu, &set); + break; + } +#endif default: r = -EINVAL; } From patchwork Fri Oct 4 14:08:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13822441 Received: from smtp-fw-80009.amazon.com (smtp-fw-80009.amazon.com [99.78.197.220]) (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 10C222141D3; Fri, 4 Oct 2024 14:10:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=99.78.197.220 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728051005; cv=none; b=YSNxDUUq4T5ETgee9uL8PkZ1n66JaN1xGckHs9GR0RRsR0Q6VSgffF2CWlLgedGH8sHb3uHs8N5gu0YIB3pKnneWbVor3C9keHxujTwfyfUlPdDKGPWCA8kEUkUCEZeZij4pWOzwtajH2b7K6l4erc5ER4uKfmlFjK5tBAEh/EE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728051005; c=relaxed/simple; bh=vrF9jUMfBrFiNavN18zZLj43ZpdBHA7TJjesVWiYw4c=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RGx7qzWNm6lbh3ARWu3KDbupyxQtEnybAuAbOukEcQwvCJrmmpPoBZ+IGGKdTMyQybgOxpYSROwRo/2k4T8ZzDQ7hH58Lm+uwgwt1A1eZR0HrT5tYY+xMLSQQFrEwelwxpbgXiwI1mhfKzl85H4Hg07svQ6v2M2ZGY1YK2OBiD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=Cpwj0U9h; arc=none smtp.client-ip=99.78.197.220 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="Cpwj0U9h" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1728051004; x=1759587004; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OeoT6WkOeJV7Rwi3GpbrV9LuWN/LKpWTB6zvQCrlovE=; b=Cpwj0U9hfHG9iT9rj2BcOB8MG3Coq919g5NgRyEowgXNmBJ3nf8XNtpN NfgUXWU9mTdFQf0jPt1EQPl8ydxY48MCtSOTvt9RjRm7f0SrTSIaXHYS2 CMTUeJpndUn8qYdsi5i5IwK3Ehr+OocI3GRgr9ePFYAOSDIBnjVQRx/9Z Y=; X-IronPort-AV: E=Sophos;i="6.11,177,1725321600"; d="scan'208";a="134729068" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-80009.pdx80.corp.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2024 14:10:02 +0000 Received: from EX19MTAEUA002.ant.amazon.com [10.0.17.79:24900] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.17.12:2525] with esmtp (Farcaster) id c23a1a42-86a1-4515-b757-3dc0de7b5e83; Fri, 4 Oct 2024 14:10:01 +0000 (UTC) X-Farcaster-Flow-ID: c23a1a42-86a1-4515-b757-3dc0de7b5e83 Received: from EX19D004EUA004.ant.amazon.com (10.252.50.183) by EX19MTAEUA002.ant.amazon.com (10.252.50.124) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:10:01 +0000 Received: from EX19MTAUEB002.ant.amazon.com (10.252.135.47) by EX19D004EUA004.ant.amazon.com (10.252.50.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:10:00 +0000 Received: from email-imr-corp-prod-iad-all-1a-f1af3bd3.us-east-1.amazon.com (10.43.8.2) by mail-relay.amazon.com (10.252.135.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Fri, 4 Oct 2024 14:10:00 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com [10.253.74.52]) by email-imr-corp-prod-iad-all-1a-f1af3bd3.us-east-1.amazon.com (Postfix) with ESMTPS id DBE154037C; Fri, 4 Oct 2024 14:09:58 +0000 (UTC) From: Nikolas Wipper To: Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Sean Christopherson , "Paolo Bonzini" , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , Nikolas Wipper , , , , , , "Nikolas Wipper" Subject: [PATCH 6/7] KVM: x86: Add trace events to track Hyper-V suspensions Date: Fri, 4 Oct 2024 14:08:09 +0000 Message-ID: <20241004140810.34231-7-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20241004140810.34231-1-nikwip@amazon.de> References: <20241004140810.34231-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add trace events to track suspensions and unsuspensions vCPUs, because of Hyper-V mechanisms. Signed-off-by: Nikolas Wipper --- arch/x86/kvm/hyperv.c | 4 ++++ arch/x86/kvm/trace.h | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 40ea8340838f..55b8f88a91cb 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2944,6 +2944,8 @@ void kvm_hv_vcpu_suspend_tlb_flush(struct kvm_vcpu *vcpu, int vcpu_id) /* waiting_on's store should happen before suspended's */ WRITE_ONCE(vcpu->arch.hyperv->waiting_on, vcpu_id); WRITE_ONCE(vcpu->arch.hyperv->suspended, true); + + trace_kvm_hv_vcpu_suspend_tlb_flush(vcpu->vcpu_id, vcpu_id); } void kvm_hv_vcpu_unsuspend_tlb_flush(struct kvm_vcpu *vcpu) @@ -2962,6 +2964,8 @@ void kvm_hv_vcpu_unsuspend_tlb_flush(struct kvm_vcpu *vcpu) WRITE_ONCE(v->arch.hyperv->waiting_on, -1); WRITE_ONCE(v->arch.hyperv->suspended, false); __set_bit(i, vcpu_mask); + + trace_kvm_hv_vcpu_unsuspend_tlb_flush(v->vcpu_id); } } diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index d3aeffd6ae75..5564ef52fd9d 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -1871,6 +1871,45 @@ TRACE_EVENT(kvm_rmp_fault, __entry->error_code, __entry->rmp_level, __entry->psmash_ret) ); +/* + * Tracepoint for Hyper-V TlbFlushInhibit suspension + */ +TRACE_EVENT(kvm_hv_vcpu_suspend_tlb_flush, + TP_PROTO(int vcpu_id, int waiting_on), + TP_ARGS(vcpu_id, waiting_on), + + TP_STRUCT__entry( + __field(int, vcpu_id) + __field(int, waiting_on) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + __entry->waiting_on = waiting_on; + ), + + TP_printk("suspending vcpu %u waiting on %u", + __entry->vcpu_id, __entry->waiting_on) +); + +/* + * Tracepoint for Hyper-V TlbFlushInhibit unsuspension + */ +TRACE_EVENT(kvm_hv_vcpu_unsuspend_tlb_flush, + TP_PROTO(int vcpu_id), + TP_ARGS(vcpu_id), + TP_STRUCT__entry( + __field(int, vcpu_id) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + ), + + TP_printk("unsuspending vcpu %u", + __entry->vcpu_id) +); + #endif /* _TRACE_KVM_H */ #undef TRACE_INCLUDE_PATH From patchwork Fri Oct 4 14:08:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nikolas Wipper X-Patchwork-Id: 13822459 Received: from smtp-fw-80008.amazon.com (smtp-fw-80008.amazon.com [99.78.197.219]) (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 ADDF32141C9; Fri, 4 Oct 2024 14:10:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=99.78.197.219 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728051029; cv=none; b=L67+pnCzYzYdOoVdGRCoo/xAv1fDHMfazUqLv2+xP74ayrBZArNYR9RyoDpEWIYHHdB+RiUQfPyvi57/jkg6ypmHPW61EUyV+EdqN4lN6b+Oqv5kHyRek+7yYjRrgv1OA3U6OoE0el57At689P4ARPN1bkMVw1e+ivOSlF2p3V8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728051029; c=relaxed/simple; bh=qLZ0dHJJR8y5UGNyoPLEZazqvffEldWZGWTPPwohkMQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tmojR2zKQ9oUxM40INLEhYRmUPkiTQkKNEN3ySC2/bvLQUIax+q9TRf6E9KMDgcS+Nm8G6PQuOuHMoSJvNzm1nzSWeDpsbDSIyQZ3XIg//5tfyz5xNxEnc+Lk+wtLcFj0UKpawpJHcXV58+aLNDVR+6gsx0G9WnDqSpbCFFkUYw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de; spf=pass smtp.mailfrom=amazon.de; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b=bOkoNvV1; arc=none smtp.client-ip=99.78.197.219 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amazon.de header.i=@amazon.de header.b="bOkoNvV1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1728051027; x=1759587027; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qLZ0dHJJR8y5UGNyoPLEZazqvffEldWZGWTPPwohkMQ=; b=bOkoNvV1ItnV6OdH9rE+EHr1daMiVKvCRqXF+YeNNPLHy2XmdwDVEww7 yqdQj5urvEEtIVv2oV4uVwA3FrcjPNSZANGPOPdlX98O/2kDwlWbTNUdI 6h4D6K8jhDYq2Sc1aQa+7QYrZhO/kweAuHTx3cWlpdMhlBEOPdbHUBSrN A=; X-IronPort-AV: E=Sophos;i="6.11,177,1725321600"; d="scan'208";a="135245914" Received: from pdx4-co-svc-p1-lb2-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.25.36.214]) by smtp-border-fw-80008.pdx80.corp.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2024 14:10:25 +0000 Received: from EX19MTAUWB002.ant.amazon.com [10.0.21.151:5490] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.57.100:2525] with esmtp (Farcaster) id cf9536d7-31c7-4604-8950-7576c1ee7d34; Fri, 4 Oct 2024 14:10:25 +0000 (UTC) X-Farcaster-Flow-ID: cf9536d7-31c7-4604-8950-7576c1ee7d34 Received: from EX19D020UWA003.ant.amazon.com (10.13.138.254) by EX19MTAUWB002.ant.amazon.com (10.250.64.231) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:10:19 +0000 Received: from EX19MTAUWB001.ant.amazon.com (10.250.64.248) by EX19D020UWA003.ant.amazon.com (10.13.138.254) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Fri, 4 Oct 2024 14:10:19 +0000 Received: from email-imr-corp-prod-pdx-all-2b-f5cd2367.us-west-2.amazon.com (10.25.36.214) by mail-relay.amazon.com (10.250.64.254) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34 via Frontend Transport; Fri, 4 Oct 2024 14:10:19 +0000 Received: from dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com (dev-dsk-nikwip-1b-bc9ec026.eu-west-1.amazon.com [10.253.74.52]) by email-imr-corp-prod-pdx-all-2b-f5cd2367.us-west-2.amazon.com (Postfix) with ESMTPS id 7A34AC0165; Fri, 4 Oct 2024 14:10:16 +0000 (UTC) From: Nikolas Wipper To: Vitaly Kuznetsov CC: Nicolas Saenz Julienne , Alexander Graf , James Gowans , , Sean Christopherson , "Paolo Bonzini" , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , Dave Hansen , Nikolas Wipper , , , , , , "Nikolas Wipper" Subject: [PATCH 7/7] KVM: selftests: Add tests for KVM_HYPERV_SET_TLB_FLUSH_INHIBIT Date: Fri, 4 Oct 2024 14:08:10 +0000 Message-ID: <20241004140810.34231-8-nikwip@amazon.de> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20241004140810.34231-1-nikwip@amazon.de> References: <20241004140810.34231-1-nikwip@amazon.de> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add basic test for KVM_HYPERV_SET_TLB_FLUSH_INHIBIT. Since information about the suspension is not communicated to userspace this test checks for suspension by checking whether the thread running a vCPU is still executing. Signed-off-by: Nikolas Wipper --- tools/testing/selftests/kvm/Makefile | 1 + .../kvm/x86_64/hyperv_tlb_flush_inhibit.c | 274 ++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush_inhibit.c diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 45cb70c048bb..098c9c3f9ad8 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -79,6 +79,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features TEST_GEN_PROGS_x86_64 += x86_64/hyperv_ipi TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush_inhibit TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush_inhibit.c b/tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush_inhibit.c new file mode 100644 index 000000000000..638ed6ec8ae1 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush_inhibit.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test for KVM's emulation of Hyper-V's TlbFlushInhibit bit + * + * Copyright © 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ +#include +#include + +#include "apic.h" +#include "hyperv.h" + +struct timespec abstime; + +struct test_data { + bool entered; + bool hypercall_done; + vm_paddr_t hcall_gpa; +}; + +void guest_main(vm_vaddr_t test_data) +{ + struct test_data *data = (struct test_data *)test_data; + + wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_LINUX_OS_ID); + wrmsr(HV_X64_MSR_HYPERCALL, data->hcall_gpa); + + WRITE_ONCE(data->entered, true); + + /* Aligned for loading into XMM registers */ + __aligned(16) u64 processor_mask = BIT(0) | BIT(1) | BIT(2); + + /* Setup fast hyper-call */ + hyperv_write_xmm_input(&processor_mask, 1); + hyperv_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE | + HV_HYPERCALL_FAST_BIT, + 0x0, HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES); + data->hypercall_done = true; + + GUEST_DONE(); +} + +struct test_data *test_data_init(struct kvm_vcpu *vcpu) +{ + vm_vaddr_t test_data_page; + + test_data_page = vm_vaddr_alloc_page(vcpu->vm); + + vcpu_args_set(vcpu, 1, test_data_page); + + return (struct test_data *)addr_gva2hva(vcpu->vm, test_data_page); +} + +static void *vcpu_thread(void *arg) +{ + struct kvm_vcpu *vcpu = (struct kvm_vcpu *)arg; + struct ucall uc; + + while (1) { + vcpu_run(vcpu); + + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); + + switch (get_ucall(vcpu, &uc)) { + case UCALL_PRINTF: + REPORT_GUEST_PRINTF(uc); + break; + default: + TEST_ASSERT_EQ(get_ucall(vcpu, &uc), UCALL_DONE); + return NULL; + } + } +} + +/* Test one vCPU being inhibited while another tries to flush its TLB */ +void test_single(struct kvm_vm *vm, struct kvm_vcpu *inhibitor, + struct kvm_vcpu *flusher) +{ + struct kvm_hyperv_tlb_flush_inhibit set; + struct test_data *data; + unsigned int to_sleep; + pthread_t thread; + + printf("%s ...\t", __func__); + + vcpu_arch_set_entry_point(flusher, guest_main); + + data = test_data_init(flusher); + + data->entered = false; + data->hypercall_done = false; + data->hcall_gpa = addr_gva2gpa(vm, vm_vaddr_alloc_pages(vm, 1)); + + set.inhibit = true; + vcpu_ioctl(inhibitor, KVM_HYPERV_SET_TLB_FLUSH_INHIBIT, &set); + + pthread_create(&thread, NULL, vcpu_thread, flusher); + + /* Waiting on the guest to fully enter */ + while (READ_ONCE(data->entered) == false) + asm volatile ("nop"); + + /* Give the guest some time to attempt the hyper-call */ + to_sleep = 2; + while ((to_sleep = sleep(to_sleep))) + asm volatile ("nop"); + + TEST_ASSERT_EQ(data->hypercall_done, false); + TEST_ASSERT(pthread_tryjoin_np(thread, NULL) != 0, "thread finished early"); + + set.inhibit = false; + vcpu_ioctl(inhibitor, KVM_HYPERV_SET_TLB_FLUSH_INHIBIT, &set); + + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_sec += 5; + TEST_ASSERT(pthread_timedjoin_np(thread, NULL, &abstime) == 0, + "couldn't join thread"); + + TEST_ASSERT_EQ(data->hypercall_done, true); + + printf("[ok]\n"); +} + +/* Test one vCPU being inhibited while two others try to flush its TLB */ +void test_multi_flusher(struct kvm_vm *vm, struct kvm_vcpu *inhibitor, + struct kvm_vcpu *flusher1, struct kvm_vcpu *flusher2) +{ + struct kvm_hyperv_tlb_flush_inhibit set; + struct test_data *data1, *data2; + pthread_t thread1, thread2; + unsigned int to_sleep; + + printf("%s ...\t", __func__); + + vcpu_arch_set_entry_point(flusher1, guest_main); + vcpu_arch_set_entry_point(flusher2, guest_main); + + data1 = test_data_init(flusher1); + data2 = test_data_init(flusher2); + + data1->entered = false; + data1->hypercall_done = false; + data1->hcall_gpa = addr_gva2gpa(vm, vm_vaddr_alloc_pages(vm, 1)); + data2->entered = false; + data2->hypercall_done = false; + data2->hcall_gpa = addr_gva2gpa(vm, vm_vaddr_alloc_pages(vm, 1)); + + set.inhibit = true; + vcpu_ioctl(inhibitor, KVM_HYPERV_SET_TLB_FLUSH_INHIBIT, &set); + + pthread_create(&thread1, NULL, vcpu_thread, flusher1); + pthread_create(&thread2, NULL, vcpu_thread, flusher2); + + /* Waiting on the guests to fully enter */ + while (READ_ONCE(data1->entered) == false) + asm volatile("nop"); + while (READ_ONCE(data2->entered) == false) + asm volatile("nop"); + + /* Give the guests some time to attempt the hyper-call */ + to_sleep = 2; + while ((to_sleep = sleep(to_sleep))) + asm volatile("nop"); + + TEST_ASSERT_EQ(data1->hypercall_done, false); + TEST_ASSERT_EQ(data2->hypercall_done, false); + + TEST_ASSERT(pthread_tryjoin_np(thread1, NULL) != 0, + "thread 1 finished early"); + TEST_ASSERT(pthread_tryjoin_np(thread2, NULL) != 0, + "thread 2 finished early"); + + set.inhibit = false; + vcpu_ioctl(inhibitor, KVM_HYPERV_SET_TLB_FLUSH_INHIBIT, &set); + + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_sec += 5; + TEST_ASSERT(pthread_timedjoin_np(thread1, NULL, &abstime) == 0, + "couldn't join thread1"); + + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_sec += 5; + TEST_ASSERT(pthread_timedjoin_np(thread2, NULL, &abstime) == 0, + "couldn't join thread2"); + + TEST_ASSERT_EQ(data1->hypercall_done, true); + TEST_ASSERT_EQ(data2->hypercall_done, true); + + printf("[ok]\n"); +} + +/* Test two vCPUs being inhibited while another tries to flush their TLBs */ +void test_multi_inhibitor(struct kvm_vm *vm, struct kvm_vcpu *inhibitor1, + struct kvm_vcpu *inhibitor2, struct kvm_vcpu *flusher) +{ + struct kvm_hyperv_tlb_flush_inhibit set; + struct test_data *data; + unsigned int to_sleep; + pthread_t thread; + + printf("%s ...\t", __func__); + + vcpu_arch_set_entry_point(flusher, guest_main); + + data = test_data_init(flusher); + + data->entered = false; + data->hypercall_done = false; + data->hcall_gpa = addr_gva2gpa(vm, vm_vaddr_alloc_pages(vm, 1)); + + set.inhibit = true; + vcpu_ioctl(inhibitor1, KVM_HYPERV_SET_TLB_FLUSH_INHIBIT, &set); + vcpu_ioctl(inhibitor2, KVM_HYPERV_SET_TLB_FLUSH_INHIBIT, &set); + + pthread_create(&thread, NULL, vcpu_thread, flusher); + + /* Waiting on the guest to fully enter */ + while (READ_ONCE(data->entered) == false) + asm volatile ("nop"); + + /* Give the guest some time to attempt the hyper-call */ + to_sleep = 2; + while ((to_sleep = sleep(to_sleep))) + asm volatile ("nop"); + + TEST_ASSERT_EQ(data->hypercall_done, false); + TEST_ASSERT(pthread_tryjoin_np(thread, NULL) != 0, "thread finished early"); + + set.inhibit = false; + vcpu_ioctl(inhibitor1, KVM_HYPERV_SET_TLB_FLUSH_INHIBIT, &set); + + to_sleep = 1; + while ((to_sleep = sleep(to_sleep))) + asm volatile ("nop"); + + TEST_ASSERT_EQ(data->hypercall_done, false); + TEST_ASSERT(pthread_tryjoin_np(thread, NULL) != 0, "thread finished early"); + + set.inhibit = false; + vcpu_ioctl(inhibitor2, KVM_HYPERV_SET_TLB_FLUSH_INHIBIT, &set); + + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_sec += 5; + TEST_ASSERT(pthread_timedjoin_np(thread, NULL, &abstime) == 0, + "couldn't join thread"); + + TEST_ASSERT_EQ(data->entered, true); + TEST_ASSERT_EQ(data->hypercall_done, true); + + printf("[ok]\n"); +} + +int main(int argc, char *argv[]) +{ + struct kvm_vcpu *vcpu[3]; + struct kvm_vm *vm; + + TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_TLBFLUSH)); + TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_TLB_FLUSH_INHIBIT)); + + vm = vm_create_with_vcpus(3, guest_main, vcpu); + + vcpu_set_hv_cpuid(vcpu[0]); + vcpu_set_hv_cpuid(vcpu[1]); + vcpu_set_hv_cpuid(vcpu[2]); + + test_single(vm, vcpu[1], vcpu[0]); + test_multi_flusher(vm, vcpu[1], vcpu[0], vcpu[2]); + test_multi_inhibitor(vm, vcpu[1], vcpu[2], vcpu[0]); + + kvm_vm_free(vm); + + return 0; +}