From nobody Thu Apr 10 18:58:27 2025 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 E787C20CCE8 for ; Tue, 1 Apr 2025 16:11:16 +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=1743523879; cv=none; b=h5AZi/IVuF/D0cmxZx9IbOYvX895FoD7WyzgdooTfEcpGOk/A52b/87kdZJ+LyPgn58GqKpc2Inm6Q3P5ByHypbsq8BSS3ip8lD1tQ6ve52oxcg7ti6NVTiLaUKp/GXQDYAfldRpKNbD/8wYtkX87NZSzt22A/jJ2HGcZ9n1hMY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523879; c=relaxed/simple; bh=J8qPggLN660CJ/gny2eLwefa7cxow24DmQlH8cqCWPU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qVfRCkHSXR+9A9F3WTK126Ro6+x146EoE6h/61xo46xnZdGrDBBmHK1xI0d5JKL7jTX+p3CRwXtK4aSqgm8oP5qzA4wdPEEA3HS06HetIVe208TyKfPe3pQlN4II27h6ThDMHCe828+pugverjhMslCx936H1bLNojbtG8iHiMA= 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=M/cxEgAX; 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="M/cxEgAX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523876; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2Ne6WCLBR/XrZ0UzXGe9+IeJgjHUMAWkVyxrLTzy0KE=; b=M/cxEgAXFBfykUvZj0AH9U7OsUEMzWE7xtQ9ukmqS/DUNCz52k1R6doIEPnOBtbSLgzjVf QIRGvi+xjD4HPEVdkqjfksiMG36ty8AU7MafL0q/N3lz3dVfa56FBRgfAbFY+N7mhvVi69 T0F1vGdYbgPX7AoYAz7CKSdO63QW6FI= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-138-cSuO_zbtOiGxr1hSr7-16w-1; Tue, 01 Apr 2025 12:11:15 -0400 X-MC-Unique: cSuO_zbtOiGxr1hSr7-16w-1 X-Mimecast-MFC-AGG-ID: cSuO_zbtOiGxr1hSr7-16w_1743523874 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-39979ad285bso3221136f8f.2 for ; Tue, 01 Apr 2025 09:11:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523873; x=1744128673; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2Ne6WCLBR/XrZ0UzXGe9+IeJgjHUMAWkVyxrLTzy0KE=; b=N10nyzUKn+9CTVodanSSQGhrYjQSlRClrUhQmoMNVMPdAjTF2dL0Qld0mvcUKX63JG PUNuyZ6k3Lj4BFNo92ZXj2ss+ROy/cBXTExOfpIFfu+mZ4LcbWQxf88kS2rIQErBkydm yjwqFlFM9GOF/7m9SNav/79pHza+sYw52pZNbgiChvk9u/P7V+0w/apx5rMm9+HG1R9s 01H/2fuhaXiPuSiG1RfE5VxmUZycfhPL8XXSoXpRPWETCSWhfOMfoCwHL8S8sC0wEVS0 jpvldXZUwGUKhi1mudPDbYpoYYQSehYNGvRKBKlMNuXmLGzYRdgrIpVx31TmZLDPg8rJ B2yg== X-Gm-Message-State: AOJu0Yxn25i8v3r9UBpTl8TAhL6I4CAXuzZeT7FFgcZ1ht+EmMe7hVjO s4BabeI2omicgU+DW4Lvsk3uTpx8lpm2+iOLDHXeMcO9f5WbtWTHtuCxliOiHfLQIvdmiRM2WDK +JKrlfqstXaYVIvLkM4XuUZJfvYCMQwSw7624By3f5Fl4J672rcbYOUT7ABR+/mIHC9XBr0Tqfx uOSailWqWIcSgazFJFZgDURTxXJUViQMhkPwpmQW3ZZYE2gQ== X-Gm-Gg: ASbGncuh4bNT6a1h2+TYfO4o4GrZHeHtunTKqLnrgIb1MDTcYc7vToxIBOJrmbBtA8Q 1p7DD+W+1+3BEO7pma/rbUlEumbGxQ9xGDvYoMjUmf62JKLJEbKQSDxmF5tu7ZbNc6XIEF4YqE+ S1sIhW2Qv4Ud16uWBo0mmziaib2g2c6RhF77WHQOuelwdSmQBJ32HlgdYyMDxxOlZX+Tuw0Luv2 R7gGCJsW0XAysE+QJnTq+OcEPwuZz9MortreLOmT8Fz/9QJjKrpvvvxC3TxyMxiLqiGRJieEWlJ LZm5/Ea+TkfCdYdG1HUNaw== X-Received: by 2002:a05:6000:1acf:b0:390:f358:85db with SMTP id ffacd0b85a97d-39c120e0bafmr10933820f8f.30.1743523872548; Tue, 01 Apr 2025 09:11:12 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE6K6N1iLNBiiCO+QMwKNhv1DNnVDzcZ/uBheUeMHVe4bav7TmYrqVRWee/NwpSbAcJtsirSw== X-Received: by 2002:a05:6000:1acf:b0:390:f358:85db with SMTP id ffacd0b85a97d-39c120e0bafmr10933738f8f.30.1743523871765; Tue, 01 Apr 2025 09:11:11 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b663470sm14413217f8f.27.2025.04.01.09.11.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:10 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 01/29] Documentation: kvm: introduce "VM plane" concept Date: Tue, 1 Apr 2025 18:10:38 +0200 Message-ID: <20250401161106.790710-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" There have been multiple occurrences of processors introducing a virtual privilege level concept for guests, where the hypervisor hosts multiple copies of a vCPU's register state (or at least of most of it) and provides hypercalls or instructions to switch between them. These include AMD VMPLs, Intel TDX partitions, Microsoft Hyper-V VTLs, and ARM CCA planes. Include documentation on how the feature will be exposed to userspace, based on a draft made between Plumbers and KVM Forum. In the past, two main solutions that were attempted, mostly in the context of Hyper-V VTLs and SEV-SNP VMPLs: - use a single vCPU file descriptor, and store multiple copies of the state in a single struct kvm_vcpu. This requires a lot of changes to provide multiple copies of affected fields, especially MMUs and APICs; and complex uAPI extensions to direct existing ioctls to a specific privilege level. This solution looked marginally okay for SEV-SNP VMPLs, but only because the copies of the register state were hidden in the VMSA (KVM does not manage it); it showed all its problems when applied to Hyper-V VTLs. - use multiple VM and vCPU file descriptors, and handle the switch entirely in userspace. This got gnarly pretty fast for even more reasons than the previous case, for example because VMs could not share anymore memslots, including dirty bitmaps and private/shared attributes (a substantial problem for SEV-SNP since VMPLs share their ASID). Another problem was the need to share _some_ register state across VTLs and to control that vCPUs did not run in parallel; there needed to be a lot of logic to be added in userspace to ensure that higher-privileged VTL properly interrupted a lower-privileged one. This solution also complicates in-kernel implementation of privilege level switch, or even makes it impossible, because there is no kernel knowledge of the relationship between vCPUs that have the same id but belong to different privilege levels. Especially given the need to accelerate switches in kernel, it is clear that KVM needs some level of knowledge of the relationship between vCPUs that have the same id but belong to different privilege levels. For this reason, I proposed a design that only gives the initial set of VM and vCPU = file descriptors the full set of ioctls + struct kvm_run; other privilege levels instead only support a small part of the KVM API. In fact for the vm file descriptor it is only three ioctls: KVM_CHECK_EXTENSION, KVM_SIGNAL_MSI, KVM_SET_MEMORY_ATTRIBUTES. For vCPUs it is basically KVM_GET/SET_*. This solves a lot of the problems in the multiple-file-descriptors solution, namely it gets for free the ability to avoid parallel execution of the same vCPUs in different privilege levels. Changes to the userspace API of course exist, but they are relatively small and more easily backwards compatible, because they boil down to the introduction of new file descriptor kinds instead of having to change the inputs to all affected ioctls. It does share some of the code churn issues in the single-file-descriptor solution; on the other hand a prototype multi-fd VMPL implementation[1] also needed large scale changes which therefore seem unavoidable when privilege levels are provided by hardware, and not a software concept only as is the case for VTLs. hardware [1] https://lore.kernel.org/lkml/cover.1726506534.git.roy.hopkins@suse.c= om/ Acknowledgements: thanks to everyone who participated in the discussions, you are too many to mention in a small margin. Thanks to Roy Hopkins, Tom Lendacky, Anel Orazgaliyeva, Nicolas Saenz-Julienne for experimenting with implementations of VTLs and VMPLs. Ah, and because x86 has three names for it and Arm has one, choose the Arm name for all architectures to avoid bikeshedding and to displease everyone---including the KVM/arm64 folks, probably. Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 235 ++++++++++++++++++++--- Documentation/virt/kvm/vcpu-requests.rst | 7 + 2 files changed, 211 insertions(+), 31 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 2a63a244e87a..e1c67bc6df47 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -56,6 +56,18 @@ be checked with :ref:`KVM_CHECK_EXTENSION `. Some capabilities also need to be enabled for VMs or VCPUs where their functionality is desired (see :ref:`cap_enable` and :ref:`cap_enable_vm`). =20 +On some architectures, a "virtual privilege level" concept may be present +apart from the usual separation between user and supervisor mode, or +between hypervisor and guest mode. When this is the case, a single vCPU +can have multiple copies of its register state (or at least most of it), +and will switch between them through a special processor instruction, +or through some kind of hypercall. + +KVM calls these privilege levels "planes". Planes other than the +initially-created one (called "plane 0") have a file descriptor each, +and so do the planes of each vCPU. Ioctls for vCPU planes should also +be issued from a single thread, unless specially marked as asynchronous +in the documentation. =20 2. Restrictions =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -119,6 +131,11 @@ description: Type: system, vm, or vcpu. =20 + File descriptors for planes other than plane 0 provide a subset + of vm and vcpu ioctls. Those that *are* supported in extra + planes are marked specially in the documentation (for example, + `vcpu (all planes)`). + Parameters: what parameters are accepted by the ioctl. =20 @@ -264,7 +281,7 @@ otherwise. =20 :Capability: basic, KVM_CAP_CHECK_EXTENSION_VM for vm ioctl :Architectures: all -:Type: system ioctl, vm ioctl +:Type: system ioctl, vm ioctl (all planes) :Parameters: extension identifier (KVM_CAP_*) :Returns: 0 if unsupported; 1 (or some other positive integer) if supported =20 @@ -421,7 +438,7 @@ kvm_run' (see below). =20 :Capability: basic :Architectures: all except arm64 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_regs (out) :Returns: 0 on success, -1 on error =20 @@ -461,7 +478,7 @@ Reads the general purpose registers from the vcpu. =20 :Capability: basic :Architectures: all except arm64 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_regs (in) :Returns: 0 on success, -1 on error =20 @@ -475,7 +492,7 @@ See KVM_GET_REGS for the data structure. =20 :Capability: basic :Architectures: x86, ppc -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_sregs (out) :Returns: 0 on success, -1 on error =20 @@ -506,7 +523,7 @@ but not yet injected into the cpu core. =20 :Capability: basic :Architectures: x86, ppc -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_sregs (in) :Returns: 0 on success, -1 on error =20 @@ -519,7 +536,7 @@ data structures. =20 :Capability: basic :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_translation (in/out) :Returns: 0 on success, -1 on error =20 @@ -645,7 +662,7 @@ This is an asynchronous vcpu ioctl and can be invoked f= rom any thread. =20 :Capability: basic (vcpu), KVM_CAP_GET_MSR_FEATURES (system) :Architectures: x86 -:Type: system ioctl, vcpu ioctl +:Type: system ioctl, vcpu ioctl (all planes) :Parameters: struct kvm_msrs (in/out) :Returns: number of msrs successfully returned; -1 on error @@ -685,7 +702,7 @@ kvm will fill in the 'data' member. =20 :Capability: basic :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_msrs (in) :Returns: number of msrs successfully set (see below), -1 on error =20 @@ -773,7 +790,7 @@ signal mask. =20 :Capability: basic :Architectures: x86, loongarch -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_fpu (out) :Returns: 0 on success, -1 on error =20 @@ -811,7 +828,7 @@ Reads the floating point state from the vcpu. =20 :Capability: basic :Architectures: x86, loongarch -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_fpu (in) :Returns: 0 on success, -1 on error =20 @@ -1126,7 +1143,7 @@ Other flags returned by ``KVM_GET_CLOCK`` are accepte= d but ignored. :Capability: KVM_CAP_VCPU_EVENTS :Extended by: KVM_CAP_INTR_SHADOW :Architectures: x86, arm64 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_vcpu_events (out) :Returns: 0 on success, -1 on error =20 @@ -1249,7 +1266,7 @@ directly to the virtual CPU). :Capability: KVM_CAP_VCPU_EVENTS :Extended by: KVM_CAP_INTR_SHADOW :Architectures: x86, arm64 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_vcpu_events (in) :Returns: 0 on success, -1 on error =20 @@ -1315,7 +1332,7 @@ See KVM_GET_VCPU_EVENTS for the data structure. =20 :Capability: KVM_CAP_DEBUGREGS :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_debugregs (out) :Returns: 0 on success, -1 on error =20 @@ -1337,7 +1354,7 @@ Reads debug registers from the vcpu. =20 :Capability: KVM_CAP_DEBUGREGS :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_debugregs (in) :Returns: 0 on success, -1 on error =20 @@ -1656,7 +1673,7 @@ otherwise it will return EBUSY error. =20 :Capability: KVM_CAP_XSAVE :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_xsave (out) :Returns: 0 on success, -1 on error =20 @@ -1676,7 +1693,7 @@ This ioctl would copy current vcpu's xsave struct to = the userspace. =20 :Capability: KVM_CAP_XSAVE and KVM_CAP_XSAVE2 :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_xsave (in) :Returns: 0 on success, -1 on error =20 @@ -1704,7 +1721,7 @@ contents of CPUID leaf 0xD on the host. =20 :Capability: KVM_CAP_XCRS :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_xcrs (out) :Returns: 0 on success, -1 on error =20 @@ -1731,7 +1748,7 @@ This ioctl would copy current vcpu's xcrs to the user= space. =20 :Capability: KVM_CAP_XCRS :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_xcrs (in) :Returns: 0 on success, -1 on error =20 @@ -2027,7 +2044,7 @@ error. =20 :Capability: KVM_CAP_IRQCHIP :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_lapic_state (out) :Returns: 0 on success, -1 on error =20 @@ -2058,7 +2075,7 @@ always uses xAPIC format. =20 :Capability: KVM_CAP_IRQCHIP :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_lapic_state (in) :Returns: 0 on success, -1 on error =20 @@ -2292,7 +2309,7 @@ prior to calling the KVM_RUN ioctl. =20 :Capability: KVM_CAP_ONE_REG :Architectures: all -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_one_reg (in) :Returns: 0 on success, negative value on failure =20 @@ -2907,7 +2924,7 @@ such as set vcpu counter or reset vcpu, and they have= the following id bit patte =20 :Capability: KVM_CAP_ONE_REG :Architectures: all -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_one_reg (in and out) :Returns: 0 on success, negative value on failure =20 @@ -2961,7 +2978,7 @@ after pausing the vcpu, but before it is resumed. =20 :Capability: KVM_CAP_SIGNAL_MSI :Architectures: x86 arm64 -:Type: vm ioctl +:Type: vm ioctl (all planes) :Parameters: struct kvm_msi (in) :Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error =20 @@ -3564,7 +3581,7 @@ VCPU matching underlying host. =20 :Capability: basic :Architectures: arm64, mips, riscv -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_reg_list (in/out) :Returns: 0 on success; -1 on error =20 @@ -4861,7 +4878,7 @@ The acceptable values for the flags field are:: =20 :Capability: KVM_CAP_NESTED_STATE :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_nested_state (in/out) :Returns: 0 on success, -1 on error =20 @@ -4935,7 +4952,7 @@ to the KVM_CHECK_EXTENSION ioctl(). =20 :Capability: KVM_CAP_NESTED_STATE :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_nested_state (in) :Returns: 0 on success, -1 on error =20 @@ -5816,7 +5833,7 @@ then ``length`` is returned. =20 :Capability: KVM_CAP_SREGS2 :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_sregs2 (out) :Returns: 0 on success, -1 on error =20 @@ -5849,7 +5866,7 @@ flags values for ``kvm_sregs2``: =20 :Capability: KVM_CAP_SREGS2 :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_sregs2 (in) :Returns: 0 on success, -1 on error =20 @@ -6065,7 +6082,7 @@ as the descriptors in Descriptors block. =20 :Capability: KVM_CAP_XSAVE2 :Architectures: x86 -:Type: vcpu ioctl +:Type: vcpu ioctl (all planes) :Parameters: struct kvm_xsave (out) :Returns: 0 on success, -1 on error =20 @@ -6323,7 +6340,7 @@ Returns -EINVAL if called on a protected VM. =20 :Capability: KVM_CAP_MEMORY_ATTRIBUTES :Architectures: x86 -:Type: vm ioctl +:Type: vm ioctl (all planes) :Parameters: struct kvm_memory_attributes (in) :Returns: 0 on success, <0 on error =20 @@ -6458,6 +6475,46 @@ the capability to be present. `flags` must currently be zero. =20 =20 +.. _KVM_CREATE_PLANE: + +4.144 KVM_CREATE_PLANE +---------------------- + +:Capability: KVM_CAP_PLANES +:Architectures: none +:Type: vm ioctl +:Parameters: plane id +:Returns: a VM fd that can be used to control the new plane. + +Creates a new *plane*, i.e. a separate privilege level for the +virtual machine. Each plane has its own memory attributes, +which can be used to enable more restricted permissions than +what is allowed with ``KVM_SET_USER_MEMORY_REGION``. + +Each plane has a numeric id that is used when communicating +with KVM through the :ref:`kvm_run ` struct. While +KVM is currently agnostic to whether low ids are more or less +privileged, it is expected that this will not always be the +case in the future. For example KVM in the future may use +the plane id when planes are supported by hardware (as is the +case for VMPLs in AMD), or if KVM supports accelerated plane +switch operations (as might be the case for Hyper-V VTLs). + +4.145 KVM_CREATE_VCPU_PLANE +--------------------------- + +:Capability: KVM_CAP_PLANES +:Architectures: none +:Type: vm ioctl (non default plane) +:Parameters: vcpu file descriptor for the default plane +:Returns: a vCPU fd that can be used to control the new plane + for the vCPU. + +Adds a vCPU to a plane; the new vCPU's id comes from the vCPU +file descriptor that is passed in the argument. Note that + because of how the API is defined, planes other than plane 0 +can only have a subset of the ids that are available in plane 0. + .. _kvm_run: =20 5. The kvm_run structure @@ -6493,7 +6550,50 @@ This field is ignored if KVM_CAP_IMMEDIATE_EXIT is n= ot available. =20 :: =20 - __u8 padding1[6]; + /* in/out */ + __u8 plane; + +The plane that will be run (usually 0). + +While this is not yet supported, in the future KVM may handle plane +switch in the kernel. In this case, the output value of this field +may differ from the input value. However, automatic switch will +have to be :ref:`explicitly enabled `. + +For backwards compatibility, this field is ignored unless a plane +other than plane 0 has been created. + +:: + + /* in/out */ + __u16 suspended_planes; + +A bitmap of planes whose execution was suspended to run a +higher-privileged plane, usually via a hypercall or due to +an interrupt in the higher-privileged plane. + +KVM right now does not use this field; it may be used in the future +once KVM implements in-kernel plane switch mechanisms. Until that +is the case, userspace can leave this to zero. + +:: + + /* in */ + __u16 req_exit_planes; + +A bitmap of planes for which KVM should exit when they have a pending +interrupt. In general, userspace should set bits corresponding to +planes that are more privileged than ``plane``; because KVM is agnostic +to whether low ids are more or less privileged, these could be the bits +*above* or *below* ``plane``. In some cases it may make sense to request +an exit for all planes---for example, if the higher-priority plane +wants to be informed about interrupts pending in lower-priority planes, +userspace may need to learn about those as well. + +The bit at position ``plane`` is ignored; interrupts for the current +plane are never delivered to userspace. + +:: =20 /* out */ __u32 exit_reason; @@ -7162,6 +7262,44 @@ The valid value for 'flags' is: - KVM_NOTIFY_CONTEXT_INVALID -- the VM context is corrupted and not valid in VMCS. It would run into unknown result if resume the target VM. =20 +:: + + /* KVM_EXIT_PLANE_EVENT */ + struct { + #define KVM_PLANE_EVENT_INTERRUPT 1 + __u16 cause; + __u16 pending_event_planes; + __u16 target; + __u16 padding; + __u32 flags; + __u64 extra; + } plane_event; + +Inform userspace of an event that affects a different plane than the +currently executing one. + +On a ``KVM_EXIT_PLANE_EVENT`` exit, ``pending_event_planes`` is always +set to the set of planes that have a pending interrupt. + +``cause`` provides the event that caused the exit, and the meaning of +``target`` depends on the cause of the exit too. + +Right now the only defined cause is ``KVM_PLANE_EVENT_INTERRUPT``, i.e. +an interrupt was received by a plane whose id is set in the +``req_exit_planes`` bitmap. In this case, ``target`` is the AND of +``req_exit_planes`` and ``pending_event_planes``. + +``flags`` and ``extra`` are currently always 0. + +If userspace wants to switch to the target plane, it should move any +shared state from the current plane to ``target``, and then invoke +``KVM_RUN`` with ``kvm_run->plane`` set to ``target`` (and +``req_exit_planes`` initialized accordingly). Note that it's also +valid to switch planes in response to other userspace exit codes, for +example ``KVM_EXIT_X86_WRMSR`` or ``KVM_EXIT_HYPERCALL``. Immediately +after ``KVM_RUN`` is entered, KVM will check ``req_exit_planes`` and +trigger a ``KVM_EXIT_PLANE_EVENT`` userspace exit if needed. + :: =20 /* Fix the size of the union. */ @@ -8511,6 +8649,26 @@ ENOSYS for the others. When enabled, KVM will exit to userspace with KVM_EXIT_SYSTEM_EVENT of type KVM_SYSTEM_EVENT_SUSPEND to process the guest suspend request. =20 +7.46 KVM_CAP_PLANES_FPU +----------------------- + +:Architectures: x86 +:Parameters: arg[0] is 0 if each vCPU plane has a separate FPU, + 1 if the FPU is shared +:Type: vm + +When enabled, such as KVM_SET_XSAVE or KVM_SET_FPU *are* available for +vCPU on all planes, but they will read and write the same data that is pre= sented +to other planes. Note that KVM_GET/SET_XSAVE also allows access to some +registers that are *not* part of FPU state; right now this is just PKRU. +Those are never shared. + +KVM_CAP_PLANES_FPU is experimental; userspace must *not* assume that +KVM_CAP_PLANES_FPU is present on x86 for *any* VM type and different +VM types may or may not allow enabling KVM_CAP_PLANES_FPU. Like for other +capabilities, KVM_CAP_PLANES_FPU can be queried on the VM file descriptor; +KVM_CHECK_EXTENSION returns 1 if it is possible to enable shared FPU mode. + 8. Other capabilities. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -9037,6 +9195,21 @@ KVM exits with the register state of either the L1 o= r L2 guest depending on which executed at the time of an exit. Userspace must take care to differentiate between these cases. =20 +8.46 KVM_CAP_PLANES +------------------- + +:Capability: KVM_CAP_PLANES +:Architectures: x86 +:Type: system, vm + +The capability returns the maximum plane id that can be passed to +:ref:`KVM_CREATE_PLANE `. Because the maximum +id can vary according to the machine type, it is recommended to +check for this capability on the VM file descriptor. + +When called on the system file descriptor, KVM returns the highest +value supported on any machine type. + 9. Known KVM API problems =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D =20 diff --git a/Documentation/virt/kvm/vcpu-requests.rst b/Documentation/virt/= kvm/vcpu-requests.rst index 06718b9bc959..86ac67b98a74 100644 --- a/Documentation/virt/kvm/vcpu-requests.rst +++ b/Documentation/virt/kvm/vcpu-requests.rst @@ -286,6 +286,13 @@ architecture dependent. kvm_vcpu_block() calls kvm_ar= ch_vcpu_runnable() to check if it should awaken. One reason to do so is to provide architectures a function where requests may be checked if necessary. =20 +VM planes +--------- + +Each plane has its own set of requests. Processing requests from +another plane needs to go through a plane switch, for example via a +`KVM_EXIT_PLANE_EVENT` userspace exit. + References =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 5AB7020D4F4 for ; Tue, 1 Apr 2025 16:11:19 +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=1743523881; cv=none; b=GSqZz/LseBoModRXUxIhiupEWR/ptohs4DzwGGQ+BZI2qEaeaLrrm4eq0FRzYLugvnGbtujPccyiB1qHSxnEcZltdagc2gPyeaYVKsu4Ro9fWTj5NRXRGcNsicxoGzQFPPMXaOfncSGkl+Ka9W+1eae57fiOMPNbCvjg2vi1I8Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523881; c=relaxed/simple; bh=P8Cr7Z2TxPF0ktXGH33ko7FhabI+md/UaeO2mhqlq9M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eEK5FjJOb6ZHUy4ksrXmkre6pqkOduykqAC8FRw7bJ0Lk8FcxsXwDvidKlHI+7hPiJ82Q5NuVW78unGiLeGLzlamYbMipeJ63VZ/tqbCdEKRhtmD0BMokPBdRxDkjgBhx0wTgJywP5iUUu/SZe3cNmI9OmXfIintlRprUrdFRwg= 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=Tqt000+5; 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="Tqt000+5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523878; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Xan579+d7KgslaidCIf/x6Agm9xb9cfRwwriUXqq5BU=; b=Tqt000+5WPb4a2EupowFeOKEkMKsZIeEpmDDIdphznd1+/vke+ntJOBqvWJPPSgjp1JiEU dN7GtZnQGO6U6NJygHhQ3jt15ZkDeaPELTTOId0DMmiUQ0a6igtIJzUfYV7OEK056pMmb4 6qhNGZnQPUV6TyuD2jLACw6JivJ8yu8= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-662-C3nW-pdcMPyxOnwZmk-KDA-1; Tue, 01 Apr 2025 12:11:17 -0400 X-MC-Unique: C3nW-pdcMPyxOnwZmk-KDA-1 X-Mimecast-MFC-AGG-ID: C3nW-pdcMPyxOnwZmk-KDA_1743523876 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43d6c65dc52so38991815e9.1 for ; Tue, 01 Apr 2025 09:11:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523875; x=1744128675; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Xan579+d7KgslaidCIf/x6Agm9xb9cfRwwriUXqq5BU=; b=qrnhXAJ82Ds5EC7oRVFh8yf/s81WicJPq6PpQX/QiPexE0RgZaSBN+zGuWQO/p5kIl fTMBA/cR5SXojNuK88P+OWolMAfBbroyNv7tYmQgttwzadV78RuTwaLATMRHrwpnPZ6J ERUfCc21jYBQkFu2FSxUioeO00mtEgp2SpO9hYgh2n9HiB3dN9WpGUZEFYMKlBJgEHq+ JJUQ/hbtv2s/oH6RtRXKVX50fzjYWa72v1jT5GiHTavAS2nAXm4O+UU4ldtsr8ZdQGkI la+uB+LChRe31+Ujoq/Bf7YuzrLc31DyID9ebZZrZHjddTAfDpyGcmO1OtLyxK4W1TKw LTzw== X-Gm-Message-State: AOJu0YwvxLkIAoANNoVuD3fRN3G04fIIfH6cXHin/60jjl/GaFqN93nS /1mg0ZHZc/+LGwzXemuNq1AsBnk6h3LpaXnmu+3VBPnkSqspCI4iWqaLZzrCf5KsB3OczU97bK3 OUx37678l0ky+weLqTVsjwGvPwy8qK63gaTqWyWyXU5TQM4gskD/YJc3Crkn5RChXQ+CQ7S5GL9 +oTDrbAPTed8+m0/Drict3DiZabr4f0pzYGHCVr3ZrWUdRkg== X-Gm-Gg: ASbGnctTUdp+177GK2Qw9TedMOlUxo94j/sdQfYGO8lDxvdDFqbhVB/IzJYOrWr/rp8 GTiC03p/tJFhlYIAhpqRntwEQbXXAPBV8LI4K4xOCDrmD7/WuFtSi+1symZO43JZAQlifqLq3vZ 2dvksp/xcCB+oMSL9m9+Bp9+/Z6ribSQdPMQ9RqV5Ro5JwiDUoe3d4bTRZL6tIpmyBediXIC2sK ZhFXKubxZI3+ozEM2CSltTwsIkVLPhSbM4gkK3e3bFVj9WMMszlWn3fIOQCHdvhQVM7LpM3domI 40yG1ur8vHT7WP3WsokQ+A== X-Received: by 2002:a05:600c:8411:b0:43c:efed:733e with SMTP id 5b1f17b1804b1-43e9532e1ebmr100629205e9.14.1743523875173; Tue, 01 Apr 2025 09:11:15 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFUdn3Vx4U1/8c8ov9d3i+5ptLX3WkvMAvnyRA6d81On2Tt/Y/tDhAYSD2hlI0h2+y0PDDicw== X-Received: by 2002:a05:600c:8411:b0:43c:efed:733e with SMTP id 5b1f17b1804b1-43e9532e1ebmr100628635e9.14.1743523874749; Tue, 01 Apr 2025 09:11:14 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d8fbc10f7sm162095215e9.14.2025.04.01.09.11.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:13 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 02/29] KVM: API definitions for plane userspace exit Date: Tue, 1 Apr 2025 18:10:39 +0200 Message-ID: <20250401161106.790710-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Copy over the uapi definitions from the Documentation/ directory. Signed-off-by: Paolo Bonzini --- include/uapi/linux/kvm.h | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 1e0a511c43d0..b0cca93ebcb3 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -135,6 +135,16 @@ struct kvm_xen_exit { } u; }; =20 +struct kvm_plane_event_exit { +#define KVM_PLANE_EVENT_INTERRUPT 1 + __u16 cause; + __u16 pending_event_planes; + __u16 target; + __u16 padding; + __u32 flags; + __u64 extra[8]; +}; + struct kvm_tdx_exit { #define KVM_EXIT_TDX_VMCALL 1 __u32 type; @@ -262,7 +272,8 @@ struct kvm_tdx_exit { #define KVM_EXIT_NOTIFY 37 #define KVM_EXIT_LOONGARCH_IOCSR 38 #define KVM_EXIT_MEMORY_FAULT 39 -#define KVM_EXIT_TDX 40 +#define KVM_EXIT_PLANE_EVENT 40 +#define KVM_EXIT_TDX 41 =20 /* For KVM_EXIT_INTERNAL_ERROR */ /* Emulate instruction failed. */ @@ -295,7 +306,13 @@ struct kvm_run { /* in */ __u8 request_interrupt_window; __u8 HINT_UNSAFE_IN_KVM(immediate_exit); - __u8 padding1[6]; + + /* in/out */ + __u8 plane; + __u16 suspended_planes; + + /* in */ + __u16 req_exit_planes; =20 /* out */ __u32 exit_reason; @@ -532,6 +549,8 @@ struct kvm_run { __u64 gpa; __u64 size; } memory_fault; + /* KVM_EXIT_PLANE_EVENT */ + struct kvm_plane_event_exit plane_event; /* KVM_EXIT_TDX */ struct kvm_tdx_exit tdx; /* Fix the size of the union. */ @@ -1017,6 +1036,8 @@ 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_PLANES 239 +#define KVM_CAP_PLANES_FPU 240 =20 struct kvm_irq_routing_irqchip { __u32 irqchip; --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 6E3A520DD54 for ; Tue, 1 Apr 2025 16:11:21 +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=1743523883; cv=none; b=PQoc9cUCAjLyxh2ndScQM798zdMXx6a0BMH/B3yTotiKx9Ev9aZbmsSeEbSMyfmpTKDBPkmeiSOiVGzDeYW6Z1Sorl9ag+dn4eefUkjrD79dshZQZT3drDEBYmsomcbniMi2V3LrKqXzU4hUdAlcVUpHlsnctSkCiQwXnlMSJJI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523883; c=relaxed/simple; bh=yRG3ANAcWURe86N1hf41BIQjs3HGQuEMu8uGmCkgimo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AyVS7yM+jKGUtYGO3cjOAzkxW7Av3dETcT/EiB+BaJtA5an7cPjVWhLEhOJ4bvERJK7XOf2xB9dil3duZIuZZocoZG4imPmoAFKHeK5GG2EKzcqWe3gY+GC1fSpluFTfwcwZEPkmjzGu13WkmtWhtD0cdtOPb/4zlDt5BGQCu9c= 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=AHTOiJuk; 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="AHTOiJuk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523880; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C5sOJ1ZN51NGUB7AKsam1Z/J0Y4Aw58lesO8LZ+8PjM=; b=AHTOiJukaE8JnXSCn8bMGuFT9DWpFpwgA+A1smcM2nFkSWrUdoYX9veOLbtIeFjb3zYkau 3oK6E2duR9u6R51woOqADUm+GWkFrJTEDNRsJLk/1rhtoMr9vy8kH/U7B2UFoFnHNjFtso L27YXizteiT5i3jnF8iPUo62B0SVjmo= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-50-RY9bVk5UO1WjH_paW8RvlA-1; Tue, 01 Apr 2025 12:11:19 -0400 X-MC-Unique: RY9bVk5UO1WjH_paW8RvlA-1 X-Mimecast-MFC-AGG-ID: RY9bVk5UO1WjH_paW8RvlA_1743523878 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43d0a037f97so35531545e9.2 for ; Tue, 01 Apr 2025 09:11:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523878; x=1744128678; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=C5sOJ1ZN51NGUB7AKsam1Z/J0Y4Aw58lesO8LZ+8PjM=; b=sXTtBPovEK+TXVfgfr+cGVsk2+rZjdqrNkESNEwPNKLffrI+emF5U5wgxQKS9un7Wh cD7yKkUweZI3HL+oVYcW4BXa/qVEG7IkWWAtbqjz1BXKMWHAMRDeD2NtutwFBzXQ4FFi 6HDaMWKKDqprr8kIXm4WsunNA4M/9Coq9/Fi53dl8latR7sFjmntjixRrAkt9oxrmGVu q4GS7htgCKcTVcuc/sihY+pFxP/EPnmgoR+6Wh7KTw3XkLoRJ6AkNnbZSBEbroVDaN6z cTxZTUYHA2xy8/tMAU03kGKS1kTXg7rnbc5NHoG/oMhgEyv35FmDaYM/tbFyPDyHcIyZ KPhw== X-Gm-Message-State: AOJu0Yx6+5F/vuYNrljaR1YwNl1QqOnJz5JqJGw6ud7yueSogq8zNr/n fGnHkJtgkhMs6vWAnonKVADprGRsJjbVkTReLsm8N6GaBEd03qQotl5IRINepzDJwA20TgvL5Df TG9hOJBwDvfVmsls99/tRXh4U2m9+3/rHlDwbkpUA+6S83TCwiEMpRC5vXPlwM6dYPsEtLfHR/p FQAQ54PWobODb5W/AkDKHnPyIqTYIXtsmR7txtg/5t4i/rEA== X-Gm-Gg: ASbGncuAn+x6sxzDYMw8O8ke9z8AVPsTahDTRk969pMxxyVGBfl2MVklbMsTcfnENTi TgtKqgvea3AjVtkVpf5gbyyjgMLojbD2PuCpu3y+mqe7xtuiHRPmBvU0+YBEBMuQMyuE9XtuAVP cUnPsc4BTIETqQocd4VaHCBHtkuYl4OAYci/eI2TznVXzJAJPS61e88m3ajREmuCfaEh6T5Q3v6 1UFSwJJP2V/ytmHXwnYpxYC9to+rTvL+EW3P1iaA48jSq0TUtdPjsZgMUK8KdgZJDOzDdWWoFgj DYI8mymckzn8MbL8DYENxg== X-Received: by 2002:a05:600c:198f:b0:43b:ca39:6c7d with SMTP id 5b1f17b1804b1-43db61d8326mr133339185e9.3.1743523877765; Tue, 01 Apr 2025 09:11:17 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFbyCKX5Aqf5nXfh6DE7+ASXGOt8qcrXWAlRQRnDUDahaaum0QoMpdBp6Nw+tK1Bgywmh1HQw== X-Received: by 2002:a05:600c:198f:b0:43b:ca39:6c7d with SMTP id 5b1f17b1804b1-43db61d8326mr133338495e9.3.1743523877277; Tue, 01 Apr 2025 09:11:17 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b7a4294sm14189742f8f.89.2025.04.01.09.11.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:15 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 03/29] KVM: add plane info to structs Date: Tue, 1 Apr 2025 18:10:40 +0200 Message-ID: <20250401161106.790710-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add some of the data to move from one plane to the other within a VM, typically from plane N to plane 0. There is quite some difference here because while separate planes provide very little of the vm file descriptor functionality, they are almost fully functional vCPUs except that non-zero planes(*) can only be ran indirectly through the initial plane. Therefore, vCPUs use struct kvm_vcpu for all planes, with just a couple fields that will be added later and will only be valid for plane 0. At the VM level instead plane info is stored in a completely different struct. For now struct kvm_plane has no architecture-specific counterpart, but this may change in the future if needed. It's possible for example that some MMU info becomes per-plane in order to support per-plane RWX permissions. (*) I will restrain from calling them astral planes. Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 17 ++++++++++++++++- include/linux/kvm_types.h | 1 + virt/kvm/kvm_main.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index c8f1facdb600..0e16c34080ef 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -84,6 +84,10 @@ #define KVM_MAX_NR_ADDRESS_SPACES 1 #endif =20 +#ifndef KVM_MAX_VCPU_PLANES +#define KVM_MAX_VCPU_PLANES 1 +#endif + /* * For the normal pfn, the highest 12 bits should be zero, * so we can mask bit 62 ~ bit 52 to indicate the error pfn, @@ -332,7 +336,8 @@ struct kvm_vcpu { #ifdef CONFIG_PROVE_RCU int srcu_depth; #endif - int mode; + short plane; + short mode; u64 requests; unsigned long guest_debug; =20 @@ -367,6 +372,8 @@ struct kvm_vcpu { } async_pf; #endif =20 + struct kvm_vcpu *plane0; + #ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT /* * Cpu relax intercept or pause loop exit optimization @@ -753,6 +760,11 @@ struct kvm_memslots { int node_idx; }; =20 +struct kvm_plane { + struct kvm *kvm; + int plane; +}; + struct kvm { #ifdef KVM_HAVE_MMU_RWLOCK rwlock_t mmu_lock; @@ -777,6 +789,9 @@ struct kvm { /* The current active memslot set for each address space */ struct kvm_memslots __rcu *memslots[KVM_MAX_NR_ADDRESS_SPACES]; struct xarray vcpu_array; + + struct kvm_plane *planes[KVM_MAX_VCPU_PLANES]; + /* * Protected by slots_lock, but can be read outside if an * incorrect answer is acceptable. diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h index 827ecc0b7e10..7d0a86108d1a 100644 --- a/include/linux/kvm_types.h +++ b/include/linux/kvm_types.h @@ -11,6 +11,7 @@ struct kvm_interrupt; struct kvm_irq_routing_table; struct kvm_memory_slot; struct kvm_one_reg; +struct kvm_plane; struct kvm_run; struct kvm_userspace_memory_region; struct kvm_vcpu; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f6c947961b78..67773b6b9576 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1095,9 +1095,22 @@ void __weak kvm_arch_create_vm_debugfs(struct kvm *k= vm) { } =20 +static struct kvm_plane *kvm_create_vm_plane(struct kvm *kvm, unsigned pla= ne_id) +{ + struct kvm_plane *plane =3D kzalloc(sizeof(struct kvm_plane), GFP_KERNEL_= ACCOUNT); + + if (!plane) + return ERR_PTR(-ENOMEM); + + plane->kvm =3D kvm; + plane->plane =3D plane_id; + return plane; +} + static struct kvm *kvm_create_vm(unsigned long type, const char *fdname) { struct kvm *kvm =3D kvm_arch_alloc_vm(); + struct kvm_plane *plane0; struct kvm_memslots *slots; int r, i, j; =20 @@ -1136,6 +1149,13 @@ static struct kvm *kvm_create_vm(unsigned long type,= const char *fdname) snprintf(kvm->stats_id, sizeof(kvm->stats_id), "kvm-%d", task_pid_nr(current)); =20 + plane0 =3D kvm_create_vm_plane(kvm, 0); + if (IS_ERR(plane0)) { + r =3D PTR_ERR(plane0); + goto out_err_no_plane0; + } + kvm->planes[0] =3D plane0; + r =3D -ENOMEM; if (init_srcu_struct(&kvm->srcu)) goto out_err_no_srcu; @@ -1227,6 +1247,8 @@ static struct kvm *kvm_create_vm(unsigned long type, = const char *fdname) out_err_no_irq_srcu: cleanup_srcu_struct(&kvm->srcu); out_err_no_srcu: + kfree(kvm->planes[0]); +out_err_no_plane0: kvm_arch_free_vm(kvm); mmdrop(current->mm); return ERR_PTR(r); @@ -1253,6 +1275,10 @@ static void kvm_destroy_devices(struct kvm *kvm) } } =20 +static void kvm_destroy_plane(struct kvm_plane *plane) +{ +} + static void kvm_destroy_vm(struct kvm *kvm) { int i; @@ -1309,6 +1335,11 @@ static void kvm_destroy_vm(struct kvm *kvm) #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES xa_destroy(&kvm->mem_attr_array); #endif + for (i =3D 0; i < ARRAY_SIZE(kvm->planes); i++) { + struct kvm_plane *plane =3D kvm->planes[i]; + if (plane) + kvm_destroy_plane(plane); + } kvm_arch_free_vm(kvm); preempt_notifier_dec(); kvm_disable_virtualization(); @@ -4110,6 +4141,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) } vcpu->run =3D page_address(page); =20 + vcpu->plane0 =3D vcpu; kvm_vcpu_init(vcpu, kvm, id); =20 r =3D kvm_arch_vcpu_create(vcpu); --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 47F3420E70A for ; Tue, 1 Apr 2025 16:11:23 +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=1743523886; cv=none; b=kPOhZyEYmP/qdoELD2EKbkLQC92sKgUBbj8pUYdW/U0dY0Sv3ZZJve8LRwNMHimkplTGjrLouFIdXbzV2pWoN9n/bFy86+LxMpMd7RasPSztzkTw6cFjUc0hjASu2PqTruvdF2UpQksA8JAtDMHofq0yzgYzofCWW3tHLjEoAfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523886; c=relaxed/simple; bh=v8jKs9c/aSFeCCmvqZ/YRl3Cj78RpyaLQZNO8QjAPqo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ev9lQRgdvNL+JjzPX83pYMLy2VBJSGsmvf/TaCbCATbr8sOgie3TMcQL9qOrlhIoxoeU3lmWyr/sD8DZxPrg2Niv81VpFoAWIv0vaCtZdAu3JcBxZ/Xh8TMBtp717ktB9Yil7159QHlwbYxzQDSDksML6q9CFpwXGZU6HU+yEIs= 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=WIwxmdRT; 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="WIwxmdRT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523883; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZVj8LxmRYtpLGVaJMpm0cMjRCHl/hUqQsU3rCt2if/8=; b=WIwxmdRTyGRmHV6x9e/jUpzRze7zwl4CJKGOXvlNmjKwdaUnLrXeY4XgfbcRl6UzI2Z/A2 GOcraVZmiosv9VzPwZVe3ASsvV4/X4EdQweYms0Yugybe7NLvOjKl9PX1MIv3r1RdNnmiM ASvnWV2lSO/NWdDvb/MoGwnbAZFEIpc= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-352-Trro0Q03NRW737rYrO59vw-1; Tue, 01 Apr 2025 12:11:22 -0400 X-MC-Unique: Trro0Q03NRW737rYrO59vw-1 X-Mimecast-MFC-AGG-ID: Trro0Q03NRW737rYrO59vw_1743523881 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43d733063cdso48590785e9.0 for ; Tue, 01 Apr 2025 09:11:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523880; x=1744128680; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZVj8LxmRYtpLGVaJMpm0cMjRCHl/hUqQsU3rCt2if/8=; b=XCyzbU3ExIU3uHatOSwEpK/imjgLJ7nB7h0rla+TPYnJD+CHkaqiBttChzV9fA66/h yAGXTEKzczp5oZfWbeBlrSSsFcXjIJZUrjbO5ZWKHm7St1VAKOtOi2U3HDj3gESyFL9u G8+qOGbbpklPxFDh6cbFy5RAGB9nd9Cegi4vkfXxNEg5yKqleKdTXRiQ4URpu32mTneY lVJ4f8WjEnl0dGv51mj1wzqnw3TNM68VIifM/IqlU9Z3d+dLETJ5moMo5uP/6OPccGve vjcQfNUKRctpu94PDJa3sbsTk2xefQpPr6kfmK0t/UbC1Y/VPEI/hR4tC814K9vX/8Sz L6cQ== X-Gm-Message-State: AOJu0Yz2Az27Rs/i35H2FLkJn2wbEEFlC+1iZ0YzQtAfMpziFJbTEcIK jmJft7nuCt/A5mCaDH6Q2unya0+w0xkdsvV+7dd+P8y0ocOtv3UHam8hrUN1IPgVbBULAgDA3tU HQasUBqvLgkIlS0NEeNpGWZdHDbaWwnMB5lDc7IkIftGBuEUydRi4xFw75NuQI1LWDss9l6a+Y+ /Thh2kxiOX/iQh292GkbQ8cKuQMBu4ctDifU5AtN+Z1cklWg== X-Gm-Gg: ASbGncsEA372pIYPYIxWAd0GF7PVMKfn52ZdKxx/3rzR3dBrMnOeTtnoflPBK0QEmyV HfXOqyq9WQyOHIKRLpDh6HKUjiqsLl1bGy5BpNFKza8d+WXSflr/I2QnRbBQJnV9ykFoGz+yNLF Eau7VXdEEEiPTxfOfPqkuBJ9S9vrD+epzny7ft8/TsNhhSFSuYL1wP+QVNy6wYcjxwzdOHKSoI0 EytItO13qHQ2K5GS76SJZQLAM5YKELpsvJeI6NypXkleFMIaDKo67c9cE5NqB1LW1KFRWj2SjgU 9dCoveqiiJVCs4zar3nf3Q== X-Received: by 2002:a05:600c:3d06:b0:43c:f184:2e16 with SMTP id 5b1f17b1804b1-43eaa03e0b9mr29476275e9.5.1743523880069; Tue, 01 Apr 2025 09:11:20 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF+E1xmwedldRJqmLtJk3EgwSLiKjTaPQFsZDp0oRIihpMjpWkbFC2kwYxD4KB/4aSNm+zhoQ== X-Received: by 2002:a05:600c:3d06:b0:43c:f184:2e16 with SMTP id 5b1f17b1804b1-43eaa03e0b9mr29475595e9.5.1743523879524; Tue, 01 Apr 2025 09:11:19 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b79e3b0sm14455968f8f.74.2025.04.01.09.11.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:18 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 04/29] KVM: introduce struct kvm_arch_plane Date: Tue, 1 Apr 2025 18:10:41 +0200 Message-ID: <20250401161106.790710-5-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Signed-off-by: Paolo Bonzini --- arch/arm64/include/asm/kvm_host.h | 5 +++++ arch/loongarch/include/asm/kvm_host.h | 5 +++++ arch/mips/include/asm/kvm_host.h | 5 +++++ arch/powerpc/include/asm/kvm_host.h | 5 +++++ arch/riscv/include/asm/kvm_host.h | 5 +++++ arch/s390/include/asm/kvm_host.h | 5 +++++ arch/x86/include/asm/kvm_host.h | 6 ++++++ include/linux/kvm_host.h | 2 ++ virt/kvm/kvm_main.c | 3 +++ 9 files changed, 41 insertions(+) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index d919557af5e5..b742275cda4d 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -227,6 +227,9 @@ struct kvm_s2_mmu { struct kvm_arch_memory_slot { }; =20 +struct kvm_arch_plane { +}; + /** * struct kvm_smccc_features: Descriptor of the hypercall services exposed= to the guests * @@ -1334,6 +1337,8 @@ static inline bool kvm_system_needs_idmapped_vectors(= void) return cpus_have_final_cap(ARM64_SPECTRE_V3A); } =20 +static inline void kvm_arch_init_plane(struct kvm_plane *plane) {} +static inline void kvm_arch_free_plane(struct kvm_plane *plane) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} =20 void kvm_init_host_debug_data(void); diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include= /asm/kvm_host.h index 2281293a5f59..24c1dafac855 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -73,6 +73,9 @@ struct kvm_arch_memory_slot { unsigned long flags; }; =20 +struct kvm_arch_plane { +}; + #define HOST_MAX_PMNUM 16 struct kvm_context { unsigned long vpid_cache; @@ -325,6 +328,8 @@ static inline bool kvm_is_ifetch_fault(struct kvm_vcpu_= arch *arch) } =20 /* Misc */ +static inline void kvm_arch_init_plane(struct kvm_plane *plane) {} +static inline void kvm_arch_free_plane(struct kvm_plane *plane) {} static inline void kvm_arch_hardware_unsetup(void) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {} diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_h= ost.h index f7222eb594ea..d7be72c529b3 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -147,6 +147,9 @@ struct kvm_vcpu_stat { struct kvm_arch_memory_slot { }; =20 +struct kvm_arch_plane { +}; + #ifdef CONFIG_CPU_LOONGSON64 struct ipi_state { uint32_t status; @@ -886,6 +889,8 @@ extern unsigned long kvm_mips_get_ramsize(struct kvm *k= vm); extern int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq); =20 +static inline void kvm_arch_init_plane(struct kvm_plane *plane) {} +static inline void kvm_arch_free_plane(struct kvm_plane *plane) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {} diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm= /kvm_host.h index 6e1108f8fce6..6023f0fd637b 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -256,6 +256,9 @@ struct kvm_arch_memory_slot { #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ }; =20 +struct kvm_arch_plane { +}; + struct kvm_hpt_info { /* Host virtual (linear mapping) address of guest HPT */ unsigned long virt; @@ -902,6 +905,8 @@ struct kvm_vcpu_arch { #define __KVM_HAVE_ARCH_WQP #define __KVM_HAVE_CREATE_DEVICE =20 +static inline void kvm_arch_init_plane(struct kvm_plane *plane) {} +static inline void kvm_arch_free_plane(struct kvm_plane *plane) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} static inline void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen) {} static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {} diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm= _host.h index cc33e35cd628..72f862194a0c 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -97,6 +97,9 @@ struct kvm_vcpu_stat { struct kvm_arch_memory_slot { }; =20 +struct kvm_arch_plane { +}; + struct kvm_vmid { /* * Writes to vmid_version and vmid happen with vmid_lock held @@ -301,6 +304,8 @@ static inline bool kvm_arch_pmi_in_guest(struct kvm_vcp= u *vcpu) return IS_ENABLED(CONFIG_GUEST_PERF_EVENTS) && !!vcpu; } =20 +static inline void kvm_arch_init_plane(struct kvm_plane *plane) {} +static inline void kvm_arch_free_plane(struct kvm_plane *plane) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} =20 #define KVM_RISCV_GSTAGE_TLB_MIN_ORDER 12 diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_h= ost.h index 9a367866cab0..63b79ce5c8ac 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -799,6 +799,9 @@ struct kvm_vm_stat { struct kvm_arch_memory_slot { }; =20 +struct kvm_arch_plane { +}; + struct s390_map_info { struct list_head list; __u64 guest_addr; @@ -1056,6 +1059,8 @@ bool kvm_s390_pv_cpu_is_protected(struct kvm_vcpu *vc= pu); extern int kvm_s390_gisc_register(struct kvm *kvm, u32 gisc); extern int kvm_s390_gisc_unregister(struct kvm *kvm, u32 gisc); =20 +static inline void kvm_arch_init_plane(struct kvm_plane *plane) {} +static inline void kvm_arch_free_plane(struct kvm_plane *plane) {} static inline void kvm_arch_sync_events(struct kvm *kvm) {} static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {} diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 383b736cc6f1..8240f565a764 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1086,6 +1086,9 @@ struct kvm_arch_memory_slot { unsigned short *gfn_write_track; }; =20 +struct kvm_arch_plane { +}; + /* * Track the mode of the optimized logical map, as the rules for decoding = the * destination vary per mode. Enabling the optimized logical map requires= all @@ -2357,6 +2360,9 @@ void kvm_make_scan_ioapic_request(struct kvm *kvm); void kvm_make_scan_ioapic_request_mask(struct kvm *kvm, unsigned long *vcpu_bitmap); =20 +static inline void kvm_arch_init_plane(struct kvm_plane *plane) {} +static inline void kvm_arch_free_plane(struct kvm_plane *plane) {} + bool kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, struct kvm_async_pf *work); void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 0e16c34080ef..6bd9b0b3cbee 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -763,6 +763,8 @@ struct kvm_memslots { struct kvm_plane { struct kvm *kvm; int plane; + + struct kvm_arch_plane arch; }; =20 struct kvm { diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 67773b6b9576..e83db27580da 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1104,6 +1104,8 @@ static struct kvm_plane *kvm_create_vm_plane(struct k= vm *kvm, unsigned plane_id) =20 plane->kvm =3D kvm; plane->plane =3D plane_id; + + kvm_arch_init_plane(plane); return plane; } =20 @@ -1277,6 +1279,7 @@ static void kvm_destroy_devices(struct kvm *kvm) =20 static void kvm_destroy_plane(struct kvm_plane *plane) { + kvm_arch_free_plane(plane); } =20 static void kvm_destroy_vm(struct kvm *kvm) --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 6F87C20F088 for ; Tue, 1 Apr 2025 16:11:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523888; cv=none; b=Myp64PZm0x98wKBBIrufT0f65UM/IzoRKjuo1BJaBvDqHSASawnoYhehaH4JnaIZQQsbBeXxPldV4+4B7cUfZ37NEmDkgja7eDNxNK7qugU5n3CGwiJtaIUNjmSc48hTFkrgVFha/T9MbcAckydOdJTMyqVDLbmTnFjpoXCQJRw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523888; c=relaxed/simple; bh=rxM4+r5oKn3FrtYxyoYERVyr2vDI5fg2rK7DFIuTtwg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=G/Bo8iY4D14KmnKmZlpxwkGcCJeF9OyNy5PVPa6oOxAfiGVhmZa//gSBDX6/++DeUcsr7n8rlPeVMFp7VsyhQIWArRSr9w+PXQEAF4xi4H0SjDLosqPHsKb26aigAUjYBeP0H+sTSsWDUYkcZ40Ff/jETIlKVItEAzs3L6LCuak= 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=e6q7JRT0; arc=none smtp.client-ip=170.10.129.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="e6q7JRT0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523885; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QaUbfvoP8aPmiGrV9eVE67gclsfaX3jw4nCiV/n0Ni4=; b=e6q7JRT0izGViacuCXk2qpAW675QODl6wzwH8s4rHsR9Qw2eV+s23TAnXZUVSD0KxmFbyV eBQyANkOThmLFO21RExFlE0/bLK6QMyOxZMq2tf9wjlsvpXlQELyDfsysU5JabolY5+ZQj D92x76ZbUA37T/7lnIow4Yuj0NPSv1w= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-523-5ftztJdKO5i2n1vV51m4lQ-1; Tue, 01 Apr 2025 12:11:24 -0400 X-MC-Unique: 5ftztJdKO5i2n1vV51m4lQ-1 X-Mimecast-MFC-AGG-ID: 5ftztJdKO5i2n1vV51m4lQ_1743523883 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43ceb011ea5so40935005e9.2 for ; Tue, 01 Apr 2025 09:11:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523882; x=1744128682; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QaUbfvoP8aPmiGrV9eVE67gclsfaX3jw4nCiV/n0Ni4=; b=wJVqGfehcUIyP++PB2/EYNt6PuWymPZ0j+zcoczF/CKrgvTUt48UFeR7Fx4dQxgXy6 E3ImaLEdyarb5gVrEVLALMCxBAEZBCmiGSjKlaz99+CV2aHCho0ClmsJZeJPzgt8HoWG rCNwe51s8uPtEju2Q9aRHGtzX+ck9feP62EAq2hCBInpy8l4O8b/tvMZzrx6+JrCE/xP hdhzhhTw8vE3A9pvLvDCQPR1bBY+f3V6PrY1jRUoALIElK3OH0p4CY933lMnN7BP+AfR /nNU9hsWOgX7HKvLfi5hbDffj3J+88HpRD3LLzh7MMkdE7faCs+PM146gru1RcnnUDEc sR2A== X-Gm-Message-State: AOJu0Yw7xs0Rs2l5u5UwRThgDjR6mcarqws85CchKzDpnrZalQk2ncxT Kd8ydK3kWUHZp6yIJnvyoC3rqIU741AcCAY0XPvIcxK2uhKNyi7gq26BcpuLVzWo5bn2cyWOSdc vYyVJBBJhMTK1lwKgcSNX2kosHIok0G/TDywo9GnTnfwKDozJfOhkpJF+jP6FZGfvvfnT6d0BH7 ejyArZg9YC4A9KzYQttElYZUhXBkURoiAVddrd+VkmMHpwrw== X-Gm-Gg: ASbGncsLYloJt9CUHTaCvUnssUhkZA4dikhYqdcRu4helNDR39HUlPX9EF4b2CgWRBz zeftWUUZ5tsmxGxIc26VYftvv2x/yLIvp09Gvhp3/lCZvwFqMlCu4TfVAriZkH/BXpUVEbY7xvb e5iIHy5GkrgPJU3hN0g5YeiSrs+e16xHZTAbicRxaDj1PLqhToEGm2tZ99cO30jC2zPOLObO4HM TJ4bnkdSPDvEah5a44lcDKi4slmy4MHNQnpBrbQv1SsWZwlOMlVUQoLcMMMycqkte6OgTFy2nNR 6NXv5+DCUP3bTpHesGqO9w== X-Received: by 2002:a05:600c:cc8:b0:43d:b3:fb1 with SMTP id 5b1f17b1804b1-43ea5f001b7mr45447985e9.27.1743523882231; Tue, 01 Apr 2025 09:11:22 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHZdEWzHsg0YswCSXrdzj6ch9i3n9G2iz9TWc1mNERKBxpVsH1+e/xNG+caFFDjVEabapAovQ== X-Received: by 2002:a05:600c:cc8:b0:43d:b3:fb1 with SMTP id 5b1f17b1804b1-43ea5f001b7mr45447655e9.27.1743523881889; Tue, 01 Apr 2025 09:11:21 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b66ab86sm14896816f8f.51.2025.04.01.09.11.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:20 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 05/29] KVM: add plane support to KVM_SIGNAL_MSI Date: Tue, 1 Apr 2025 18:10:42 +0200 Message-ID: <20250401161106.790710-6-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" struct kvm_kernel_irq_routing_entry is the main tool for sending cross-plane IPIs. Make kvm_send_userspace_msi the first function to accept a struct kvm_plane pointer, in preparation for making it available from plane file descriptors. Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 3 ++- virt/kvm/irqchip.c | 5 ++++- virt/kvm/kvm_main.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 6bd9b0b3cbee..98bae5dc3515 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -684,6 +684,7 @@ struct kvm_kernel_irq_routing_entry { u32 data; u32 flags; u32 devid; + u32 plane; } msi; struct kvm_s390_adapter_int adapter; struct kvm_hv_sint hv_sint; @@ -2218,7 +2219,7 @@ static inline int kvm_init_irq_routing(struct kvm *kv= m) =20 #endif =20 -int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); +int kvm_send_userspace_msi(struct kvm_plane *plane, struct kvm_msi *msi); =20 void kvm_eventfd_init(struct kvm *kvm); int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args); diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index 162d8ed889f2..84952345e3c2 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -45,8 +45,10 @@ int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqch= ip, unsigned pin) return irq_rt->chip[irqchip][pin]; } =20 -int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) +int kvm_send_userspace_msi(struct kvm_plane *plane, struct kvm_msi *msi) { + struct kvm *kvm =3D plane->kvm; + unsigned plane_id =3D plane->plane; struct kvm_kernel_irq_routing_entry route; =20 if (!kvm_arch_irqchip_in_kernel(kvm) || (msi->flags & ~KVM_MSI_VALID_DEVI= D)) @@ -57,6 +59,7 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_ms= i *msi) route.msi.data =3D msi->data; route.msi.flags =3D msi->flags; route.msi.devid =3D msi->devid; + route.msi.plane =3D plane_id; =20 return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false); } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index e83db27580da..5b44a7f9e52e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5207,7 +5207,7 @@ static long kvm_vm_ioctl(struct file *filp, r =3D -EFAULT; if (copy_from_user(&msi, argp, sizeof(msi))) goto out; - r =3D kvm_send_userspace_msi(kvm, &msi); + r =3D kvm_send_userspace_msi(kvm->planes[0], &msi); break; } #endif --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 3ADB121018D for ; Tue, 1 Apr 2025 16:11:29 +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=1743523891; cv=none; b=GQLxAsUILDFYkPT1y2kk/sMm6TzuslKIYWYVmJPoEpY3p3t0wJT/9wrYxjVDKsL5947fFzWthYyBiGK2aSw5XGSNvjnbd8HNJ9CKz87+yQHzLSIE2KyjYjCPaGair/7xuU7cyMYW2433oT9FHADotf2TFxTGZtWMSnKVDlavX1U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523891; c=relaxed/simple; bh=wgQBBmc1qbxZtdWIBwi2SbIZVYBQeBi9r18IbBZZndo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ABgzlxDnc/pO4f+3D4I6GHrK9SenARUagv3MMSV8A8TV4zdkjwtBW0k07sMxwFwPArmSgd71QwK+58YnOI3+ljVOuCKs+2nCy3UNoYTQGOviO7UePnEQhnIw3XXP9Pk/GQybIjTKvy5vNWsAvtOXUJ8yqKRUSjAAWX6J5qcAsQk= 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=AJ6Noud/; 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="AJ6Noud/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523888; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2sGhYUJTD12TKfaq4UZWtS0jUt1FVjaz51Eq07OqDF4=; b=AJ6Noud/YEWKh8K/T4eXK+jz7ktfjh8b/3mIvK1oo17WqINdMTaxmMl+3spOum/Xwu/jq+ /ADpqcZODyc71cIcCgTIYIsxjfKiQUZngK5rbcfY820gy5X7m+5uEIFFZot5eI0Yr68B7w uEkkP5CIruic5FMr5usd2W9Vx0OKZfw= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-614-xWGQXLkcPVaysWSBduE75w-1; Tue, 01 Apr 2025 12:11:27 -0400 X-MC-Unique: xWGQXLkcPVaysWSBduE75w-1 X-Mimecast-MFC-AGG-ID: xWGQXLkcPVaysWSBduE75w_1743523886 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-43cf3168b87so32471395e9.2 for ; Tue, 01 Apr 2025 09:11:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523885; x=1744128685; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2sGhYUJTD12TKfaq4UZWtS0jUt1FVjaz51Eq07OqDF4=; b=VNQm0oSREHLowdVPAR8w/9FT5AgYwLNiXVOh52lSDwB1haKtm7s4RpIdI+rdNS3AXk SF2vkPO4sJehIicPvqgJ/cjTxEhz5QIVYwvL+4eM89Bs32JDkBugJR32HxJTtgMXehMh AWK+wEmqg/DH4MKjyOmBZBlkTPRTDGSkTUxdXVMRFREj723kZ6XNmaxMtYJIpcOqS0rb B8odK86BMF6N/6qefpXtX0PmNGISc47fYVk7jV0fvNBJkdPCHDcpv9MPjvE0xajUhvmH +faGpHCHuLqc+1tQWlY5K2EiOa7zDjya/6Qn9e5MsJsbZIVwSqzdZhQS1x/kNUC8W9oW n0Jg== X-Gm-Message-State: AOJu0Yz0BiGugLemJU5nO8iLOLWOgQoaPdkiFCMsgiu5YNOMWfEg1CNy Dk8yOQxYGB6vfQPk6tb5CCFZf3CaAb2lv1LO2i8r86RHb9f1mJMZYA48ihbly6u62Q2/dXQhkVO J5pjp7J2LR6ADwwrq7W4eXNK2N9KTwpQ1Xcj0OrC6JLLk7K0CV3iDeYcHsVCnUOHHkwCahdDbxS +VjDrB5fIZ41zCpghVFLAHaRXo9vUwHAeY5YLPFP/dzuhmiA== X-Gm-Gg: ASbGncubiyaVNBGyn6AZOvmJd+1LGCamoY6VqpAiNuZpsy73eYLEkvR5aUwH03xmtAb sYHPDGloWUXhmWxz3Zi82MOZbounmvJPSIyOW9tqk7EDikANSkJTHnJYwJDFjOyY0Khh9g9GIsT 56hSg17Xjx3KdT7nkeiNVWWnx3UlILi8MhvV1RBjdJ5rdFbBX/a2Q6Yu+1X9gaOAYZDi9eRM/JZ lBz6W+vZ0p7QnjJvDRZxOzMOLXVAPkORDmkaY8hCmPmGUBkB59VpjFgl/fY1hRrYXzYgJsk3IzM G4NJ8ZNq9XsgQ/oc6fJ+sg== X-Received: by 2002:a05:600c:1d14:b0:43c:fe15:41e1 with SMTP id 5b1f17b1804b1-43ea7c4e878mr34970995e9.4.1743523884914; Tue, 01 Apr 2025 09:11:24 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEw0KCQptOpUzsEJC9h+J15baLRxkJXWFt4YysKwcuqvA/vSlOPdWF/S+38oX+DaBh6C3XLCA== X-Received: by 2002:a05:600c:1d14:b0:43c:fe15:41e1 with SMTP id 5b1f17b1804b1-43ea7c4e878mr34970365e9.4.1743523884345; Tue, 01 Apr 2025 09:11:24 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43ea97895e1sm19840855e9.1.2025.04.01.09.11.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:23 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 06/29] KVM: move mem_attr_array to kvm_plane Date: Tue, 1 Apr 2025 18:10:43 +0200 Message-ID: <20250401161106.790710-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Another aspect of the VM that is now different for separate planes is memory attributes, in order to support RWX permissions in the future. The existing vm-level ioctls apply to plane 0 and the underlying functionality operates on struct kvm_plane, which now hosts the mem_attr_array xarray. As a result, the pre/post architecture-specific callbacks also take a plane. Private/shared is a global attribute and only applies to plane 0. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 23 ++++++----- include/linux/kvm_host.h | 24 +++++++----- virt/kvm/guest_memfd.c | 3 +- virt/kvm/kvm_main.c | 85 +++++++++++++++++++++++++--------------- 4 files changed, 84 insertions(+), 51 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index a284dce227a0..04e4b041e248 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -7670,9 +7670,11 @@ void kvm_mmu_pre_destroy_vm(struct kvm *kvm) } =20 #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES -bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, +bool kvm_arch_pre_set_memory_attributes(struct kvm_plane *plane, struct kvm_gfn_range *range) { + struct kvm *kvm =3D plane->kvm; + /* * Zap SPTEs even if the slot can't be mapped PRIVATE. KVM x86 only * supports KVM_MEMORY_ATTRIBUTE_PRIVATE, and so it *seems* like KVM @@ -7714,26 +7716,27 @@ static void hugepage_set_mixed(struct kvm_memory_sl= ot *slot, gfn_t gfn, lpage_info_slot(gfn, slot, level)->disallow_lpage |=3D KVM_LPAGE_MIXED_FL= AG; } =20 -static bool hugepage_has_attrs(struct kvm *kvm, struct kvm_memory_slot *sl= ot, +static bool hugepage_has_attrs(struct kvm_plane *plane, struct kvm_memory_= slot *slot, gfn_t gfn, int level, unsigned long attrs) { const unsigned long start =3D gfn; const unsigned long end =3D start + KVM_PAGES_PER_HPAGE(level); =20 if (level =3D=3D PG_LEVEL_2M) - return kvm_range_has_memory_attributes(kvm, start, end, ~0, attrs); + return kvm_range_has_memory_attributes(plane, start, end, ~0, attrs); =20 for (gfn =3D start; gfn < end; gfn +=3D KVM_PAGES_PER_HPAGE(level - 1)) { if (hugepage_test_mixed(slot, gfn, level - 1) || - attrs !=3D kvm_get_memory_attributes(kvm, gfn)) + attrs !=3D kvm_get_plane_memory_attributes(plane, gfn)) return false; } return true; } =20 -bool kvm_arch_post_set_memory_attributes(struct kvm *kvm, +bool kvm_arch_post_set_memory_attributes(struct kvm_plane *plane, struct kvm_gfn_range *range) { + struct kvm *kvm =3D plane->kvm; unsigned long attrs =3D range->arg.attributes; struct kvm_memory_slot *slot =3D range->slot; int level; @@ -7767,7 +7770,7 @@ bool kvm_arch_post_set_memory_attributes(struct kvm *= kvm, */ if (gfn >=3D slot->base_gfn && gfn + nr_pages <=3D slot->base_gfn + slot->npages) { - if (hugepage_has_attrs(kvm, slot, gfn, level, attrs)) + if (hugepage_has_attrs(plane, slot, gfn, level, attrs)) hugepage_clear_mixed(slot, gfn, level); else hugepage_set_mixed(slot, gfn, level); @@ -7789,7 +7792,7 @@ bool kvm_arch_post_set_memory_attributes(struct kvm *= kvm, */ if (gfn < range->end && (gfn + nr_pages) <=3D (slot->base_gfn + slot->npages)) { - if (hugepage_has_attrs(kvm, slot, gfn, level, attrs)) + if (hugepage_has_attrs(plane, slot, gfn, level, attrs)) hugepage_clear_mixed(slot, gfn, level); else hugepage_set_mixed(slot, gfn, level); @@ -7801,11 +7804,13 @@ bool kvm_arch_post_set_memory_attributes(struct kvm= *kvm, void kvm_mmu_init_memslot_memory_attributes(struct kvm *kvm, struct kvm_memory_slot *slot) { + struct kvm_plane *plane0; int level; =20 if (!kvm_arch_has_private_mem(kvm)) return; =20 + plane0 =3D kvm->planes[0]; for (level =3D PG_LEVEL_2M; level <=3D KVM_MAX_HUGEPAGE_LEVEL; level++) { /* * Don't bother tracking mixed attributes for pages that can't @@ -7825,9 +7830,9 @@ void kvm_mmu_init_memslot_memory_attributes(struct kv= m *kvm, * be manually checked as the attributes may already be mixed. */ for (gfn =3D start; gfn < end; gfn +=3D nr_pages) { - unsigned long attrs =3D kvm_get_memory_attributes(kvm, gfn); + unsigned long attrs =3D kvm_get_plane_memory_attributes(plane0, gfn); =20 - if (hugepage_has_attrs(kvm, slot, gfn, level, attrs)) + if (hugepage_has_attrs(plane0, slot, gfn, level, attrs)) hugepage_clear_mixed(slot, gfn, level); else hugepage_set_mixed(slot, gfn, level); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 98bae5dc3515..4d408d1d5ccc 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -763,6 +763,10 @@ struct kvm_memslots { =20 struct kvm_plane { struct kvm *kvm; +#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES + /* Protected by slots_locks (for writes) and RCU (for reads) */ + struct xarray mem_attr_array; +#endif int plane; =20 struct kvm_arch_plane arch; @@ -875,10 +879,6 @@ struct kvm { =20 #ifdef CONFIG_HAVE_KVM_PM_NOTIFIER struct notifier_block pm_notifier; -#endif -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES - /* Protected by slots_locks (for writes) and RCU (for reads) */ - struct xarray mem_attr_array; #endif char stats_id[KVM_STATS_NAME_SIZE]; }; @@ -2511,20 +2511,26 @@ static inline void kvm_prepare_memory_fault_exit(st= ruct kvm_vcpu *vcpu, } =20 #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES -static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn= _t gfn) +static inline unsigned long kvm_get_plane_memory_attributes(struct kvm_pla= ne *plane, gfn_t gfn) { - return xa_to_value(xa_load(&kvm->mem_attr_array, gfn)); + return xa_to_value(xa_load(&plane->mem_attr_array, gfn)); } =20 -bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t e= nd, +static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn= _t gfn) +{ + return kvm_get_plane_memory_attributes(kvm->planes[0], gfn); +} + +bool kvm_range_has_memory_attributes(struct kvm_plane *plane, gfn_t start,= gfn_t end, unsigned long mask, unsigned long attrs); -bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, +bool kvm_arch_pre_set_memory_attributes(struct kvm_plane *plane, struct kvm_gfn_range *range); -bool kvm_arch_post_set_memory_attributes(struct kvm *kvm, +bool kvm_arch_post_set_memory_attributes(struct kvm_plane *plane, struct kvm_gfn_range *range); =20 static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) { + /* Private/shared is always in plane 0 */ return IS_ENABLED(CONFIG_KVM_PRIVATE_MEM) && kvm_get_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIVATE; } diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index b2aa6bf24d3a..f07102bcaf24 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -642,6 +642,7 @@ EXPORT_SYMBOL_GPL(kvm_gmem_get_pfn); long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src,= long npages, kvm_gmem_populate_cb post_populate, void *opaque) { + struct kvm_plane *plane0 =3D kvm->planes[0]; struct file *file; struct kvm_memory_slot *slot; void __user *p; @@ -694,7 +695,7 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn= , void __user *src, long (npages - i) < (1 << max_order)); =20 ret =3D -EINVAL; - while (!kvm_range_has_memory_attributes(kvm, gfn, gfn + (1 << max_order), + while (!kvm_range_has_memory_attributes(plane0, gfn, gfn + (1 << max_ord= er), KVM_MEMORY_ATTRIBUTE_PRIVATE, KVM_MEMORY_ATTRIBUTE_PRIVATE)) { if (!max_order) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 5b44a7f9e52e..e343905e46d8 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -500,6 +500,7 @@ static inline struct kvm *mmu_notifier_to_kvm(struct mm= u_notifier *mn) } =20 typedef bool (*gfn_handler_t)(struct kvm *kvm, struct kvm_gfn_range *range= ); +typedef bool (*plane_gfn_handler_t)(struct kvm_plane *plane, struct kvm_gf= n_range *range); =20 typedef void (*on_lock_fn_t)(struct kvm *kvm); =20 @@ -511,7 +512,11 @@ struct kvm_mmu_notifier_range { u64 start; u64 end; union kvm_mmu_notifier_arg arg; - gfn_handler_t handler; + /* The only difference is the type of the first parameter. */ + union { + gfn_handler_t handler; + plane_gfn_handler_t handler_plane; + }; on_lock_fn_t on_lock; bool flush_on_ret; bool may_block; @@ -1105,6 +1110,9 @@ static struct kvm_plane *kvm_create_vm_plane(struct k= vm *kvm, unsigned plane_id) plane->kvm =3D kvm; plane->plane =3D plane_id; =20 +#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES + xa_init(&plane->mem_attr_array); +#endif kvm_arch_init_plane(plane); return plane; } @@ -1130,9 +1138,6 @@ static struct kvm *kvm_create_vm(unsigned long type, = const char *fdname) spin_lock_init(&kvm->mn_invalidate_lock); rcuwait_init(&kvm->mn_memslots_update_rcuwait); xa_init(&kvm->vcpu_array); -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES - xa_init(&kvm->mem_attr_array); -#endif =20 INIT_LIST_HEAD(&kvm->gpc_list); spin_lock_init(&kvm->gpc_lock); @@ -1280,6 +1285,10 @@ static void kvm_destroy_devices(struct kvm *kvm) static void kvm_destroy_plane(struct kvm_plane *plane) { kvm_arch_free_plane(plane); + +#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES + xa_destroy(&plane->mem_attr_array); +#endif } =20 static void kvm_destroy_vm(struct kvm *kvm) @@ -1335,9 +1344,6 @@ static void kvm_destroy_vm(struct kvm *kvm) } cleanup_srcu_struct(&kvm->irq_srcu); cleanup_srcu_struct(&kvm->srcu); -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES - xa_destroy(&kvm->mem_attr_array); -#endif for (i =3D 0; i < ARRAY_SIZE(kvm->planes); i++) { struct kvm_plane *plane =3D kvm->planes[i]; if (plane) @@ -2385,9 +2391,9 @@ static int kvm_vm_ioctl_clear_dirty_log(struct kvm *k= vm, #endif /* CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT */ =20 #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES -static u64 kvm_supported_mem_attributes(struct kvm *kvm) +static u64 kvm_supported_mem_attributes(struct kvm_plane *plane) { - if (!kvm || kvm_arch_has_private_mem(kvm)) + if (!plane || (!plane->plane && kvm_arch_has_private_mem(plane->kvm))) return KVM_MEMORY_ATTRIBUTE_PRIVATE; =20 return 0; @@ -2397,19 +2403,20 @@ static u64 kvm_supported_mem_attributes(struct kvm = *kvm) * Returns true if _all_ gfns in the range [@start, @end) have attributes * such that the bits in @mask match @attrs. */ -bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t e= nd, +bool kvm_range_has_memory_attributes(struct kvm_plane *plane, + gfn_t start, gfn_t end, unsigned long mask, unsigned long attrs) { - XA_STATE(xas, &kvm->mem_attr_array, start); + XA_STATE(xas, &plane->mem_attr_array, start); unsigned long index; void *entry; =20 - mask &=3D kvm_supported_mem_attributes(kvm); + mask &=3D kvm_supported_mem_attributes(plane); if (attrs & ~mask) return false; =20 if (end =3D=3D start + 1) - return (kvm_get_memory_attributes(kvm, start) & mask) =3D=3D attrs; + return (kvm_get_plane_memory_attributes(plane, start) & mask) =3D=3D att= rs; =20 guard(rcu)(); if (!attrs) @@ -2428,8 +2435,8 @@ bool kvm_range_has_memory_attributes(struct kvm *kvm,= gfn_t start, gfn_t end, return true; } =20 -static __always_inline void kvm_handle_gfn_range(struct kvm *kvm, - struct kvm_mmu_notifier_range *range) +static __always_inline void __kvm_handle_gfn_range(struct kvm *kvm, void *= arg1, + struct kvm_mmu_notifier_range *range) { struct kvm_gfn_range gfn_range; struct kvm_memory_slot *slot; @@ -2469,7 +2476,7 @@ static __always_inline void kvm_handle_gfn_range(stru= ct kvm *kvm, range->on_lock(kvm); } =20 - ret |=3D range->handler(kvm, &gfn_range); + ret |=3D range->handler(arg1, &gfn_range); } } =20 @@ -2480,7 +2487,19 @@ static __always_inline void kvm_handle_gfn_range(str= uct kvm *kvm, KVM_MMU_UNLOCK(kvm); } =20 -static bool kvm_pre_set_memory_attributes(struct kvm *kvm, +static __always_inline void kvm_handle_gfn_range(struct kvm *kvm, + struct kvm_mmu_notifier_range *range) +{ + __kvm_handle_gfn_range(kvm, kvm, range); +} + +static __always_inline void kvm_plane_handle_gfn_range(struct kvm_plane *p= lane, + struct kvm_mmu_notifier_range *range) +{ + __kvm_handle_gfn_range(plane->kvm, plane, range); +} + +static bool kvm_pre_set_memory_attributes(struct kvm_plane *plane, struct kvm_gfn_range *range) { /* @@ -2494,20 +2513,21 @@ static bool kvm_pre_set_memory_attributes(struct kv= m *kvm, * but it's not obvious that allowing new mappings while the attributes * are in flux is desirable or worth the complexity. */ - kvm_mmu_invalidate_range_add(kvm, range->start, range->end); + kvm_mmu_invalidate_range_add(plane->kvm, range->start, range->end); =20 - return kvm_arch_pre_set_memory_attributes(kvm, range); + return kvm_arch_pre_set_memory_attributes(plane, range); } =20 /* Set @attributes for the gfn range [@start, @end). */ -static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t e= nd, +static int kvm_vm_set_mem_attributes(struct kvm_plane *plane, gfn_t start,= gfn_t end, unsigned long attributes) { + struct kvm *kvm =3D plane->kvm; struct kvm_mmu_notifier_range pre_set_range =3D { .start =3D start, .end =3D end, .arg.attributes =3D attributes, - .handler =3D kvm_pre_set_memory_attributes, + .handler_plane =3D kvm_pre_set_memory_attributes, .on_lock =3D kvm_mmu_invalidate_begin, .flush_on_ret =3D true, .may_block =3D true, @@ -2516,7 +2536,7 @@ static int kvm_vm_set_mem_attributes(struct kvm *kvm,= gfn_t start, gfn_t end, .start =3D start, .end =3D end, .arg.attributes =3D attributes, - .handler =3D kvm_arch_post_set_memory_attributes, + .handler_plane =3D kvm_arch_post_set_memory_attributes, .on_lock =3D kvm_mmu_invalidate_end, .may_block =3D true, }; @@ -2529,7 +2549,7 @@ static int kvm_vm_set_mem_attributes(struct kvm *kvm,= gfn_t start, gfn_t end, mutex_lock(&kvm->slots_lock); =20 /* Nothing to do if the entire range as the desired attributes. */ - if (kvm_range_has_memory_attributes(kvm, start, end, ~0, attributes)) + if (kvm_range_has_memory_attributes(plane, start, end, ~0, attributes)) goto out_unlock; =20 /* @@ -2537,27 +2557,28 @@ static int kvm_vm_set_mem_attributes(struct kvm *kv= m, gfn_t start, gfn_t end, * partway through setting the new attributes. */ for (i =3D start; i < end; i++) { - r =3D xa_reserve(&kvm->mem_attr_array, i, GFP_KERNEL_ACCOUNT); + r =3D xa_reserve(&plane->mem_attr_array, i, GFP_KERNEL_ACCOUNT); if (r) goto out_unlock; } =20 - kvm_handle_gfn_range(kvm, &pre_set_range); + kvm_plane_handle_gfn_range(plane, &pre_set_range); =20 for (i =3D start; i < end; i++) { - r =3D xa_err(xa_store(&kvm->mem_attr_array, i, entry, + r =3D xa_err(xa_store(&plane->mem_attr_array, i, entry, GFP_KERNEL_ACCOUNT)); KVM_BUG_ON(r, kvm); } =20 - kvm_handle_gfn_range(kvm, &post_set_range); + kvm_plane_handle_gfn_range(plane, &post_set_range); =20 out_unlock: mutex_unlock(&kvm->slots_lock); =20 return r; } -static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm, + +static int kvm_vm_ioctl_set_mem_attributes(struct kvm_plane *plane, struct kvm_memory_attributes *attrs) { gfn_t start, end; @@ -2565,7 +2586,7 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm= *kvm, /* flags is currently not used. */ if (attrs->flags) return -EINVAL; - if (attrs->attributes & ~kvm_supported_mem_attributes(kvm)) + if (attrs->attributes & ~kvm_supported_mem_attributes(plane)) return -EINVAL; if (attrs->size =3D=3D 0 || attrs->address + attrs->size < attrs->address) return -EINVAL; @@ -2582,7 +2603,7 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm= *kvm, */ BUILD_BUG_ON(sizeof(attrs->attributes) !=3D sizeof(unsigned long)); =20 - return kvm_vm_set_mem_attributes(kvm, start, end, attrs->attributes); + return kvm_vm_set_mem_attributes(plane, start, end, attrs->attributes); } #endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ =20 @@ -4867,7 +4888,7 @@ static int kvm_vm_ioctl_check_extension_generic(struc= t kvm *kvm, long arg) return 1; #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES case KVM_CAP_MEMORY_ATTRIBUTES: - return kvm_supported_mem_attributes(kvm); + return kvm_supported_mem_attributes(kvm ? kvm->planes[0] : NULL); #endif #ifdef CONFIG_KVM_PRIVATE_MEM case KVM_CAP_GUEST_MEMFD: @@ -5274,7 +5295,7 @@ static long kvm_vm_ioctl(struct file *filp, if (copy_from_user(&attrs, argp, sizeof(attrs))) goto out; =20 - r =3D kvm_vm_ioctl_set_mem_attributes(kvm, &attrs); + r =3D kvm_vm_ioctl_set_mem_attributes(kvm->planes[0], &attrs); break; } #endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 B549320D4F2 for ; Tue, 1 Apr 2025 16:11:31 +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=1743523893; cv=none; b=LAsRuzi8rdThr6KSs55XG3kXiO7g2Fe8GJmlYHhCy/gQMwCcXbYPyIQumM/AlTgAfpOgfZWUVh+RLRW5M/J88EkKFpyTxKvXKJOXYS5RK1+BskkFr1NGPdsZPYgSeHTMFimTvQ4ohrDuhH1Q+FgSIH5ToHUn8t4I0fW3EbFnYmo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523893; c=relaxed/simple; bh=ZfkfOM480M1YBqKpC2/kM72sR6VmePA1K6dauSV8B3s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dC9z8ohrKR2hm3FwVCiHlD2bXNAixvsRNdPzyHBDjNE0CV5J6pCC9gMOfEqDhCYz8BwCABN7wCeDg7AkI9wQHITVL/xlBn4//fLlEB6mVggFflUIYJuqp3fdYR10JPg9RA0Z0RacHNnpFAJIf5s4XDHroRXIvfGJ0mlTVc0SgO4= 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=T7QbLDvG; 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="T7QbLDvG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523890; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KsKBW7BEHbNNA2EQflKemABN/u2ulObIcmH48WXDJ8s=; b=T7QbLDvGMwg8nESFawk9kYozEVXVPArJoRXUQfXRNPfb0X7R2I6gDB5qUnOBS+u1HUziPp rHKiNZ5BnvMppSh86Ht5A6+XVyr1KsOLQSFb/i/0Xr2qcwJrsFvKcW4j2kt9jWHNgAPKiJ ew98ApazTF3fin8qehlWIzvhh1jHeWQ= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-6-jmiAbRM3MyuUNgN_LlSP9g-1; Tue, 01 Apr 2025 12:11:29 -0400 X-MC-Unique: jmiAbRM3MyuUNgN_LlSP9g-1 X-Mimecast-MFC-AGG-ID: jmiAbRM3MyuUNgN_LlSP9g_1743523888 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43ceb011ea5so40935915e9.2 for ; Tue, 01 Apr 2025 09:11:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523887; x=1744128687; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KsKBW7BEHbNNA2EQflKemABN/u2ulObIcmH48WXDJ8s=; b=tnpGB4fINEJadzVZQ9rytUWO14CqT0jqGomcbscpy/+381XG2vCFIBaRx6GA8CXwRp a18XiKk2OkLJyjVp+A6ibPRDEYDRA6TYgBdnUyIT9GEY4svhigzWoSyenvXIcjzakR3x OxfJKfVKYKBjLcXMWHNWLO58LlWnnIo/3dw52tZiZUpQ8K5l8BJNRjF6ZTai2AC8m4xS y6XQmAz4o1ysSWHLnwx83HyzX0Cd8Z7fC4nz3j7qAKZV4l0T4Z+tWKCrfEFfZCoW5V9o KuxoRaz2HIOBMv7U3LjMvC7QOcIXep9q1hM2L+xvQbTWlhE6bG0+D9ULnXbEI8wH18+D fxlg== X-Gm-Message-State: AOJu0YzUneLDkgyzqkqEFPnlEPHspnXc6Oysd540/QdLPYRCW1duj/x4 91qq6R6KSH1GxAA0foKYMCIRaLwnHtYeXz+XpyokyRkVvcFVLnvOaUj+aPqC7+ZMNFSe2zQNF0v rIR8C6e2eHSHGtrm8brlh/qW/iTij85JevVGAnTst5+6aKwE6GNYSaV4SDRElNhbaJY4377Vce4 dUzefyAgW5a7us5e7KXxWt0yY0UewBeeB2v0C06nFSxYuBpQ== X-Gm-Gg: ASbGncvt+AwEmLQqqn4+PmcsiDIhf1q5ilk7AB3t17whRZoG/GtPYSg/ORYWgzdKm3G 8PgrMLw4LrDDjhp7By+yijkhFwS5ZfCxF9vlckg9jwZKUfnWbXemm+62TOHoboE6I66vWArJw/Y cvngnnMuQm6EhaIuKDov+k9v6TmqRzq7V276eL6jwbAbxXEy/P/hSV1c2Uq6hCieoJwiQatA3cG 90DOrQruSa3klEWYtz5Hf/3XawKL7ROA4SZmlbTjkWZsHnkH4pElVBNNpg8yOdB9b4NGM6qzVyy TCObO3khsmG3LOEwKQLPwg== X-Received: by 2002:a05:6000:2410:b0:39c:142a:35f9 with SMTP id ffacd0b85a97d-39c142a35famr11329201f8f.10.1743523887505; Tue, 01 Apr 2025 09:11:27 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEUBBONFMxXubuB0rFZnmFR8I8IBPlykXIOGysFwqjq21RAjnf88FJ3fTcF64SWlqgmRjwgcw== X-Received: by 2002:a05:6000:2410:b0:39c:142a:35f9 with SMTP id ffacd0b85a97d-39c142a35famr11329136f8f.10.1743523887070; Tue, 01 Apr 2025 09:11:27 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b66a9d2sm14476457f8f.43.2025.04.01.09.11.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:25 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 07/29] KVM: do not use online_vcpus to test vCPU validity Date: Tue, 1 Apr 2025 18:10:44 +0200 Message-ID: <20250401161106.790710-8-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Different planes can initialize their vCPUs separately, therefore there is no single online_vcpus value that can be used to test that a vCPU has indeed been fully initialized. Use the shiny new plane field instead, initializing it to an invalid value (-1) while the vCPU is visible in the xarray but may still disappear if the creation fails. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/i8254.c | 3 ++- include/linux/kvm_host.h | 23 ++++++----------------- virt/kvm/kvm_main.c | 20 +++++++++++++------- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index d7ab8780ab9e..e3a3e7b90c26 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -260,9 +260,10 @@ static void pit_do_work(struct kthread_work *work) * VCPUs and only when LVT0 is in NMI mode. The interrupt can * also be simultaneously delivered through PIC and IOAPIC. */ - if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0) + if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0) { kvm_for_each_vcpu(i, vcpu, kvm) kvm_apic_nmi_wd_deliver(vcpu); + } } =20 static enum hrtimer_restart pit_timer_fn(struct hrtimer *data) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 4d408d1d5ccc..0db27814294f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -992,27 +992,16 @@ static inline struct kvm_io_bus *kvm_get_bus(struct k= vm *kvm, enum kvm_bus idx) =20 static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) { - int num_vcpus =3D atomic_read(&kvm->online_vcpus); - - /* - * Explicitly verify the target vCPU is online, as the anti-speculation - * logic only limits the CPU's ability to speculate, e.g. given a "bad" - * index, clamping the index to 0 would return vCPU0, not NULL. - */ - if (i >=3D num_vcpus) + struct kvm_vcpu *vcpu =3D xa_load(&kvm->vcpu_array, i); + if (vcpu && unlikely(vcpu->plane =3D=3D -1)) return NULL; =20 - i =3D array_index_nospec(i, num_vcpus); - - /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ - smp_rmb(); - return xa_load(&kvm->vcpu_array, i); + return vcpu; } =20 -#define kvm_for_each_vcpu(idx, vcpup, kvm) \ - if (atomic_read(&kvm->online_vcpus)) \ - xa_for_each_range(&kvm->vcpu_array, idx, vcpup, 0, \ - (atomic_read(&kvm->online_vcpus) - 1)) +#define kvm_for_each_vcpu(idx, vcpup, kvm) \ + xa_for_each(&kvm->vcpu_array, idx, vcpup) \ + if ((vcpup)->plane =3D=3D -1) ; else \ =20 static inline struct kvm_vcpu *kvm_get_vcpu_by_id(struct kvm *kvm, int id) { diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index e343905e46d8..eba02cb7cc57 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4186,6 +4186,11 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm,= unsigned long id) goto unlock_vcpu_destroy; } =20 + /* + * Store an invalid plane number until fully initialized. xa_insert() has + * release semantics, which ensures the write is visible to kvm_get_vcpu(= ). + */ + vcpu->plane =3D -1; vcpu->vcpu_idx =3D atomic_read(&kvm->online_vcpus); r =3D xa_insert(&kvm->vcpu_array, vcpu->vcpu_idx, vcpu, GFP_KERNEL_ACCOUN= T); WARN_ON_ONCE(r =3D=3D -EBUSY); @@ -4195,7 +4200,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) /* * Now it's all set up, let userspace reach it. Grab the vCPU's mutex * so that userspace can't invoke vCPU ioctl()s until the vCPU is fully - * visible (per online_vcpus), e.g. so that KVM doesn't get tricked + * visible (valid vcpu->plane), e.g. so that KVM doesn't get tricked * into a NULL-pointer dereference because KVM thinks the _current_ * vCPU doesn't exist. As a bonus, taking vcpu->mutex ensures lockdep * knows it's taken *inside* kvm->lock. @@ -4206,12 +4211,13 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm= , unsigned long id) if (r < 0) goto kvm_put_xa_erase; =20 - /* - * Pairs with smp_rmb() in kvm_get_vcpu. Store the vcpu - * pointer before kvm->online_vcpu's incremented value. - */ - smp_wmb(); atomic_inc(&kvm->online_vcpus); + + /* + * Pairs with xa_load() in kvm_get_vcpu, ensuring that online_vcpus + * is updated before vcpu->plane. + */ + smp_store_release(&vcpu->plane, 0); mutex_unlock(&vcpu->mutex); =20 mutex_unlock(&kvm->lock); @@ -4355,7 +4361,7 @@ static int kvm_wait_for_vcpu_online(struct kvm_vcpu *= vcpu) * In practice, this happy path will always be taken, as a well-behaved * VMM will never invoke a vCPU ioctl() before KVM_CREATE_VCPU returns. */ - if (likely(vcpu->vcpu_idx < atomic_read(&kvm->online_vcpus))) + if (likely(vcpu->plane !=3D -1)) return 0; =20 /* --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 37A102147E6 for ; Tue, 1 Apr 2025 16:11:33 +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=1743523895; cv=none; b=C52fxSCUBN1ewGuVuTE/7+VLjAaMpWVyXFSFbNmd2pQ1MB1C4ee7w3xGp0uSwb8LhG4cBLgPk5hz3JjXJKmBvonxK34+kWsovWq35YWEJpk+dQTkWR7Zb1XwMrH2tz8W/4W1CuAwIKublE5DB2Vb5FfxjO0vu9Qqort8Qyre5Ik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523895; c=relaxed/simple; bh=U6yMn8cBq8sVKBGacb4GZasvrwVKcSNV989ya6C5aGg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ezl7ZP1xrDHRAmuPCXCtkr/dmJTLGNJRpqzJi1OeI8zZC59x5a4aeid8WINVZGRYcepG6qgeJN4e8DfEA/evDedKYb6NvULz+xMLZvLKZJnIHsSCNhmh9GFjXgy7ceOMBQxBqOci+JuD++wkyT92po8fm5vnjrKavilDiMKQoFk= 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=LvBP984M; 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="LvBP984M" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523893; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Cb+CmZ3WRWsV/9FrwrAoBArv5drunjdteeEUhGgbJHE=; b=LvBP984MMw6oD1slshN1PSkOrnvyuvjmbebalCi6cCb41yfQ+OPE3mEStrZujdnr+2tOpI 1hRQINxj2XMfuaEefuOE8Lj+zfrp2oJhwuU7/DBVvj54YsGLH7KMkUTPyXyAXP/3wncLec l8R9lGMXzwR5StYTfDK2eVfsafmWXJM= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-670-IwgK8cutP9Cn2J-BtP5gNQ-1; Tue, 01 Apr 2025 12:11:32 -0400 X-MC-Unique: IwgK8cutP9Cn2J-BtP5gNQ-1 X-Mimecast-MFC-AGG-ID: IwgK8cutP9Cn2J-BtP5gNQ_1743523891 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-391315098b2so2512543f8f.2 for ; Tue, 01 Apr 2025 09:11:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523890; x=1744128690; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Cb+CmZ3WRWsV/9FrwrAoBArv5drunjdteeEUhGgbJHE=; b=RjC001sQ/rEIEiys8rdQFaGzRZmdMg9iYWtbTNa6RWmC/cS03GzjwnjUIyNiQsz731 1uEpkhJbsV+Ep/8GhbDnas/tVO/olV7VGROPxJIDAOSS4B5zOav/XWToEGpRSuA0a9eF q2xNzSWqNEY+XXB71oTafEENRok555+mWPmkzwMLRP9XTsPkmwHP1PkIHBhuv3llTrZ3 x1/wu+GbPoq/7LNpxEwerSZfcj9EYluiXOke9lcl25fIvYZzFuAbo9sHScd+O2eaABUt vmn90ZpE0hmSilhQXxObaa8Zmd4cUHf8jFSkWMhSAU4Sl901v/gOl1Gz82jb7WUUjysu plrw== X-Gm-Message-State: AOJu0YynkPHBnepBaAfREpNkBV59YyG5Sz83iopmhBZuLSLO6qthhmxb fb7vrj0HlIk2jPDAqMpVcNjKxg0CdUHffjHnWUcaMLFeyL+v4IRP0mCDBFpKarSVJP58lwUCYGm /A1fM1ab5g/u+Zm/H+yhjKXFFYGD9E0FX78q2k5d6+6ZjUwv50eXJ2r/preQfr4eZG0Y/siTXZN ZH2BcBugZbiJbo526aOWoIQ7nHBdZa3SYKHtiY8/z+DbEwMA== X-Gm-Gg: ASbGncuHoWPy1ZQPlQq0GjdW3io7+P1M0k0ur2Ah/GAigUQwmc9AMEOtWRswBH56orm RbKOG7CI8knsJjp+CbUnNPtV6Rcv2OkchgmDjbIvQRYFOjRqIrfGWJf9H7mNZqk2ry2Bi4gaptT pzHk+9UoXRNZPjZ3nieswt005/yCKLZzP1XtAqJBGd6blbCGKMyKmVIq06ebUy+lzh+8DPTQzIU atFQmnfw7ycRdMyggbPYSyX2kAw/6NmE3gkm4LeU1rQT8lWKTRQrHrZPck2LnO6DHH86yQBaTHZ 4C0EqOyqXeBG2uDCoL9FZQ== X-Received: by 2002:a05:6000:2406:b0:39c:1424:2827 with SMTP id ffacd0b85a97d-39c1424288amr10394887f8f.15.1743523890117; Tue, 01 Apr 2025 09:11:30 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF4bSLgkcclAnLgXImQoVywXonho7NhGNG6jPdFeVRkXIeTp4vzQ53xbuKaIBnWKYfV8gHRsg== X-Received: by 2002:a05:6000:2406:b0:39c:1424:2827 with SMTP id ffacd0b85a97d-39c1424288amr10394829f8f.15.1743523889638; Tue, 01 Apr 2025 09:11:29 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b663617sm14614220f8f.34.2025.04.01.09.11.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:28 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 08/29] KVM: move vcpu_array to struct kvm_plane Date: Tue, 1 Apr 2025 18:10:45 +0200 Message-ID: <20250401161106.790710-9-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Different planes may have only a subset of the vCPUs available in the initial plane, therefore vcpu_array must also be moved to struct kvm_plane. New functions allow accessing the vCPUs of a struct kvm_plane and, as usual, the older names automatically go through kvm->planes[0]. Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 29 +++++++++++++++++++++-------- virt/kvm/kvm_main.c | 22 +++++++++++++++------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 0db27814294f..0a91b556767e 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -763,6 +763,7 @@ struct kvm_memslots { =20 struct kvm_plane { struct kvm *kvm; + struct xarray vcpu_array; #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES /* Protected by slots_locks (for writes) and RCU (for reads) */ struct xarray mem_attr_array; @@ -795,7 +796,6 @@ struct kvm { struct kvm_memslots __memslots[KVM_MAX_NR_ADDRESS_SPACES][2]; /* The current active memslot set for each address space */ struct kvm_memslots __rcu *memslots[KVM_MAX_NR_ADDRESS_SPACES]; - struct xarray vcpu_array; =20 struct kvm_plane *planes[KVM_MAX_VCPU_PLANES]; =20 @@ -990,20 +990,20 @@ static inline struct kvm_io_bus *kvm_get_bus(struct k= vm *kvm, enum kvm_bus idx) !refcount_read(&kvm->users_count)); } =20 -static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) +static inline struct kvm_vcpu *kvm_get_plane_vcpu(struct kvm_plane *plane,= int i) { - struct kvm_vcpu *vcpu =3D xa_load(&kvm->vcpu_array, i); + struct kvm_vcpu *vcpu =3D xa_load(&plane->vcpu_array, i); if (vcpu && unlikely(vcpu->plane =3D=3D -1)) return NULL; =20 return vcpu; } =20 -#define kvm_for_each_vcpu(idx, vcpup, kvm) \ - xa_for_each(&kvm->vcpu_array, idx, vcpup) \ +#define kvm_for_each_plane_vcpu(idx, vcpup, plane_) \ + xa_for_each(&(plane_)->vcpu_array, idx, vcpup) \ if ((vcpup)->plane =3D=3D -1) ; else \ =20 -static inline struct kvm_vcpu *kvm_get_vcpu_by_id(struct kvm *kvm, int id) +static inline struct kvm_vcpu *kvm_get_plane_vcpu_by_id(struct kvm_plane *= plane, int id) { struct kvm_vcpu *vcpu =3D NULL; unsigned long i; @@ -1011,15 +1011,28 @@ static inline struct kvm_vcpu *kvm_get_vcpu_by_id(s= truct kvm *kvm, int id) if (id < 0) return NULL; if (id < KVM_MAX_VCPUS) - vcpu =3D kvm_get_vcpu(kvm, id); + vcpu =3D kvm_get_plane_vcpu(plane, id); if (vcpu && vcpu->vcpu_id =3D=3D id) return vcpu; - kvm_for_each_vcpu(i, vcpu, kvm) + kvm_for_each_plane_vcpu(i, vcpu, plane) if (vcpu->vcpu_id =3D=3D id) return vcpu; return NULL; } =20 +static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) +{ + return kvm_get_plane_vcpu(kvm->planes[0], i); +} + +#define kvm_for_each_vcpu(idx, vcpup, kvm) \ + kvm_for_each_plane_vcpu(idx, vcpup, kvm->planes[0]) + +static inline struct kvm_vcpu *kvm_get_vcpu_by_id(struct kvm *kvm, int id) +{ + return kvm_get_plane_vcpu_by_id(kvm->planes[0], id); +} + void kvm_destroy_vcpus(struct kvm *kvm); =20 void vcpu_load(struct kvm_vcpu *vcpu); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index eba02cb7cc57..cd4dfc399cad 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -481,12 +481,19 @@ static void kvm_vcpu_destroy(struct kvm_vcpu *vcpu) =20 void kvm_destroy_vcpus(struct kvm *kvm) { + int j; unsigned long i; struct kvm_vcpu *vcpu; =20 - kvm_for_each_vcpu(i, vcpu, kvm) { - kvm_vcpu_destroy(vcpu); - xa_erase(&kvm->vcpu_array, i); + for (j =3D ARRAY_SIZE(kvm->planes) - 1; j >=3D 0; j--) { + struct kvm_plane *plane =3D kvm->planes[j]; + if (!plane) + continue; + + kvm_for_each_plane_vcpu(i, vcpu, plane) { + kvm_vcpu_destroy(vcpu); + xa_erase(&plane->vcpu_array, i); + } } =20 atomic_set(&kvm->online_vcpus, 0); @@ -1110,6 +1117,7 @@ static struct kvm_plane *kvm_create_vm_plane(struct k= vm *kvm, unsigned plane_id) plane->kvm =3D kvm; plane->plane =3D plane_id; =20 + xa_init(&plane->vcpu_array); #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES xa_init(&plane->mem_attr_array); #endif @@ -1137,7 +1145,6 @@ static struct kvm *kvm_create_vm(unsigned long type, = const char *fdname) mutex_init(&kvm->slots_arch_lock); spin_lock_init(&kvm->mn_invalidate_lock); rcuwait_init(&kvm->mn_memslots_update_rcuwait); - xa_init(&kvm->vcpu_array); =20 INIT_LIST_HEAD(&kvm->gpc_list); spin_lock_init(&kvm->gpc_lock); @@ -3930,6 +3937,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield= _to_kernel_mode) { int nr_vcpus, start, i, idx, yielded; struct kvm *kvm =3D me->kvm; + struct kvm_plane *plane =3D kvm->planes[me->plane]; struct kvm_vcpu *vcpu; int try =3D 3; =20 @@ -3967,7 +3975,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield= _to_kernel_mode) if (idx =3D=3D me->vcpu_idx) continue; =20 - vcpu =3D xa_load(&kvm->vcpu_array, idx); + vcpu =3D xa_load(&plane->vcpu_array, idx); if (!READ_ONCE(vcpu->ready)) continue; if (kvm_vcpu_is_blocking(vcpu) && !vcpu_dy_runnable(vcpu)) @@ -4192,7 +4200,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) */ vcpu->plane =3D -1; vcpu->vcpu_idx =3D atomic_read(&kvm->online_vcpus); - r =3D xa_insert(&kvm->vcpu_array, vcpu->vcpu_idx, vcpu, GFP_KERNEL_ACCOUN= T); + r =3D xa_insert(&kvm->planes[0]->vcpu_array, vcpu->vcpu_idx, vcpu, GFP_KE= RNEL_ACCOUNT); WARN_ON_ONCE(r =3D=3D -EBUSY); if (r) goto unlock_vcpu_destroy; @@ -4228,7 +4236,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) kvm_put_xa_erase: mutex_unlock(&vcpu->mutex); kvm_put_kvm_no_destroy(kvm); - xa_erase(&kvm->vcpu_array, vcpu->vcpu_idx); + xa_erase(&kvm->planes[0]->vcpu_array, vcpu->vcpu_idx); unlock_vcpu_destroy: mutex_unlock(&kvm->lock); kvm_dirty_ring_free(&vcpu->dirty_ring); --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 4018B2165E4 for ; Tue, 1 Apr 2025 16:11:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523899; cv=none; b=KfgUB1WOrq5xOt5hml8S9hqJXLyP15rSOtQgTs+5b6CAlJkhOfpUxZ6qT0Vev4M9UPXN5jwwi6saq2oZMNWJRmk/98pJQc76oOzYD0jaOU/hjSZxabhUhdwgq81a3OM1y2Xt9NbPAXgkLO7uPSi+9C1rup7qGhdztYFG+q2Njbc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523899; c=relaxed/simple; bh=pIyJCdOg5EfnYtvOavzOlQjVJCjnaMJWsL07IXTnXPc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l2BJ8ij4aM18ntr0x04FqertmSsX4Tqir/z6bOMTShzMKqvyqXl0Yb1jCpG8HZ7UwjWxQJF5EWvuPXuGgQ1npTdUb0giN4vjVmF++ZFD2w9gO0oJWSJ4bAAPCoaQD75j6b3bxGHJj4hQ6V9tLV7kcWu0txW5FAjXuPbl7MrQs0M= 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=DEM2U3/U; arc=none smtp.client-ip=170.10.129.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="DEM2U3/U" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523896; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=P25Au7R1dwmJRVWNgpsYsEFXlIeAhOMlbUwIILW5U9Q=; b=DEM2U3/U3eeO8QNjncAjrysgyTNYgHeOrpTGxDqd6pK0BRwng0Rq3n2qsUdUVMtcZKDi0L dhf1iTzfdS9S2x7TlX/+E2CaItBXve0E8ncpQa8uCO33THRiIoRgWFOMElxd+jppAFJe+p paMtNMaeSKTsd+0CALb4j4cnqjK4xTs= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-113-R1Ko05RoNO-PCmOXPOiWQQ-1; Tue, 01 Apr 2025 12:11:35 -0400 X-MC-Unique: R1Ko05RoNO-PCmOXPOiWQQ-1 X-Mimecast-MFC-AGG-ID: R1Ko05RoNO-PCmOXPOiWQQ_1743523894 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-3978ef9a284so2694248f8f.3 for ; Tue, 01 Apr 2025 09:11:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523893; x=1744128693; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=P25Au7R1dwmJRVWNgpsYsEFXlIeAhOMlbUwIILW5U9Q=; b=RuJiqMhWIUW2mRy7Jv3sFcrIgGYO54JzDF4ir2qGvcdbYjUJUnJ2Kz4HvH7/DFiz1u R2oSEnz5JPXwqp9AjXKZ+vm86+JYKAzMgBaRuIfBDhWj/w2l6n0lPADObkyi+a7rQqqt a/aKnyKE3GWTP4ESqkazLkifvK+TerRBUca31uBxw5FgmSnRBzBqZhyBJkFI3EiJdycR eJEBTDLwEQWTlhrN+t8lB6eFe7bvXckFXLM+6qznIAkfjOx8buIr328J1K/IRQPHMGy/ 3qHN4dRbpDV0GEgPKHwte8W2zbcf78FduE7MQuKE/OjcEgguGwtq72Z+f9mo/aWLuApt bJqA== X-Gm-Message-State: AOJu0Yw4jRLlYMkieDlXMYv+J0PUujNyZnQuqQ19aVdraLOFw/JQt21J dPb78+z3MsrzFEQxMV1AjLW9Imf3H6PLHT93NtzT6Ef2VSSvDOVfEKh6VWpfjc1DvJjjevNLl4J 2QtrYcmqbPvushbMeUWZmqiZ1NnQEAAepJ26AEKobdz0UhQgPO3qbueZguyMwpQk+MccVe/nqlg 5ki6hJ822Zy6kLFyvAA+p/FhjU8cloU8xNrP8ENGPuvsjv5w== X-Gm-Gg: ASbGnctH8dLvd5UpaRO2+82euSki0bOrD5DUiH6Z8FdfzxooV2Nxr2fFI/fzyrM+rSt aTGIhUHXxFSOccalNgU/NjdS1SN731lGmRaEqWpKL0nHOHLX6b4PDOyU7F7hq/N6bKyi1bbwIIa H1zo7Ctm7LHAMjODskt1Fwg/IY9EK8gVwdn6nHMxiIRSLnVNxBWQCohGSZoGLWDeBIj/+KiPodk VUo2x7P0t4zPykkN4IQsgz2YrRK44n59oM1zJxOexjrNvGL43S3p1f7mJ6/4U85Zb54Fr1ec0MX G62n4brKFvyIw3yu5Ke7KA== X-Received: by 2002:a05:6000:2913:b0:391:4ca:490 with SMTP id ffacd0b85a97d-39c120e35d1mr10486580f8f.29.1743523893070; Tue, 01 Apr 2025 09:11:33 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHRUznHPy00F+DVXJZ81FziQ7RotBaykrjs+9d/ucxw73LPo+iiCJX9scu8bMnyNgr21RT/Iw== X-Received: by 2002:a05:6000:2913:b0:391:4ca:490 with SMTP id ffacd0b85a97d-39c120e35d1mr10486516f8f.29.1743523892530; Tue, 01 Apr 2025 09:11:32 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d82efeacasm203836695e9.23.2025.04.01.09.11.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:30 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 09/29] KVM: implement plane file descriptors ioctl and creation Date: Tue, 1 Apr 2025 18:10:46 +0200 Message-ID: <20250401161106.790710-10-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the file_operations for planes, the means to create new file descriptors for them, and the KVM_CHECK_EXTENSION implementation for the two new capabilities. KVM_SIGNAL_MSI and KVM_SET_MEMORY_ATTRIBUTES are now available through both vm and plane file descriptors, forward them to the same function that is used by the file_operations for planes. KVM_CHECK_EXTENSION instead remains separate, because it only advertises a very small subset of capabilities when applied to plane file descriptors. Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 19 +++++ include/uapi/linux/kvm.h | 2 + virt/kvm/kvm_main.c | 154 +++++++++++++++++++++++++++++++++------ 3 files changed, 154 insertions(+), 21 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 0a91b556767e..dbca418d64f5 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -342,6 +342,8 @@ struct kvm_vcpu { unsigned long guest_debug; =20 struct mutex mutex; + + /* Shared for all planes */ struct kvm_run *run; =20 #ifndef __KVM_HAVE_ARCH_WQP @@ -922,6 +924,23 @@ static inline void kvm_vm_bugged(struct kvm *kvm) } =20 =20 +#if KVM_MAX_VCPU_PLANES =3D=3D 1 +static inline int kvm_arch_nr_vcpu_planes(struct kvm *kvm) +{ + return KVM_MAX_VCPU_PLANES; +} + +static inline struct kvm_plane *vcpu_to_plane(struct kvm_vcpu *vcpu) +{ + return vcpu->kvm->planes[0]; +} +#else +static inline struct kvm_plane *vcpu_to_plane(struct kvm_vcpu *vcpu) +{ + return vcpu->kvm->planes[vcpu->plane_id]; +} +#endif + #define KVM_BUG(cond, kvm, fmt...) \ ({ \ bool __ret =3D !!(cond); \ diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index b0cca93ebcb3..96d25c7fa18f 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1690,4 +1690,6 @@ struct kvm_pre_fault_memory { __u64 padding[5]; }; =20 +#define KVM_CREATE_PLANE _IO(KVMIO, 0xd6) + #endif /* __LINUX_KVM_H */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index cd4dfc399cad..b08fea91dc74 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4388,6 +4388,80 @@ static int kvm_wait_for_vcpu_online(struct kvm_vcpu = *vcpu) return 0; } =20 +static int kvm_plane_ioctl_check_extension(struct kvm_plane *plane, long a= rg) +{ + switch (arg) { +#ifdef CONFIG_HAVE_KVM_MSI + case KVM_CAP_SIGNAL_MSI: +#endif + case KVM_CAP_CHECK_EXTENSION_VM: + return 1; +#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES + case KVM_CAP_MEMORY_ATTRIBUTES: + return kvm_supported_mem_attributes(plane); +#endif + default: + return 0; + } +} + +static long __kvm_plane_ioctl(struct kvm_plane *plane, unsigned int ioctl, + unsigned long arg) +{ + void __user *argp =3D (void __user *)arg; + + switch (ioctl) { +#ifdef CONFIG_HAVE_KVM_MSI + case KVM_SIGNAL_MSI: { + struct kvm_msi msi; + + if (copy_from_user(&msi, argp, sizeof(msi))) + return -EFAULT; + return kvm_send_userspace_msi(plane, &msi); + } +#endif +#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES + case KVM_SET_MEMORY_ATTRIBUTES: { + struct kvm_memory_attributes attrs; + + if (copy_from_user(&attrs, argp, sizeof(attrs))) + return -EFAULT; + return kvm_vm_ioctl_set_mem_attributes(plane, &attrs); + } +#endif + case KVM_CHECK_EXTENSION: + return kvm_plane_ioctl_check_extension(plane, arg); + default: + return -ENOTTY; + } +} + +static long kvm_plane_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) +{ + struct kvm_plane *plane =3D filp->private_data; + + if (plane->kvm->mm !=3D current->mm || plane->kvm->vm_dead) + return -EIO; + + return __kvm_plane_ioctl(plane, ioctl, arg); +} + +static int kvm_plane_release(struct inode *inode, struct file *filp) +{ + struct kvm_plane *plane =3D filp->private_data; + + kvm_put_kvm(plane->kvm); + return 0; +} + +static struct file_operations kvm_plane_fops =3D { + .unlocked_ioctl =3D kvm_plane_ioctl, + .release =3D kvm_plane_release, + KVM_COMPAT(kvm_plane_ioctl), +}; + + static long kvm_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -4878,6 +4952,14 @@ static int kvm_vm_ioctl_check_extension_generic(stru= ct kvm *kvm, long arg) if (kvm) return kvm_arch_nr_memslot_as_ids(kvm); return KVM_MAX_NR_ADDRESS_SPACES; +#endif +#if KVM_MAX_VCPU_PLANES > 1 + case KVM_CAP_PLANES: + if (kvm) + return kvm_arch_nr_vcpu_planes(kvm); + return KVM_MAX_PLANES; + case KVM_CAP_PLANES_FPU: + return kvm_arch_planes_share_fpu(kvm); #endif case KVM_CAP_NR_MEMSLOTS: return KVM_USER_MEM_SLOTS; @@ -5112,6 +5194,48 @@ static int kvm_vm_ioctl_get_stats_fd(struct kvm *kvm) return fd; } =20 +static int kvm_vm_ioctl_create_plane(struct kvm *kvm, unsigned id) +{ + struct kvm_plane *plane; + struct file *file; + int r, fd; + + if (id >=3D KVM_MAX_VCPU_PLANES) + return -EINVAL; + + guard(mutex)(&kvm->lock); + if (kvm->planes[id]) + return -EEXIST; + + fd =3D get_unused_fd_flags(O_CLOEXEC); + if (fd < 0) + return fd; + + plane =3D kvm_create_vm_plane(kvm, id); + if (IS_ERR(plane)) { + r =3D PTR_ERR(plane); + goto put_fd; + } + + kvm_get_kvm(kvm); + file =3D anon_inode_getfile("kvm-plane", &kvm_plane_fops, plane, O_RDWR); + if (IS_ERR(file)) { + r =3D PTR_ERR(file); + goto put_kvm; + } + + kvm->planes[id] =3D plane; + fd_install(fd, file); + return fd; + +put_kvm: + kvm_put_kvm(kvm); + kfree(plane); +put_fd: + put_unused_fd(fd); + return r; +} + #define SANITY_CHECK_MEM_REGION_FIELD(field) \ do { \ BUILD_BUG_ON(offsetof(struct kvm_userspace_memory_region, field) !=3D \ @@ -5130,6 +5254,9 @@ static long kvm_vm_ioctl(struct file *filp, if (kvm->mm !=3D current->mm || kvm->vm_dead) return -EIO; switch (ioctl) { + case KVM_CREATE_PLANE: + r =3D kvm_vm_ioctl_create_plane(kvm, arg); + break; case KVM_CREATE_VCPU: r =3D kvm_vm_ioctl_create_vcpu(kvm, arg); break; @@ -5236,16 +5363,12 @@ static long kvm_vm_ioctl(struct file *filp, break; } #ifdef CONFIG_HAVE_KVM_MSI - case KVM_SIGNAL_MSI: { - struct kvm_msi msi; - - r =3D -EFAULT; - if (copy_from_user(&msi, argp, sizeof(msi))) - goto out; - r =3D kvm_send_userspace_msi(kvm->planes[0], &msi); - break; - } + case KVM_SIGNAL_MSI: #endif +#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES + case KVM_SET_MEMORY_ATTRIBUTES: +#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ + return __kvm_plane_ioctl(kvm->planes[0], ioctl, arg); #ifdef __KVM_HAVE_IRQ_LINE case KVM_IRQ_LINE_STATUS: case KVM_IRQ_LINE: { @@ -5301,18 +5424,6 @@ static long kvm_vm_ioctl(struct file *filp, break; } #endif /* CONFIG_HAVE_KVM_IRQ_ROUTING */ -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES - case KVM_SET_MEMORY_ATTRIBUTES: { - struct kvm_memory_attributes attrs; - - r =3D -EFAULT; - if (copy_from_user(&attrs, argp, sizeof(attrs))) - goto out; - - r =3D kvm_vm_ioctl_set_mem_attributes(kvm->planes[0], &attrs); - break; - } -#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ case KVM_CREATE_DEVICE: { struct kvm_create_device cd; =20 @@ -6467,6 +6578,7 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align,= struct module *module) kvm_chardev_ops.owner =3D module; kvm_vm_fops.owner =3D module; kvm_vcpu_fops.owner =3D module; + kvm_plane_fops.owner =3D module; kvm_device_fops.owner =3D module; =20 kvm_preempt_ops.sched_in =3D kvm_sched_in; --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 A5A7621C9F5 for ; Tue, 1 Apr 2025 16:11:45 +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=1743523911; cv=none; b=PVKvk1bmxFe1fVcbXItiCzoM6PTV7vm1Gvxf2W4qbLV4RArVb84I8U3QrwsEXVJDw6cCxs/qyLpGOxhajUcOhOSeQt+dzpPx+a4WlWEv49IhhvRB4rubMw9LDCLtpJbtR50sMeTdaee8Qq5sc+7e9tLe/gJZMZM57Hmfcnh/EfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523911; c=relaxed/simple; bh=kEadPKdm26YjO/piLtcno0OXMST7Rw/BeIh7YNl9zus=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Vn1tDnNb0lNFBKiFAT+QQw2F8/BUEJzVwqbj24odTFwuPV3hvWJCh8U1vE6NbgczXSW0yCFV5Az1rqwUW4cGRlJsRKc/n0egs47a8AHPSZwGHR46TCkH6+YrCZayEEyRiaxf4fuIgt5UISWqOzsg+wf6zb1G5loLPZ1emDaqNkw= 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=gaj+cmUe; 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="gaj+cmUe" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523904; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hCHXVPRRw32Pd1RYLwaglPcIyP0wPV42w+9KPzLStsA=; b=gaj+cmUe9BbcQ3JGu3m/o5tNud6R3zEf1s0nfHsKEgi9hXWyjb+UOCHy2EyFKnh+VM55gx SZu6m+n6YHUcCmK/OQmPgwL/b2CX3mLfCarxQl2H40ymwA2EQeQMBTtm16yjQfu4MBKyRr xk+1tTQkkrKPMP+oVK5kkbcb3VK1iK0= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-150-94YpE4bSMfqrkmBWc3ILVw-1; Tue, 01 Apr 2025 12:11:42 -0400 X-MC-Unique: 94YpE4bSMfqrkmBWc3ILVw-1 X-Mimecast-MFC-AGG-ID: 94YpE4bSMfqrkmBWc3ILVw_1743523901 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43d733063cdso48595355e9.0 for ; Tue, 01 Apr 2025 09:11:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523898; x=1744128698; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hCHXVPRRw32Pd1RYLwaglPcIyP0wPV42w+9KPzLStsA=; b=ADzin4pCw+kjptYg6yKfzoiFnAH7L031HCtyaDq83gXU8hiyNuL6ZI6+1GZGPbhuS+ a7kixe65AXhz+dxVgcMgg94nLWYpVb1ZSvXOjNJl1w/KJeMCkVJF8+/p4UxQGKulszGm 7f3kloAH/VuKOTJcuwZGR0u8I2kzP+IR5YKLMBsUQx7fCNC3iMwrbuY2fACFNzimyFKi Z6kIVYlpIqFmLqF5enIz3mQzC2KmqkKneMlz3Ssmw3v1Ixl7e6hHCxPn5UnJjKTUcR/j OsgACbRTMtJK2mIutKa3VahwFoqikVG2ZSHRfDx0JMI8CbzRXsTst28toRNQhGW1IK5w 277A== X-Gm-Message-State: AOJu0YyKDI9f11ifLy6wAB6Lh3BeymmQ5uGXBkNeoW3O+U5r1n1z3p63 2HaXA2BM/9wYSqyGl5DlXlkNIRsWQkm6/fbHZYUhdxFguZoEaeuxYuXuwvtg0iVhogMMXunIbFe UM4r4A5nD5mGtUMrtkA4dsA8ixBdy15YtMFQTek75SdrKX9kkRYr3PBphws9oRAaLn67z5J0pwE cUFthRyma/9o0bhvzxRwZa9LRI8G3pSih4BLXxfXPXn3gWtQ== X-Gm-Gg: ASbGncsm76wQ4Qac3SYv5dYUv7rVV+f2ZZXP2Y91IdzOFlZLiTw8CqLmaQ89aN8H4f+ BFOa/Cdk/XeyxE7sikvZ7OdvBvzy5TAT0HIEYdrA5sryViXyBK7rRDOZGDm0g9QdUfR3e8W9tMt EgL9qnvNb6C4di3SrzJFoSjp/eT9O1NkdkMiEMmPCQXU4+nqo3Y/QeOwkgccQpzo5ojRHgi2Ffo ql84P6eP+jDJ/zH/Hvc1mF4ZphuLT+zRrwjZyFM9EzbwhS+U9pJNmI9it/+VuBOc1xgJDBEYgsq 3HVNaCmLiZTf2Wj9Uc39Xw== X-Received: by 2002:a05:6000:2910:b0:391:39bd:a381 with SMTP id ffacd0b85a97d-39c120e3eebmr11210988f8f.30.1743523897195; Tue, 01 Apr 2025 09:11:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEqqHlFfEfqmQu9lXk0Qp8CQTjqYvrEJE3OM2uPTiGullHjMI6tXRieoqUgnFZx9Yd8mHv74A== X-Received: by 2002:a05:6000:2910:b0:391:39bd:a381 with SMTP id ffacd0b85a97d-39c120e3eebmr11210831f8f.30.1743523895269; Tue, 01 Apr 2025 09:11:35 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b662c05sm14316291f8f.23.2025.04.01.09.11.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:33 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 10/29] KVM: share statistics for same vCPU id on different planes Date: Tue, 1 Apr 2025 18:10:47 +0200 Message-ID: <20250401161106.790710-11-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Statistics are protected by vcpu->mutex; because KVM_RUN takes the plane-0 vCPU mutex, there is no race on applying statistics for all planes to the plane-0 kvm_vcpu struct. This saves the burden on the kernel of implementing the binary stats interface for vCPU plane file descriptors, and on userspace of gathering info from multiple planes. The disadvantage is a slight loss of information, and an extra pointer dereference when updating stats. Signed-off-by: Paolo Bonzini --- arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/handle_exit.c | 6 +-- arch/arm64/kvm/hyp/nvhe/gen-hyprel.c | 4 +- arch/arm64/kvm/mmio.c | 4 +- arch/loongarch/kvm/exit.c | 8 ++-- arch/loongarch/kvm/vcpu.c | 2 +- arch/mips/kvm/emulate.c | 2 +- arch/mips/kvm/mips.c | 30 +++++++------- arch/mips/kvm/vz.c | 18 ++++----- arch/powerpc/kvm/book3s.c | 2 +- arch/powerpc/kvm/book3s_hv.c | 46 ++++++++++----------- arch/powerpc/kvm/book3s_hv_rm_xics.c | 8 ++-- arch/powerpc/kvm/book3s_pr.c | 22 +++++----- arch/powerpc/kvm/book3s_pr_papr.c | 2 +- arch/powerpc/kvm/powerpc.c | 4 +- arch/powerpc/kvm/timing.h | 28 ++++++------- arch/riscv/kvm/vcpu.c | 2 +- arch/riscv/kvm/vcpu_exit.c | 10 ++--- arch/riscv/kvm/vcpu_insn.c | 16 ++++---- arch/riscv/kvm/vcpu_sbi.c | 2 +- arch/riscv/kvm/vcpu_sbi_hsm.c | 2 +- arch/s390/kvm/diag.c | 18 ++++----- arch/s390/kvm/intercept.c | 20 +++++----- arch/s390/kvm/interrupt.c | 48 +++++++++++----------- arch/s390/kvm/kvm-s390.c | 8 ++-- arch/s390/kvm/priv.c | 60 ++++++++++++++-------------- arch/s390/kvm/sigp.c | 50 +++++++++++------------ arch/s390/kvm/vsie.c | 2 +- arch/x86/kvm/debugfs.c | 2 +- arch/x86/kvm/hyperv.c | 4 +- arch/x86/kvm/kvm_cache_regs.h | 4 +- arch/x86/kvm/mmu/mmu.c | 18 ++++----- arch/x86/kvm/mmu/tdp_mmu.c | 2 +- arch/x86/kvm/svm/sev.c | 2 +- arch/x86/kvm/svm/svm.c | 18 ++++----- arch/x86/kvm/vmx/tdx.c | 8 ++-- arch/x86/kvm/vmx/vmx.c | 20 +++++----- arch/x86/kvm/x86.c | 40 +++++++++---------- include/linux/kvm_host.h | 5 ++- virt/kvm/kvm_main.c | 19 ++++----- 40 files changed, 285 insertions(+), 283 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 0160b4924351..94fae442a8b8 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1187,7 +1187,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) ret =3D kvm_arm_vcpu_enter_exit(vcpu); =20 vcpu->mode =3D OUTSIDE_GUEST_MODE; - vcpu->stat.exits++; + vcpu->stat->exits++; /* * Back from guest *************************************************************/ diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 512d152233ff..b4f69beedd88 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -38,7 +38,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu) { trace_kvm_hvc_arm64(*vcpu_pc(vcpu), vcpu_get_reg(vcpu, 0), kvm_vcpu_hvc_get_imm(vcpu)); - vcpu->stat.hvc_exit_stat++; + vcpu->stat->hvc_exit_stat++; =20 /* Forward hvc instructions to the virtual EL2 if the guest has EL2. */ if (vcpu_has_nv(vcpu)) { @@ -132,10 +132,10 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu) =20 if (esr & ESR_ELx_WFx_ISS_WFE) { trace_kvm_wfx_arm64(*vcpu_pc(vcpu), true); - vcpu->stat.wfe_exit_stat++; + vcpu->stat->wfe_exit_stat++; } else { trace_kvm_wfx_arm64(*vcpu_pc(vcpu), false); - vcpu->stat.wfi_exit_stat++; + vcpu->stat->wfi_exit_stat++; } =20 if (esr & ESR_ELx_WFx_ISS_WFxT) { diff --git a/arch/arm64/kvm/hyp/nvhe/gen-hyprel.c b/arch/arm64/kvm/hyp/nvhe= /gen-hyprel.c index b63f4e1c1033..b7c3f3b8cc26 100644 --- a/arch/arm64/kvm/hyp/nvhe/gen-hyprel.c +++ b/arch/arm64/kvm/hyp/nvhe/gen-hyprel.c @@ -266,7 +266,7 @@ static void init_elf(const char *path) } =20 /* mmap() the entire ELF file read-only at an arbitrary address. */ - elf.begin =3D mmap(0, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + elf.begin =3D mmap(0, stat->st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (elf.begin =3D=3D MAP_FAILED) { close(fd); fatal_perror("Could not mmap ELF file"); @@ -276,7 +276,7 @@ static void init_elf(const char *path) close(fd); =20 /* Get pointer to the ELF header. */ - assert_ge(stat.st_size, sizeof(*elf.ehdr), "%lu"); + assert_ge(stat->st_size, sizeof(*elf.ehdr), "%lu"); elf.ehdr =3D elf_ptr(Elf64_Ehdr, 0); =20 /* Check the ELF magic. */ diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c index ab365e839874..96c5fd5146ba 100644 --- a/arch/arm64/kvm/mmio.c +++ b/arch/arm64/kvm/mmio.c @@ -221,14 +221,14 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t f= ault_ipa) /* We handled the access successfully in the kernel. */ if (!is_write) memcpy(run->mmio.data, data_buf, len); - vcpu->stat.mmio_exit_kernel++; + vcpu->stat->mmio_exit_kernel++; kvm_handle_mmio_return(vcpu); return 1; } =20 if (is_write) memcpy(run->mmio.data, data_buf, len); - vcpu->stat.mmio_exit_user++; + vcpu->stat->mmio_exit_user++; run->exit_reason =3D KVM_EXIT_MMIO; return 0; } diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c index ea321403644a..ee5b3673efc8 100644 --- a/arch/loongarch/kvm/exit.c +++ b/arch/loongarch/kvm/exit.c @@ -31,7 +31,7 @@ static int kvm_emu_cpucfg(struct kvm_vcpu *vcpu, larch_in= st inst) =20 rd =3D inst.reg2_format.rd; rj =3D inst.reg2_format.rj; - ++vcpu->stat.cpucfg_exits; + ++vcpu->stat->cpucfg_exits; index =3D vcpu->arch.gprs[rj]; =20 /* @@ -264,7 +264,7 @@ int kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, stru= ct kvm_run *run) =20 int kvm_emu_idle(struct kvm_vcpu *vcpu) { - ++vcpu->stat.idle_exits; + ++vcpu->stat->idle_exits; trace_kvm_exit_idle(vcpu, KVM_TRACE_EXIT_IDLE); =20 if (!kvm_arch_vcpu_runnable(vcpu)) @@ -884,7 +884,7 @@ static int kvm_handle_hypercall(struct kvm_vcpu *vcpu) =20 switch (code) { case KVM_HCALL_SERVICE: - vcpu->stat.hypercall_exits++; + vcpu->stat->hypercall_exits++; kvm_handle_service(vcpu); break; case KVM_HCALL_USER_SERVICE: @@ -893,7 +893,7 @@ static int kvm_handle_hypercall(struct kvm_vcpu *vcpu) break; } =20 - vcpu->stat.hypercall_exits++; + vcpu->stat->hypercall_exits++; vcpu->run->exit_reason =3D KVM_EXIT_HYPERCALL; vcpu->run->hypercall.nr =3D KVM_HCALL_USER_SERVICE; vcpu->run->hypercall.args[0] =3D kvm_read_reg(vcpu, LOONGARCH_GPR_A0); diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 552cde722932..470c79e79281 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -330,7 +330,7 @@ static int kvm_handle_exit(struct kvm_run *run, struct = kvm_vcpu *vcpu) ret =3D kvm_handle_fault(vcpu, ecode); } else { WARN(!intr, "vm exiting with suspicious irq\n"); - ++vcpu->stat.int_exits; + ++vcpu->stat->int_exits; } =20 if (ret =3D=3D RESUME_GUEST) diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index 0feec52222fb..c9f83b500078 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c @@ -947,7 +947,7 @@ enum emulation_result kvm_mips_emul_wait(struct kvm_vcp= u *vcpu) kvm_debug("[%#lx] !!!WAIT!!! (%#lx)\n", vcpu->arch.pc, vcpu->arch.pending_exceptions); =20 - ++vcpu->stat.wait_exits; + ++vcpu->stat->wait_exits; trace_kvm_exit(vcpu, KVM_TRACE_EXIT_WAIT); if (!vcpu->arch.pending_exceptions) { kvm_vz_lose_htimer(vcpu); diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 60b43ea85c12..77637d201699 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -1199,7 +1199,7 @@ static int __kvm_mips_handle_exit(struct kvm_vcpu *vc= pu) case EXCCODE_INT: kvm_debug("[%d]EXCCODE_INT @ %p\n", vcpu->vcpu_id, opc); =20 - ++vcpu->stat.int_exits; + ++vcpu->stat->int_exits; =20 if (need_resched()) cond_resched(); @@ -1210,7 +1210,7 @@ static int __kvm_mips_handle_exit(struct kvm_vcpu *vc= pu) case EXCCODE_CPU: kvm_debug("EXCCODE_CPU: @ PC: %p\n", opc); =20 - ++vcpu->stat.cop_unusable_exits; + ++vcpu->stat->cop_unusable_exits; ret =3D kvm_mips_callbacks->handle_cop_unusable(vcpu); /* XXXKYMA: Might need to return to user space */ if (run->exit_reason =3D=3D KVM_EXIT_IRQ_WINDOW_OPEN) @@ -1218,7 +1218,7 @@ static int __kvm_mips_handle_exit(struct kvm_vcpu *vc= pu) break; =20 case EXCCODE_MOD: - ++vcpu->stat.tlbmod_exits; + ++vcpu->stat->tlbmod_exits; ret =3D kvm_mips_callbacks->handle_tlb_mod(vcpu); break; =20 @@ -1227,7 +1227,7 @@ static int __kvm_mips_handle_exit(struct kvm_vcpu *vc= pu) cause, kvm_read_c0_guest_status(&vcpu->arch.cop0), opc, badvaddr); =20 - ++vcpu->stat.tlbmiss_st_exits; + ++vcpu->stat->tlbmiss_st_exits; ret =3D kvm_mips_callbacks->handle_tlb_st_miss(vcpu); break; =20 @@ -1235,52 +1235,52 @@ static int __kvm_mips_handle_exit(struct kvm_vcpu *= vcpu) kvm_debug("TLB LD fault: cause %#x, PC: %p, BadVaddr: %#lx\n", cause, opc, badvaddr); =20 - ++vcpu->stat.tlbmiss_ld_exits; + ++vcpu->stat->tlbmiss_ld_exits; ret =3D kvm_mips_callbacks->handle_tlb_ld_miss(vcpu); break; =20 case EXCCODE_ADES: - ++vcpu->stat.addrerr_st_exits; + ++vcpu->stat->addrerr_st_exits; ret =3D kvm_mips_callbacks->handle_addr_err_st(vcpu); break; =20 case EXCCODE_ADEL: - ++vcpu->stat.addrerr_ld_exits; + ++vcpu->stat->addrerr_ld_exits; ret =3D kvm_mips_callbacks->handle_addr_err_ld(vcpu); break; =20 case EXCCODE_SYS: - ++vcpu->stat.syscall_exits; + ++vcpu->stat->syscall_exits; ret =3D kvm_mips_callbacks->handle_syscall(vcpu); break; =20 case EXCCODE_RI: - ++vcpu->stat.resvd_inst_exits; + ++vcpu->stat->resvd_inst_exits; ret =3D kvm_mips_callbacks->handle_res_inst(vcpu); break; =20 case EXCCODE_BP: - ++vcpu->stat.break_inst_exits; + ++vcpu->stat->break_inst_exits; ret =3D kvm_mips_callbacks->handle_break(vcpu); break; =20 case EXCCODE_TR: - ++vcpu->stat.trap_inst_exits; + ++vcpu->stat->trap_inst_exits; ret =3D kvm_mips_callbacks->handle_trap(vcpu); break; =20 case EXCCODE_MSAFPE: - ++vcpu->stat.msa_fpe_exits; + ++vcpu->stat->msa_fpe_exits; ret =3D kvm_mips_callbacks->handle_msa_fpe(vcpu); break; =20 case EXCCODE_FPE: - ++vcpu->stat.fpe_exits; + ++vcpu->stat->fpe_exits; ret =3D kvm_mips_callbacks->handle_fpe(vcpu); break; =20 case EXCCODE_MSADIS: - ++vcpu->stat.msa_disabled_exits; + ++vcpu->stat->msa_disabled_exits; ret =3D kvm_mips_callbacks->handle_msa_disabled(vcpu); break; =20 @@ -1317,7 +1317,7 @@ static int __kvm_mips_handle_exit(struct kvm_vcpu *vc= pu) if (signal_pending(current)) { run->exit_reason =3D KVM_EXIT_INTR; ret =3D (-EINTR << 2) | RESUME_HOST; - ++vcpu->stat.signal_exits; + ++vcpu->stat->signal_exits; trace_kvm_exit(vcpu, KVM_TRACE_EXIT_SIGNAL); } } diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c index ccab4d76b126..c37fd7b3e608 100644 --- a/arch/mips/kvm/vz.c +++ b/arch/mips/kvm/vz.c @@ -1162,7 +1162,7 @@ static enum emulation_result kvm_vz_gpsi_lwc2(union m= ips_instruction inst, rd =3D inst.loongson3_lscsr_format.rd; switch (inst.loongson3_lscsr_format.fr) { case 0x8: /* Read CPUCFG */ - ++vcpu->stat.vz_cpucfg_exits; + ++vcpu->stat->vz_cpucfg_exits; hostcfg =3D read_cpucfg(vcpu->arch.gprs[rs]); =20 switch (vcpu->arch.gprs[rs]) { @@ -1491,38 +1491,38 @@ static int kvm_trap_vz_handle_guest_exit(struct kvm= _vcpu *vcpu) trace_kvm_exit(vcpu, KVM_TRACE_EXIT_GEXCCODE_BASE + gexccode); switch (gexccode) { case MIPS_GCTL0_GEXC_GPSI: - ++vcpu->stat.vz_gpsi_exits; + ++vcpu->stat->vz_gpsi_exits; er =3D kvm_trap_vz_handle_gpsi(cause, opc, vcpu); break; case MIPS_GCTL0_GEXC_GSFC: - ++vcpu->stat.vz_gsfc_exits; + ++vcpu->stat->vz_gsfc_exits; er =3D kvm_trap_vz_handle_gsfc(cause, opc, vcpu); break; case MIPS_GCTL0_GEXC_HC: - ++vcpu->stat.vz_hc_exits; + ++vcpu->stat->vz_hc_exits; er =3D kvm_trap_vz_handle_hc(cause, opc, vcpu); break; case MIPS_GCTL0_GEXC_GRR: - ++vcpu->stat.vz_grr_exits; + ++vcpu->stat->vz_grr_exits; er =3D kvm_trap_vz_no_handler_guest_exit(gexccode, cause, opc, vcpu); break; case MIPS_GCTL0_GEXC_GVA: - ++vcpu->stat.vz_gva_exits; + ++vcpu->stat->vz_gva_exits; er =3D kvm_trap_vz_no_handler_guest_exit(gexccode, cause, opc, vcpu); break; case MIPS_GCTL0_GEXC_GHFC: - ++vcpu->stat.vz_ghfc_exits; + ++vcpu->stat->vz_ghfc_exits; er =3D kvm_trap_vz_handle_ghfc(cause, opc, vcpu); break; case MIPS_GCTL0_GEXC_GPA: - ++vcpu->stat.vz_gpa_exits; + ++vcpu->stat->vz_gpa_exits; er =3D kvm_trap_vz_no_handler_guest_exit(gexccode, cause, opc, vcpu); break; default: - ++vcpu->stat.vz_resvd_exits; + ++vcpu->stat->vz_resvd_exits; er =3D kvm_trap_vz_no_handler_guest_exit(gexccode, cause, opc, vcpu); break; diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index d79c5d1098c0..7ea6955cd96c 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -178,7 +178,7 @@ void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcp= u, =20 void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec) { - vcpu->stat.queue_intr++; + vcpu->stat->queue_intr++; =20 set_bit(kvmppc_book3s_vec2irqprio(vec), &vcpu->arch.pending_exceptions); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 86bff159c51e..6e94ffc0bb6b 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -238,7 +238,7 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *v= cpu) =20 waitp =3D kvm_arch_vcpu_get_wait(vcpu); if (rcuwait_wake_up(waitp)) - ++vcpu->stat.generic.halt_wakeup; + ++vcpu->stat->generic.halt_wakeup; =20 cpu =3D READ_ONCE(vcpu->arch.thread_cpu); if (cpu >=3D 0 && kvmppc_ipi_thread(cpu)) @@ -1633,7 +1633,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcp= u, struct kvm_run *run =3D vcpu->run; int r =3D RESUME_HOST; =20 - vcpu->stat.sum_exits++; + vcpu->stat->sum_exits++; =20 /* * This can happen if an interrupt occurs in the last stages @@ -1662,13 +1662,13 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *v= cpu, vcpu->arch.trap =3D BOOK3S_INTERRUPT_HV_DECREMENTER; fallthrough; case BOOK3S_INTERRUPT_HV_DECREMENTER: - vcpu->stat.dec_exits++; + vcpu->stat->dec_exits++; r =3D RESUME_GUEST; break; case BOOK3S_INTERRUPT_EXTERNAL: case BOOK3S_INTERRUPT_H_DOORBELL: case BOOK3S_INTERRUPT_H_VIRT: - vcpu->stat.ext_intr_exits++; + vcpu->stat->ext_intr_exits++; r =3D RESUME_GUEST; break; /* SR/HMI/PMI are HV interrupts that host has handled. Resume guest.*/ @@ -1971,7 +1971,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu = *vcpu) int r; int srcu_idx; =20 - vcpu->stat.sum_exits++; + vcpu->stat->sum_exits++; =20 /* * This can happen if an interrupt occurs in the last stages @@ -1992,22 +1992,22 @@ static int kvmppc_handle_nested_exit(struct kvm_vcp= u *vcpu) switch (vcpu->arch.trap) { /* We're good on these - the host merely wanted to get our attention */ case BOOK3S_INTERRUPT_HV_DECREMENTER: - vcpu->stat.dec_exits++; + vcpu->stat->dec_exits++; r =3D RESUME_GUEST; break; case BOOK3S_INTERRUPT_EXTERNAL: - vcpu->stat.ext_intr_exits++; + vcpu->stat->ext_intr_exits++; r =3D RESUME_HOST; break; case BOOK3S_INTERRUPT_H_DOORBELL: case BOOK3S_INTERRUPT_H_VIRT: - vcpu->stat.ext_intr_exits++; + vcpu->stat->ext_intr_exits++; r =3D RESUME_GUEST; break; /* These need to go to the nested HV */ case BOOK3S_INTERRUPT_NESTED_HV_DECREMENTER: vcpu->arch.trap =3D BOOK3S_INTERRUPT_HV_DECREMENTER; - vcpu->stat.dec_exits++; + vcpu->stat->dec_exits++; r =3D RESUME_HOST; break; /* SR/HMI/PMI are HV interrupts that host has handled. Resume guest.*/ @@ -4614,7 +4614,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore = *vc) cur =3D start_poll =3D ktime_get(); if (vc->halt_poll_ns) { ktime_t stop =3D ktime_add_ns(start_poll, vc->halt_poll_ns); - ++vc->runner->stat.generic.halt_attempted_poll; + ++vc->runner->stat->generic.halt_attempted_poll; =20 vc->vcore_state =3D VCORE_POLLING; spin_unlock(&vc->lock); @@ -4631,7 +4631,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore = *vc) vc->vcore_state =3D VCORE_INACTIVE; =20 if (!do_sleep) { - ++vc->runner->stat.generic.halt_successful_poll; + ++vc->runner->stat->generic.halt_successful_poll; goto out; } } @@ -4643,7 +4643,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore = *vc) do_sleep =3D 0; /* If we polled, count this as a successful poll */ if (vc->halt_poll_ns) - ++vc->runner->stat.generic.halt_successful_poll; + ++vc->runner->stat->generic.halt_successful_poll; goto out; } =20 @@ -4657,7 +4657,7 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore = *vc) spin_lock(&vc->lock); vc->vcore_state =3D VCORE_INACTIVE; trace_kvmppc_vcore_blocked(vc->runner, 1); - ++vc->runner->stat.halt_successful_wait; + ++vc->runner->stat->halt_successful_wait; =20 cur =3D ktime_get(); =20 @@ -4666,29 +4666,29 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcor= e *vc) =20 /* Attribute wait time */ if (do_sleep) { - vc->runner->stat.generic.halt_wait_ns +=3D + vc->runner->stat->generic.halt_wait_ns +=3D ktime_to_ns(cur) - ktime_to_ns(start_wait); KVM_STATS_LOG_HIST_UPDATE( - vc->runner->stat.generic.halt_wait_hist, + vc->runner->stat->generic.halt_wait_hist, ktime_to_ns(cur) - ktime_to_ns(start_wait)); /* Attribute failed poll time */ if (vc->halt_poll_ns) { - vc->runner->stat.generic.halt_poll_fail_ns +=3D + vc->runner->stat->generic.halt_poll_fail_ns +=3D ktime_to_ns(start_wait) - ktime_to_ns(start_poll); KVM_STATS_LOG_HIST_UPDATE( - vc->runner->stat.generic.halt_poll_fail_hist, + vc->runner->stat->generic.halt_poll_fail_hist, ktime_to_ns(start_wait) - ktime_to_ns(start_poll)); } } else { /* Attribute successful poll time */ if (vc->halt_poll_ns) { - vc->runner->stat.generic.halt_poll_success_ns +=3D + vc->runner->stat->generic.halt_poll_success_ns +=3D ktime_to_ns(cur) - ktime_to_ns(start_poll); KVM_STATS_LOG_HIST_UPDATE( - vc->runner->stat.generic.halt_poll_success_hist, + vc->runner->stat->generic.halt_poll_success_hist, ktime_to_ns(cur) - ktime_to_ns(start_poll)); } } @@ -4807,7 +4807,7 @@ static int kvmppc_run_vcpu(struct kvm_vcpu *vcpu) kvmppc_core_prepare_to_enter(v); if (signal_pending(v->arch.run_task)) { kvmppc_remove_runnable(vc, v, mftb()); - v->stat.signal_exits++; + v->stat->signal_exits++; v->run->exit_reason =3D KVM_EXIT_INTR; v->arch.ret =3D -EINTR; wake_up(&v->arch.cpu_run); @@ -4848,7 +4848,7 @@ static int kvmppc_run_vcpu(struct kvm_vcpu *vcpu) =20 if (vcpu->arch.state =3D=3D KVMPPC_VCPU_RUNNABLE) { kvmppc_remove_runnable(vc, vcpu, mftb()); - vcpu->stat.signal_exits++; + vcpu->stat->signal_exits++; run->exit_reason =3D KVM_EXIT_INTR; vcpu->arch.ret =3D -EINTR; } @@ -5047,7 +5047,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 = time_limit, for (;;) { set_current_state(TASK_INTERRUPTIBLE); if (signal_pending(current)) { - vcpu->stat.signal_exits++; + vcpu->stat->signal_exits++; run->exit_reason =3D KVM_EXIT_INTR; vcpu->arch.ret =3D -EINTR; break; @@ -5070,7 +5070,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 = time_limit, return vcpu->arch.ret; =20 sigpend: - vcpu->stat.signal_exits++; + vcpu->stat->signal_exits++; run->exit_reason =3D KVM_EXIT_INTR; vcpu->arch.ret =3D -EINTR; out: diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s= _hv_rm_xics.c index f2636414d82a..59f740a88581 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c @@ -132,7 +132,7 @@ static void icp_rm_set_vcpu_irq(struct kvm_vcpu *vcpu, int hcore; =20 /* Mark the target VCPU as having an interrupt pending */ - vcpu->stat.queue_intr++; + vcpu->stat->queue_intr++; set_bit(BOOK3S_IRQPRIO_EXTERNAL, &vcpu->arch.pending_exceptions); =20 /* Kick self ? Just set MER and return */ @@ -713,14 +713,14 @@ static int ics_rm_eoi(struct kvm_vcpu *vcpu, u32 irq) =20 /* Handle passthrough interrupts */ if (state->host_irq) { - ++vcpu->stat.pthru_all; + ++vcpu->stat->pthru_all; if (state->intr_cpu !=3D -1) { int pcpu =3D raw_smp_processor_id(); =20 pcpu =3D cpu_first_thread_sibling(pcpu); - ++vcpu->stat.pthru_host; + ++vcpu->stat->pthru_host; if (state->intr_cpu !=3D pcpu) { - ++vcpu->stat.pthru_bad_aff; + ++vcpu->stat->pthru_bad_aff; xics_opal_set_server(state->host_irq, pcpu); } state->intr_cpu =3D -1; diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 83bcdc80ce51..8cbf7ecc796d 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -493,7 +493,7 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u6= 4 msr) if (msr & MSR_POW) { if (!vcpu->arch.pending_exceptions) { kvm_vcpu_halt(vcpu); - vcpu->stat.generic.halt_wakeup++; + vcpu->stat->generic.halt_wakeup++; =20 /* Unset POW bit after we woke up */ msr &=3D ~MSR_POW; @@ -776,13 +776,13 @@ static int kvmppc_handle_pagefault(struct kvm_vcpu *v= cpu, return RESUME_HOST; } if (data) - vcpu->stat.sp_storage++; + vcpu->stat->sp_storage++; else if (vcpu->arch.mmu.is_dcbz32(vcpu) && (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) kvmppc_patch_dcbz(vcpu, &pte); } else { /* MMIO */ - vcpu->stat.mmio_exits++; + vcpu->stat->mmio_exits++; vcpu->arch.paddr_accessed =3D pte.raddr; vcpu->arch.vaddr_accessed =3D pte.eaddr; r =3D kvmppc_emulate_mmio(vcpu); @@ -1103,7 +1103,7 @@ static int kvmppc_exit_pr_progint(struct kvm_vcpu *vc= pu, unsigned int exit_nr) } } =20 - vcpu->stat.emulated_inst_exits++; + vcpu->stat->emulated_inst_exits++; er =3D kvmppc_emulate_instruction(vcpu); switch (er) { case EMULATE_DONE: @@ -1138,7 +1138,7 @@ int kvmppc_handle_exit_pr(struct kvm_vcpu *vcpu, unsi= gned int exit_nr) int r =3D RESUME_HOST; int s; =20 - vcpu->stat.sum_exits++; + vcpu->stat->sum_exits++; =20 run->exit_reason =3D KVM_EXIT_UNKNOWN; run->ready_for_interrupt_injection =3D 1; @@ -1152,7 +1152,7 @@ int kvmppc_handle_exit_pr(struct kvm_vcpu *vcpu, unsi= gned int exit_nr) case BOOK3S_INTERRUPT_INST_STORAGE: { ulong shadow_srr1 =3D vcpu->arch.shadow_srr1; - vcpu->stat.pf_instruc++; + vcpu->stat->pf_instruc++; =20 if (kvmppc_is_split_real(vcpu)) kvmppc_fixup_split_real(vcpu); @@ -1180,7 +1180,7 @@ int kvmppc_handle_exit_pr(struct kvm_vcpu *vcpu, unsi= gned int exit_nr) int idx =3D srcu_read_lock(&vcpu->kvm->srcu); r =3D kvmppc_handle_pagefault(vcpu, kvmppc_get_pc(vcpu), exit_nr); srcu_read_unlock(&vcpu->kvm->srcu, idx); - vcpu->stat.sp_instruc++; + vcpu->stat->sp_instruc++; } else if (vcpu->arch.mmu.is_dcbz32(vcpu) && (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) { /* @@ -1201,7 +1201,7 @@ int kvmppc_handle_exit_pr(struct kvm_vcpu *vcpu, unsi= gned int exit_nr) { ulong dar =3D kvmppc_get_fault_dar(vcpu); u32 fault_dsisr =3D vcpu->arch.fault_dsisr; - vcpu->stat.pf_storage++; + vcpu->stat->pf_storage++; =20 #ifdef CONFIG_PPC_BOOK3S_32 /* We set segments as unused segments when invalidating them. So @@ -1256,13 +1256,13 @@ int kvmppc_handle_exit_pr(struct kvm_vcpu *vcpu, un= signed int exit_nr) case BOOK3S_INTERRUPT_HV_DECREMENTER: case BOOK3S_INTERRUPT_DOORBELL: case BOOK3S_INTERRUPT_H_DOORBELL: - vcpu->stat.dec_exits++; + vcpu->stat->dec_exits++; r =3D RESUME_GUEST; break; case BOOK3S_INTERRUPT_EXTERNAL: case BOOK3S_INTERRUPT_EXTERNAL_HV: case BOOK3S_INTERRUPT_H_VIRT: - vcpu->stat.ext_intr_exits++; + vcpu->stat->ext_intr_exits++; r =3D RESUME_GUEST; break; case BOOK3S_INTERRUPT_HMI: @@ -1331,7 +1331,7 @@ int kvmppc_handle_exit_pr(struct kvm_vcpu *vcpu, unsi= gned int exit_nr) r =3D RESUME_GUEST; } else { /* Guest syscalls */ - vcpu->stat.syscall_exits++; + vcpu->stat->syscall_exits++; kvmppc_book3s_queue_irqprio(vcpu, exit_nr); r =3D RESUME_GUEST; } diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr= _papr.c index b2c89e850d7a..8f007a86de40 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c @@ -393,7 +393,7 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cm= d) case H_CEDE: kvmppc_set_msr_fast(vcpu, kvmppc_get_msr(vcpu) | MSR_EE); kvm_vcpu_halt(vcpu); - vcpu->stat.generic.halt_wakeup++; + vcpu->stat->generic.halt_wakeup++; return EMULATE_DONE; case H_LOGICAL_CI_LOAD: return kvmppc_h_pr_logical_ci_load(vcpu); diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index ce1d91eed231..a39919dbaffb 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -352,7 +352,7 @@ int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int = size, void *ptr, struct kvmppc_pte pte; int r =3D -EINVAL; =20 - vcpu->stat.st++; + vcpu->stat->st++; =20 if (vcpu->kvm->arch.kvm_ops && vcpu->kvm->arch.kvm_ops->store_to_eaddr) r =3D vcpu->kvm->arch.kvm_ops->store_to_eaddr(vcpu, eaddr, ptr, @@ -395,7 +395,7 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int = size, void *ptr, struct kvmppc_pte pte; int rc =3D -EINVAL; =20 - vcpu->stat.ld++; + vcpu->stat->ld++; =20 if (vcpu->kvm->arch.kvm_ops && vcpu->kvm->arch.kvm_ops->load_from_eaddr) rc =3D vcpu->kvm->arch.kvm_ops->load_from_eaddr(vcpu, eaddr, ptr, diff --git a/arch/powerpc/kvm/timing.h b/arch/powerpc/kvm/timing.h index 45817ab82bb4..529f32e7aaf1 100644 --- a/arch/powerpc/kvm/timing.h +++ b/arch/powerpc/kvm/timing.h @@ -45,46 +45,46 @@ static inline void kvmppc_account_exit_stat(struct kvm_= vcpu *vcpu, int type) */ switch (type) { case EXT_INTR_EXITS: - vcpu->stat.ext_intr_exits++; + vcpu->stat->ext_intr_exits++; break; case DEC_EXITS: - vcpu->stat.dec_exits++; + vcpu->stat->dec_exits++; break; case EMULATED_INST_EXITS: - vcpu->stat.emulated_inst_exits++; + vcpu->stat->emulated_inst_exits++; break; case DSI_EXITS: - vcpu->stat.dsi_exits++; + vcpu->stat->dsi_exits++; break; case ISI_EXITS: - vcpu->stat.isi_exits++; + vcpu->stat->isi_exits++; break; case SYSCALL_EXITS: - vcpu->stat.syscall_exits++; + vcpu->stat->syscall_exits++; break; case DTLB_REAL_MISS_EXITS: - vcpu->stat.dtlb_real_miss_exits++; + vcpu->stat->dtlb_real_miss_exits++; break; case DTLB_VIRT_MISS_EXITS: - vcpu->stat.dtlb_virt_miss_exits++; + vcpu->stat->dtlb_virt_miss_exits++; break; case MMIO_EXITS: - vcpu->stat.mmio_exits++; + vcpu->stat->mmio_exits++; break; case ITLB_REAL_MISS_EXITS: - vcpu->stat.itlb_real_miss_exits++; + vcpu->stat->itlb_real_miss_exits++; break; case ITLB_VIRT_MISS_EXITS: - vcpu->stat.itlb_virt_miss_exits++; + vcpu->stat->itlb_virt_miss_exits++; break; case SIGNAL_EXITS: - vcpu->stat.signal_exits++; + vcpu->stat->signal_exits++; break; case DBELL_EXITS: - vcpu->stat.dbell_exits++; + vcpu->stat->dbell_exits++; break; case GDBELL_EXITS: - vcpu->stat.gdbell_exits++; + vcpu->stat->gdbell_exits++; break; } } diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 60d684c76c58..55fb16307cc6 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -967,7 +967,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) kvm_riscv_vcpu_enter_exit(vcpu, &trap); =20 vcpu->mode =3D OUTSIDE_GUEST_MODE; - vcpu->stat.exits++; + vcpu->stat->exits++; =20 /* Syncup interrupts state with HW */ kvm_riscv_vcpu_sync_interrupts(vcpu); diff --git a/arch/riscv/kvm/vcpu_exit.c b/arch/riscv/kvm/vcpu_exit.c index 6e0c18412795..73116dd903e5 100644 --- a/arch/riscv/kvm/vcpu_exit.c +++ b/arch/riscv/kvm/vcpu_exit.c @@ -195,27 +195,27 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct= kvm_run *run, switch (trap->scause) { case EXC_INST_ILLEGAL: kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_ILLEGAL_INSN); - vcpu->stat.instr_illegal_exits++; + vcpu->stat->instr_illegal_exits++; ret =3D vcpu_redirect(vcpu, trap); break; case EXC_LOAD_MISALIGNED: kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_MISALIGNED_LOAD); - vcpu->stat.load_misaligned_exits++; + vcpu->stat->load_misaligned_exits++; ret =3D vcpu_redirect(vcpu, trap); break; case EXC_STORE_MISALIGNED: kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_MISALIGNED_STORE); - vcpu->stat.store_misaligned_exits++; + vcpu->stat->store_misaligned_exits++; ret =3D vcpu_redirect(vcpu, trap); break; case EXC_LOAD_ACCESS: kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_ACCESS_LOAD); - vcpu->stat.load_access_exits++; + vcpu->stat->load_access_exits++; ret =3D vcpu_redirect(vcpu, trap); break; case EXC_STORE_ACCESS: kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_ACCESS_STORE); - vcpu->stat.store_access_exits++; + vcpu->stat->store_access_exits++; ret =3D vcpu_redirect(vcpu, trap); break; case EXC_INST_ACCESS: diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c index 97dec18e6989..43911b8a3f1b 100644 --- a/arch/riscv/kvm/vcpu_insn.c +++ b/arch/riscv/kvm/vcpu_insn.c @@ -201,14 +201,14 @@ void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu) =20 static int wfi_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn) { - vcpu->stat.wfi_exit_stat++; + vcpu->stat->wfi_exit_stat++; kvm_riscv_vcpu_wfi(vcpu); return KVM_INSN_CONTINUE_NEXT_SEPC; } =20 static int wrs_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn) { - vcpu->stat.wrs_exit_stat++; + vcpu->stat->wrs_exit_stat++; kvm_vcpu_on_spin(vcpu, vcpu->arch.guest_context.sstatus & SR_SPP); return KVM_INSN_CONTINUE_NEXT_SEPC; } @@ -335,7 +335,7 @@ static int csr_insn(struct kvm_vcpu *vcpu, struct kvm_r= un *run, ulong insn) if (rc > KVM_INSN_EXIT_TO_USER_SPACE) { if (rc =3D=3D KVM_INSN_CONTINUE_NEXT_SEPC) { run->riscv_csr.ret_value =3D val; - vcpu->stat.csr_exit_kernel++; + vcpu->stat->csr_exit_kernel++; kvm_riscv_vcpu_csr_return(vcpu, run); rc =3D KVM_INSN_CONTINUE_SAME_SEPC; } @@ -345,7 +345,7 @@ static int csr_insn(struct kvm_vcpu *vcpu, struct kvm_r= un *run, ulong insn) =20 /* Exit to user-space for CSR emulation */ if (rc <=3D KVM_INSN_EXIT_TO_USER_SPACE) { - vcpu->stat.csr_exit_user++; + vcpu->stat->csr_exit_user++; run->exit_reason =3D KVM_EXIT_RISCV_CSR; } =20 @@ -576,13 +576,13 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, s= truct kvm_run *run, if (!kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_addr, len, data_buf)) { /* Successfully handled MMIO access in the kernel so resume */ memcpy(run->mmio.data, data_buf, len); - vcpu->stat.mmio_exit_kernel++; + vcpu->stat->mmio_exit_kernel++; kvm_riscv_vcpu_mmio_return(vcpu, run); return 1; } =20 /* Exit to userspace for MMIO emulation */ - vcpu->stat.mmio_exit_user++; + vcpu->stat->mmio_exit_user++; run->exit_reason =3D KVM_EXIT_MMIO; =20 return 0; @@ -709,13 +709,13 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, = struct kvm_run *run, if (!kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_addr, len, run->mmio.data)) { /* Successfully handled MMIO access in the kernel so resume */ - vcpu->stat.mmio_exit_kernel++; + vcpu->stat->mmio_exit_kernel++; kvm_riscv_vcpu_mmio_return(vcpu, run); return 1; } =20 /* Exit to userspace for MMIO emulation */ - vcpu->stat.mmio_exit_user++; + vcpu->stat->mmio_exit_user++; run->exit_reason =3D KVM_EXIT_MMIO; =20 return 0; diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index d1c83a77735e..b500bcaf7b11 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -121,7 +121,7 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, = struct kvm_run *run) struct kvm_cpu_context *cp =3D &vcpu->arch.guest_context; =20 vcpu->arch.sbi_context.return_handled =3D 0; - vcpu->stat.ecall_exit_stat++; + vcpu->stat->ecall_exit_stat++; run->exit_reason =3D KVM_EXIT_RISCV_SBI; run->riscv_sbi.extension_id =3D cp->a7; run->riscv_sbi.function_id =3D cp->a6; diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c index 3070bb31745d..519671760674 100644 --- a/arch/riscv/kvm/vcpu_sbi_hsm.c +++ b/arch/riscv/kvm/vcpu_sbi_hsm.c @@ -82,7 +82,7 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *v= cpu) return SBI_ERR_INVALID_PARAM; if (kvm_riscv_vcpu_stopped(target_vcpu)) return SBI_HSM_STATE_STOPPED; - else if (target_vcpu->stat.generic.blocking) + else if (target_vcpu->stat->generic.blocking) return SBI_HSM_STATE_SUSPENDED; else return SBI_HSM_STATE_STARTED; diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 74f73141f9b9..359d562f7b81 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -24,7 +24,7 @@ static int diag_release_pages(struct kvm_vcpu *vcpu) =20 start =3D vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; end =3D vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + PAGE_SI= ZE; - vcpu->stat.instruction_diagnose_10++; + vcpu->stat->instruction_diagnose_10++; =20 if (start & ~PAGE_MASK || end & ~PAGE_MASK || start >=3D end || start < 2 * PAGE_SIZE) @@ -74,7 +74,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu) =20 VCPU_EVENT(vcpu, 3, "diag page reference parameter block at 0x%llx", vcpu->run->s.regs.gprs[rx]); - vcpu->stat.instruction_diagnose_258++; + vcpu->stat->instruction_diagnose_258++; if (vcpu->run->s.regs.gprs[rx] & 7) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); rc =3D read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(pa= rm)); @@ -145,7 +145,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcp= u) static int __diag_time_slice_end(struct kvm_vcpu *vcpu) { VCPU_EVENT(vcpu, 5, "%s", "diag time slice end"); - vcpu->stat.instruction_diagnose_44++; + vcpu->stat->instruction_diagnose_44++; kvm_vcpu_on_spin(vcpu, true); return 0; } @@ -170,7 +170,7 @@ static int __diag_time_slice_end_directed(struct kvm_vc= pu *vcpu) int tid; =20 tid =3D vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; - vcpu->stat.instruction_diagnose_9c++; + vcpu->stat->instruction_diagnose_9c++; =20 /* yield to self */ if (tid =3D=3D vcpu->vcpu_id) @@ -194,7 +194,7 @@ static int __diag_time_slice_end_directed(struct kvm_vc= pu *vcpu) VCPU_EVENT(vcpu, 5, "diag time slice end directed to %d: yield forwarded", tid); - vcpu->stat.diag_9c_forward++; + vcpu->stat->diag_9c_forward++; return 0; } =20 @@ -205,7 +205,7 @@ static int __diag_time_slice_end_directed(struct kvm_vc= pu *vcpu) return 0; no_yield: VCPU_EVENT(vcpu, 5, "diag time slice end directed to %d: ignored", tid); - vcpu->stat.diag_9c_ignored++; + vcpu->stat->diag_9c_ignored++; return 0; } =20 @@ -215,7 +215,7 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu) unsigned long subcode =3D vcpu->run->s.regs.gprs[reg] & 0xffff; =20 VCPU_EVENT(vcpu, 3, "diag ipl functions, subcode %lx", subcode); - vcpu->stat.instruction_diagnose_308++; + vcpu->stat->instruction_diagnose_308++; switch (subcode) { case 3: vcpu->run->s390_reset_flags =3D KVM_S390_RESET_CLEAR; @@ -247,7 +247,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcp= u) { int ret; =20 - vcpu->stat.instruction_diagnose_500++; + vcpu->stat->instruction_diagnose_500++; /* No virtio-ccw notification? Get out quickly. */ if (!vcpu->kvm->arch.css_support || (vcpu->run->s.regs.gprs[1] !=3D KVM_S390_VIRTIO_CCW_NOTIFY)) @@ -301,7 +301,7 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) case 0x500: return __diag_virtio_hypercall(vcpu); default: - vcpu->stat.instruction_diagnose_other++; + vcpu->stat->instruction_diagnose_other++; return -EOPNOTSUPP; } } diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 610dd44a948b..74d01f67a257 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -57,7 +57,7 @@ static int handle_stop(struct kvm_vcpu *vcpu) int rc =3D 0; uint8_t flags, stop_pending; =20 - vcpu->stat.exit_stop_request++; + vcpu->stat->exit_stop_request++; =20 /* delay the stop if any non-stop irq is pending */ if (kvm_s390_vcpu_has_irq(vcpu, 1)) @@ -93,7 +93,7 @@ static int handle_validity(struct kvm_vcpu *vcpu) { int viwhy =3D vcpu->arch.sie_block->ipb >> 16; =20 - vcpu->stat.exit_validity++; + vcpu->stat->exit_validity++; trace_kvm_s390_intercept_validity(vcpu, viwhy); KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%pK)", viwhy, current->pid, vcpu->kvm); @@ -106,7 +106,7 @@ static int handle_validity(struct kvm_vcpu *vcpu) =20 static int handle_instruction(struct kvm_vcpu *vcpu) { - vcpu->stat.exit_instruction++; + vcpu->stat->exit_instruction++; trace_kvm_s390_intercept_instruction(vcpu, vcpu->arch.sie_block->ipa, vcpu->arch.sie_block->ipb); @@ -249,7 +249,7 @@ static int handle_prog(struct kvm_vcpu *vcpu) psw_t psw; int rc; =20 - vcpu->stat.exit_program_interruption++; + vcpu->stat->exit_program_interruption++; =20 /* * Intercept 8 indicates a loop of specification exceptions @@ -307,7 +307,7 @@ static int handle_external_interrupt(struct kvm_vcpu *v= cpu) psw_t newpsw; int rc; =20 - vcpu->stat.exit_external_interrupt++; + vcpu->stat->exit_external_interrupt++; =20 if (kvm_s390_pv_cpu_is_protected(vcpu)) { newpsw =3D vcpu->arch.sie_block->gpsw; @@ -388,7 +388,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu) =20 static int handle_partial_execution(struct kvm_vcpu *vcpu) { - vcpu->stat.exit_pei++; + vcpu->stat->exit_pei++; =20 if (vcpu->arch.sie_block->ipa =3D=3D 0xb254) /* MVPG */ return handle_mvpg_pei(vcpu); @@ -416,7 +416,7 @@ int handle_sthyi(struct kvm_vcpu *vcpu) code =3D vcpu->run->s.regs.gprs[reg1]; addr =3D vcpu->run->s.regs.gprs[reg2]; =20 - vcpu->stat.instruction_sthyi++; + vcpu->stat->instruction_sthyi++; VCPU_EVENT(vcpu, 3, "STHYI: fc: %llu addr: 0x%016llx", code, addr); trace_kvm_s390_handle_sthyi(vcpu, code, addr); =20 @@ -465,7 +465,7 @@ static int handle_operexc(struct kvm_vcpu *vcpu) psw_t oldpsw, newpsw; int rc; =20 - vcpu->stat.exit_operation_exception++; + vcpu->stat->exit_operation_exception++; trace_kvm_s390_handle_operexc(vcpu, vcpu->arch.sie_block->ipa, vcpu->arch.sie_block->ipb); =20 @@ -609,10 +609,10 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu) =20 switch (vcpu->arch.sie_block->icptcode) { case ICPT_EXTREQ: - vcpu->stat.exit_external_request++; + vcpu->stat->exit_external_request++; return 0; case ICPT_IOREQ: - vcpu->stat.exit_io_request++; + vcpu->stat->exit_io_request++; return 0; case ICPT_INST: rc =3D handle_instruction(vcpu); diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 07ff0e10cb7f..7576df5305c3 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -479,7 +479,7 @@ static int __must_check __deliver_cpu_timer(struct kvm_= vcpu *vcpu) struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; int rc =3D 0; =20 - vcpu->stat.deliver_cputm++; + vcpu->stat->deliver_cputm++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER, 0, 0); if (kvm_s390_pv_cpu_is_protected(vcpu)) { @@ -503,7 +503,7 @@ static int __must_check __deliver_ckc(struct kvm_vcpu *= vcpu) struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; int rc =3D 0; =20 - vcpu->stat.deliver_ckc++; + vcpu->stat->deliver_ckc++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP, 0, 0); if (kvm_s390_pv_cpu_is_protected(vcpu)) { @@ -707,7 +707,7 @@ static int __must_check __deliver_machine_check(struct = kvm_vcpu *vcpu) trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_MCHK, mchk.cr14, mchk.mcic); - vcpu->stat.deliver_machine_check++; + vcpu->stat->deliver_machine_check++; rc =3D __write_machine_check(vcpu, &mchk); } return rc; @@ -719,7 +719,7 @@ static int __must_check __deliver_restart(struct kvm_vc= pu *vcpu) int rc =3D 0; =20 VCPU_EVENT(vcpu, 3, "%s", "deliver: cpu restart"); - vcpu->stat.deliver_restart_signal++; + vcpu->stat->deliver_restart_signal++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); =20 if (kvm_s390_pv_cpu_is_protected(vcpu)) { @@ -746,7 +746,7 @@ static int __must_check __deliver_set_prefix(struct kvm= _vcpu *vcpu) clear_bit(IRQ_PEND_SET_PREFIX, &li->pending_irqs); spin_unlock(&li->lock); =20 - vcpu->stat.deliver_prefix_signal++; + vcpu->stat->deliver_prefix_signal++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_SIGP_SET_PREFIX, prefix.address, 0); @@ -769,7 +769,7 @@ static int __must_check __deliver_emergency_signal(stru= ct kvm_vcpu *vcpu) spin_unlock(&li->lock); =20 VCPU_EVENT(vcpu, 4, "%s", "deliver: sigp emerg"); - vcpu->stat.deliver_emergency_signal++; + vcpu->stat->deliver_emergency_signal++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY, cpu_addr, 0); if (kvm_s390_pv_cpu_is_protected(vcpu)) { @@ -802,7 +802,7 @@ static int __must_check __deliver_external_call(struct = kvm_vcpu *vcpu) spin_unlock(&li->lock); =20 VCPU_EVENT(vcpu, 4, "%s", "deliver: sigp ext call"); - vcpu->stat.deliver_external_call++; + vcpu->stat->deliver_external_call++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_EXTERNAL_CALL, extcall.code, 0); @@ -854,7 +854,7 @@ static int __must_check __deliver_prog(struct kvm_vcpu = *vcpu) ilen =3D pgm_info.flags & KVM_S390_PGM_FLAGS_ILC_MASK; VCPU_EVENT(vcpu, 3, "deliver: program irq code 0x%x, ilen:%d", pgm_info.code, ilen); - vcpu->stat.deliver_program++; + vcpu->stat->deliver_program++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, pgm_info.code, 0); =20 @@ -1004,7 +1004,7 @@ static int __must_check __deliver_service(struct kvm_= vcpu *vcpu) =20 VCPU_EVENT(vcpu, 4, "deliver: sclp parameter 0x%x", ext.ext_params); - vcpu->stat.deliver_service_signal++; + vcpu->stat->deliver_service_signal++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_SERVICE, ext.ext_params, 0); =20 @@ -1028,7 +1028,7 @@ static int __must_check __deliver_service_ev(struct k= vm_vcpu *vcpu) spin_unlock(&fi->lock); =20 VCPU_EVENT(vcpu, 4, "%s", "deliver: sclp parameter event"); - vcpu->stat.deliver_service_signal++; + vcpu->stat->deliver_service_signal++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_SERVICE, ext.ext_params, 0); =20 @@ -1091,7 +1091,7 @@ static int __must_check __deliver_virtio(struct kvm_v= cpu *vcpu) VCPU_EVENT(vcpu, 4, "deliver: virtio parm: 0x%x,parm64: 0x%llx", inti->ext.ext_params, inti->ext.ext_params2); - vcpu->stat.deliver_virtio++; + vcpu->stat->deliver_virtio++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, inti->ext.ext_params, @@ -1177,7 +1177,7 @@ static int __must_check __deliver_io(struct kvm_vcpu = *vcpu, inti->io.subchannel_id >> 1 & 0x3, inti->io.subchannel_nr); =20 - vcpu->stat.deliver_io++; + vcpu->stat->deliver_io++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, ((__u32)inti->io.subchannel_id << 16) | @@ -1205,7 +1205,7 @@ static int __must_check __deliver_io(struct kvm_vcpu = *vcpu, VCPU_EVENT(vcpu, 4, "%s isc %u", "deliver: I/O (AI/gisa)", isc); memset(&io, 0, sizeof(io)); io.io_int_word =3D isc_to_int_word(isc); - vcpu->stat.deliver_io++; + vcpu->stat->deliver_io++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_IO(1, 0, 0, 0), ((__u32)io.subchannel_id << 16) | @@ -1290,7 +1290,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) struct kvm_s390_gisa_interrupt *gi =3D &vcpu->kvm->arch.gisa_int; u64 sltime; =20 - vcpu->stat.exit_wait_state++; + vcpu->stat->exit_wait_state++; =20 /* fast path */ if (kvm_arch_vcpu_runnable(vcpu)) @@ -1476,7 +1476,7 @@ static int __inject_prog(struct kvm_vcpu *vcpu, struc= t kvm_s390_irq *irq) { struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; =20 - vcpu->stat.inject_program++; + vcpu->stat->inject_program++; VCPU_EVENT(vcpu, 3, "inject: program irq code 0x%x", irq->u.pgm.code); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, irq->u.pgm.code, 0); @@ -1518,7 +1518,7 @@ static int __inject_pfault_init(struct kvm_vcpu *vcpu= , struct kvm_s390_irq *irq) { struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; =20 - vcpu->stat.inject_pfault_init++; + vcpu->stat->inject_pfault_init++; VCPU_EVENT(vcpu, 4, "inject: pfault init parameter block at 0x%llx", irq->u.ext.ext_params2); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_PFAULT_INIT, @@ -1537,7 +1537,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, st= ruct kvm_s390_irq *irq) struct kvm_s390_extcall_info *extcall =3D &li->irq.extcall; uint16_t src_id =3D irq->u.extcall.code; =20 - vcpu->stat.inject_external_call++; + vcpu->stat->inject_external_call++; VCPU_EVENT(vcpu, 4, "inject: external call source-cpu:%u", src_id); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EXTERNAL_CALL, @@ -1562,7 +1562,7 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu,= struct kvm_s390_irq *irq) struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; struct kvm_s390_prefix_info *prefix =3D &li->irq.prefix; =20 - vcpu->stat.inject_set_prefix++; + vcpu->stat->inject_set_prefix++; VCPU_EVENT(vcpu, 3, "inject: set prefix to %x", irq->u.prefix.address); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_SET_PREFIX, @@ -1583,7 +1583,7 @@ static int __inject_sigp_stop(struct kvm_vcpu *vcpu, = struct kvm_s390_irq *irq) struct kvm_s390_stop_info *stop =3D &li->irq.stop; int rc =3D 0; =20 - vcpu->stat.inject_stop_signal++; + vcpu->stat->inject_stop_signal++; trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0); =20 if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS) @@ -1607,7 +1607,7 @@ static int __inject_sigp_restart(struct kvm_vcpu *vcp= u) { struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; =20 - vcpu->stat.inject_restart++; + vcpu->stat->inject_restart++; VCPU_EVENT(vcpu, 3, "%s", "inject: restart int"); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); =20 @@ -1620,7 +1620,7 @@ static int __inject_sigp_emergency(struct kvm_vcpu *v= cpu, { struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; =20 - vcpu->stat.inject_emergency_signal++; + vcpu->stat->inject_emergency_signal++; VCPU_EVENT(vcpu, 4, "inject: emergency from cpu %u", irq->u.emerg.code); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY, @@ -1641,7 +1641,7 @@ static int __inject_mchk(struct kvm_vcpu *vcpu, struc= t kvm_s390_irq *irq) struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; struct kvm_s390_mchk_info *mchk =3D &li->irq.mchk; =20 - vcpu->stat.inject_mchk++; + vcpu->stat->inject_mchk++; VCPU_EVENT(vcpu, 3, "inject: machine check mcic 0x%llx", irq->u.mchk.mcic); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_MCHK, 0, @@ -1672,7 +1672,7 @@ static int __inject_ckc(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; =20 - vcpu->stat.inject_ckc++; + vcpu->stat->inject_ckc++; VCPU_EVENT(vcpu, 3, "%s", "inject: clock comparator external"); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP, 0, 0); @@ -1686,7 +1686,7 @@ static int __inject_cpu_timer(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li =3D &vcpu->arch.local_int; =20 - vcpu->stat.inject_cputm++; + vcpu->stat->inject_cputm++; VCPU_EVENT(vcpu, 3, "%s", "inject: cpu timer external"); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER, 0, 0); diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 020502af7dc9..46759021e924 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -4133,7 +4133,7 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu) /* do not poll with more than halt_poll_max_steal percent of steal time */ if (get_lowcore()->avg_steal_timer * 100 / (TICK_USEC << 12) >=3D READ_ONCE(halt_poll_max_steal)) { - vcpu->stat.halt_no_poll_steal++; + vcpu->stat->halt_no_poll_steal++; return true; } return false; @@ -4898,7 +4898,7 @@ int __kvm_s390_handle_dat_fault(struct kvm_vcpu *vcpu= , gfn_t gfn, gpa_t gaddr, u trace_kvm_s390_major_guest_pfault(vcpu); if (kvm_arch_setup_async_pf(vcpu)) return 0; - vcpu->stat.pfault_sync++; + vcpu->stat->pfault_sync++; /* Could not setup async pfault, try again synchronously */ flags &=3D ~FOLL_NOWAIT; goto try_again; @@ -4960,7 +4960,7 @@ static int vcpu_post_run_handle_fault(struct kvm_vcpu= *vcpu) =20 switch (current->thread.gmap_int_code & PGM_INT_CODE_MASK) { case 0: - vcpu->stat.exit_null++; + vcpu->stat->exit_null++; break; case PGM_SECURE_STORAGE_ACCESS: case PGM_SECURE_STORAGE_VIOLATION: @@ -5351,7 +5351,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) =20 kvm_sigset_deactivate(vcpu); =20 - vcpu->stat.exit_userspace++; + vcpu->stat->exit_userspace++; out: vcpu_put(vcpu); return rc; diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 1a49b89706f8..6ff66373f115 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -31,7 +31,7 @@ =20 static int handle_ri(struct kvm_vcpu *vcpu) { - vcpu->stat.instruction_ri++; + vcpu->stat->instruction_ri++; =20 if (test_kvm_facility(vcpu->kvm, 64)) { VCPU_EVENT(vcpu, 3, "%s", "ENABLE: RI (lazy)"); @@ -52,7 +52,7 @@ int kvm_s390_handle_aa(struct kvm_vcpu *vcpu) =20 static int handle_gs(struct kvm_vcpu *vcpu) { - vcpu->stat.instruction_gs++; + vcpu->stat->instruction_gs++; =20 if (test_kvm_facility(vcpu->kvm, 133)) { VCPU_EVENT(vcpu, 3, "%s", "ENABLE: GS (lazy)"); @@ -87,7 +87,7 @@ static int handle_set_clock(struct kvm_vcpu *vcpu) u8 ar; u64 op2; =20 - vcpu->stat.instruction_sck++; + vcpu->stat->instruction_sck++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -126,7 +126,7 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu) int rc; u8 ar; =20 - vcpu->stat.instruction_spx++; + vcpu->stat->instruction_spx++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -164,7 +164,7 @@ static int handle_store_prefix(struct kvm_vcpu *vcpu) int rc; u8 ar; =20 - vcpu->stat.instruction_stpx++; + vcpu->stat->instruction_stpx++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -194,7 +194,7 @@ static int handle_store_cpu_address(struct kvm_vcpu *vc= pu) int rc; u8 ar; =20 - vcpu->stat.instruction_stap++; + vcpu->stat->instruction_stap++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -261,7 +261,7 @@ static int handle_iske(struct kvm_vcpu *vcpu) bool unlocked; int rc; =20 - vcpu->stat.instruction_iske++; + vcpu->stat->instruction_iske++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -308,7 +308,7 @@ static int handle_rrbe(struct kvm_vcpu *vcpu) bool unlocked; int rc; =20 - vcpu->stat.instruction_rrbe++; + vcpu->stat->instruction_rrbe++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -359,7 +359,7 @@ static int handle_sske(struct kvm_vcpu *vcpu) bool unlocked; int rc; =20 - vcpu->stat.instruction_sske++; + vcpu->stat->instruction_sske++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -438,7 +438,7 @@ static int handle_sske(struct kvm_vcpu *vcpu) =20 static int handle_ipte_interlock(struct kvm_vcpu *vcpu) { - vcpu->stat.instruction_ipte_interlock++; + vcpu->stat->instruction_ipte_interlock++; if (psw_bits(vcpu->arch.sie_block->gpsw).pstate) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); wait_event(vcpu->kvm->arch.ipte_wq, !ipte_lock_held(vcpu->kvm)); @@ -452,7 +452,7 @@ static int handle_test_block(struct kvm_vcpu *vcpu) gpa_t addr; int reg2; =20 - vcpu->stat.instruction_tb++; + vcpu->stat->instruction_tb++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -486,7 +486,7 @@ static int handle_tpi(struct kvm_vcpu *vcpu) u64 addr; u8 ar; =20 - vcpu->stat.instruction_tpi++; + vcpu->stat->instruction_tpi++; =20 addr =3D kvm_s390_get_base_disp_s(vcpu, &ar); if (addr & 3) @@ -548,7 +548,7 @@ static int handle_tsch(struct kvm_vcpu *vcpu) struct kvm_s390_interrupt_info *inti =3D NULL; const u64 isc_mask =3D 0xffUL << 24; /* all iscs set */ =20 - vcpu->stat.instruction_tsch++; + vcpu->stat->instruction_tsch++; =20 /* a valid schid has at least one bit set */ if (vcpu->run->s.regs.gprs[1]) @@ -593,7 +593,7 @@ static int handle_io_inst(struct kvm_vcpu *vcpu) if (vcpu->arch.sie_block->ipa =3D=3D 0xb235) return handle_tsch(vcpu); /* Handle in userspace. */ - vcpu->stat.instruction_io_other++; + vcpu->stat->instruction_io_other++; return -EOPNOTSUPP; } else { /* @@ -702,7 +702,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) int rc; unsigned int fac; =20 - vcpu->stat.instruction_stfl++; + vcpu->stat->instruction_stfl++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -751,7 +751,7 @@ int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu) int rc; u8 ar; =20 - vcpu->stat.instruction_lpsw++; + vcpu->stat->instruction_lpsw++; =20 if (gpsw->mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -780,7 +780,7 @@ static int handle_lpswe(struct kvm_vcpu *vcpu) int rc; u8 ar; =20 - vcpu->stat.instruction_lpswe++; + vcpu->stat->instruction_lpswe++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -804,7 +804,7 @@ static int handle_lpswey(struct kvm_vcpu *vcpu) int rc; u8 ar; =20 - vcpu->stat.instruction_lpswey++; + vcpu->stat->instruction_lpswey++; =20 if (!test_kvm_facility(vcpu->kvm, 193)) return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); @@ -834,7 +834,7 @@ static int handle_stidp(struct kvm_vcpu *vcpu) int rc; u8 ar; =20 - vcpu->stat.instruction_stidp++; + vcpu->stat->instruction_stidp++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -900,7 +900,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu) int rc =3D 0; u8 ar; =20 - vcpu->stat.instruction_stsi++; + vcpu->stat->instruction_stsi++; VCPU_EVENT(vcpu, 3, "STSI: fc: %u sel1: %u sel2: %u", fc, sel1, sel2); =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) @@ -1044,7 +1044,7 @@ static int handle_epsw(struct kvm_vcpu *vcpu) { int reg1, reg2; =20 - vcpu->stat.instruction_epsw++; + vcpu->stat->instruction_epsw++; =20 kvm_s390_get_regs_rre(vcpu, ®1, ®2); =20 @@ -1076,7 +1076,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) unsigned long start, end; unsigned char key; =20 - vcpu->stat.instruction_pfmf++; + vcpu->stat->instruction_pfmf++; =20 kvm_s390_get_regs_rre(vcpu, ®1, ®2); =20 @@ -1256,7 +1256,7 @@ static int handle_essa(struct kvm_vcpu *vcpu) =20 VCPU_EVENT(vcpu, 4, "ESSA: release %d pages", entries); gmap =3D vcpu->arch.gmap; - vcpu->stat.instruction_essa++; + vcpu->stat->instruction_essa++; if (!vcpu->kvm->arch.use_cmma) return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); =20 @@ -1345,7 +1345,7 @@ int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu) u64 ga; u8 ar; =20 - vcpu->stat.instruction_lctl++; + vcpu->stat->instruction_lctl++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -1384,7 +1384,7 @@ int kvm_s390_handle_stctl(struct kvm_vcpu *vcpu) u64 ga; u8 ar; =20 - vcpu->stat.instruction_stctl++; + vcpu->stat->instruction_stctl++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -1418,7 +1418,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) u64 ga; u8 ar; =20 - vcpu->stat.instruction_lctlg++; + vcpu->stat->instruction_lctlg++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -1456,7 +1456,7 @@ static int handle_stctg(struct kvm_vcpu *vcpu) u64 ga; u8 ar; =20 - vcpu->stat.instruction_stctg++; + vcpu->stat->instruction_stctg++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -1508,7 +1508,7 @@ static int handle_tprot(struct kvm_vcpu *vcpu) int ret, cc; u8 ar; =20 - vcpu->stat.instruction_tprot++; + vcpu->stat->instruction_tprot++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -1572,7 +1572,7 @@ static int handle_sckpf(struct kvm_vcpu *vcpu) { u32 value; =20 - vcpu->stat.instruction_sckpf++; + vcpu->stat->instruction_sckpf++; =20 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); @@ -1589,7 +1589,7 @@ static int handle_sckpf(struct kvm_vcpu *vcpu) =20 static int handle_ptff(struct kvm_vcpu *vcpu) { - vcpu->stat.instruction_ptff++; + vcpu->stat->instruction_ptff++; =20 /* we don't emulate any control instructions yet */ kvm_s390_set_psw_cc(vcpu, 3); diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 55c34cb35428..79cf7f77fec6 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -306,61 +306,61 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 = order_code, =20 switch (order_code) { case SIGP_SENSE: - vcpu->stat.instruction_sigp_sense++; + vcpu->stat->instruction_sigp_sense++; rc =3D __sigp_sense(vcpu, dst_vcpu, status_reg); break; case SIGP_EXTERNAL_CALL: - vcpu->stat.instruction_sigp_external_call++; + vcpu->stat->instruction_sigp_external_call++; rc =3D __sigp_external_call(vcpu, dst_vcpu, status_reg); break; case SIGP_EMERGENCY_SIGNAL: - vcpu->stat.instruction_sigp_emergency++; + vcpu->stat->instruction_sigp_emergency++; rc =3D __sigp_emergency(vcpu, dst_vcpu); break; case SIGP_STOP: - vcpu->stat.instruction_sigp_stop++; + vcpu->stat->instruction_sigp_stop++; rc =3D __sigp_stop(vcpu, dst_vcpu); break; case SIGP_STOP_AND_STORE_STATUS: - vcpu->stat.instruction_sigp_stop_store_status++; + vcpu->stat->instruction_sigp_stop_store_status++; rc =3D __sigp_stop_and_store_status(vcpu, dst_vcpu, status_reg); break; case SIGP_STORE_STATUS_AT_ADDRESS: - vcpu->stat.instruction_sigp_store_status++; + vcpu->stat->instruction_sigp_store_status++; rc =3D __sigp_store_status_at_addr(vcpu, dst_vcpu, parameter, status_reg); break; case SIGP_SET_PREFIX: - vcpu->stat.instruction_sigp_prefix++; + vcpu->stat->instruction_sigp_prefix++; rc =3D __sigp_set_prefix(vcpu, dst_vcpu, parameter, status_reg); break; case SIGP_COND_EMERGENCY_SIGNAL: - vcpu->stat.instruction_sigp_cond_emergency++; + vcpu->stat->instruction_sigp_cond_emergency++; rc =3D __sigp_conditional_emergency(vcpu, dst_vcpu, parameter, status_reg); break; case SIGP_SENSE_RUNNING: - vcpu->stat.instruction_sigp_sense_running++; + vcpu->stat->instruction_sigp_sense_running++; rc =3D __sigp_sense_running(vcpu, dst_vcpu, status_reg); break; case SIGP_START: - vcpu->stat.instruction_sigp_start++; + vcpu->stat->instruction_sigp_start++; rc =3D __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); break; case SIGP_RESTART: - vcpu->stat.instruction_sigp_restart++; + vcpu->stat->instruction_sigp_restart++; rc =3D __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); break; case SIGP_INITIAL_CPU_RESET: - vcpu->stat.instruction_sigp_init_cpu_reset++; + vcpu->stat->instruction_sigp_init_cpu_reset++; rc =3D __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); break; case SIGP_CPU_RESET: - vcpu->stat.instruction_sigp_cpu_reset++; + vcpu->stat->instruction_sigp_cpu_reset++; rc =3D __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); break; default: - vcpu->stat.instruction_sigp_unknown++; + vcpu->stat->instruction_sigp_unknown++; rc =3D __prepare_sigp_unknown(vcpu, dst_vcpu); } =20 @@ -387,34 +387,34 @@ static int handle_sigp_order_in_user_space(struct kvm= _vcpu *vcpu, u8 order_code, return 0; /* update counters as we're directly dropping to user space */ case SIGP_STOP: - vcpu->stat.instruction_sigp_stop++; + vcpu->stat->instruction_sigp_stop++; break; case SIGP_STOP_AND_STORE_STATUS: - vcpu->stat.instruction_sigp_stop_store_status++; + vcpu->stat->instruction_sigp_stop_store_status++; break; case SIGP_STORE_STATUS_AT_ADDRESS: - vcpu->stat.instruction_sigp_store_status++; + vcpu->stat->instruction_sigp_store_status++; break; case SIGP_STORE_ADDITIONAL_STATUS: - vcpu->stat.instruction_sigp_store_adtl_status++; + vcpu->stat->instruction_sigp_store_adtl_status++; break; case SIGP_SET_PREFIX: - vcpu->stat.instruction_sigp_prefix++; + vcpu->stat->instruction_sigp_prefix++; break; case SIGP_START: - vcpu->stat.instruction_sigp_start++; + vcpu->stat->instruction_sigp_start++; break; case SIGP_RESTART: - vcpu->stat.instruction_sigp_restart++; + vcpu->stat->instruction_sigp_restart++; break; case SIGP_INITIAL_CPU_RESET: - vcpu->stat.instruction_sigp_init_cpu_reset++; + vcpu->stat->instruction_sigp_init_cpu_reset++; break; case SIGP_CPU_RESET: - vcpu->stat.instruction_sigp_cpu_reset++; + vcpu->stat->instruction_sigp_cpu_reset++; break; default: - vcpu->stat.instruction_sigp_unknown++; + vcpu->stat->instruction_sigp_unknown++; } VCPU_EVENT(vcpu, 3, "SIGP: order %u for CPU %d handled in userspace", order_code, cpu_addr); @@ -447,7 +447,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter); switch (order_code) { case SIGP_SET_ARCHITECTURE: - vcpu->stat.instruction_sigp_arch++; + vcpu->stat->instruction_sigp_arch++; rc =3D __sigp_set_arch(vcpu, parameter, &vcpu->run->s.regs.gprs[r1]); break; diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index a78df3a4f353..904a3d84c1b3 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -1456,7 +1456,7 @@ int kvm_s390_handle_vsie(struct kvm_vcpu *vcpu) unsigned long scb_addr; int rc; =20 - vcpu->stat.instruction_sie++; + vcpu->stat->instruction_sie++; if (!test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_SIEF2)) return -EOPNOTSUPP; if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) diff --git a/arch/x86/kvm/debugfs.c b/arch/x86/kvm/debugfs.c index 999227fc7c66..ff31d1bb49ec 100644 --- a/arch/x86/kvm/debugfs.c +++ b/arch/x86/kvm/debugfs.c @@ -24,7 +24,7 @@ DEFINE_SIMPLE_ATTRIBUTE(vcpu_timer_advance_ns_fops, vcpu_= get_timer_advance_ns, N static int vcpu_get_guest_mode(void *data, u64 *val) { struct kvm_vcpu *vcpu =3D (struct kvm_vcpu *) data; - *val =3D vcpu->stat.guest_mode; + *val =3D vcpu->stat->guest_mode; return 0; } =20 diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 6ebeb6cea6c0..c6592e7f40a2 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1988,7 +1988,7 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) for (j =3D 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) kvm_x86_call(flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE); =20 - ++vcpu->stat.tlb_flush; + ++vcpu->stat->tlb_flush; } return 0; =20 @@ -2390,7 +2390,7 @@ static int kvm_hv_hypercall_complete(struct kvm_vcpu = *vcpu, u64 result) =20 trace_kvm_hv_hypercall_done(result); kvm_hv_hypercall_set_result(vcpu, result); - ++vcpu->stat.hypercalls; + ++vcpu->stat->hypercalls; =20 ret =3D kvm_skip_emulated_instruction(vcpu); =20 diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index 36a8786db291..1b9232aad730 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h @@ -225,7 +225,7 @@ static inline u64 kvm_read_edx_eax(struct kvm_vcpu *vcp= u) static inline void enter_guest_mode(struct kvm_vcpu *vcpu) { vcpu->arch.hflags |=3D HF_GUEST_MASK; - vcpu->stat.guest_mode =3D 1; + vcpu->stat->guest_mode =3D 1; } =20 static inline void leave_guest_mode(struct kvm_vcpu *vcpu) @@ -237,7 +237,7 @@ static inline void leave_guest_mode(struct kvm_vcpu *vc= pu) kvm_make_request(KVM_REQ_LOAD_EOI_EXITMAP, vcpu); } =20 - vcpu->stat.guest_mode =3D 0; + vcpu->stat->guest_mode =3D 0; } =20 static inline bool is_guest_mode(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 04e4b041e248..2d8953163fa0 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3014,7 +3014,7 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct= kvm_memory_slot *slot, bool write_fault =3D fault && fault->write; =20 if (unlikely(is_noslot_pfn(pfn))) { - vcpu->stat.pf_mmio_spte_created++; + vcpu->stat->pf_mmio_spte_created++; mark_mmio_spte(vcpu, sptep, gfn, pte_access); return RET_PF_EMULATE; } @@ -3689,7 +3689,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, str= uct kvm_page_fault *fault) walk_shadow_page_lockless_end(vcpu); =20 if (ret !=3D RET_PF_INVALID) - vcpu->stat.pf_fast++; + vcpu->stat->pf_fast++; =20 return ret; } @@ -4446,7 +4446,7 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu,= struct kvm_async_pf *work) * truly spurious and never trigger emulation */ if (r =3D=3D RET_PF_FIXED) - vcpu->stat.pf_fixed++; + vcpu->stat->pf_fixed++; } =20 static inline u8 kvm_max_level_for_order(int order) @@ -6262,7 +6262,7 @@ int noinline kvm_mmu_page_fault(struct kvm_vcpu *vcpu= , gpa_t cr2_or_gpa, u64 err } =20 if (r =3D=3D RET_PF_INVALID) { - vcpu->stat.pf_taken++; + vcpu->stat->pf_taken++; =20 r =3D kvm_mmu_do_page_fault(vcpu, cr2_or_gpa, error_code, false, &emulation_type, NULL); @@ -6278,11 +6278,11 @@ int noinline kvm_mmu_page_fault(struct kvm_vcpu *vc= pu, gpa_t cr2_or_gpa, u64 err &emulation_type); =20 if (r =3D=3D RET_PF_FIXED) - vcpu->stat.pf_fixed++; + vcpu->stat->pf_fixed++; else if (r =3D=3D RET_PF_EMULATE) - vcpu->stat.pf_emulate++; + vcpu->stat->pf_emulate++; else if (r =3D=3D RET_PF_SPURIOUS) - vcpu->stat.pf_spurious++; + vcpu->stat->pf_spurious++; =20 /* * None of handle_mmio_page_fault(), kvm_mmu_do_page_fault(), or @@ -6396,7 +6396,7 @@ void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva) * done here for them. */ kvm_mmu_invalidate_addr(vcpu, vcpu->arch.walk_mmu, gva, KVM_MMU_ROOTS_ALL= ); - ++vcpu->stat.invlpg; + ++vcpu->stat->invlpg; } EXPORT_SYMBOL_GPL(kvm_mmu_invlpg); =20 @@ -6418,7 +6418,7 @@ void kvm_mmu_invpcid_gva(struct kvm_vcpu *vcpu, gva_t= gva, unsigned long pcid) =20 if (roots) kvm_mmu_invalidate_addr(vcpu, mmu, gva, roots); - ++vcpu->stat.invlpg; + ++vcpu->stat->invlpg; =20 /* * Mappings not reachable via the current cr3 or the prev_roots will be diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index b23b1b2e60a8..72f81c99d665 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1181,7 +1181,7 @@ static int tdp_mmu_map_handle_target_level(struct kvm= _vcpu *vcpu, =20 /* If a MMIO SPTE is installed, the MMIO will need to be emulated. */ if (unlikely(is_mmio_spte(vcpu->kvm, new_spte))) { - vcpu->stat.pf_mmio_spte_created++; + vcpu->stat->pf_mmio_spte_created++; trace_mark_mmio_spte(rcu_dereference(iter->sptep), iter->gfn, new_spte); ret =3D RET_PF_EMULATE; diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 0bc708ee2788..827dbe4d2b3b 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -4306,7 +4306,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) svm->sev_es.ghcb_sa); break; case SVM_VMGEXIT_NMI_COMPLETE: - ++vcpu->stat.nmi_window_exits; + ++vcpu->stat->nmi_window_exits; svm->nmi_masked =3D false; kvm_make_request(KVM_REQ_EVENT, vcpu); ret =3D 1; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index f692794d18a2..f6a435ff7e2d 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1577,7 +1577,7 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) =20 svm_prepare_host_switch(vcpu); =20 - ++vcpu->stat.host_state_reload; + ++vcpu->stat->host_state_reload; } =20 static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) @@ -2238,7 +2238,7 @@ static int io_interception(struct kvm_vcpu *vcpu) int size, in, string; unsigned port; =20 - ++vcpu->stat.io_exits; + ++vcpu->stat->io_exits; string =3D (io_info & SVM_IOIO_STR_MASK) !=3D 0; in =3D (io_info & SVM_IOIO_TYPE_MASK) !=3D 0; port =3D io_info >> 16; @@ -2268,7 +2268,7 @@ static int smi_interception(struct kvm_vcpu *vcpu) =20 static int intr_interception(struct kvm_vcpu *vcpu) { - ++vcpu->stat.irq_exits; + ++vcpu->stat->irq_exits; return 1; } =20 @@ -2592,7 +2592,7 @@ static int iret_interception(struct kvm_vcpu *vcpu) =20 WARN_ON_ONCE(sev_es_guest(vcpu->kvm)); =20 - ++vcpu->stat.nmi_window_exits; + ++vcpu->stat->nmi_window_exits; svm->awaiting_iret_completion =3D true; =20 svm_clr_iret_intercept(svm); @@ -3254,7 +3254,7 @@ static int interrupt_window_interception(struct kvm_v= cpu *vcpu) */ kvm_clear_apicv_inhibit(vcpu->kvm, APICV_INHIBIT_REASON_IRQWIN); =20 - ++vcpu->stat.irq_window_exits; + ++vcpu->stat->irq_window_exits; return 1; } =20 @@ -3664,7 +3664,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) svm->nmi_masked =3D true; svm_set_iret_intercept(svm); } - ++vcpu->stat.nmi_injections; + ++vcpu->stat->nmi_injections; } =20 static bool svm_is_vnmi_pending(struct kvm_vcpu *vcpu) @@ -3695,7 +3695,7 @@ static bool svm_set_vnmi_pending(struct kvm_vcpu *vcp= u) * the NMI is "injected", but for all intents and purposes, passing the * NMI off to hardware counts as injection. */ - ++vcpu->stat.nmi_injections; + ++vcpu->stat->nmi_injections; =20 return true; } @@ -3716,7 +3716,7 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu, boo= l reinjected) =20 trace_kvm_inj_virq(vcpu->arch.interrupt.nr, vcpu->arch.interrupt.soft, reinjected); - ++vcpu->stat.irq_injections; + ++vcpu->stat->irq_injections; =20 svm->vmcb->control.event_inj =3D vcpu->arch.interrupt.nr | SVM_EVTINJ_VALID | type; @@ -4368,7 +4368,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_= vcpu *vcpu, /* Track VMRUNs that have made past consistency checking */ if (svm->nested.nested_run_pending && svm->vmcb->control.exit_code !=3D SVM_EXIT_ERR) - ++vcpu->stat.nested_run; + ++vcpu->stat->nested_run; =20 svm->nested.nested_run_pending =3D 0; } diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 84369f539fb2..cf894f572321 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -813,7 +813,7 @@ static void tdx_prepare_switch_to_host(struct kvm_vcpu = *vcpu) if (!vt->guest_state_loaded) return; =20 - ++vcpu->stat.host_state_reload; + ++vcpu->stat->host_state_reload; wrmsrl(MSR_KERNEL_GS_BASE, vt->msr_host_kernel_gs_base); =20 if (tdx->guest_entered) { @@ -1082,7 +1082,7 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool f= orce_immediate_exit) =20 void tdx_inject_nmi(struct kvm_vcpu *vcpu) { - ++vcpu->stat.nmi_injections; + ++vcpu->stat->nmi_injections; td_management_write8(to_tdx(vcpu), TD_VCPU_PEND_NMI, 1); /* * From KVM's perspective, NMI injection is completed right after @@ -1321,7 +1321,7 @@ static int tdx_emulate_io(struct kvm_vcpu *vcpu) u64 size, write; int ret; =20 - ++vcpu->stat.io_exits; + ++vcpu->stat->io_exits; =20 size =3D tdx->vp_enter_args.r12; write =3D tdx->vp_enter_args.r13; @@ -2072,7 +2072,7 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t= fastpath) case EXIT_REASON_EXCEPTION_NMI: return tdx_handle_exception_nmi(vcpu); case EXIT_REASON_EXTERNAL_INTERRUPT: - ++vcpu->stat.irq_exits; + ++vcpu->stat->irq_exits; return 1; case EXIT_REASON_CPUID: return tdx_emulate_cpuid(vcpu); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 19dc85e5ac37..02458bb0b486 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1361,7 +1361,7 @@ static void vmx_prepare_switch_to_host(struct vcpu_vm= x *vmx) =20 host_state =3D &vmx->loaded_vmcs->host_state; =20 - ++vmx->vcpu.stat.host_state_reload; + ++vmx->vcpu.stat->host_state_reload; =20 #ifdef CONFIG_X86_64 rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); @@ -4922,7 +4922,7 @@ void vmx_inject_irq(struct kvm_vcpu *vcpu, bool reinj= ected) =20 trace_kvm_inj_virq(irq, vcpu->arch.interrupt.soft, reinjected); =20 - ++vcpu->stat.irq_injections; + ++vcpu->stat->irq_injections; if (vmx->rmode.vm86_active) { int inc_eip =3D 0; if (vcpu->arch.interrupt.soft) @@ -4959,7 +4959,7 @@ void vmx_inject_nmi(struct kvm_vcpu *vcpu) vmx->loaded_vmcs->vnmi_blocked_time =3D 0; } =20 - ++vcpu->stat.nmi_injections; + ++vcpu->stat->nmi_injections; vmx->loaded_vmcs->nmi_known_unmasked =3D false; =20 if (vmx->rmode.vm86_active) { @@ -5353,7 +5353,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) =20 static __always_inline int handle_external_interrupt(struct kvm_vcpu *vcpu) { - ++vcpu->stat.irq_exits; + ++vcpu->stat->irq_exits; return 1; } =20 @@ -5373,7 +5373,7 @@ static int handle_io(struct kvm_vcpu *vcpu) exit_qualification =3D vmx_get_exit_qual(vcpu); string =3D (exit_qualification & 16) !=3D 0; =20 - ++vcpu->stat.io_exits; + ++vcpu->stat->io_exits; =20 if (string) return kvm_emulate_instruction(vcpu, 0); @@ -5633,7 +5633,7 @@ static int handle_interrupt_window(struct kvm_vcpu *v= cpu) =20 kvm_make_request(KVM_REQ_EVENT, vcpu); =20 - ++vcpu->stat.irq_window_exits; + ++vcpu->stat->irq_window_exits; return 1; } =20 @@ -5811,7 +5811,7 @@ static int handle_nmi_window(struct kvm_vcpu *vcpu) return -EIO; =20 exec_controls_clearbit(to_vmx(vcpu), CPU_BASED_NMI_WINDOW_EXITING); - ++vcpu->stat.nmi_window_exits; + ++vcpu->stat->nmi_window_exits; kvm_make_request(KVM_REQ_EVENT, vcpu); =20 return 1; @@ -6062,7 +6062,7 @@ static int handle_notify(struct kvm_vcpu *vcpu) unsigned long exit_qual =3D vmx_get_exit_qual(vcpu); bool context_invalid =3D exit_qual & NOTIFY_VM_CONTEXT_INVALID; =20 - ++vcpu->stat.notify_window_exits; + ++vcpu->stat->notify_window_exits; =20 /* * Notify VM exit happened while executing iret from NMI, @@ -6666,7 +6666,7 @@ static noinstr void vmx_l1d_flush(struct kvm_vcpu *vc= pu) return; } =20 - vcpu->stat.l1d_flush++; + vcpu->stat->l1d_flush++; =20 if (static_cpu_has(X86_FEATURE_FLUSH_L1D)) { native_wrmsrl(MSR_IA32_FLUSH_CMD, L1D_FLUSH); @@ -7450,7 +7450,7 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool f= orce_immediate_exit) */ if (vmx->nested.nested_run_pending && !vmx_get_exit_reason(vcpu).failed_vmentry) - ++vcpu->stat.nested_run; + ++vcpu->stat->nested_run; =20 vmx->nested.nested_run_pending =3D 0; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 98a36df7cf62..2c8bdb139b75 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -949,7 +949,7 @@ static int complete_emulated_insn_gp(struct kvm_vcpu *v= cpu, int err) =20 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fa= ult) { - ++vcpu->stat.pf_guest; + ++vcpu->stat->pf_guest; =20 /* * Async #PF in L2 is always forwarded to L1 as a VM-Exit regardless of @@ -3607,7 +3607,7 @@ static void kvmclock_reset(struct kvm_vcpu *vcpu) =20 static void kvm_vcpu_flush_tlb_all(struct kvm_vcpu *vcpu) { - ++vcpu->stat.tlb_flush; + ++vcpu->stat->tlb_flush; kvm_x86_call(flush_tlb_all)(vcpu); =20 /* Flushing all ASIDs flushes the current ASID... */ @@ -3616,7 +3616,7 @@ static void kvm_vcpu_flush_tlb_all(struct kvm_vcpu *v= cpu) =20 static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu) { - ++vcpu->stat.tlb_flush; + ++vcpu->stat->tlb_flush; =20 if (!tdp_enabled) { /* @@ -3641,7 +3641,7 @@ static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu = *vcpu) =20 static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu) { - ++vcpu->stat.tlb_flush; + ++vcpu->stat->tlb_flush; kvm_x86_call(flush_tlb_current)(vcpu); } =20 @@ -5067,11 +5067,11 @@ static void kvm_steal_time_set_preempted(struct kvm= _vcpu *vcpu) * preempted if and only if the VM-Exit was due to a host interrupt. */ if (!vcpu->arch.at_instruction_boundary) { - vcpu->stat.preemption_other++; + vcpu->stat->preemption_other++; return; } =20 - vcpu->stat.preemption_reported++; + vcpu->stat->preemption_reported++; if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) return; =20 @@ -8874,7 +8874,7 @@ static int handle_emulation_failure(struct kvm_vcpu *= vcpu, int emulation_type) { struct kvm *kvm =3D vcpu->kvm; =20 - ++vcpu->stat.insn_emulation_fail; + ++vcpu->stat->insn_emulation_fail; trace_kvm_emulate_insn_failed(vcpu); =20 if (emulation_type & EMULTYPE_VMWARE_GP) { @@ -9119,7 +9119,7 @@ int x86_decode_emulated_instruction(struct kvm_vcpu *= vcpu, int emulation_type, r =3D x86_decode_insn(ctxt, insn, insn_len, emulation_type); =20 trace_kvm_emulate_insn_start(vcpu); - ++vcpu->stat.insn_emulation; + ++vcpu->stat->insn_emulation; =20 return r; } @@ -9285,7 +9285,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gp= a_t cr2_or_gpa, } r =3D 0; } else if (vcpu->mmio_needed) { - ++vcpu->stat.mmio_exits; + ++vcpu->stat->mmio_exits; =20 if (!vcpu->mmio_is_write) writeback =3D false; @@ -10011,7 +10011,7 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, = unsigned long dest_id) struct kvm_vcpu *target =3D NULL; struct kvm_apic_map *map; =20 - vcpu->stat.directed_yield_attempted++; + vcpu->stat->directed_yield_attempted++; =20 if (single_task_running()) goto no_yield; @@ -10034,7 +10034,7 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, = unsigned long dest_id) if (kvm_vcpu_yield_to(target) <=3D 0) goto no_yield; =20 - vcpu->stat.directed_yield_successful++; + vcpu->stat->directed_yield_successful++; =20 no_yield: return; @@ -10061,7 +10061,7 @@ int ____kvm_emulate_hypercall(struct kvm_vcpu *vcpu= , int cpl, unsigned long a3 =3D kvm_rsi_read(vcpu); int op_64_bit =3D is_64_bit_hypercall(vcpu); =20 - ++vcpu->stat.hypercalls; + ++vcpu->stat->hypercalls; =20 trace_kvm_hypercall(nr, a0, a1, a2, a3); =20 @@ -10916,7 +10916,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) =20 if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win || kvm_xen_has_interrupt(vcpu)) { - ++vcpu->stat.req_event; + ++vcpu->stat->req_event; r =3D kvm_apic_accept_events(vcpu); if (r < 0) { r =3D 0; @@ -11048,7 +11048,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) } =20 /* Note, VM-Exits that go down the "slow" path are accounted below. */ - ++vcpu->stat.exits; + ++vcpu->stat->exits; } =20 /* @@ -11099,11 +11099,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) * VM-Exit on SVM and any ticks that occur between VM-Exit and now. * An instruction is required after local_irq_enable() to fully unblock * interrupts on processors that implement an interrupt shadow, the - * stat.exits increment will do nicely. + * stat->exits increment will do nicely. */ kvm_before_interrupt(vcpu, KVM_HANDLING_IRQ); local_irq_enable(); - ++vcpu->stat.exits; + ++vcpu->stat->exits; local_irq_disable(); kvm_after_interrupt(vcpu); =20 @@ -11321,7 +11321,7 @@ static int vcpu_run(struct kvm_vcpu *vcpu) kvm_vcpu_ready_for_interrupt_injection(vcpu)) { r =3D 0; vcpu->run->exit_reason =3D KVM_EXIT_IRQ_WINDOW_OPEN; - ++vcpu->stat.request_irq_exits; + ++vcpu->stat->request_irq_exits; break; } =20 @@ -11346,7 +11346,7 @@ static int __kvm_emulate_halt(struct kvm_vcpu *vcpu= , int state, int reason) * managed by userspace, in which case userspace is responsible for * handling wake events. */ - ++vcpu->stat.halt_exits; + ++vcpu->stat->halt_exits; if (lapic_in_kernel(vcpu)) { if (kvm_vcpu_has_events(vcpu) || vcpu->arch.pv.pv_unhalted) state =3D KVM_MP_STATE_RUNNABLE; @@ -11515,7 +11515,7 @@ static void kvm_load_guest_fpu(struct kvm_vcpu *vcp= u) static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) { fpu_swap_kvm_fpstate(&vcpu->arch.guest_fpu, false); - ++vcpu->stat.fpu_reload; + ++vcpu->stat->fpu_reload; trace_kvm_fpu(0); } =20 @@ -11564,7 +11564,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) if (signal_pending(current)) { r =3D -EINTR; kvm_run->exit_reason =3D KVM_EXIT_INTR; - ++vcpu->stat.signal_exits; + ++vcpu->stat->signal_exits; } goto out; } diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index dbca418d64f5..d2e0c0e8ff17 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -393,7 +393,8 @@ struct kvm_vcpu { bool ready; bool scheduled_out; struct kvm_vcpu_arch arch; - struct kvm_vcpu_stat stat; + struct kvm_vcpu_stat *stat; + struct kvm_vcpu_stat __stat; char stats_id[KVM_STATS_NAME_SIZE]; struct kvm_dirty_ring dirty_ring; =20 @@ -2489,7 +2490,7 @@ static inline int kvm_arch_vcpu_run_pid_change(struct= kvm_vcpu *vcpu) static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu) { vcpu->run->exit_reason =3D KVM_EXIT_INTR; - vcpu->stat.signal_exits++; + vcpu->stat->signal_exits++; } #endif /* CONFIG_KVM_XFER_TO_GUEST_WORK */ =20 diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b08fea91dc74..dce89a2f0a31 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3632,7 +3632,7 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu) struct rcuwait *wait =3D kvm_arch_vcpu_get_wait(vcpu); bool waited =3D false; =20 - vcpu->stat.generic.blocking =3D 1; + vcpu->stat->generic.blocking =3D 1; =20 preempt_disable(); kvm_arch_vcpu_blocking(vcpu); @@ -3654,7 +3654,7 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu) kvm_arch_vcpu_unblocking(vcpu); preempt_enable(); =20 - vcpu->stat.generic.blocking =3D 0; + vcpu->stat->generic.blocking =3D 0; =20 return waited; } @@ -3662,16 +3662,16 @@ bool kvm_vcpu_block(struct kvm_vcpu *vcpu) static inline void update_halt_poll_stats(struct kvm_vcpu *vcpu, ktime_t s= tart, ktime_t end, bool success) { - struct kvm_vcpu_stat_generic *stats =3D &vcpu->stat.generic; + struct kvm_vcpu_stat_generic *stats =3D &vcpu->stat->generic; u64 poll_ns =3D ktime_to_ns(ktime_sub(end, start)); =20 - ++vcpu->stat.generic.halt_attempted_poll; + ++vcpu->stat->generic.halt_attempted_poll; =20 if (success) { - ++vcpu->stat.generic.halt_successful_poll; + ++vcpu->stat->generic.halt_successful_poll; =20 if (!vcpu_valid_wakeup(vcpu)) - ++vcpu->stat.generic.halt_poll_invalid; + ++vcpu->stat->generic.halt_poll_invalid; =20 stats->halt_poll_success_ns +=3D poll_ns; KVM_STATS_LOG_HIST_UPDATE(stats->halt_poll_success_hist, poll_ns); @@ -3735,9 +3735,9 @@ void kvm_vcpu_halt(struct kvm_vcpu *vcpu) =20 cur =3D ktime_get(); if (waited) { - vcpu->stat.generic.halt_wait_ns +=3D + vcpu->stat->generic.halt_wait_ns +=3D ktime_to_ns(cur) - ktime_to_ns(poll_end); - KVM_STATS_LOG_HIST_UPDATE(vcpu->stat.generic.halt_wait_hist, + KVM_STATS_LOG_HIST_UPDATE(vcpu->stat->generic.halt_wait_hist, ktime_to_ns(cur) - ktime_to_ns(poll_end)); } out: @@ -3782,7 +3782,7 @@ bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu) { if (__kvm_vcpu_wake_up(vcpu)) { WRITE_ONCE(vcpu->ready, true); - ++vcpu->stat.generic.halt_wakeup; + ++vcpu->stat->generic.halt_wakeup; return true; } =20 @@ -4174,6 +4174,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) vcpu->run =3D page_address(page); =20 vcpu->plane0 =3D vcpu; + vcpu->stat =3D &vcpu->__stat; kvm_vcpu_init(vcpu, kvm, id); =20 r =3D kvm_arch_vcpu_create(vcpu); --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 ED1AA21931B for ; Tue, 1 Apr 2025 16:11:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523903; cv=none; b=kSJM9Q2CeDPyPIaDWUpI1bEUHgmywrDksdQXKCKFgaKuAeH4zm/9ZZ7lpCsDsCyXwr6Fo/sE8m5+g3gpPQTdAN1iOHlhyq22bG5GSuja66yEn1gBCfVrTpYI/55BfG/8BADH+EuUJ2BemOZFMNbcmO16DaATI0tDJbPr4rWCBnk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523903; c=relaxed/simple; bh=RE4EXCpfxhno9yiUXTtOFR2cTLxZp7UNPnnGbcmpDXs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q6JE6FOvoXg+YzHQX/ROZIPIfskJqf8nCGbfHqDE51wK6MuugxZZ57NE0iYemipWFtAOjKwTv4NzDHnLKtKikFKYh5IVf8NSiZfUIb3nxPmpWa0MxngvVnBofYK9KjEwQ/5wo1HsHjNpfoYdbYbCQgKTadw1K1uHefakEfycOc0= 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=L09+prFm; arc=none smtp.client-ip=170.10.129.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="L09+prFm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523900; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yjR3mqM2w8v8J+UuArqg6Kc21meadYNT6Oek6yPNa0w=; b=L09+prFm1/04hc/+LM3Mne8810t+B/ri5hwsO7QGSX22NL300PzutUWQCZyv253UQzrmZM SF3yMhpHRTWPZDhUXhntGkxG4YgpDzZfGSnj9A+7DkognaDaKD4bmav2pmlVH8/DIuEeW4 ySxru+pLT30gmF4X6SVrP/HVwtlWsfo= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-675-9GYbNK46PKy_nIm-QFHTFw-1; Tue, 01 Apr 2025 12:11:39 -0400 X-MC-Unique: 9GYbNK46PKy_nIm-QFHTFw-1 X-Mimecast-MFC-AGG-ID: 9GYbNK46PKy_nIm-QFHTFw_1743523898 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-39c1b1c0969so1860315f8f.1 for ; Tue, 01 Apr 2025 09:11:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523898; x=1744128698; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yjR3mqM2w8v8J+UuArqg6Kc21meadYNT6Oek6yPNa0w=; b=lAhrJSvI8/UORUcPAyC0EKK169ZveDY36IeOsTGKqhzMnANtEvZ9fTlQMAF/0cHh4T LKiL4E0kRcjay32XttBeWt21LcDD2JVm7B7qnyq/GhBzMRmPfaxr7KPByGdURAGMeXUR FC+RFoVDWx75o/sOCQd+79OOuIcxYi+WbvOKYWYoXA7UG6tRM6RroftwoqIks2aOgrwo eQc5WOf4NhliYirhG5QQqXjZCeX+3wadH6EeM4ylOmU9FTH5avXZPkN4dL+l4pKCu50C zgKAlXw9bh74volD/jaxHXjsyWqLVO7g4bwtMG5Kqtq1A8Hi+NhAgorkFpFIhPi7/+MN jpnw== X-Gm-Message-State: AOJu0YzYg+u333RoP7CfSiKcXlmjCmzgDHqE85H6qA7XsVswEixdfDOt n69QxtXMGy+AtlWzdVoRTKewd59+8mhMSz8ogRrpQDC/QU8eXf4S7Pf5A/Xo/nTUT5cdYy2GKwg oaUY5TZsVBonYKspocXOOwF1OSwNgcVYjuKhtGQNc4tNOzENVufGgsMovLBxco3P0TvB3CwfX7u 5QzXcTUMkE8bNlwdcZylX+KAeeGWlUDMzQS7T430ONurjNcA== X-Gm-Gg: ASbGncswMgO38U+L+DLBpbFLrSSeHy8y1i7Thw9bawGqKzNZtfuuV5sTzVd8NYf/Mdg VqrZDwEBhgwbHU72YwzvzkvHwxwUd+87UNnTwIH0v4InF/FrDb9Gtx2uWOuY8+KnRUIweB/5eG/ ZCG/Xo/jKL8ivgj50eV/8kumQOl1HEjUDwdQucHnxkQ3aos5pnzDJZw8GcNg0gh3ivSlMQ8uCEo 6pXC4RSHdO7WPGtk7pPS6BX45wW/+ycxjQQMRDJlW+XlYt8YK4zB16MCMQuFGQ+1KmmpdTGrJ1Z Ajx3d4Zdre69Hk50kgTBPA== X-Received: by 2002:a05:6000:1863:b0:399:6dd9:9f40 with SMTP id ffacd0b85a97d-39c120cc8a1mr11575921f8f.9.1743523897800; Tue, 01 Apr 2025 09:11:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFf14Rq+IqwJ0RMb19wAyhNB4F46l/fAlyv854rgC7681D5ZIz2UVlu3+YdbiTNo+4kZUtxqg== X-Received: by 2002:a05:6000:1863:b0:399:6dd9:9f40 with SMTP id ffacd0b85a97d-39c120cc8a1mr11575872f8f.9.1743523897271; Tue, 01 Apr 2025 09:11:37 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b79e0afsm14662940f8f.65.2025.04.01.09.11.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:36 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 11/29] KVM: anticipate allocation of dirty ring Date: Tue, 1 Apr 2025 18:10:48 +0200 Message-ID: <20250401161106.790710-12-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Put together code that deals with data that is shared by all planes: vcpu->run and dirty ring. Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index dce89a2f0a31..4c7e379fbf7d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4173,20 +4173,20 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm= , unsigned long id) } vcpu->run =3D page_address(page); =20 + if (kvm->dirty_ring_size) { + r =3D kvm_dirty_ring_alloc(kvm, &vcpu->dirty_ring, + id, kvm->dirty_ring_size); + if (r) + goto vcpu_free_run_page; + } + vcpu->plane0 =3D vcpu; vcpu->stat =3D &vcpu->__stat; kvm_vcpu_init(vcpu, kvm, id); =20 r =3D kvm_arch_vcpu_create(vcpu); if (r) - goto vcpu_free_run_page; - - if (kvm->dirty_ring_size) { - r =3D kvm_dirty_ring_alloc(kvm, &vcpu->dirty_ring, - id, kvm->dirty_ring_size); - if (r) - goto arch_vcpu_destroy; - } + goto vcpu_free_dirty_ring; =20 mutex_lock(&kvm->lock); =20 @@ -4240,9 +4240,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) xa_erase(&kvm->planes[0]->vcpu_array, vcpu->vcpu_idx); unlock_vcpu_destroy: mutex_unlock(&kvm->lock); - kvm_dirty_ring_free(&vcpu->dirty_ring); -arch_vcpu_destroy: kvm_arch_vcpu_destroy(vcpu); +vcpu_free_dirty_ring: + kvm_dirty_ring_free(&vcpu->dirty_ring); vcpu_free_run_page: free_page((unsigned long)vcpu->run); vcpu_free: --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 6D9E421CC51 for ; Tue, 1 Apr 2025 16:11:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523909; cv=none; b=InaxPGzCXwMxySuErM4KgpAYlnfXA61meqTvkX216ThHQabSAPmvdpurAUwbG4bz6WtDIHZI+iqzvmXnFl5ZOuYUCNVTEicCy5+UOTRIBDYcchMUbmPCgg29F6vJRDlJ9fN/AdNQr+3DGwj+sLXWliEH+2SRFCbhtgao0jiJ6QY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523909; c=relaxed/simple; bh=xknqBKrnf/cRf6MzXxubS95UH7TntUJgejhgAFT3r9g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tm1MhXc51k5s/shbSYKTvlppQH+PmmglC5UzYcaB10SiujsT9ZaRvbkFYM0jTLQ5Q6Pj8N5AIqUTGx1SE/C5ZQhE2AzekutqYAP/k+YlydWVGzaKOI2PCZ/n6E91CbTW/nnnFBISP94YqLlemfyx/7eV4NsZvB+4QRfTqCuEoFY= 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=Aa1MsJjz; arc=none smtp.client-ip=170.10.129.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="Aa1MsJjz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523906; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cF+qO0yatMZdwcKNEFIrHdbvxZj7acs2e7VdEaArYVg=; b=Aa1MsJjzyG6ZkQS9cDWbySFS0KVmwSAoWjMcqhpg2GRj2O9PNdvrK+CcYW7qOQ/CEqEQ2B TnMxpf3jKhppqGckGXLs/0TWwCE61gjEgZTgz0QiJQwVHzOD2IBNrFK7IFl9/OzE/+bJWd 1KrSU4f+bdSgfTe4arti90NPcsM6hZc= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-593-5dEkrn1uM2OS_DE-EgoDHw-1; Tue, 01 Apr 2025 12:11:44 -0400 X-MC-Unique: 5dEkrn1uM2OS_DE-EgoDHw-1 X-Mimecast-MFC-AGG-ID: 5dEkrn1uM2OS_DE-EgoDHw_1743523904 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43d0a037f97so35535095e9.2 for ; Tue, 01 Apr 2025 09:11:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523903; x=1744128703; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cF+qO0yatMZdwcKNEFIrHdbvxZj7acs2e7VdEaArYVg=; b=heLE86cVLjYSxgbjXWNNTv8GA6YpoeuSxToOZUDl8WBjr050TEPXuA8hcm7tycBINE lZPCMYyk5WZl4+A1s8QTHcU9yNjCQwSKCcEY4qJl026fbycLcEY/eXERv7UrcEU0qp+9 RY6WYU5sDhMP987lDPDBMsjb6yEmo7vfOE3SUJmJXL7eps+tj/L/uTmk8SWYbEKQT3bC MNfvrI8nwspgIjRdelfIFQESWudB7XquFrIzzeKM4v5UzqRCF0raCVhEYelFK0M9QaQ3 ny1iOLrB7WOkxgUX5IgHZQIQ0hk7XNmdJjxgYraMxzyYMEJTho/pkVJZ3owCo/MZ2ASz Wk1A== X-Gm-Message-State: AOJu0Yzlp2/Y7JKChrOmsFLI9DrvCh4Xbs6nST/IqOEQHHlvEFNgibKZ tb+AQsLlKXp9Jd5ydtsdYejA42wTdPxW3fxcunu1ixbwSu9KtOkDZ9aPQgHMBQRl8p2/fqrpQBL 6cgFFpw3USzTHrHs0gD8epAx1Xu3OPQkPB1jmjtz2Qd7YWanRN9wFP4G56a0JELtU/Ij/8sjxp2 MphFyEomwOdV+r+uLbUpvCRJ2hs9LPsgMmiC07wEaP3QyoKA== X-Gm-Gg: ASbGnctGJS7D7QKCwHuu0ZbGAWf+UOHd7932lbfHXZ55VoTUzWhv2m0rLyh5ibtmwjW kQE/rZnr1KlDbfvCL08P/zO8xVQzbO7cnvMoLAttRBn4rrU7XQ0UoRJGRPOctzAmFLZ9+s9UCmt e1zR6h5kJYLEimKoUNyN4Vp2Cz9H7Qj+HbyOonmweq+z4vsMpoJfqPlUQJsaYKXKARpluAvb8le AlvUSuPCJi0FconBqkgu0omJT2qk2onR0XSypwJANb6GLiVlQZuEsEKnfpcUdb1f3x45aqvgjzj 8aWklAIqNwJRIuP+sFDTyg== X-Received: by 2002:a05:6000:2b03:b0:391:4674:b10f with SMTP id ffacd0b85a97d-39c121188demr8496028f8f.36.1743523902938; Tue, 01 Apr 2025 09:11:42 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGqJ3rJ6+IP5QCotzUgeA4XjgsMo38RrmP0uvZCP5poVx+NlUkpMpatJ7KifS+nAPHv2myHRg== X-Received: by 2002:a05:6000:2b03:b0:391:4674:b10f with SMTP id ffacd0b85a97d-39c121188demr8495987f8f.36.1743523902498; Tue, 01 Apr 2025 09:11:42 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b79e0dcsm14597487f8f.64.2025.04.01.09.11.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:38 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 12/29] KVM: share dirty ring for same vCPU id on different planes Date: Tue, 1 Apr 2025 18:10:49 +0200 Message-ID: <20250401161106.790710-13-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The dirty page ring is read by mmap()-ing the vCPU file descriptor, which is only possible for plane 0. This is not a problem because it is only filled by KVM_RUN which takes the plane-0 vCPU mutex, and it is therefore possible to share it for vCPUs that have the same id but are on different planes. (TODO: double check). Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 6 ++++-- virt/kvm/dirty_ring.c | 5 +++-- virt/kvm/kvm_main.c | 10 +++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index d2e0c0e8ff17..b511aed2de8e 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -394,9 +394,11 @@ struct kvm_vcpu { bool scheduled_out; struct kvm_vcpu_arch arch; struct kvm_vcpu_stat *stat; - struct kvm_vcpu_stat __stat; char stats_id[KVM_STATS_NAME_SIZE]; - struct kvm_dirty_ring dirty_ring; + struct kvm_dirty_ring *dirty_ring; + + struct kvm_vcpu_stat __stat; + struct kvm_dirty_ring __dirty_ring; =20 /* * The most recently used memslot by this vCPU and the slots generation diff --git a/virt/kvm/dirty_ring.c b/virt/kvm/dirty_ring.c index d14ffc7513ee..66e6a6a67d13 100644 --- a/virt/kvm/dirty_ring.c +++ b/virt/kvm/dirty_ring.c @@ -172,11 +172,12 @@ int kvm_dirty_ring_reset(struct kvm *kvm, struct kvm_= dirty_ring *ring) =20 void kvm_dirty_ring_push(struct kvm_vcpu *vcpu, u32 slot, u64 offset) { - struct kvm_dirty_ring *ring =3D &vcpu->dirty_ring; + struct kvm_dirty_ring *ring =3D vcpu->dirty_ring; struct kvm_dirty_gfn *entry; =20 /* It should never get full */ WARN_ON_ONCE(kvm_dirty_ring_full(ring)); + lockdep_assert_held(&vcpu->plane0->mutex); =20 entry =3D &ring->dirty_gfns[ring->dirty_index & (ring->size - 1)]; =20 @@ -204,7 +205,7 @@ bool kvm_dirty_ring_check_request(struct kvm_vcpu *vcpu) * the dirty ring is reset by userspace. */ if (kvm_check_request(KVM_REQ_DIRTY_RING_SOFT_FULL, vcpu) && - kvm_dirty_ring_soft_full(&vcpu->dirty_ring)) { + kvm_dirty_ring_soft_full(vcpu->dirty_ring)) { kvm_make_request(KVM_REQ_DIRTY_RING_SOFT_FULL, vcpu); vcpu->run->exit_reason =3D KVM_EXIT_DIRTY_RING_FULL; trace_kvm_dirty_ring_exit(vcpu); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 4c7e379fbf7d..863fd80ddfbe 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -466,7 +466,7 @@ static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct= kvm *kvm, unsigned id) static void kvm_vcpu_destroy(struct kvm_vcpu *vcpu) { kvm_arch_vcpu_destroy(vcpu); - kvm_dirty_ring_free(&vcpu->dirty_ring); + kvm_dirty_ring_free(vcpu->dirty_ring); =20 /* * No need for rcu_read_lock as VCPU_RUN is the only place that changes @@ -4038,7 +4038,7 @@ static vm_fault_t kvm_vcpu_fault(struct vm_fault *vmf) #endif else if (kvm_page_in_dirty_ring(vcpu->kvm, vmf->pgoff)) page =3D kvm_dirty_ring_get_page( - &vcpu->dirty_ring, + vcpu->dirty_ring, vmf->pgoff - KVM_DIRTY_LOG_PAGE_OFFSET); else return kvm_arch_vcpu_fault(vcpu, vmf); @@ -4174,7 +4174,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) vcpu->run =3D page_address(page); =20 if (kvm->dirty_ring_size) { - r =3D kvm_dirty_ring_alloc(kvm, &vcpu->dirty_ring, + r =3D kvm_dirty_ring_alloc(kvm, &vcpu->__dirty_ring, id, kvm->dirty_ring_size); if (r) goto vcpu_free_run_page; @@ -4242,7 +4242,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) mutex_unlock(&kvm->lock); kvm_arch_vcpu_destroy(vcpu); vcpu_free_dirty_ring: - kvm_dirty_ring_free(&vcpu->dirty_ring); + kvm_dirty_ring_free(&vcpu->__dirty_ring); vcpu_free_run_page: free_page((unsigned long)vcpu->run); vcpu_free: @@ -5047,7 +5047,7 @@ static int kvm_vm_ioctl_reset_dirty_pages(struct kvm = *kvm) mutex_lock(&kvm->slots_lock); =20 kvm_for_each_vcpu(i, vcpu, kvm) - cleared +=3D kvm_dirty_ring_reset(vcpu->kvm, &vcpu->dirty_ring); + cleared +=3D kvm_dirty_ring_reset(vcpu->kvm, vcpu->dirty_ring); =20 mutex_unlock(&kvm->slots_lock); =20 --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 0A2CC21D3C7 for ; Tue, 1 Apr 2025 16:11:49 +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=1743523912; cv=none; b=ba3vNpXgT5DrUM9ChVnKJi6IA85XMNLZS16W3vij8ozvd9sWSt+QKGX+v2new5pJOw1KfPbsfmBIVU473Zqm2pFbHuXbKo8pU7Yq3bYmEXRM3gyZseossBdBolAG+i7K8JWVWZBbybqZomjyOkuNfiy1utB/oPH36SzSRgYPrIU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523912; c=relaxed/simple; bh=qcCJMIEB/YYA+Wr5VMPjm8ILdoDyBhZd0vKvkLuJklw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U3STp8/xry84rLXu+YoJZH4liOE/z+qpYb8jryxdpfnsnQRPrMBV6JdyRZaavrWJE9dU/vvEs9F5ESX+wztJ7rb/j6tWPYZZmy5+u3VG+rdJ679BlcQQdahgU2NU8R7ek38mIuIb0cQKcS4qriaWQstBnQt8Jm5BJzQJrbVO9JQ= 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=Ax8eK36S; 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="Ax8eK36S" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523909; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=V4ffDXlDC4IXD1cfMgUEPRkug63IDolKcU/ffLWZ1l4=; b=Ax8eK36SNZa/dvRapMC6bMqZkV9+1deQc7QTpIIKZ3MgB7/qje7GKmenouc+s1P27NWWs8 NfSR8+fqf4nkuAm6mEoKYMhfPsH0/9usj6l+TIu2lnKMbirKfnoJYRRV/VxjuA18azzsrl LVD5GkpOFKbH8ROIq9nWX60p64JHOkU= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-624-3qbyGHfPO_6C6r0v3YdtXw-1; Tue, 01 Apr 2025 12:11:47 -0400 X-MC-Unique: 3qbyGHfPO_6C6r0v3YdtXw-1 X-Mimecast-MFC-AGG-ID: 3qbyGHfPO_6C6r0v3YdtXw_1743523907 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43d00017e9dso39784885e9.0 for ; Tue, 01 Apr 2025 09:11:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523906; x=1744128706; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=V4ffDXlDC4IXD1cfMgUEPRkug63IDolKcU/ffLWZ1l4=; b=QZAqjjAaFMSttqyqgStnfFRNOKcB0eG/l3z8MeueIKNaU1uEkLsQI8WR3+IZnr8pM8 6Zsmib3/hk5qJn/XNjWuXq4/dSvUz7KsAnRA6HDdjjcSM8+W7ZTJiCngCBHXktWB43Ex g59fjtq4Zv2YKxK0VNjPJ5wPtWvmWBHDXXMoxpT8iSBS9NY7AtBTYdEAl+Xxa1n/I141 YMte1haIsTzPgL2P8e8IbkFqhF6Ol9pKGjR1I++5d1s9Yuyn0rYHP5+Zdp2y+vSqaJgT osn+YhSZaDAfgLGm/ORgU8RHg/ZLVbtSHiY4y9G2KeHl09L4Fcp7mmnsC/zyC1u02u4z v2mg== X-Gm-Message-State: AOJu0YxczKeoFtwvYWm0m2g9Yeo/pqavEvgTp+qMOZoPL4FZ+eE8b670 U1M84ZlUX7D7N+ZP74pAQum6R8o4ICjkZQbletxGZ0b37zDFUIPD7Ydvld4bLJOejzON0gjtMAV D68pxOjig4iQCwrImCHMUeDvYAf4PfcjMfnP3F0YnscJzUy3w4O595vwgLye+lCoJ84pCaWVpPG 2bDmovbZ4+EJVmP/sYV3M8u4YopbluD36L5KP70jpzoFfEtg== X-Gm-Gg: ASbGncsej5vfYF20ls5kY6b1UvTfaluE049uWbRnSm5KaDCxl31TiiypVA2Z18iim0K Uqr5j0rFchzHcbUhe2Idd2mD3rTjQEOnF/QxDDvakiVS7SUC4trsWoGMZp1QrDSRblSHRAKlzPE 2r1g4C4q4ZsOkEAxgpJRCi8lzEEszCjHIZbB7AZOHx6VQ9sMfOC2tRPKNWteZMVlC15y7TqgSiD tLxkBDFuyx4nmMVmKLOr7hnPEIqkbT6QZcyr5MIIO/S+puSeuRsakWkc8F+JNRuGbRBj+DcGdy+ ZPaG64vykQYpXW/j5EOIUw== X-Received: by 2002:a05:600c:4e87:b0:43c:f8fc:f686 with SMTP id 5b1f17b1804b1-43db61d6c2fmr101787285e9.3.1743523905742; Tue, 01 Apr 2025 09:11:45 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGSQ1wvUh2eHOLlh8NcVQtz5xS01dfxv4KX3HPNNarZ4kwVszorKHWEoxoNvdgXqk1Sv1qazA== X-Received: by 2002:a05:600c:4e87:b0:43c:f8fc:f686 with SMTP id 5b1f17b1804b1-43db61d6c2fmr101786685e9.3.1743523905112; Tue, 01 Apr 2025 09:11:45 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d82e83482sm207502195e9.14.2025.04.01.09.11.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:43 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 13/29] KVM: implement vCPU creation for extra planes Date: Tue, 1 Apr 2025 18:10:50 +0200 Message-ID: <20250401161106.790710-14-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For userspace to have fun with planes it is probably useful to let them create vCPUs on the non-zero planes as well. Since such vCPUs are backed by the same struct kvm_vcpu, these are regular vCPU file descriptors except that they only allow a small subset of ioctls (mostly get/set) and they share some of the backing resources, notably vcpu->run. TODO: prefault might be useful on non-default planes as well? Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/locking.rst | 3 + include/linux/kvm_host.h | 4 +- include/uapi/linux/kvm.h | 1 + virt/kvm/kvm_main.c | 167 +++++++++++++++++++++++------ 4 files changed, 142 insertions(+), 33 deletions(-) diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/lo= cking.rst index ae8bce7fecbe..ad22344deb28 100644 --- a/Documentation/virt/kvm/locking.rst +++ b/Documentation/virt/kvm/locking.rst @@ -26,6 +26,9 @@ The acquisition orders for mutexes are as follows: are taken on the waiting side when modifying memslots, so MMU notifiers must not take either kvm->slots_lock or kvm->slots_arch_lock. =20 +- when VMs have multiple planes, vcpu->mutex for plane 0 can taken + outside vcpu->mutex for the same id and another plane + cpus_read_lock() vs kvm_lock: =20 - Taking cpus_read_lock() outside of kvm_lock is problematic, despite that diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index b511aed2de8e..99fd90c5d71b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -343,6 +343,9 @@ struct kvm_vcpu { =20 struct mutex mutex; =20 + /* Only valid on plane 0 */ + bool wants_to_run; + /* Shared for all planes */ struct kvm_run *run; =20 @@ -388,7 +391,6 @@ struct kvm_vcpu { bool dy_eligible; } spin_loop; #endif - bool wants_to_run; bool preempted; bool ready; bool scheduled_out; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 96d25c7fa18f..24fa002cd7c1 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1691,5 +1691,6 @@ struct kvm_pre_fault_memory { }; =20 #define KVM_CREATE_PLANE _IO(KVMIO, 0xd6) +#define KVM_CREATE_VCPU_PLANE _IO(KVMIO, 0xd7) =20 #endif /* __LINUX_KVM_H */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 863fd80ddfbe..06fa2a6ad96f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -438,11 +438,11 @@ void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memor= y_cache *mc) } #endif =20 -static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned= id) +static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm_plane *plane, = unsigned id) { mutex_init(&vcpu->mutex); vcpu->cpu =3D -1; - vcpu->kvm =3D kvm; + vcpu->kvm =3D plane->kvm; vcpu->vcpu_id =3D id; vcpu->pid =3D NULL; rwlock_init(&vcpu->pid_lock); @@ -459,8 +459,13 @@ static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struc= t kvm *kvm, unsigned id) vcpu->last_used_slot =3D NULL; =20 /* Fill the stats id string for the vcpu */ - snprintf(vcpu->stats_id, sizeof(vcpu->stats_id), "kvm-%d/vcpu-%d", - task_pid_nr(current), id); + if (plane->plane) { + snprintf(vcpu->stats_id, sizeof(vcpu->stats_id), "kvm-%d/vcpu-%d:%d", + task_pid_nr(current), id, plane->plane); + } else { + snprintf(vcpu->stats_id, sizeof(vcpu->stats_id), "kvm-%d/vcpu-%d", + task_pid_nr(current), id); + } } =20 static void kvm_vcpu_destroy(struct kvm_vcpu *vcpu) @@ -475,7 +480,9 @@ static void kvm_vcpu_destroy(struct kvm_vcpu *vcpu) */ put_pid(vcpu->pid); =20 - free_page((unsigned long)vcpu->run); + if (!vcpu->plane) + free_page((unsigned long)vcpu->run); + kmem_cache_free(kvm_vcpu_cache, vcpu); } =20 @@ -4026,6 +4033,9 @@ static vm_fault_t kvm_vcpu_fault(struct vm_fault *vmf) struct kvm_vcpu *vcpu =3D vmf->vma->vm_file->private_data; struct page *page; =20 + if (vcpu->plane) + return VM_FAULT_SIGBUS; + if (vmf->pgoff =3D=3D 0) page =3D virt_to_page(vcpu->run); #ifdef CONFIG_X86 @@ -4113,7 +4123,10 @@ static void kvm_create_vcpu_debugfs(struct kvm_vcpu = *vcpu) if (!debugfs_initialized()) return; =20 - snprintf(dir_name, sizeof(dir_name), "vcpu%d", vcpu->vcpu_id); + if (vcpu->plane) + snprintf(dir_name, sizeof(dir_name), "vcpu%d:%d", vcpu->vcpu_id, vcpu->p= lane); + else + snprintf(dir_name, sizeof(dir_name), "vcpu%d", vcpu->vcpu_id); debugfs_dentry =3D debugfs_create_dir(dir_name, vcpu->kvm->debugfs_dentry); debugfs_create_file("pid", 0444, debugfs_dentry, vcpu, @@ -4126,9 +4139,10 @@ static void kvm_create_vcpu_debugfs(struct kvm_vcpu = *vcpu) /* * Creates some virtual cpus. Good luck creating more than one. */ -static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, unsigned long id) +static int kvm_vm_ioctl_create_vcpu(struct kvm_plane *plane, struct kvm_vc= pu *plane0_vcpu, unsigned long id) { int r; + struct kvm *kvm =3D plane->kvm; struct kvm_vcpu *vcpu; struct page *page; =20 @@ -4165,24 +4179,33 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm= , unsigned long id) goto vcpu_decrement; } =20 - BUILD_BUG_ON(sizeof(struct kvm_run) > PAGE_SIZE); - page =3D alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); - if (!page) { - r =3D -ENOMEM; - goto vcpu_free; - } - vcpu->run =3D page_address(page); + if (plane->plane) { + page =3D NULL; + vcpu->run =3D plane0_vcpu->run; + } else { + WARN_ON(plane0_vcpu !=3D NULL); + plane0_vcpu =3D vcpu; =20 - if (kvm->dirty_ring_size) { - r =3D kvm_dirty_ring_alloc(kvm, &vcpu->__dirty_ring, - id, kvm->dirty_ring_size); - if (r) - goto vcpu_free_run_page; + BUILD_BUG_ON(sizeof(struct kvm_run) > PAGE_SIZE); + page =3D alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); + if (!page) { + r =3D -ENOMEM; + goto vcpu_free; + } + vcpu->run =3D page_address(page); + + if (kvm->dirty_ring_size) { + r =3D kvm_dirty_ring_alloc(kvm, &vcpu->__dirty_ring, + id, kvm->dirty_ring_size); + if (r) + goto vcpu_free_run_page; + } } =20 - vcpu->plane0 =3D vcpu; - vcpu->stat =3D &vcpu->__stat; - kvm_vcpu_init(vcpu, kvm, id); + vcpu->plane0 =3D plane0_vcpu; + vcpu->stat =3D &plane0_vcpu->__stat; + vcpu->dirty_ring =3D &plane0_vcpu->__dirty_ring; + kvm_vcpu_init(vcpu, plane, id); =20 r =3D kvm_arch_vcpu_create(vcpu); if (r) @@ -4190,7 +4213,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, = unsigned long id) =20 mutex_lock(&kvm->lock); =20 - if (kvm_get_vcpu_by_id(kvm, id)) { + if (kvm_get_plane_vcpu_by_id(plane, id)) { r =3D -EEXIST; goto unlock_vcpu_destroy; } @@ -4200,8 +4223,13 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm,= unsigned long id) * release semantics, which ensures the write is visible to kvm_get_vcpu(= ). */ vcpu->plane =3D -1; - vcpu->vcpu_idx =3D atomic_read(&kvm->online_vcpus); - r =3D xa_insert(&kvm->planes[0]->vcpu_array, vcpu->vcpu_idx, vcpu, GFP_KE= RNEL_ACCOUNT); + if (plane->plane) + vcpu->vcpu_idx =3D atomic_read(&kvm->online_vcpus); + else + vcpu->vcpu_idx =3D plane0_vcpu->vcpu_idx; + + r =3D xa_insert(&plane->vcpu_array, vcpu->vcpu_idx, + vcpu, GFP_KERNEL_ACCOUNT); WARN_ON_ONCE(r =3D=3D -EBUSY); if (r) goto unlock_vcpu_destroy; @@ -4220,13 +4248,14 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm= , unsigned long id) if (r < 0) goto kvm_put_xa_erase; =20 - atomic_inc(&kvm->online_vcpus); + if (!plane0_vcpu) + atomic_inc(&kvm->online_vcpus); =20 /* * Pairs with xa_load() in kvm_get_vcpu, ensuring that online_vcpus * is updated before vcpu->plane. */ - smp_store_release(&vcpu->plane, 0); + smp_store_release(&vcpu->plane, plane->plane); mutex_unlock(&vcpu->mutex); =20 mutex_unlock(&kvm->lock); @@ -4237,14 +4266,15 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm= , unsigned long id) kvm_put_xa_erase: mutex_unlock(&vcpu->mutex); kvm_put_kvm_no_destroy(kvm); - xa_erase(&kvm->planes[0]->vcpu_array, vcpu->vcpu_idx); + xa_erase(&plane->vcpu_array, vcpu->vcpu_idx); unlock_vcpu_destroy: mutex_unlock(&kvm->lock); kvm_arch_vcpu_destroy(vcpu); vcpu_free_dirty_ring: kvm_dirty_ring_free(&vcpu->__dirty_ring); vcpu_free_run_page: - free_page((unsigned long)vcpu->run); + if (page) + __free_page(page); vcpu_free: kmem_cache_free(kvm_vcpu_cache, vcpu); vcpu_decrement: @@ -4406,6 +4436,35 @@ static int kvm_plane_ioctl_check_extension(struct kv= m_plane *plane, long arg) } } =20 +static int kvm_plane_ioctl_create_vcpu(struct kvm_plane *plane, long arg) +{ + int r =3D -EINVAL; + struct file *file; + struct kvm_vcpu *vcpu; + int fd; + + if (arg !=3D (int)arg) + return -EBADF; + + fd =3D arg; + file =3D fget(fd); + if (!file) + return -EBADF; + + if (file->f_op !=3D &kvm_vcpu_fops) + goto err; + + vcpu =3D file->private_data; + if (vcpu->kvm !=3D plane->kvm) + goto err; + + r =3D kvm_vm_ioctl_create_vcpu(plane, vcpu, vcpu->vcpu_id); + +err: + fput(file); + return r; +} + static long __kvm_plane_ioctl(struct kvm_plane *plane, unsigned int ioctl, unsigned long arg) { @@ -4432,6 +4491,8 @@ static long __kvm_plane_ioctl(struct kvm_plane *plane= , unsigned int ioctl, #endif case KVM_CHECK_EXTENSION: return kvm_plane_ioctl_check_extension(plane, arg); + case KVM_CREATE_VCPU_PLANE: + return kvm_plane_ioctl_create_vcpu(plane, arg); default: return -ENOTTY; } @@ -4463,6 +4524,44 @@ static struct file_operations kvm_plane_fops =3D { }; =20 =20 +static inline bool kvm_arch_is_vcpu_plane_ioctl(unsigned ioctl) +{ + switch (ioctl) { + case KVM_GET_DEBUGREGS: + case KVM_SET_DEBUGREGS: + case KVM_GET_FPU: + case KVM_SET_FPU: + case KVM_GET_LAPIC: + case KVM_SET_LAPIC: + case KVM_GET_MSRS: + case KVM_SET_MSRS: + case KVM_GET_NESTED_STATE: + case KVM_SET_NESTED_STATE: + case KVM_GET_ONE_REG: + case KVM_SET_ONE_REG: + case KVM_GET_REGS: + case KVM_SET_REGS: + case KVM_GET_SREGS: + case KVM_SET_SREGS: + case KVM_GET_SREGS2: + case KVM_SET_SREGS2: + case KVM_GET_VCPU_EVENTS: + case KVM_SET_VCPU_EVENTS: + case KVM_GET_XCRS: + case KVM_SET_XCRS: + case KVM_GET_XSAVE: + case KVM_GET_XSAVE2: + case KVM_SET_XSAVE: + + case KVM_GET_REG_LIST: + case KVM_TRANSLATE: + return true; + + default: + return false; + } +} + static long kvm_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -4475,6 +4574,9 @@ static long kvm_vcpu_ioctl(struct file *filp, if (vcpu->kvm->mm !=3D current->mm || vcpu->kvm->vm_dead) return -EIO; =20 + if (vcpu->plane && !kvm_arch_is_vcpu_plane_ioctl(ioctl)) + return -EINVAL; + if (unlikely(_IOC_TYPE(ioctl) !=3D KVMIO)) return -EINVAL; =20 @@ -4958,7 +5060,7 @@ static int kvm_vm_ioctl_check_extension_generic(struc= t kvm *kvm, long arg) case KVM_CAP_PLANES: if (kvm) return kvm_arch_nr_vcpu_planes(kvm); - return KVM_MAX_PLANES; + return KVM_MAX_VCPU_PLANES; case KVM_CAP_PLANES_FPU: return kvm_arch_planes_share_fpu(kvm); #endif @@ -5201,7 +5303,8 @@ static int kvm_vm_ioctl_create_plane(struct kvm *kvm,= unsigned id) struct file *file; int r, fd; =20 - if (id >=3D KVM_MAX_VCPU_PLANES) + if (id >=3D kvm_arch_nr_vcpu_planes(kvm) + || WARN_ON_ONCE(id >=3D KVM_MAX_VCPU_PLANES)) return -EINVAL; =20 guard(mutex)(&kvm->lock); @@ -5259,7 +5362,7 @@ static long kvm_vm_ioctl(struct file *filp, r =3D kvm_vm_ioctl_create_plane(kvm, arg); break; case KVM_CREATE_VCPU: - r =3D kvm_vm_ioctl_create_vcpu(kvm, arg); + r =3D kvm_vm_ioctl_create_vcpu(kvm->planes[0], NULL, arg); break; case KVM_ENABLE_CAP: { struct kvm_enable_cap cap; --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 A525621D596 for ; Tue, 1 Apr 2025 16:11:52 +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=1743523914; cv=none; b=B2hQZqdQmKmarrExgu7hOVgm7aSyC/86vDm+AJGp0TW4F3izocM6bUrOKTnyLSnX2uV3JTSD87ZhjXwHo/tJ+O43WJEBjDyCBHfKWHlWjlaQs3nAwSDFxzvF1c6WVXvbXDJz2tdedf0SXAfT8jLaAxsQUEFXCm9/d5gl1grQCOI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523914; c=relaxed/simple; bh=RefrmAkQ0L+4IQy+OTCdYSqXd/r04zNM+VND4kN61fk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EetsRYcdPpMGHlXhFyjKXs1fHgarcy3gvg5praz3MBP6ZheTNj7qzeEU37A2mb3K1yHdpQTthK3lZu/X75yDtBbyIw3qSRofVBKkvwSlEzMOcoVdgVYA0wqj/Q82G1ggNsp95lkWv2sZ08tiaahh/yjfzCeJbblfAhtMuqVVzoI= 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=L0aONPLX; 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="L0aONPLX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523911; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dIfnqOGSQOH72XfcWRssGMHV1iaqS8FYDinT6SkIDjk=; b=L0aONPLXxzvdHp1JIHZC+0II1jdX5vchpaXb0RO/OK5wQyt21U1J0+bPRJ+d9+fhZvxXjq 2t6N+XMpLPV4qhW2UZ242esbb7msukr+Gmf5jpMPc010CsVSAvA0aNrGB4Idhb0mMNVGt3 lUVHTH16v9GK3QRo2b1L6l6vqEvUrnU= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-692-9kax3A6IP5Wqo44BMnVglA-1; Tue, 01 Apr 2025 12:11:50 -0400 X-MC-Unique: 9kax3A6IP5Wqo44BMnVglA-1 X-Mimecast-MFC-AGG-ID: 9kax3A6IP5Wqo44BMnVglA_1743523909 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-39135d31ca4so3063388f8f.1 for ; Tue, 01 Apr 2025 09:11:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523908; x=1744128708; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dIfnqOGSQOH72XfcWRssGMHV1iaqS8FYDinT6SkIDjk=; b=sTLh539faEhtYiq9EeUwO7TZpdYesjEkL5YSaoDYuJ2nkA5ggbu3GdgP7qdZQEQ9Rq boXmPtWmueSOWeY8gO6HRjLQSd+rOCNbREgwMAlqVneDzv8ghca395dQvPnrOMzVyrIK Cb7bG38rV+DUz6nAljb/xiX37wCOKFPgYEiSf+Ya7NT8WCoItl8YB4Q1aLvpp1gFBqf+ rO9p/3gtAS6xrihP+zGDyKprWFco7SuhVIweCRibdHA9WVlpjE+2+hlytsmcCadrUETq xueEmID6IlbE2qAtIdTrS6xyOf/pOH5ELFjRElYUpaInnlRKOCED5Ky4XiJgr5skQ9+D 12oA== X-Gm-Message-State: AOJu0YxfqiOEvjGd6/2gEiFN5EoL2LhSfgaIVZ8CqV9kJN1xWwG5IldF VuOCE/Rmi0+7Ngie5Yyh5oqOi1/YJC4J9/Vb0vdBnbI0G5eWAbrOMsDRFEQ8xfBTbHVOtujRyCy lABjxo5uZmu/xE3idwp7ig/a9efEp+qMrOGYp/9miE4ZUmJOMRuidMHkElLSGBNQVUCSOTwfuyJ EMZA8pdi2ypMto0M+xm0bC5foHDgPVsBcmHVPPMg1Ucw4XgQ== X-Gm-Gg: ASbGncsVAPoDEXGgPXe/In+mb956yYU9A5a0bCoccsS1FjvvPQIG21xdbXxO7X7oQBl pN3ATRRAthkZKdAnKvdWHdcJi8Xys7AT5bIe2O7Xn1aps3Xi0F+1hwhXRZ8z+PvBcZk2mX4nBAA v+kXhiGeRP3Svq2Ye7Xj7COdddXAmCklrpImRPLGgp1MQJ4lwTzVOp4bSwuCwo+LadGi13+rMjO MY4YxOCyefmhgl9quYYOJzUb0o9UTUSJAoB/F6M0UBqv3WL8Bht39wd0RhIE4OmnXzbjLp8pe+j hBSyDmzHSxVEAlpsgP9dTA== X-Received: by 2002:a05:6000:18a2:b0:39c:dfa:e86c with SMTP id ffacd0b85a97d-39c27efc018mr542266f8f.13.1743523908039; Tue, 01 Apr 2025 09:11:48 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFEH9kQ+udDvKebNrdMvaVgGuN+oLXLUK6O9cvy6KAk/oIwzHbZqyR7QPJ1CTGQr9niaqGFOA== X-Received: by 2002:a05:6000:18a2:b0:39c:dfa:e86c with SMTP id ffacd0b85a97d-39c27efc018mr542224f8f.13.1743523907620; Tue, 01 Apr 2025 09:11:47 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b66ad1esm14707692f8f.52.2025.04.01.09.11.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:46 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 14/29] KVM: pass plane to kvm_arch_vcpu_create Date: Tue, 1 Apr 2025 18:10:51 +0200 Message-ID: <20250401161106.790710-15-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Pass the plane to architecture-specific code, so that it can also share backing data between plane 0 and the non-zero planes. Signed-off-by: Paolo Bonzini --- arch/arm64/kvm/arm.c | 2 +- arch/loongarch/kvm/vcpu.c | 2 +- arch/mips/kvm/mips.c | 2 +- arch/powerpc/kvm/powerpc.c | 2 +- arch/riscv/kvm/vcpu.c | 2 +- arch/s390/kvm/kvm-s390.c | 2 +- arch/x86/kvm/x86.c | 2 +- include/linux/kvm_host.h | 2 +- virt/kvm/kvm_main.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 94fae442a8b8..3df9a7c164a3 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -427,7 +427,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned i= nt id) return 0; } =20 -int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { int err; =20 diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 470c79e79281..71b0fd05917f 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -1479,7 +1479,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned= int id) return 0; } =20 -int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { unsigned long timer_hz; struct loongarch_csrs *csr; diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 77637d201699..fec95594c041 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -275,7 +275,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned i= nt id) return 0; } =20 -int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { int err, size; void *gebase, *p, *handler, *refill_start, *refill_end; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index a39919dbaffb..359ca3924461 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -762,7 +762,7 @@ static enum hrtimer_restart kvmppc_decrementer_wakeup(s= truct hrtimer *timer) return HRTIMER_NORESTART; } =20 -int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { int err; =20 diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 55fb16307cc6..0f114c01484e 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -107,7 +107,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned i= nt id) return 0; } =20 -int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { int rc; struct kvm_cpu_context *cntx; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 46759021e924..8e3f8bc04a42 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -3970,7 +3970,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned= int id) return 0; } =20 -int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { struct sie_page *sie_page; int rc; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2c8bdb139b75..9f699f056ce6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -12293,7 +12293,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsign= ed int id) return kvm_x86_call(vcpu_precreate)(kvm); } =20 -int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { struct page *page; int r; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 99fd90c5d71b..16a8b3adb76d 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1622,7 +1622,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu); void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu); int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id); -int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu); +int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane); void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu); =20 diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 06fa2a6ad96f..cb04fe6f8a2c 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4207,7 +4207,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm_plane = *plane, struct kvm_vcpu *pl vcpu->dirty_ring =3D &plane0_vcpu->__dirty_ring; kvm_vcpu_init(vcpu, plane, id); =20 - r =3D kvm_arch_vcpu_create(vcpu); + r =3D kvm_arch_vcpu_create(vcpu, plane); if (r) goto vcpu_free_dirty_ring; =20 --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 9C7E82206BF for ; Tue, 1 Apr 2025 16:11:58 +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=1743523920; cv=none; b=AllMgTmFYm1kM5DOD3u1gFMuUNq1nZ7jE4IsbSOdaYBtgTatDRTIjl8O21yeJPqYXoa/7EcKXAw19E4XydlfsaBIXR9khEBmyls3nnSZanytDMLniaq9Kz87CURtYsdBrFlHHtvGhgQFdg33tgJo/51LpioNOjjttYQctG+AKTY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523920; c=relaxed/simple; bh=aUHeMAtza3lALIkrYa7Cju0Ow+Rzlcu6X1bDd+6rBGE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ir/zaJXcpJs6RleLqnYjHy3qj7sW+mB71c3OzHgNT30aOtULRC34ayGNnZopnW3XfMXeemFMPJwVTOT6jAl8RiwU5A5N5ocw7w9bBw2OmWhtVJ5Li1UFp/GnKFAz3htIQEoi/ahgep65bubbX5YtcktIIOerKDGhysCJrdpYvAI= 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=KfXaY4Or; 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="KfXaY4Or" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523917; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DC/nMXHGZlSx0sJ7rLf3alDuDl6Zb/0M1re23sBSw4g=; b=KfXaY4OrTh5qNkXM2uPRt8LL+xurGk1bB5cyjc11brzhi0R7eHPWzrSUbk2FpU5bErMLOe sdZlzbHfbedhxAQ4cUnO7I73QmEjINqDi6HswCEM489QWhIn4xZVJDfWCsbM6ClPSF21K3 JxOLZ5tLSqWxwhh5po/Er5CqP/+tfts= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-330-JHOL8XskNqSl2ex-hmMmhw-1; Tue, 01 Apr 2025 12:11:55 -0400 X-MC-Unique: JHOL8XskNqSl2ex-hmMmhw-1 X-Mimecast-MFC-AGG-ID: JHOL8XskNqSl2ex-hmMmhw_1743523912 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43d51bd9b41so51390285e9.3 for ; Tue, 01 Apr 2025 09:11:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523911; x=1744128711; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DC/nMXHGZlSx0sJ7rLf3alDuDl6Zb/0M1re23sBSw4g=; b=EqbuA8G0DRPOoHTLoqaqT48MDIlY6mZJNMRggre12leMIKFaIPiQlA7COJCBPRbH2W EJQNbzS7DTXWHaSRLRWVxvUFKIT5vHboswVW6j4VFLiUgvfp+SHNa4jKWiJjxSnOPH2k hMthzzXO+55WRgp1bJ0+Q4KxQKVDK/alpHig1UNhLb2PJHo0ecxAz6Wikt1D88cwL8XU Oki8XpSTVk8TeTBCiOmLU/3t+DVvpirwz5m2UiHbWIAt879pY5oLyOwn11vE7slzyr2x Bgx3MgarkeXz6NOxvTJNpJJB8Ht2Dz5HQCR0LweYNlS7PyDMGVBLy3+STx61zMr2flrm 1naQ== X-Gm-Message-State: AOJu0Yw6b9ju4wi3o/pqUHvxeo24jvZ9hODDR0uZhwphFEYU8fqB8cnE O0rCuB+MIGbodENqAidQeIqldM9yfAQUrF099adIkaKDtvdxLhcprVXrd0juwfhfHuj9C59YzE+ lCUmojLoBqQnQF61ZVTwUUyp8rTZ3E6a1wFYgVUYFKhGuuPwtx2JyhQwdy8kaPO3PrOr/l9M5yN fXFgoFmD0F519aOzOrjRJO1zRu5ERv6B06/fYI16IYtlTRjA== X-Gm-Gg: ASbGncvDKhziXboGGd/KEjzgum7GAWSsYHrj3f8Vp0qNO8ptwVnHcKhFhRuIJP1f5E3 tQBPsaoeup8005aNwhi0aBpbvlexiZuo/orYhxYAou2CYg6wzbQ/NP8AOmdoIKvxW/vPHlUhV5A +UQ3dNAAIVhtFOCb6SGMk9IayPr+EOLePrcQpF1abaxYGC8qo7W26Kv/T8yxXJeS2x4QD3fmQG0 NXdqlkJJ00qhtzHwDFnMeQxkXsaWC2S5BX/IO5kYxSSJ+x9UyM4MYVQ/6ik42aGZPOGb9hYM3ll VaXkHE9dG0m/uF/BLFK/Hw== X-Received: by 2002:a05:600c:444d:b0:43c:fe85:e4ba with SMTP id 5b1f17b1804b1-43db6248f51mr106824795e9.15.1743523910868; Tue, 01 Apr 2025 09:11:50 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE6cteiO2nE177KrCSu7vAEZTo6A+KIZLn6H0SoIEEXCGg9tK9PGpoiT8WxAi5lNC52sLjZ4w== X-Received: by 2002:a05:600c:444d:b0:43c:fe85:e4ba with SMTP id 5b1f17b1804b1-43db6248f51mr106824335e9.15.1743523910433; Tue, 01 Apr 2025 09:11:50 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b6588d0sm14276926f8f.7.2025.04.01.09.11.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:48 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 15/29] KVM: x86: pass vcpu to kvm_pv_send_ipi() Date: Tue, 1 Apr 2025 18:10:52 +0200 Message-ID: <20250401161106.790710-16-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/lapic.c | 4 ++-- arch/x86/kvm/x86.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 8240f565a764..e29694a97a19 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2334,7 +2334,7 @@ int kvm_cpu_get_extint(struct kvm_vcpu *v); int kvm_cpu_get_interrupt(struct kvm_vcpu *v); void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); =20 -int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, +int kvm_pv_send_ipi(struct kvm_vcpu *source, unsigned long ipi_bitmap_low, unsigned long ipi_bitmap_high, u32 min, unsigned long icr, int op_64_bit); =20 diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index d8d11d9fd30a..c078269f7b1d 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -861,7 +861,7 @@ static int __pv_send_ipi(unsigned long *ipi_bitmap, str= uct kvm_apic_map *map, return count; } =20 -int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, +int kvm_pv_send_ipi(struct kvm_vcpu *source, unsigned long ipi_bitmap_low, unsigned long ipi_bitmap_high, u32 min, unsigned long icr, int op_64_bit) { @@ -879,7 +879,7 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_= bitmap_low, irq.trig_mode =3D icr & APIC_INT_LEVELTRIG; =20 rcu_read_lock(); - map =3D rcu_dereference(kvm->arch.apic_map); + map =3D rcu_dereference(source->kvm->arch.apic_map); =20 count =3D -EOPNOTSUPP; if (likely(map)) { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9f699f056ce6..a527a425c55d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10101,7 +10101,7 @@ int ____kvm_emulate_hypercall(struct kvm_vcpu *vcpu= , int cpl, if (!guest_pv_has(vcpu, KVM_FEATURE_PV_SEND_IPI)) break; =20 - ret =3D kvm_pv_send_ipi(vcpu->kvm, a0, a1, a2, a3, op_64_bit); + ret =3D kvm_pv_send_ipi(vcpu, a0, a1, a2, a3, op_64_bit); break; case KVM_HC_SCHED_YIELD: if (!guest_pv_has(vcpu, KVM_FEATURE_PV_SCHED_YIELD)) --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 66E97220693 for ; Tue, 1 Apr 2025 16:11:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523919; cv=none; b=pF657aptzwY3i1jxfpq7Gqz23EZ3NeEfY9DQUdfI79CfdlXHP9FUkW+Qt0Vi+A6b3jQvyV/Rn5aA0MoSMIrR4TAOQxufXv8/s48St3gjuT2b0O4l/HdP0lpab8kcgr958YLD+p2OhqVVGoTNUnJSOAsCJ4fjJAKv7U18WMzui0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523919; c=relaxed/simple; bh=4+ShkaclNBVkSqlXTUWslO5wly515CBbMa70/QPy/14=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qZXZ0cQ8WDvseV1BO2ZEP2z15oNaqeTKpzRJUwpTMlWMr9XhgGTjCxNVCi1XrO8nPIJF6Gkl2DCHugpu85GHKcW0WLoX3l6DS01MYH90FilJXrl02LDty9DpTXfZjLlXquJ+HexTYaAJV/eWfLL5zk1E7jtW56stsEK1+8fq0HM= 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=a5ziWGK0; arc=none smtp.client-ip=170.10.129.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="a5ziWGK0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523916; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UaINNrC6inNW3Mym/pTKp2ET1N4DSwNzn/ffTCwZc4A=; b=a5ziWGK0oKoIHNuJiQnGEyZq+DPHg7XmLjZcn5tlBwoJUbdMHwT0ayn/ErPo3Bf3xIvA/7 5qXhc5Lo0TQ+dZDYi8+RjHPVO9FWf26rMuHiaIUyQGS2GEBS4PDu68Tg42LXkYu5U0oTif VC1VRMZoqL22QsTLmjy8nnsN4yipIU4= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-499-w22qqOqoNwerR4J-IIjKBw-1; Tue, 01 Apr 2025 12:11:55 -0400 X-MC-Unique: w22qqOqoNwerR4J-IIjKBw-1 X-Mimecast-MFC-AGG-ID: w22qqOqoNwerR4J-IIjKBw_1743523914 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-3914bc0cc4aso2885721f8f.3 for ; Tue, 01 Apr 2025 09:11:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523913; x=1744128713; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UaINNrC6inNW3Mym/pTKp2ET1N4DSwNzn/ffTCwZc4A=; b=GQvdHrQSTB0cJ4BEzhC5O2yOgH58Ktqui0CM2y08172oaJrupSMWnybMqVt1l4Turs qwthxNn9adzTQD1cX44nPRfvFZjMX8LLqG1eInu67WOGtWVq54jpt/6OavBbS9Nv/SOS /63lBt/r/2bhdnKx7cjiNK1Fp3UzAW9o/2+QzWGdu2g7TnjfPJAL3Jn0eZtf27f/Gklg DUuV8WYf733qvsRcIwRwcXutxNs0XKl7Ih96cAIiBb7wq3Tg8+tQRcEooJd3Ly/8ildM uc2/Oq5qmLnYWF9oW/M9gyFBUepW0RPYkwMrgf5HK3/tcFE6jUW2JTLX9eo8VB7h6O/F tMWA== X-Gm-Message-State: AOJu0Yy8OK5kO9UT1SxKN33iuzRgU0HwjEBZVJVqs8g6GRRjL+RAKiOI sv835MxQT6uuPqslZhkXl7ArWL9tBmEO3BDJnvFbK44SALTl1SxMmAFziALjN2AzQDccFWbdSy5 SydSe5SV2q8o670fKx7/Ih975vS6ojrs/J6WypK5p9c3S7xVr6GMEgwRqPQwQRkyQg9t+03Durq BjgyCoqq0idwcD2AR5IAbouZi5ngXmeSyyot4W12Dv5dT5Sg== X-Gm-Gg: ASbGncsVmo9e9HvLfaX76knvxC9UQUpbFd8/lWiM+sKi02DMosZ6FJV37SysEWyEqvQ +r+x2J9+R5w4QNzLFiA/Ms8WwP0to3qZpWQ4lGuwz9Iov4Yf/u/tYiPxQ5j4MVcrysSulIhqeN1 wcEvXRPRMv6iyrXlZvPts+ImKlf3Hnqp5A0KSpnBd4SUcolRaXFnizQLtcsECQpnm+M7GGmg1/F wLOcojMxEWMVN3ur121AES19A/BQGK1N0PyN3meBLptPL/cJD+kECcK4GIjGiTI376nu0RAxxAB qIyn9LoFvYA6LYG+hbexKQ== X-Received: by 2002:a05:6000:430e:b0:39c:268e:ae04 with SMTP id ffacd0b85a97d-39c268eae24mr2570939f8f.0.1743523913230; Tue, 01 Apr 2025 09:11:53 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEHP7UEfcGfLr0vO0H9IZqm3DR9p/GuTN1cmhrTGdbGPRl5CO1PoNYMm3svPGs26HA+6q4WUQ== X-Received: by 2002:a05:6000:430e:b0:39c:268e:ae04 with SMTP id ffacd0b85a97d-39c268eae24mr2570871f8f.0.1743523912597; Tue, 01 Apr 2025 09:11:52 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b7a41b4sm14291601f8f.85.2025.04.01.09.11.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:51 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 16/29] KVM: x86: split "if" in __kvm_set_or_clear_apicv_inhibit Date: Tue, 1 Apr 2025 18:10:53 +0200 Message-ID: <20250401161106.790710-17-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a527a425c55d..f70d9a572455 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10637,6 +10637,7 @@ void __kvm_set_or_clear_apicv_inhibit(struct kvm *k= vm, enum kvm_apicv_inhibit reason, bool set) { unsigned long old, new; + bool changed; =20 lockdep_assert_held_write(&kvm->arch.apicv_update_lock); =20 @@ -10644,10 +10645,10 @@ void __kvm_set_or_clear_apicv_inhibit(struct kvm = *kvm, return; =20 old =3D new =3D kvm->arch.apicv_inhibit_reasons; - set_or_clear_apicv_inhibit(&new, reason, set); + changed =3D (!!old !=3D !!new); =20 - if (!!old !=3D !!new) { + if (changed) { /* * Kick all vCPUs before setting apicv_inhibit_reasons to avoid * false positives in the sanity check WARN in vcpu_enter_guest(). @@ -10661,16 +10662,16 @@ void __kvm_set_or_clear_apicv_inhibit(struct kvm = *kvm, * servicing the request with a stale apicv_inhibit_reasons. */ kvm_make_all_cpus_request(kvm, KVM_REQ_APICV_UPDATE); - kvm->arch.apicv_inhibit_reasons =3D new; - if (new) { - unsigned long gfn =3D gpa_to_gfn(APIC_DEFAULT_PHYS_BASE); - int idx =3D srcu_read_lock(&kvm->srcu); + } =20 - kvm_zap_gfn_range(kvm, gfn, gfn+1); - srcu_read_unlock(&kvm->srcu, idx); - } - } else { - kvm->arch.apicv_inhibit_reasons =3D new; + kvm->arch.apicv_inhibit_reasons =3D new; + + if (changed && set) { + unsigned long gfn =3D gpa_to_gfn(APIC_DEFAULT_PHYS_BASE); + int idx =3D srcu_read_lock(&kvm->srcu); + + kvm_zap_gfn_range(kvm, gfn, gfn+1); + srcu_read_unlock(&kvm->srcu, idx); } } =20 --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 97771221703 for ; Tue, 1 Apr 2025 16:12:01 +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=1743523923; cv=none; b=OR3x+8vAc47FovmIVugug3XrFr+0VFvCEPV9eACoZ44PYAbgjZSRBcLbsL5uW25ySnyRVkx7IPMmJc/Hca3Ug6ezl/1sDef5rYkG8TKV1S8S2vbuMN4mY8Xo3rpDlkIiwxUB5diZiDwGN+HuarOB4gfE6B1H9NGB3jwlKMEYANQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523923; c=relaxed/simple; bh=2CI/mkWBrTgnbik9OCHRAn1y+W1g2QV9UjWHcVB514o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XhcMEApsptTeJynU3Gu7NZApijbWziQNncwEeS85Qocv9P/22etPxqJPqYCDi8tMNP1XpB9CUnZ+q57Me0sVdujXyGrKjXbQ/3vpi8aUfp+wj9VY5s0e+kR7ib5ULdfoT3KxlaULnIzhO0qNd9a5kcsEfqzfd2xdVg60rWej9Dw= 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=L5+R+PkQ; 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="L5+R+PkQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523920; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jloFR1LDGvNeXK6NZWVsMX9b3AeMl8ttvkfYFFUhR2s=; b=L5+R+PkQBVIojOOAGNx8XWaJ/sB5vhxU4ca2PQ7fHXyfsr4D/BFHogDf5OkNp2DV0+QA9M DEoiNwBweEuvGZ4rd/BTMQEZMunrXaPk2yIFdHL4FaNoHBoXZvATCdWpscf1yRwjGaSFBd sPPLEcRzFGOA2Xvl/LevGIN6Lut6OXA= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-448-HcHhYcCzPyOF83xDi8NCJw-1; Tue, 01 Apr 2025 12:11:59 -0400 X-MC-Unique: HcHhYcCzPyOF83xDi8NCJw-1 X-Mimecast-MFC-AGG-ID: HcHhYcCzPyOF83xDi8NCJw_1743523917 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43d0830c3f7so47371935e9.2 for ; Tue, 01 Apr 2025 09:11:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523916; x=1744128716; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jloFR1LDGvNeXK6NZWVsMX9b3AeMl8ttvkfYFFUhR2s=; b=dF8z8gnP0qXb86pp2ENL5Pw1U2h09yrd6pf8ID72Jq/nXxneoqKXQdtMu8eaZsim+P axGxVq6JpjpFUzpBkkQdQl+gczy2cHtBDCq8zcGaleP9IHfGgPGeEubbbK+lfUXNfJfT oAMYkrZg+UcJijtNCCSmk4Lx24t01OHai72Kzn5/zyV/0zGSAt5RitCz3t7MHitO5Wl0 qlEImjc6cMokFLv77o7YJy8rb1oHNoEe1niU+4GszNvqFAgm4sVpIE0oh7DTsrSTZHtl lNSKlAb0FxitHaWKR2gbLaVxUYTtkHv77mUnsMJKYWPjXLe/2pwxksdxiIIUBFHR6xrj 5aNA== X-Gm-Message-State: AOJu0Yw8f2nj3icGhIqpypx/CaPvrJKHCHPzP4Av9POAAeVYw3t4ldTI YcCPyWvXQIksMSaR+XpJav+j+b4XdViSrfaI5jqamOHjj46QGW44ZEbGOZjsg7X11O1zMJ6G9U8 flC9I7Mp9xqbFL7Ut8UXRm+jJVZef6bcy8NcYLDeXyiweY5sY1x4yfN2zf2r9JMHKQ4mhCjiWRa jR/m+afSATJNQ9FxzkkUIrWkh8iDhTwtEo95SVceEK889tug== X-Gm-Gg: ASbGnct+4TsJm4MrYY801nc2QMnkUqSx3gVlcolhF808UpxW86FT78mBmZY3cnBquMB kYJAJA1f+yOKzYc0rTnAOfJHU5v5j4/SssQdcEGhHqQSAmQ2BRO06/s8mRgHhIPy+M4ZkoVkdjR TpoSrhGJ3FBgHGc9tlUN1MANRp/1nVLj2UpqdD4HlGmnA/igRsRHoCUmCUcFh4kc2BPrapuWah5 IVOy2CXrZKkSIqrfQJIC96fF8lvY48VhrZPusGnMeQJzhqJ7wnuOb7L9DrMJSbIiQi8oVQDTSJp eoUHxcsoY0lYwi9mkfV3YA== X-Received: by 2002:a05:600c:3b9d:b0:43c:fe15:41c9 with SMTP id 5b1f17b1804b1-43db6227a09mr118810675e9.9.1743523916436; Tue, 01 Apr 2025 09:11:56 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGeSHmn91hmeZ7x284dZn+qQrcC5V3D8Ul3VDkKtIvDkX2ROgQp+v6dSPuSJJ1Vzfw+gbjPKg== X-Received: by 2002:a05:600c:3b9d:b0:43c:fe15:41c9 with SMTP id 5b1f17b1804b1-43db6227a09mr118810055e9.9.1743523915943; Tue, 01 Apr 2025 09:11:55 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d82efe9d1sm203529975e9.24.2025.04.01.09.11.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:53 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 17/29] KVM: x86: block creating irqchip if planes are active Date: Tue, 1 Apr 2025 18:10:54 +0200 Message-ID: <20250401161106.790710-18-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Force creating the irqchip before planes, so that APICV_INHIBIT_REASON_ABSE= NT only needs to be removed from plane 0. Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 6 ++++-- arch/x86/kvm/x86.c | 4 ++-- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index e1c67bc6df47..16d836b954dc 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -882,6 +882,8 @@ On s390, a dummy irq routing table is created. Note that on s390 the KVM_CAP_S390_IRQCHIP vm capability needs to be enabl= ed before KVM_CREATE_IRQCHIP can be used. =20 +The interrupt controller must be created before any extra VM planes. + =20 4.25 KVM_IRQ_LINE ----------------- @@ -7792,8 +7794,8 @@ used in the IRQ routing table. The first args[0] MSI= routes are reserved for the IOAPIC pins. Whenever the LAPIC receives an EOI for these routes, a KVM_EXIT_IOAPIC_EOI vmexit will be reported to userspace. =20 -Fails if VCPU has already been created, or if the irqchip is already in the -kernel (i.e. KVM_CREATE_IRQCHIP has already been called). +Fails if VCPUs or planes have already been created, or if the irqchip is +already in the kernel (i.e. KVM_CREATE_IRQCHIP has already been called). =20 7.6 KVM_CAP_S390_RI ------------------- diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f70d9a572455..653886e6e1c8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6561,7 +6561,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, r =3D -EEXIST; if (irqchip_in_kernel(kvm)) goto split_irqchip_unlock; - if (kvm->created_vcpus) + if (kvm->created_vcpus || kvm->has_planes) goto split_irqchip_unlock; /* Pairs with irqchip_in_kernel. */ smp_wmb(); @@ -7087,7 +7087,7 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int= ioctl, unsigned long arg) goto create_irqchip_unlock; =20 r =3D -EINVAL; - if (kvm->created_vcpus) + if (kvm->created_vcpus || kvm->has_planes) goto create_irqchip_unlock; =20 r =3D kvm_pic_init(kvm); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 16a8b3adb76d..152dc5845309 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -883,6 +883,7 @@ struct kvm { bool dirty_ring_with_bitmap; bool vm_bugged; bool vm_dead; + bool has_planes; =20 #ifdef CONFIG_HAVE_KVM_PM_NOTIFIER struct notifier_block pm_notifier; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index cb04fe6f8a2c..db38894f6fa3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5316,6 +5316,7 @@ static int kvm_vm_ioctl_create_plane(struct kvm *kvm,= unsigned id) return fd; =20 plane =3D kvm_create_vm_plane(kvm, id); + kvm->has_planes =3D true; if (IS_ERR(plane)) { r =3D PTR_ERR(plane); goto put_fd; --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 E676522172F for ; Tue, 1 Apr 2025 16:12:02 +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=1743523924; cv=none; b=OQRz+othiROxngsb2AJZx+kpbOmVIy7GQ2KNI0iPgaBwAvpCdEje4Vwu3l1DWuPS68fWZGp2fvtKasi3BpG1F3fGtbJg1WiKuDM+7nFDqDfbZ8njSk1GjEoIFFVA8eveYTuAUfQfOyIrn0fylEPevOVTlfcS85EQKNHgzML05Gw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523924; c=relaxed/simple; bh=ZS7aDIfTrGTsc3CaJTz/rmizqT3vdz4Mep7cX4xxC20=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cbo6Bhtn7BK9jVoYnzFd57guzghOfROHCGbTyf8PPukzRuHHJ1E1zK6e9UKvE2O29eOFFPKtB4ZzThU6luryb+QdkDXtVbWN1ixh/yu6WQLFTFg4nTID0YyHRJDrmH6bvMr98i2j36tIbo60k3WUmt2m2FdY2SohuQZN4mQ8IbY= 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=HvdamQs4; 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="HvdamQs4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523922; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MGWdj9YvBEqpmgwNvC3/3vvpLMl37emPFU+fvsJE+7I=; b=HvdamQs4gLOoBOKuGz0sqg6xxb54vyijXCnWFO/WNcRBnCGrNk8zegmyIb4XD0nogrbd5y ZTR3hwB4Qjo0oJhDJy3gHbxJ4ACilyOcEm9cg9l+NLRivjzIit3rnqPW5MhneoBNpwMiTq t+CnDB6X6wgfbN0+2IFu8DDwv7Gk6RM= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-474-xQQT1V8EPjmXFrb3wctkGw-1; Tue, 01 Apr 2025 12:12:00 -0400 X-MC-Unique: xQQT1V8EPjmXFrb3wctkGw-1 X-Mimecast-MFC-AGG-ID: xQQT1V8EPjmXFrb3wctkGw_1743523920 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43d007b2c79so47306405e9.2 for ; Tue, 01 Apr 2025 09:12:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523919; x=1744128719; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MGWdj9YvBEqpmgwNvC3/3vvpLMl37emPFU+fvsJE+7I=; b=M6vYXervfdqgCBT7VzlLuh1UqdvnrLoRvXO7PCnCkLCF9H+YbRIuQLC0JSkaZsNXy7 DYkxjtYTAk/Vw4RjRP2ypNL08nQx0Egfh2d99RBLpZas4+A5tkgnIUh69wNbnjojy2cG mgFWyf0h6chk0Xq8Ekg550zGGjMGcqKDjSiGHfGXzCDhz0JyM1KVtJi4Z3o9MRYwf3Gk Ui1Mv+t/BBnVDGJ8b2t7AE6BZ4/7gHf/92KiLouzEhAxMIdJNfl+lMIHYqpM9U36I21I uT9VwM8f3OqM9VQxX3flvZggWl80eoRMzkpPBZwN6OARYJEBTGMrBh5dU2mloA1B9KUu yjkQ== X-Gm-Message-State: AOJu0YwyGxxKXbXQBmemOJkQ4JOtn1Kj1tLCieC18mvHIXOS/F/hQTLK CBt0F5tkPIbnJV4XbO4hyFQf4+GjjdHYOHVlUo543PppS7DXi5c2xGJ9tIG6FPtxdlnFeISlLWs 3lGbYiPUFqDAjlQxkKphsRcNJwi68xZveuUpNgxfGVHrzqoSh55B5iFqffVT8rHyTDzdTwqQKju Xlrq3k0zrKSiOzi+9vDIhcqiky34Xa2q7xovycNLfwzGxWfQ== X-Gm-Gg: ASbGnctMG86kELkXc9Ak0DI8eFXmsxyFGYnoNkuV5R8j9fcSOmAZPKsvXArQzJAdkml ZR9vs/oU9vVZKzevHnUwT1KJT5DGAhCJT44G7J796KqIhw5k2OVxUhvPsB/OrwvvcOdw8rFrRGN P6sQ224jjWQy2qwcY1fr847n5QOSJma/Izi0/oWbyDo2O3SJFrQORouCJAqur0B9BXu0FF9gwZB FC8Q50mpayHuipFhNHSjps8hFUvNgpWQidAEHUKL6MeIwO+R/nw/N4yWQs96N3vkwSjpXcU5HJs /3cn5MXq72qJprE6idneMQ== X-Received: by 2002:a05:6000:2508:b0:39c:2688:4ebf with SMTP id ffacd0b85a97d-39c26884ef7mr2250165f8f.6.1743523918702; Tue, 01 Apr 2025 09:11:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHej+s4j6aGPDin98dlsYk56EQfZoCit5BuzqKpA6tBi49RGgt4j5M4CiOy46C9AQy9PMLW9Q== X-Received: by 2002:a05:6000:2508:b0:39c:2688:4ebf with SMTP id ffacd0b85a97d-39c26884ef7mr2250116f8f.6.1743523918194; Tue, 01 Apr 2025 09:11:58 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0ddeecc9sm13258499f8f.83.2025.04.01.09.11.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:57 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 18/29] KVM: x86: track APICv inhibits per plane Date: Tue, 1 Apr 2025 18:10:55 +0200 Message-ID: <20250401161106.790710-19-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" As a first step towards per-plane APIC maps, track APICv inhibits per plane. Most of the inhibits are set or cleared when building the map, and the virtual machine as a whole will have the OR of the inhibits of the individual plane. Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 21 +++++---- arch/x86/kvm/hyperv.c | 2 +- arch/x86/kvm/i8254.c | 4 +- arch/x86/kvm/lapic.c | 15 +++--- arch/x86/kvm/svm/sev.c | 2 +- arch/x86/kvm/svm/svm.c | 3 +- arch/x86/kvm/x86.c | 83 +++++++++++++++++++++++++-------- include/linux/kvm_host.h | 2 +- 8 files changed, 90 insertions(+), 42 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index e29694a97a19..d07ab048d7cc 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1087,6 +1087,7 @@ struct kvm_arch_memory_slot { }; =20 struct kvm_arch_plane { + unsigned long apicv_inhibit_reasons; }; =20 /* @@ -1299,11 +1300,13 @@ enum kvm_apicv_inhibit { /* * PIT (i8254) 're-inject' mode, relies on EOI intercept, * which AVIC doesn't support for edge triggered interrupts. + * Applied only to plane 0. */ APICV_INHIBIT_REASON_PIT_REINJ, =20 /* - * AVIC is disabled because SEV doesn't support it. + * AVIC is disabled because SEV doesn't support it. Sticky and applied + * only to plane 0. */ APICV_INHIBIT_REASON_SEV, =20 @@ -2232,21 +2235,21 @@ gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vc= pu, gva_t gva, bool kvm_apicv_activated(struct kvm *kvm); bool kvm_vcpu_apicv_activated(struct kvm_vcpu *vcpu); void __kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu); -void __kvm_set_or_clear_apicv_inhibit(struct kvm *kvm, +void __kvm_set_or_clear_apicv_inhibit(struct kvm_plane *plane, enum kvm_apicv_inhibit reason, bool set); -void kvm_set_or_clear_apicv_inhibit(struct kvm *kvm, +void kvm_set_or_clear_apicv_inhibit(struct kvm_plane *plane, enum kvm_apicv_inhibit reason, bool set); =20 -static inline void kvm_set_apicv_inhibit(struct kvm *kvm, +static inline void kvm_set_apicv_inhibit(struct kvm_plane *plane, enum kvm_apicv_inhibit reason) { - kvm_set_or_clear_apicv_inhibit(kvm, reason, true); + kvm_set_or_clear_apicv_inhibit(plane, reason, true); } =20 -static inline void kvm_clear_apicv_inhibit(struct kvm *kvm, +static inline void kvm_clear_apicv_inhibit(struct kvm_plane *plane, enum kvm_apicv_inhibit reason) { - kvm_set_or_clear_apicv_inhibit(kvm, reason, false); + kvm_set_or_clear_apicv_inhibit(plane, reason, false); } =20 int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_= code, @@ -2360,8 +2363,8 @@ void kvm_make_scan_ioapic_request(struct kvm *kvm); void kvm_make_scan_ioapic_request_mask(struct kvm *kvm, unsigned long *vcpu_bitmap); =20 -static inline void kvm_arch_init_plane(struct kvm_plane *plane) {} -static inline void kvm_arch_free_plane(struct kvm_plane *plane) {} +void kvm_arch_init_plane(struct kvm_plane *plane); +void kvm_arch_free_plane(struct kvm_plane *plane); =20 bool kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, struct kvm_async_pf *work); diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index c6592e7f40a2..a522b467be48 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -145,7 +145,7 @@ static void synic_update_vector(struct kvm_vcpu_hv_syni= c *synic, * Inhibit APICv if any vCPU is using SynIC's AutoEOI, which relies on * the hypervisor to manually inject IRQs. */ - __kvm_set_or_clear_apicv_inhibit(vcpu->kvm, + __kvm_set_or_clear_apicv_inhibit(vcpu_to_plane(vcpu), APICV_INHIBIT_REASON_HYPERV, !!hv->synic_auto_eoi_used); =20 diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index e3a3e7b90c26..ded1a9565c36 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -306,13 +306,13 @@ void kvm_pit_set_reinject(struct kvm_pit *pit, bool r= einject) * So, deactivate APICv when PIT is in reinject mode. */ if (reinject) { - kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_PIT_REINJ); + kvm_set_apicv_inhibit(kvm->planes[0], APICV_INHIBIT_REASON_PIT_REINJ); /* The initial state is preserved while ps->reinject =3D=3D 0. */ kvm_pit_reset_reinject(pit); kvm_register_irq_ack_notifier(kvm, &ps->irq_ack_notifier); kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier); } else { - kvm_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_PIT_REINJ); + kvm_clear_apicv_inhibit(kvm->planes[0], APICV_INHIBIT_REASON_PIT_REINJ); kvm_unregister_irq_ack_notifier(kvm, &ps->irq_ack_notifier); kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier); } diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index c078269f7b1d..4077c8d1e37e 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -377,6 +377,7 @@ enum { =20 static void kvm_recalculate_apic_map(struct kvm *kvm) { + struct kvm_plane *plane =3D kvm->planes[0]; struct kvm_apic_map *new, *old =3D NULL; struct kvm_vcpu *vcpu; unsigned long i; @@ -456,19 +457,19 @@ static void kvm_recalculate_apic_map(struct kvm *kvm) * map also applies to APICv. */ if (!new) - kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_PHYSICAL_ID_ALIASED); + kvm_set_apicv_inhibit(plane, APICV_INHIBIT_REASON_PHYSICAL_ID_ALIASED); else - kvm_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_PHYSICAL_ID_ALIASED); + kvm_clear_apicv_inhibit(plane, APICV_INHIBIT_REASON_PHYSICAL_ID_ALIASED); =20 if (!new || new->logical_mode =3D=3D KVM_APIC_MODE_MAP_DISABLED) - kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_LOGICAL_ID_ALIASED); + kvm_set_apicv_inhibit(plane, APICV_INHIBIT_REASON_LOGICAL_ID_ALIASED); else - kvm_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_LOGICAL_ID_ALIASED); + kvm_clear_apicv_inhibit(plane, APICV_INHIBIT_REASON_LOGICAL_ID_ALIASED); =20 if (xapic_id_mismatch) - kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_APIC_ID_MODIFIED); + kvm_set_apicv_inhibit(plane, APICV_INHIBIT_REASON_APIC_ID_MODIFIED); else - kvm_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_APIC_ID_MODIFIED); + kvm_clear_apicv_inhibit(plane, APICV_INHIBIT_REASON_APIC_ID_MODIFIED); =20 old =3D rcu_dereference_protected(kvm->arch.apic_map, lockdep_is_held(&kvm->arch.apic_map_lock)); @@ -2630,7 +2631,7 @@ static void __kvm_apic_set_base(struct kvm_vcpu *vcpu= , u64 value) =20 if ((value & MSR_IA32_APICBASE_ENABLE) && apic->base_address !=3D APIC_DEFAULT_PHYS_BASE) { - kvm_set_apicv_inhibit(apic->vcpu->kvm, + kvm_set_apicv_inhibit(vcpu_to_plane(vcpu), APICV_INHIBIT_REASON_APIC_BASE_MODIFIED); } } diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 827dbe4d2b3b..130d895f1d95 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -458,7 +458,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm= _sev_cmd *argp, INIT_LIST_HEAD(&sev->mirror_vms); sev->need_init =3D false; =20 - kvm_set_apicv_inhibit(kvm, APICV_INHIBIT_REASON_SEV); + kvm_set_apicv_inhibit(kvm->planes[0], APICV_INHIBIT_REASON_SEV); =20 return 0; =20 diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index f6a435ff7e2d..917bfe8db101 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3926,7 +3926,8 @@ static void svm_enable_irq_window(struct kvm_vcpu *vc= pu) * the VM wide AVIC inhibition. */ if (!is_guest_mode(vcpu)) - kvm_set_apicv_inhibit(vcpu->kvm, APICV_INHIBIT_REASON_IRQWIN); + kvm_set_apicv_inhibit(vcpu_to_plane(vcpu), + APICV_INHIBIT_REASON_IRQWIN); =20 svm_set_vintr(svm); } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 653886e6e1c8..382d8ace131f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6567,7 +6567,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, smp_wmb(); kvm->arch.irqchip_mode =3D KVM_IRQCHIP_SPLIT; kvm->arch.nr_reserved_ioapic_pins =3D cap->args[0]; - kvm_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_ABSENT); + kvm_clear_apicv_inhibit(kvm->planes[0], APICV_INHIBIT_REASON_ABSENT); r =3D 0; split_irqchip_unlock: mutex_unlock(&kvm->lock); @@ -7109,7 +7109,7 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int= ioctl, unsigned long arg) /* Write kvm->irq_routing before enabling irqchip_in_kernel. */ smp_wmb(); kvm->arch.irqchip_mode =3D KVM_IRQCHIP_KERNEL; - kvm_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_ABSENT); + kvm_clear_apicv_inhibit(kvm->planes[0], APICV_INHIBIT_REASON_ABSENT); create_irqchip_unlock: mutex_unlock(&kvm->lock); break; @@ -9996,14 +9996,18 @@ static void set_or_clear_apicv_inhibit(unsigned lon= g *inhibits, trace_kvm_apicv_inhibit_changed(reason, set, *inhibits); } =20 -static void kvm_apicv_init(struct kvm *kvm) +static void kvm_apicv_init(struct kvm *kvm, unsigned long *apicv_inhibit_r= easons) { - enum kvm_apicv_inhibit reason =3D enable_apicv ? APICV_INHIBIT_REASON_ABS= ENT : - APICV_INHIBIT_REASON_DISABLED; + enum kvm_apicv_inhibit reason; =20 - set_or_clear_apicv_inhibit(&kvm->arch.apicv_inhibit_reasons, reason, true= ); + if (!enable_apicv) + reason =3D APICV_INHIBIT_REASON_DISABLED; + else if (!irqchip_kernel(kvm)) + reason =3D APICV_INHIBIT_REASON_ABSENT; + else + return; =20 - init_rwsem(&kvm->arch.apicv_update_lock); + set_or_clear_apicv_inhibit(apicv_inhibit_reasons, reason, true); } =20 static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id) @@ -10633,10 +10637,22 @@ static void kvm_vcpu_update_apicv(struct kvm_vcpu= *vcpu) __kvm_vcpu_update_apicv(vcpu); } =20 -void __kvm_set_or_clear_apicv_inhibit(struct kvm *kvm, +static bool kvm_compute_apicv_inhibit(struct kvm *kvm, + enum kvm_apicv_inhibit reason) +{ + int i; + for (i =3D 0; i < KVM_MAX_VCPU_PLANES; i++) + if (test_bit(reason, &kvm->planes[i]->arch.apicv_inhibit_reasons)) + return true; + + return false; +} + +void __kvm_set_or_clear_apicv_inhibit(struct kvm_plane *plane, enum kvm_apicv_inhibit reason, bool set) { - unsigned long old, new; + struct kvm *kvm =3D plane->kvm; + unsigned long local, global; bool changed; =20 lockdep_assert_held_write(&kvm->arch.apicv_update_lock); @@ -10644,9 +10660,24 @@ void __kvm_set_or_clear_apicv_inhibit(struct kvm *= kvm, if (!(kvm_x86_ops.required_apicv_inhibits & BIT(reason))) return; =20 - old =3D new =3D kvm->arch.apicv_inhibit_reasons; - set_or_clear_apicv_inhibit(&new, reason, set); - changed =3D (!!old !=3D !!new); + local =3D plane->arch.apicv_inhibit_reasons; + set_or_clear_apicv_inhibit(&local, reason, set); + + /* Could this flip change the global state? */ + global =3D kvm->arch.apicv_inhibit_reasons; + if ((local & BIT(reason)) =3D=3D (global & BIT(reason))) { + /* Easy case 1, the bit is now the same as for the whole VM. */ + changed =3D false; + } else if (set) { + /* Easy case 2, maybe the bit flipped globally from clear to set? */ + changed =3D !global; + set_or_clear_apicv_inhibit(&global, reason, set); + } else { + /* Harder case, check if no other plane had this inhibit. */ + set =3D kvm_compute_apicv_inhibit(kvm, reason); + set_or_clear_apicv_inhibit(&global, reason, set); + changed =3D !global; + } =20 if (changed) { /* @@ -10664,7 +10695,8 @@ void __kvm_set_or_clear_apicv_inhibit(struct kvm *k= vm, kvm_make_all_cpus_request(kvm, KVM_REQ_APICV_UPDATE); } =20 - kvm->arch.apicv_inhibit_reasons =3D new; + plane->arch.apicv_inhibit_reasons =3D local; + kvm->arch.apicv_inhibit_reasons =3D global; =20 if (changed && set) { unsigned long gfn =3D gpa_to_gfn(APIC_DEFAULT_PHYS_BASE); @@ -10675,14 +10707,17 @@ void __kvm_set_or_clear_apicv_inhibit(struct kvm = *kvm, } } =20 -void kvm_set_or_clear_apicv_inhibit(struct kvm *kvm, +void kvm_set_or_clear_apicv_inhibit(struct kvm_plane *plane, enum kvm_apicv_inhibit reason, bool set) { + struct kvm *kvm; + if (!enable_apicv) return; =20 + kvm =3D plane->kvm; down_write(&kvm->arch.apicv_update_lock); - __kvm_set_or_clear_apicv_inhibit(kvm, reason, set); + __kvm_set_or_clear_apicv_inhibit(plane, reason, set); up_write(&kvm->arch.apicv_update_lock); } EXPORT_SYMBOL_GPL(kvm_set_or_clear_apicv_inhibit); @@ -12083,24 +12118,26 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu= *vcpu, return ret; } =20 -static void kvm_arch_vcpu_guestdbg_update_apicv_inhibit(struct kvm *kvm) +static void kvm_arch_vcpu_guestdbg_update_apicv_inhibit(struct kvm_plane *= plane) { bool set =3D false; + struct kvm *kvm; struct kvm_vcpu *vcpu; unsigned long i; =20 if (!enable_apicv) return; =20 + kvm =3D plane->kvm; down_write(&kvm->arch.apicv_update_lock); =20 - kvm_for_each_vcpu(i, vcpu, kvm) { + kvm_for_each_plane_vcpu(i, vcpu, plane) { if (vcpu->guest_debug & KVM_GUESTDBG_BLOCKIRQ) { set =3D true; break; } } - __kvm_set_or_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_BLOCKIRQ, set); + __kvm_set_or_clear_apicv_inhibit(plane, APICV_INHIBIT_REASON_BLOCKIRQ, se= t); up_write(&kvm->arch.apicv_update_lock); } =20 @@ -12156,7 +12193,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_= vcpu *vcpu, =20 kvm_x86_call(update_exception_bitmap)(vcpu); =20 - kvm_arch_vcpu_guestdbg_update_apicv_inhibit(vcpu->kvm); + kvm_arch_vcpu_guestdbg_update_apicv_inhibit(vcpu_to_plane(vcpu)); =20 r =3D 0; =20 @@ -12732,6 +12769,11 @@ void kvm_arch_free_vm(struct kvm *kvm) } =20 =20 +void kvm_arch_init_plane(struct kvm_plane *plane) +{ + kvm_apicv_init(plane->kvm, &plane->arch.apicv_inhibit_reasons); +} + int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { int ret; @@ -12767,6 +12809,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long= type) set_bit(KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); =20 + init_rwsem(&kvm->arch.apicv_update_lock); raw_spin_lock_init(&kvm->arch.tsc_write_lock); mutex_init(&kvm->arch.apic_map_lock); seqcount_raw_spinlock_init(&kvm->arch.pvclock_sc, &kvm->arch.tsc_write_lo= ck); @@ -12789,7 +12832,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long= type) INIT_DELAYED_WORK(&kvm->arch.kvmclock_update_work, kvmclock_update_fn); INIT_DELAYED_WORK(&kvm->arch.kvmclock_sync_work, kvmclock_sync_fn); =20 - kvm_apicv_init(kvm); + kvm_apicv_init(kvm, &kvm->arch.apicv_inhibit_reasons); kvm_hv_init_vm(kvm); kvm_xen_init_vm(kvm); =20 diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 152dc5845309..5cade1c04646 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -943,7 +943,7 @@ static inline struct kvm_plane *vcpu_to_plane(struct kv= m_vcpu *vcpu) #else static inline struct kvm_plane *vcpu_to_plane(struct kvm_vcpu *vcpu) { - return vcpu->kvm->planes[vcpu->plane_id]; + return vcpu->kvm->planes[vcpu->plane]; } #endif =20 --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 79D66221D96 for ; Tue, 1 Apr 2025 16:12:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523927; cv=none; b=E5hmbyc82j1r+f7T8f5+hYFqDZt+SOZV/5yCwSF2hxXNP6LL5irhwcbA1z4VD1HzOAMYLbL7UFYMJ9qs3MCzRL4e0MY59UsGR/4jwOK9TgItxpENtvEQ/ZUx7v0e5HfQVIvuC5Bauzjv1+dBotZpRnVYEu67gte+blKTwX5q8p0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523927; c=relaxed/simple; bh=5tt6gGijGYJr7yu5paRKM0yRgVu/D/f2JfLQVjaI0xc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Imqg6E0mj2m4LNKiXSwgK1RoLoohbLavt+iz+X/oYoLTn+hartN9HPwV/UAzspJ4OGwzpHbsKndRajnuQM7JCKcmE52LcSETpsdFwLHGpGQzK+T2CWs0eaYKFiSwlqcZwkp8WhNwy/xhyRxBaqnYAFDT/8vWqLoM5YEnR1Ko0Yc= 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=YRf6/fdZ; arc=none smtp.client-ip=170.10.129.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="YRf6/fdZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523924; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VvZ6p2WrQQTblruIVD9gbYy1bh08r8hJdsaxuYeoEEI=; b=YRf6/fdZlmOzuZ1tk+FLjaAqDGz1twfqzvDg0uvtopLWgWSsJwZk5AsdfDQogn0FRohkOg EMKSt5pfYf8yrRHympdx+P1kK6+ImX8TjMf5ycMcbZ0IYO+7oQrVeD3Cf1wupE6u+hWzC2 hpbr0EdK6BLzWq1lyE/pnIAgp7Dum4c= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-423-lgt7YKawPAedr5tC9m9U_A-1; Tue, 01 Apr 2025 12:12:03 -0400 X-MC-Unique: lgt7YKawPAedr5tC9m9U_A-1 X-Mimecast-MFC-AGG-ID: lgt7YKawPAedr5tC9m9U_A_1743523922 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-3912b54611dso3080931f8f.1 for ; Tue, 01 Apr 2025 09:12:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523922; x=1744128722; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VvZ6p2WrQQTblruIVD9gbYy1bh08r8hJdsaxuYeoEEI=; b=FGQHb7Odzv5uSFDnryEqUv4Y37cjwq/HMMpmCOvvv56qrb0NL3TE8V3LDKG6mWNg0x b2KXje4b1mNlgbjMuaZ9G7Vdx95BSgU7OL4a8plK7UsvxZeO5rt9poKaiU8wROOIEhLj O4KV3YPFz540nvrf0A/SkIhGW/i69vB+DvRzBa5eb5Ie0N9XvAuhlq9M0Von8nWob3Np O+jJs912vyZ21yCKX2XVFJHAF68b3oyc8Ay22C29fxYMjD6dPgXV7fWvEkMj/emMaNNR 4kXzRpbemZDJPYkZh/ipQcFAJRcjy9qAkF/8ABM7fMLmAhk8jjoGYdFq1JltXsIG2Ya1 GDyg== X-Gm-Message-State: AOJu0YwuTd22hEkP8iC+DdevjyEhUw1ahUJZ3qO76XhxypzcXwY5Xq71 5a0RYvzIBUObS2BcGKWI/L3QQlYQXTGqc/H8LUn1HPsvLG96/+6sy/5DQ7wOFhZtSZNWCrW0N0z uP9bYpfqc2VRAy1pUTepWUdP9sbAK35Y7uyBBMhBrvVrYcdMWhfsr/lpst9v82DXxSkjLbFRc0H W4/fK2s89rdwvfqp/iMCRk/WVJFBTayNHCiOxoxwi5LDYdVQ== X-Gm-Gg: ASbGncv6/c34kv3AqUG3fm5N0f3tuA84N1RtlgFuZIvWqrE0ybu6VLB7qhXjNSqBail CuWPdZnC6oNOq86E2d3dyDE6m3TeST8F4gh1TX8sJ4DFHVQgptDLw1NltPKieLPVQbiiO1NWo0O sTyH3BInyllQY2I/HOwpwQuFCQRoGspqHhevtRaMp561jEI5j6ng7e7jzJ0X0YOVwbt3bAy7Z/V OQbH+QxCs6LqHsikOnMcHuSHtgEhpfYeXJP9kaMtj5iEmVHZGv3fACWnQSSYKl7I3QU7sgakyfo Fy/wCDBKj1M0GHZpqOwCkg== X-Received: by 2002:a05:6000:290f:b0:390:f552:d291 with SMTP id ffacd0b85a97d-39c120dc53emr14114223f8f.22.1743523921499; Tue, 01 Apr 2025 09:12:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFEjZPOv67fdn5slA2kWJTIKa56TO0rlWQ9//KKstMEhjPv7ui4gb+V8jJo68vRdLNVttSIuA== X-Received: by 2002:a05:6000:290f:b0:390:f552:d291 with SMTP id ffacd0b85a97d-39c120dc53emr14114152f8f.22.1743523920948; Tue, 01 Apr 2025 09:12:00 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b79e33asm14665265f8f.66.2025.04.01.09.11.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:11:59 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 19/29] KVM: x86: move APIC map to kvm_arch_plane Date: Tue, 1 Apr 2025 18:10:56 +0200 Message-ID: <20250401161106.790710-20-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" IRQs need to be directed to the appropriate plane (typically, but not always, the same as the vCPU that is running). Because each plane has a separate struct kvm_vcpu *, the map that holds the pointers to them must be individual to the plane as well. This works fine as long as all IRQs (even those directed at multiple CPUs) only target a single plane. Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 7 +-- arch/x86/kvm/lapic.c | 94 +++++++++++++++++++-------------- arch/x86/kvm/svm/sev.c | 2 +- arch/x86/kvm/x86.c | 10 ++-- 4 files changed, 67 insertions(+), 46 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index d07ab048d7cc..f832352cf4d3 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1087,6 +1087,10 @@ struct kvm_arch_memory_slot { }; =20 struct kvm_arch_plane { + struct mutex apic_map_lock; + struct kvm_apic_map __rcu *apic_map; + atomic_t apic_map_dirty; + unsigned long apicv_inhibit_reasons; }; =20 @@ -1381,9 +1385,6 @@ struct kvm_arch { struct kvm_ioapic *vioapic; struct kvm_pit *vpit; atomic_t vapics_in_nmi_mode; - struct mutex apic_map_lock; - struct kvm_apic_map __rcu *apic_map; - atomic_t apic_map_dirty; =20 bool apic_access_memslot_enabled; bool apic_access_memslot_inhibited; diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 4077c8d1e37e..6ed5f5b4f878 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -375,9 +375,9 @@ enum { DIRTY }; =20 -static void kvm_recalculate_apic_map(struct kvm *kvm) +static void kvm_recalculate_apic_map(struct kvm_plane *plane) { - struct kvm_plane *plane =3D kvm->planes[0]; + struct kvm *kvm =3D plane->kvm; struct kvm_apic_map *new, *old =3D NULL; struct kvm_vcpu *vcpu; unsigned long i; @@ -385,27 +385,27 @@ static void kvm_recalculate_apic_map(struct kvm *kvm) bool xapic_id_mismatch; int r; =20 - /* Read kvm->arch.apic_map_dirty before kvm->arch.apic_map. */ - if (atomic_read_acquire(&kvm->arch.apic_map_dirty) =3D=3D CLEAN) + /* Read plane->arch.apic_map_dirty before plane->arch.apic_map. */ + if (atomic_read_acquire(&plane->arch.apic_map_dirty) =3D=3D CLEAN) return; =20 WARN_ONCE(!irqchip_in_kernel(kvm), "Dirty APIC map without an in-kernel local APIC"); =20 - mutex_lock(&kvm->arch.apic_map_lock); + mutex_lock(&plane->arch.apic_map_lock); =20 retry: /* - * Read kvm->arch.apic_map_dirty before kvm->arch.apic_map (if clean) + * Read plane->arch.apic_map_dirty before plane->arch.apic_map (if clean) * or the APIC registers (if dirty). Note, on retry the map may have * not yet been marked dirty by whatever task changed a vCPU's x2APIC * ID, i.e. the map may still show up as in-progress. In that case * this task still needs to retry and complete its calculation. */ - if (atomic_cmpxchg_acquire(&kvm->arch.apic_map_dirty, + if (atomic_cmpxchg_acquire(&plane->arch.apic_map_dirty, DIRTY, UPDATE_IN_PROGRESS) =3D=3D CLEAN) { /* Someone else has updated the map. */ - mutex_unlock(&kvm->arch.apic_map_lock); + mutex_unlock(&plane->arch.apic_map_lock); return; } =20 @@ -418,7 +418,7 @@ static void kvm_recalculate_apic_map(struct kvm *kvm) */ xapic_id_mismatch =3D false; =20 - kvm_for_each_vcpu(i, vcpu, kvm) + kvm_for_each_plane_vcpu(i, vcpu, plane) if (kvm_apic_present(vcpu)) max_id =3D max(max_id, kvm_x2apic_id(vcpu->arch.apic)); =20 @@ -432,7 +432,7 @@ static void kvm_recalculate_apic_map(struct kvm *kvm) new->max_apic_id =3D max_id; new->logical_mode =3D KVM_APIC_MODE_SW_DISABLED; =20 - kvm_for_each_vcpu(i, vcpu, kvm) { + kvm_for_each_plane_vcpu(i, vcpu, plane) { if (!kvm_apic_present(vcpu)) continue; =20 @@ -471,21 +471,29 @@ static void kvm_recalculate_apic_map(struct kvm *kvm) else kvm_clear_apicv_inhibit(plane, APICV_INHIBIT_REASON_APIC_ID_MODIFIED); =20 - old =3D rcu_dereference_protected(kvm->arch.apic_map, - lockdep_is_held(&kvm->arch.apic_map_lock)); - rcu_assign_pointer(kvm->arch.apic_map, new); + old =3D rcu_dereference_protected(plane->arch.apic_map, + lockdep_is_held(&plane->arch.apic_map_lock)); + rcu_assign_pointer(plane->arch.apic_map, new); /* - * Write kvm->arch.apic_map before clearing apic->apic_map_dirty. + * Write plane->arch.apic_map before clearing apic->apic_map_dirty. * If another update has come in, leave it DIRTY. */ - atomic_cmpxchg_release(&kvm->arch.apic_map_dirty, + atomic_cmpxchg_release(&plane->arch.apic_map_dirty, UPDATE_IN_PROGRESS, CLEAN); - mutex_unlock(&kvm->arch.apic_map_lock); + mutex_unlock(&plane->arch.apic_map_lock); =20 if (old) kvfree_rcu(old, rcu); =20 - kvm_make_scan_ioapic_request(kvm); + if (plane->plane =3D=3D 0) + kvm_make_scan_ioapic_request(kvm); +} + +static inline void kvm_mark_apic_map_dirty(struct kvm_vcpu *vcpu) +{ + struct kvm_plane *plane =3D vcpu_to_plane(vcpu); + + atomic_set_release(&plane->arch.apic_map_dirty, DIRTY); } =20 static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) @@ -501,7 +509,7 @@ static inline void apic_set_spiv(struct kvm_lapic *apic= , u32 val) else static_branch_inc(&apic_sw_disabled.key); =20 - atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); + kvm_mark_apic_map_dirty(apic->vcpu); } =20 /* Check if there are APF page ready requests pending */ @@ -514,19 +522,19 @@ static inline void apic_set_spiv(struct kvm_lapic *ap= ic, u32 val) static inline void kvm_apic_set_xapic_id(struct kvm_lapic *apic, u8 id) { kvm_lapic_set_reg(apic, APIC_ID, id << 24); - atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); + kvm_mark_apic_map_dirty(apic->vcpu); } =20 static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id) { kvm_lapic_set_reg(apic, APIC_LDR, id); - atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); + kvm_mark_apic_map_dirty(apic->vcpu); } =20 static inline void kvm_apic_set_dfr(struct kvm_lapic *apic, u32 val) { kvm_lapic_set_reg(apic, APIC_DFR, val); - atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); + kvm_mark_apic_map_dirty(apic->vcpu); } =20 static inline void kvm_apic_set_x2apic_id(struct kvm_lapic *apic, u32 id) @@ -537,7 +545,7 @@ static inline void kvm_apic_set_x2apic_id(struct kvm_la= pic *apic, u32 id) =20 kvm_lapic_set_reg(apic, APIC_ID, id); kvm_lapic_set_reg(apic, APIC_LDR, ldr); - atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); + kvm_mark_apic_map_dirty(apic->vcpu); } =20 static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type) @@ -866,6 +874,7 @@ int kvm_pv_send_ipi(struct kvm_vcpu *source, unsigned l= ong ipi_bitmap_low, unsigned long ipi_bitmap_high, u32 min, unsigned long icr, int op_64_bit) { + struct kvm_plane *plane =3D vcpu_to_plane(source); struct kvm_apic_map *map; struct kvm_lapic_irq irq =3D {0}; int cluster_size =3D op_64_bit ? 64 : 32; @@ -880,7 +889,7 @@ int kvm_pv_send_ipi(struct kvm_vcpu *source, unsigned l= ong ipi_bitmap_low, irq.trig_mode =3D icr & APIC_INT_LEVELTRIG; =20 rcu_read_lock(); - map =3D rcu_dereference(source->kvm->arch.apic_map); + map =3D rcu_dereference(plane->arch.apic_map); =20 count =3D -EOPNOTSUPP; if (likely(map)) { @@ -1152,7 +1161,7 @@ static bool kvm_apic_is_broadcast_dest(struct kvm *kv= m, struct kvm_lapic **src, * means that the interrupt should be dropped. In this case, *bitmap woul= d be * zero and *dst undefined. */ -static inline bool kvm_apic_map_get_dest_lapic(struct kvm *kvm, +static inline bool kvm_apic_map_get_dest_lapic(struct kvm_plane *plane, struct kvm_lapic **src, struct kvm_lapic_irq *irq, struct kvm_apic_map *map, struct kvm_lapic ***dst, unsigned long *bitmap) @@ -1166,7 +1175,7 @@ static inline bool kvm_apic_map_get_dest_lapic(struct= kvm *kvm, } else if (irq->shorthand) return false; =20 - if (!map || kvm_apic_is_broadcast_dest(kvm, src, irq, map)) + if (!map || kvm_apic_is_broadcast_dest(plane->kvm, src, irq, map)) return false; =20 if (irq->dest_mode =3D=3D APIC_DEST_PHYSICAL) { @@ -1207,7 +1216,7 @@ static inline bool kvm_apic_map_get_dest_lapic(struct= kvm *kvm, bitmap, 16); =20 if (!(*dst)[lowest]) { - kvm_apic_disabled_lapic_found(kvm); + kvm_apic_disabled_lapic_found(plane->kvm); *bitmap =3D 0; return true; } @@ -1221,6 +1230,7 @@ static inline bool kvm_apic_map_get_dest_lapic(struct= kvm *kvm, bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map) { + struct kvm_plane *plane =3D kvm->planes[0]; struct kvm_apic_map *map; unsigned long bitmap; struct kvm_lapic **dst =3D NULL; @@ -1228,6 +1238,10 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, = struct kvm_lapic *src, bool ret; =20 *r =3D -1; + if (KVM_BUG_ON(!plane, kvm)) { + *r =3D 0; + return true; + } =20 if (irq->shorthand =3D=3D APIC_DEST_SELF) { if (KVM_BUG_ON(!src, kvm)) { @@ -1239,9 +1253,9 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, s= truct kvm_lapic *src, } =20 rcu_read_lock(); - map =3D rcu_dereference(kvm->arch.apic_map); + map =3D rcu_dereference(plane->arch.apic_map); =20 - ret =3D kvm_apic_map_get_dest_lapic(kvm, &src, irq, map, &dst, &bitmap); + ret =3D kvm_apic_map_get_dest_lapic(plane, &src, irq, map, &dst, &bitmap); if (ret) { *r =3D 0; for_each_set_bit(i, &bitmap, 16) { @@ -1272,6 +1286,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, s= truct kvm_lapic *src, bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *i= rq, struct kvm_vcpu **dest_vcpu) { + struct kvm_plane *plane =3D kvm->planes[0]; struct kvm_apic_map *map; unsigned long bitmap; struct kvm_lapic **dst =3D NULL; @@ -1281,9 +1296,9 @@ bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, st= ruct kvm_lapic_irq *irq, return false; =20 rcu_read_lock(); - map =3D rcu_dereference(kvm->arch.apic_map); + map =3D rcu_dereference(plane->arch.apic_map); =20 - if (kvm_apic_map_get_dest_lapic(kvm, NULL, irq, map, &dst, &bitmap) && + if (kvm_apic_map_get_dest_lapic(plane, NULL, irq, map, &dst, &bitmap) && hweight16(bitmap) =3D=3D 1) { unsigned long i =3D find_first_bit(&bitmap, 16); =20 @@ -1407,6 +1422,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, = int delivery_mode, void kvm_bitmap_or_dest_vcpus(struct kvm *kvm, struct kvm_lapic_irq *irq, unsigned long *vcpu_bitmap) { + struct kvm_plane *plane =3D kvm->planes[0]; struct kvm_lapic **dest_vcpu =3D NULL; struct kvm_lapic *src =3D NULL; struct kvm_apic_map *map; @@ -1416,9 +1432,9 @@ void kvm_bitmap_or_dest_vcpus(struct kvm *kvm, struct= kvm_lapic_irq *irq, bool ret; =20 rcu_read_lock(); - map =3D rcu_dereference(kvm->arch.apic_map); + map =3D rcu_dereference(plane->arch.apic_map); =20 - ret =3D kvm_apic_map_get_dest_lapic(kvm, &src, irq, map, &dest_vcpu, + ret =3D kvm_apic_map_get_dest_lapic(plane, &src, irq, map, &dest_vcpu, &bitmap); if (ret) { for_each_set_bit(i, &bitmap, 16) { @@ -2420,7 +2436,7 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic= , u32 reg, u32 val) * was toggled, the APIC ID changed, etc... The maps are marked dirty * on relevant changes, i.e. this is a nop for most writes. */ - kvm_recalculate_apic_map(apic->vcpu->kvm); + kvm_recalculate_apic_map(vcpu_to_plane(apic->vcpu)); =20 return ret; } @@ -2610,7 +2626,7 @@ static void __kvm_apic_set_base(struct kvm_vcpu *vcpu= , u64 value) kvm_make_request(KVM_REQ_APF_READY, vcpu); } else { static_branch_inc(&apic_hw_disabled.key); - atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); + kvm_mark_apic_map_dirty(apic->vcpu); } } =20 @@ -2657,7 +2673,7 @@ int kvm_apic_set_base(struct kvm_vcpu *vcpu, u64 valu= e, bool host_initiated) } =20 __kvm_apic_set_base(vcpu, value); - kvm_recalculate_apic_map(vcpu->kvm); + kvm_recalculate_apic_map(vcpu_to_plane(vcpu)); return 0; } EXPORT_SYMBOL_GPL(kvm_apic_set_base); @@ -2823,7 +2839,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init= _event) vcpu->arch.apic_arb_prio =3D 0; vcpu->arch.apic_attention =3D 0; =20 - kvm_recalculate_apic_map(vcpu->kvm); + kvm_recalculate_apic_map(vcpu_to_plane(apic->vcpu)); } =20 /* @@ -3115,13 +3131,13 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struc= t kvm_lapic_state *s) =20 r =3D kvm_apic_state_fixup(vcpu, s, true); if (r) { - kvm_recalculate_apic_map(vcpu->kvm); + kvm_recalculate_apic_map(vcpu_to_plane(apic->vcpu)); return r; } memcpy(vcpu->arch.apic->regs, s->regs, sizeof(*s)); =20 - atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); - kvm_recalculate_apic_map(vcpu->kvm); + kvm_mark_apic_map_dirty(apic->vcpu); + kvm_recalculate_apic_map(vcpu_to_plane(apic->vcpu)); kvm_apic_set_version(vcpu); =20 apic_update_ppr(apic); diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 130d895f1d95..9d4492862c11 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -458,7 +458,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm= _sev_cmd *argp, INIT_LIST_HEAD(&sev->mirror_vms); sev->need_init =3D false; =20 - kvm_set_apicv_inhibit(kvm->planes[0], APICV_INHIBIT_REASON_SEV); + kvm_set_apicv_inhibit(kvm->planes[[0], APICV_INHIBIT_REASON_SEV); =20 return 0; =20 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 382d8ace131f..19e3bb33bf7d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10021,7 +10021,7 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, = unsigned long dest_id) goto no_yield; =20 rcu_read_lock(); - map =3D rcu_dereference(vcpu->kvm->arch.apic_map); + map =3D rcu_dereference(vcpu_to_plane(vcpu)->arch.apic_map); =20 if (likely(map) && dest_id <=3D map->max_apic_id && map->phys_map[dest_id= ]) target =3D map->phys_map[dest_id]->vcpu; @@ -12771,6 +12771,7 @@ void kvm_arch_free_vm(struct kvm *kvm) =20 void kvm_arch_init_plane(struct kvm_plane *plane) { + mutex_init(&plane->arch.apic_map_lock); kvm_apicv_init(plane->kvm, &plane->arch.apicv_inhibit_reasons); } =20 @@ -12811,7 +12812,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long= type) =20 init_rwsem(&kvm->arch.apicv_update_lock); raw_spin_lock_init(&kvm->arch.tsc_write_lock); - mutex_init(&kvm->arch.apic_map_lock); seqcount_raw_spinlock_init(&kvm->arch.pvclock_sc, &kvm->arch.tsc_write_lo= ck); kvm->arch.kvmclock_offset =3D -get_kvmclock_base_ns(); =20 @@ -12960,6 +12960,11 @@ void kvm_arch_pre_destroy_vm(struct kvm *kvm) static_call_cond(kvm_x86_vm_pre_destroy)(kvm); } =20 +void kvm_arch_free_plane(struct kvm_plane *plane) +{ + kvfree(rcu_dereference_check(plane->arch.apic_map, 1)); +} + void kvm_arch_destroy_vm(struct kvm *kvm) { if (current->mm =3D=3D kvm->mm) { @@ -12981,7 +12986,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm) kvm_free_msr_filter(srcu_dereference_check(kvm->arch.msr_filter, &kvm->sr= cu, 1)); kvm_pic_destroy(kvm); kvm_ioapic_destroy(kvm); - kvfree(rcu_dereference_check(kvm->arch.apic_map, 1)); kfree(srcu_dereference_check(kvm->arch.pmu_event_filter, &kvm->srcu, 1)); kvm_mmu_uninit_vm(kvm); kvm_page_track_cleanup(kvm); --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 E2ACE221F0D for ; Tue, 1 Apr 2025 16:12:08 +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=1743523930; cv=none; b=SFj2MdleJKGRvKSSLEWPy3nrQAAf4eU4n0kME4GEE/HXmtFFVUOM9SJiVFTlko3TLV/rE9+gFsM4pygu0NQh6LBA7DiHg2/W4jrcTdmp9qJ1cVi8UZpQCvLQviNFhkc+pwH4JGKu2YXRszaORbhhvdEAF41IuWzx2STQE8y0DCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523930; c=relaxed/simple; bh=u5ldWiz2cXiotD/cOofMPUD+9S2OYpN2imw/B/Aw+M0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hg47+x7Bss1NjhvnhaxR8bF79DC+EbgJThm15fvokJg7APZaavn94tr0B/hgY68LYQC3xmYGmaaJMYNEmH/tvJc7RdYJDVc+QK4cmyWButr108HrAUoHKKUlmu4WwOx1wqOAJ907rHM9YF12EKYeE1ZSPlK2pat8Ol3lk4cWLb8= 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=YsppG4+P; 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="YsppG4+P" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523927; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Vrf7NR/iVZ/2wCl5JeoFe4lGIXCBAxX7ph94CsZNoVw=; b=YsppG4+P/VGc3p3wmw2XXtNkRb36F5fIPM+Tj4WJ0y7/4GK6LoKebDehpSgNkRphVQ2k7o 0MfcGsTtpVaOl7ubzyMKGcHAJzgoBdQNqY7bD+UHZY5A7Ef4OK8vyQUUN4hAFmCse9H/6W 0u7umTG/1VgwDclCuT+OSPA/MJYnJug= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-690-qjKZY9zcPeqhtUsZpNe8VA-1; Tue, 01 Apr 2025 12:12:06 -0400 X-MC-Unique: qjKZY9zcPeqhtUsZpNe8VA-1 X-Mimecast-MFC-AGG-ID: qjKZY9zcPeqhtUsZpNe8VA_1743523925 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43e9b0fd00cso13352825e9.0 for ; Tue, 01 Apr 2025 09:12:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523925; x=1744128725; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Vrf7NR/iVZ/2wCl5JeoFe4lGIXCBAxX7ph94CsZNoVw=; b=AHU/24sBIyjaX/op6uwRe8eKRdT2XW4+9of+ed4jUvP9u2s5MLD2dRPtmjycjVtUBw KtS62o25IjP6vM9kJoFi/5A+fnVrXq/oShjl6Wm6yM1nyYJPPVtoqvzkLzp+HmqrnraJ vk0aPyUI5msyR12MuArV+QwusG/ShCxTLgDXmxu5XD2K6kjRLFHt9nUbyfQf8UztngVt HMbbQJVwuS4XQoryA7BKhgWI2ZpZI5zvbSfDv3TT+fhpfjvLklfQcaoA3aWJEsvQxV7d n8SxPif+6vq36doATK6NM8b9F5fC4b6In9jdEWHeMsjxRM5nHBpgm1J+xsCIceffnJrt XP3w== X-Gm-Message-State: AOJu0Ywnt5mnvtcft3JR2YrZfDH1nx7qy1QOLSSNQvo1XXqXs+t7A+xU V5Un8c4Dk5zQwiq6y9s5q2NWLSpM0+M6tTrfFdsU06AgLKlkvjabmiIhQ2vShnHqeIGWTOwAN3I nuzTxCxtf2wM07w9aAzWx9jAztPk0yIKu6knmXKDJ9bkbDE2XEb/EwvyLSh47umanM8EJEeyf6Z Vpod+FaXaTDwDhXy3ROqC+4pSWjcvel1KNEo6fWUUi0BKFyw== X-Gm-Gg: ASbGnct5fOXa8vBOD5Pg063HgwNoISIjdA6c3M7WkVR/uzvCfZMECkLT9NTKVnoIE5p /9ptrcl0egH3OvKffodUnqIcGcG5glBA0vYi/oe63M9GS+0kNB0TNsVgVH+5ZhiH0uwJ8x/dDKX Fdb2RYjkRmNqvEUxl++uRbULyaF6X5gVF4Z6HhSKIzazl35oU4jJuG14pB/dXX3Dx0WlnuCH5Nj iZc3V+paAs+jyiDBCynGtZuc2RLSYRfVXPNhp8aAP70s3A3BDFyrL+vQRRPEeNoOr+C+OFZ3ZBq wUM0O1TAdVLIXAeTqV4glQ== X-Received: by 2002:a7b:c410:0:b0:43d:174:2668 with SMTP id 5b1f17b1804b1-43eb0432f65mr5326895e9.0.1743523924972; Tue, 01 Apr 2025 09:12:04 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEk/I3vo1cRXa7Mz4utMMm6kLtNUQbKtvEfiervEB5Xb0Kb0XowzumjTcrRZh98kiO/aEFnGA== X-Received: by 2002:a7b:c410:0:b0:43d:174:2668 with SMTP id 5b1f17b1804b1-43eb0432f65mr5326525e9.0.1743523924573; Tue, 01 Apr 2025 09:12:04 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d82dede21sm203158185e9.4.2025.04.01.09.12.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:02 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 20/29] KVM: x86: add planes support for interrupt delivery Date: Tue, 1 Apr 2025 18:10:57 +0200 Message-ID: <20250401161106.790710-21-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Plumb the destination plane into struct kvm_lapic_irq and propagate it everywhere. The in-kernel IOAPIC only targets plane 0. Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/hyperv.c | 1 + arch/x86/kvm/ioapic.c | 4 ++-- arch/x86/kvm/irq_comm.c | 14 +++++++++++--- arch/x86/kvm/lapic.c | 8 ++++---- arch/x86/kvm/x86.c | 8 +++++--- arch/x86/kvm/xen.c | 1 + 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index f832352cf4d3..283d8a4b5b14 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1661,6 +1661,7 @@ struct kvm_lapic_irq { u16 delivery_mode; u16 dest_mode; bool level; + u8 plane; u16 trig_mode; u32 shorthand; u32 dest_id; diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index a522b467be48..cd1ff31038d2 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -491,6 +491,7 @@ static int synic_set_irq(struct kvm_vcpu_hv_synic *syni= c, u32 sint) irq.delivery_mode =3D APIC_DM_FIXED; irq.vector =3D vector; irq.level =3D 1; + irq.plane =3D vcpu->plane; =20 ret =3D kvm_irq_delivery_to_apic(vcpu->kvm, vcpu->arch.apic, &irq, NULL); trace_kvm_hv_synic_set_irq(vcpu->vcpu_id, sint, irq.vector, ret); diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index 995eb5054360..c538867afceb 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -402,7 +402,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *io= apic, u32 val) ioapic_service(ioapic, index, false); } if (e->fields.delivery_mode =3D=3D APIC_DM_FIXED) { - struct kvm_lapic_irq irq; + struct kvm_lapic_irq irq =3D { 0 }; =20 irq.vector =3D e->fields.vector; irq.delivery_mode =3D e->fields.delivery_mode << 8; @@ -442,7 +442,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *io= apic, u32 val) static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_st= atus) { union kvm_ioapic_redirect_entry *entry =3D &ioapic->redirtbl[irq]; - struct kvm_lapic_irq irqe; + struct kvm_lapic_irq irqe =3D { 0 }; int ret; =20 if (entry->fields.mask || diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c index 8136695f7b96..94f9db50384e 100644 --- a/arch/x86/kvm/irq_comm.c +++ b/arch/x86/kvm/irq_comm.c @@ -48,6 +48,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_= lapic *src, struct kvm_lapic_irq *irq, struct dest_map *dest_map) { int r =3D -1; + struct kvm_plane *plane =3D kvm->planes[irq->plane]; struct kvm_vcpu *vcpu, *lowest =3D NULL; unsigned long i, dest_vcpu_bitmap[BITS_TO_LONGS(KVM_MAX_VCPUS)]; unsigned int dest_vcpus =3D 0; @@ -63,7 +64,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_= lapic *src, =20 memset(dest_vcpu_bitmap, 0, sizeof(dest_vcpu_bitmap)); =20 - kvm_for_each_vcpu(i, vcpu, kvm) { + kvm_for_each_plane_vcpu(i, vcpu, plane) { if (!kvm_apic_present(vcpu)) continue; =20 @@ -92,7 +93,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_= lapic *src, int idx =3D kvm_vector_to_index(irq->vector, dest_vcpus, dest_vcpu_bitmap, KVM_MAX_VCPUS); =20 - lowest =3D kvm_get_vcpu(kvm, idx); + lowest =3D kvm_get_plane_vcpu(plane, idx); } =20 if (lowest) @@ -119,13 +120,20 @@ void kvm_set_msi_irq(struct kvm *kvm, struct kvm_kern= el_irq_routing_entry *e, irq->msi_redir_hint =3D msg.arch_addr_lo.redirect_hint; irq->level =3D 1; irq->shorthand =3D APIC_DEST_NOSHORT; + irq->plane =3D e->msi.plane; } EXPORT_SYMBOL_GPL(kvm_set_msi_irq); =20 static inline bool kvm_msi_route_invalid(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e) { - return kvm->arch.x2apic_format && (e->msi.address_hi & 0xff); + if (kvm->arch.x2apic_format && (e->msi.address_hi & 0xff)) + return true; + + if (!kvm->planes[e->msi.plane]) + return true; + + return false; } =20 int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 6ed5f5b4f878..16a0e2387f2c 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1223,14 +1223,13 @@ static inline bool kvm_apic_map_get_dest_lapic(stru= ct kvm_plane *plane, } =20 *bitmap =3D (lowest >=3D 0) ? 1 << lowest : 0; - return true; } =20 bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map) { - struct kvm_plane *plane =3D kvm->planes[0]; + struct kvm_plane *plane =3D kvm->planes[irq->plane]; struct kvm_apic_map *map; unsigned long bitmap; struct kvm_lapic **dst =3D NULL; @@ -1286,7 +1285,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, s= truct kvm_lapic *src, bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *i= rq, struct kvm_vcpu **dest_vcpu) { - struct kvm_plane *plane =3D kvm->planes[0]; + struct kvm_plane *plane =3D kvm->planes[irq->plane]; struct kvm_apic_map *map; unsigned long bitmap; struct kvm_lapic **dst =3D NULL; @@ -1422,7 +1421,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, = int delivery_mode, void kvm_bitmap_or_dest_vcpus(struct kvm *kvm, struct kvm_lapic_irq *irq, unsigned long *vcpu_bitmap) { - struct kvm_plane *plane =3D kvm->planes[0]; + struct kvm_plane *plane =3D kvm->planes[irq->plane]; struct kvm_lapic **dest_vcpu =3D NULL; struct kvm_lapic *src =3D NULL; struct kvm_apic_map *map; @@ -1544,6 +1543,7 @@ void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 ic= r_low, u32 icr_high) irq.trig_mode =3D icr_low & APIC_INT_LEVELTRIG; irq.shorthand =3D icr_low & APIC_SHORT_MASK; irq.msi_redir_hint =3D false; + irq.plane =3D apic->vcpu->plane; if (apic_x2apic_mode(apic)) irq.dest_id =3D icr_high; else diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 19e3bb33bf7d..ce8e623052a7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9949,7 +9949,7 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu= , gpa_t paddr, * * @apicid - apicid of vcpu to be kicked. */ -static void kvm_pv_kick_cpu_op(struct kvm *kvm, int apicid) +static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned plane_id, int api= cid) { /* * All other fields are unused for APIC_DM_REMRD, but may be consumed by @@ -9960,6 +9960,7 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, int a= picid) .dest_mode =3D APIC_DEST_PHYSICAL, .shorthand =3D APIC_DEST_NOSHORT, .dest_id =3D apicid, + .plane =3D plane_id, }; =20 kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL); @@ -10092,7 +10093,7 @@ int ____kvm_emulate_hypercall(struct kvm_vcpu *vcpu= , int cpl, if (!guest_pv_has(vcpu, KVM_FEATURE_PV_UNHALT)) break; =20 - kvm_pv_kick_cpu_op(vcpu->kvm, a1); + kvm_pv_kick_cpu_op(vcpu->kvm, vcpu->plane, a1); kvm_sched_yield(vcpu, a1); ret =3D 0; break; @@ -13559,7 +13560,8 @@ void kvm_arch_async_page_present(struct kvm_vcpu *v= cpu, { struct kvm_lapic_irq irq =3D { .delivery_mode =3D APIC_DM_FIXED, - .vector =3D vcpu->arch.apf.vec + .vector =3D vcpu->arch.apf.vec, + .plane =3D vcpu->plane, }; =20 if (work->wakeup_all) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index 7449be30d701..ac9c69f2190b 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -625,6 +625,7 @@ void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v) irq.shorthand =3D APIC_DEST_NOSHORT; irq.delivery_mode =3D APIC_DM_FIXED; irq.level =3D 1; + irq.plane =3D v->plane; =20 kvm_irq_delivery_to_apic(v->kvm, NULL, &irq, NULL); } --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 6E171221F2E for ; Tue, 1 Apr 2025 16:12:11 +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=1743523933; cv=none; b=I0+owWu7O6Hn/qcC7Spc69pQj1PD03xTnvEx5yBQc260qZ3mH0SwvQtOeTkoARSAmJmpkM/cb1M+wFxhNHisLzVU6XxjcHI73Yb+7rHohNABu5A6IVilJWPsRvF5fUYuCLlEASPhgPYxyP3ad3k68uSMrk28VBzUtHyEZM43mBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523933; c=relaxed/simple; bh=6R6OEQxDgjR/HZg6sCVP87ZgC7PikBueK2/660D907Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P9XWdpTjzSx0WvG3h9iIqj+lOrt7J8IJE2FeIVgmSPPihTSVvWEJtSlDn79v4mIFh6ngkPGvgFThgeKxr3l7vJSLUgTtYvAP+ZMDpUSlsVZR40CaZgoEz4bdpgIN79FsnJ9mKIjT4FrhloEX72jxPWyiNregcafgaugm7e70hsw= 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=jNa/YZn1; 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="jNa/YZn1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kkUQYRtnACncLvUHjuKhMmXCrd7LF2Jtv0MEz++g5Qo=; b=jNa/YZn18AGdJYyhGetBKQze3JnhIXcJNPQQVX3TegeQLAzAlCTEzrPqc3mq2Lsc3p4MUQ SlLZNMUfaOOZlglCeAHD8vTGn/Oti1JViYynzxeJG9uk+Gxviwp+kOF2eoq8q4JkMEYLkF A2qrZwEJCgMoTtLpH8G4gX6MlzzVWZc= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-176-14iTeA3iNn-1I_OT5xVzKw-1; Tue, 01 Apr 2025 12:12:09 -0400 X-MC-Unique: 14iTeA3iNn-1I_OT5xVzKw-1 X-Mimecast-MFC-AGG-ID: 14iTeA3iNn-1I_OT5xVzKw_1743523928 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43d5ca7c86aso35589615e9.0 for ; Tue, 01 Apr 2025 09:12:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523927; x=1744128727; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kkUQYRtnACncLvUHjuKhMmXCrd7LF2Jtv0MEz++g5Qo=; b=bvaJBPRXaDcYxe2obom3fA53B5F5Qs817rglw0NRQEkGqH8qyYsvmey50PmWuXhPyD Er9Gz0kahpPyq5/M1eNn172WHVii42PjpkWcO506xOJx4Twh3KMnRaKMX8nZOa5foi1p khdO5NmCLoFMyOYG801PjEdHQ4POPJweTEa+aLCCWrigPIBAY+CDSu7Ah175gdaAYKPf l6M81fntiHUK/EBoa/0Y6OZlK9lgIcgkKoceaiiXlcBxpvitg/lJWP1hFWGvjlUs3OHK f8ph3osJY7bwTyNdoJsUiyNHgUQK+9A4ZXmJbe2bgX8ATIugAp/vUudp+3WlON2u8iZh 1OKw== X-Gm-Message-State: AOJu0YzKJwF/19goLXXlWa7NVBPqbMBPZaNtOWKuudkR14sio/zJyN0W eAyYwO1ndRAxBh4dr9GlDrxGgy2iX7PfzzJIpZ18FTEOPALWYQa0wX8H1EFVbydusrD6GbdNxie gNBtnF7o1AAh2SMf/Tg1LWgDwnjeQ5kEWxy69HBFEsD3CK+7FhWm8WGJa9GjjjP7gX/0ANwCEcp pTcp2AevSP5RDp6YkV4yk47sK7YmfJaSGLeGcD+pYxykJJug== X-Gm-Gg: ASbGnctkhUzyIgxtWpoqewXw4L+WLPCNI9fV3Np1rTpM0CH/Tl6MpFUZD0H9/DmcyFE kdJPU3O6ZM/Tkv0hBHIjLDE4ZmwOJqLZa3E026QLWWll9jNxG2tLB+JVNVP4IprDmm/V5o705gg HYihaH5S6yDxR+U/utj11sf3l9ulBCdkfCw6s4kx4/NDd2SP1qv561N1HYDuJa8+rt+/q1l3R6f 95+yjAXUIlvWGhEmcYr8sGtG9rujeg9y8OVAxKw1Pj+3MHR6EXfV1jC2YDbjrMYPwm5ni+ontm8 aa8wjWAPppxOSDZTHKSu3Q== X-Received: by 2002:a05:600c:6792:b0:43c:e9f7:d6a3 with SMTP id 5b1f17b1804b1-43ea7c717femr33648935e9.13.1743523927403; Tue, 01 Apr 2025 09:12:07 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGnhM5o4ZnKjk9+MG32jGQEDPKEoKojaSrwXizsO3e6J/Rj02GKdm3qrLDu+19IPPoL3w0DsA== X-Received: by 2002:a05:600c:6792:b0:43c:e9f7:d6a3 with SMTP id 5b1f17b1804b1-43ea7c717femr33648325e9.13.1743523926906; Tue, 01 Apr 2025 09:12:06 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d82e83482sm207511105e9.14.2025.04.01.09.12.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:05 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 21/29] KVM: x86: add infrastructure to share FPU across planes Date: Tue, 1 Apr 2025 18:10:58 +0200 Message-ID: <20250401161106.790710-22-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Wrap fpu_alloc_guest_fpstate() and fpu_free_guest_fpstate() so that only one FPU exists for vCPUs that are in different planes but share the same vCPU id. This API could be handy for VTL implementation but it may be tricky because for some registers sharing would be a bad idea (even MPX right now if it weren't deprecated, but APX in the future could be worse). Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/x86.c | 47 ++++++++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 283d8a4b5b14..9ac39f128a53 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1347,6 +1347,7 @@ struct kvm_arch { unsigned int indirect_shadow_pages; u8 mmu_valid_gen; u8 vm_type; + bool planes_share_fpu; bool has_private_mem; bool has_protected_state; bool pre_fault_allowed; @@ -2447,4 +2448,6 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, = unsigned long npages); */ #define KVM_EXIT_HYPERCALL_MBZ GENMASK_ULL(31, 1) =20 +bool kvm_arch_planes_share_fpu(struct kvm *kvm); + #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ce8e623052a7..ebdbd08a840b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6626,6 +6626,17 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, kvm->arch.triple_fault_event =3D cap->args[0]; r =3D 0; break; + case KVM_CAP_PLANES_FPU: + r =3D -EINVAL; + if (atomic_read(&kvm->online_vcpus)) + break; + if (cap->args[0] > 1) + break; + if (cap->args[0] && kvm->arch.has_protected_state) + break; + kvm->arch.planes_share_fpu =3D cap->args[0]; + r =3D 0; + break; case KVM_CAP_X86_USER_SPACE_MSR: r =3D -EINVAL; if (cap->args[0] & ~KVM_MSR_EXIT_REASON_VALID_MASK) @@ -12332,6 +12343,27 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsig= ned int id) return kvm_x86_call(vcpu_precreate)(kvm); } =20 +static void kvm_free_guest_fpstate(struct kvm_vcpu *vcpu, unsigned plane) +{ + if (plane =3D=3D 0 || !vcpu->kvm->arch.planes_share_fpu) + fpu_free_guest_fpstate(&vcpu->arch.guest_fpu); +} + +static int kvm_init_guest_fpstate(struct kvm_vcpu *vcpu, struct kvm_vcpu *= plane0_vcpu) +{ + if (plane0_vcpu && vcpu->kvm->arch.planes_share_fpu) { + vcpu->arch.guest_fpu =3D plane0_vcpu->arch.guest_fpu; + return 0; + } + + if (!fpu_alloc_guest_fpstate(&vcpu->arch.guest_fpu)) { + pr_err("failed to allocate vcpu's fpu\n"); + return -ENOMEM; + } + + return 0; +} + int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { struct page *page; @@ -12378,10 +12410,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, st= ruct kvm_plane *plane) if (!alloc_emulate_ctxt(vcpu)) goto free_wbinvd_dirty_mask; =20 - if (!fpu_alloc_guest_fpstate(&vcpu->arch.guest_fpu)) { - pr_err("failed to allocate vcpu's fpu\n"); + if (kvm_init_guest_fpstate(vcpu, plane->plane ? vcpu->plane0 : NULL) < 0) goto free_emulate_ctxt; - } =20 kvm_async_pf_hash_reset(vcpu); =20 @@ -12413,7 +12443,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, str= uct kvm_plane *plane) return 0; =20 free_guest_fpu: - fpu_free_guest_fpstate(&vcpu->arch.guest_fpu); + kvm_free_guest_fpstate(vcpu, plane->plane); free_emulate_ctxt: kmem_cache_free(x86_emulator_cache, vcpu->arch.emulate_ctxt); free_wbinvd_dirty_mask: @@ -12459,7 +12489,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) =20 kmem_cache_free(x86_emulator_cache, vcpu->arch.emulate_ctxt); free_cpumask_var(vcpu->arch.wbinvd_dirty_mask); - fpu_free_guest_fpstate(&vcpu->arch.guest_fpu); + kvm_free_guest_fpstate(vcpu, vcpu->plane); =20 kvm_xen_destroy_vcpu(vcpu); kvm_hv_vcpu_uninit(vcpu); @@ -12824,7 +12854,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long= type) kvm->arch.apic_bus_cycle_ns =3D APIC_BUS_CYCLE_NS_DEFAULT; kvm->arch.guest_can_read_msr_platform_info =3D true; kvm->arch.enable_pmu =3D enable_pmu; - + kvm->arch.planes_share_fpu =3D false; #if IS_ENABLED(CONFIG_HYPERV) spin_lock_init(&kvm->arch.hv_root_tdp_lock); kvm->arch.hv_root_tdp =3D INVALID_PAGE; @@ -13881,6 +13911,11 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsi= gned long type, gva_t gva) } EXPORT_SYMBOL_GPL(kvm_handle_invpcid); =20 +bool kvm_arch_planes_share_fpu(struct kvm *kvm) +{ + return !kvm || kvm->arch.planes_share_fpu; +} + static int complete_sev_es_emulated_mmio(struct kvm_vcpu *vcpu) { struct kvm_run *run =3D vcpu->run; --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 BEFCC2222AD for ; Tue, 1 Apr 2025 16:12:13 +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=1743523935; cv=none; b=kqWvIj23lXWCOdJtHGjvxckaIs6i4GKEfeU8T+BvWoYGrZAnvxCaUXYEjurqOVd3IRNgXjdYG4dm91nF+91dpRu9MKbB/9ONPfFD86yHSiIjc9M1zjVNLsMb3AmnFitQXbxzLHQUwMSlJQPXWf1iHTuxKgNpbEeGT0zgKSJAWF0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523935; c=relaxed/simple; bh=kQoni2s9+27EXmP2XI2+CYoemw/pJEF7XDPIcFmDe2g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DsTFHp5Y5NyPXR9a6JSLB6UR9s5Wsig3sEv5WSgDDffIBIXwcLuK9aHo6GtM9EYZVLwOZWupRgEO3NOJWutLsrh40+qSGd7PI5opfzuck0n06uGEp6iL7A3qLfJrkTvkjlwmfu/sXFKFQLIUP++lAty7kEs2/O891CL5SeK0r0s= 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=CIgVf/80; 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="CIgVf/80" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523932; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ChySLp6+UIK2NHqTKpsGQPiliMxZce6mgamUWnpoK/k=; b=CIgVf/80JkAVEyct9qC1txCqW5Y4H4e6r7CJROF1qibDV5TJFRdkugl+wNKrR7IgAGAJHF fwUm7BiulzOG/DQog8b2j/k1pDQYdQdJu968YipdLXhBMiv2fvj2Mr22789/2QK5UpAQg4 aSSgYozVEbFLtEtudSV+NCqg46EfnsE= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-610-06pVHRwPMzmXxrz1ItmeAQ-1; Tue, 01 Apr 2025 12:12:12 -0400 X-MC-Unique: 06pVHRwPMzmXxrz1ItmeAQ-1 X-Mimecast-MFC-AGG-ID: 06pVHRwPMzmXxrz1ItmeAQ_1743523931 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-43bd0586a73so44997205e9.2 for ; Tue, 01 Apr 2025 09:12:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523930; x=1744128730; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ChySLp6+UIK2NHqTKpsGQPiliMxZce6mgamUWnpoK/k=; b=SZUzF2+cGrwWBLM7RfeRFcx8rMXj8fy0JM7H22jN6dRUxjZYWESLcMt8VI6LfkBtAt FZUSO+r0oVBBj5EMKHZa8zFFmsT3wgrfNLWx2mhvSoimFuZEwhyFtg2Dos/p8NPvBwOR fTiuQDV3mNtgPjn+9lnCYGH9adZ2G4ZWc3AwiN+PKzxyRKsWLXYJ9JwQrf2bOTUMmVB/ xnd6/r6OaSJA2ZsgD4zhHK1ljOuUMok3FQiSFNP5pC0qiM5DgSDG7vMIT39ZiuIILgNT e6zCO13aGd0uONycvOymR9AqMguOsvrh9enKueXhTm+r0z2ikkQr1QkDfOnreSyy4iaS f7JQ== X-Gm-Message-State: AOJu0YzFxvvMrP5MIOFoBJxxM6p7ctW5aQf140DW1VYK89qJT638gOCQ 9thM3xQh4do1F5p4quwAr9QQB49hlCSTQ13VoVh8Ivq71LfumD/AI/9LIAMlFOy+1ByhxOj2G/m 2OR7ftTu2ZLU2LVh//mleHucnIlxfMoUpty7Blq7RJYke4JzeH9x45Q3cHY2eIqKDdgKc2HXE74 bgl7PnNNxld9VLa/UNA+Lkh16i2qhIPBglfLrv6+CJnr2uxg== X-Gm-Gg: ASbGncuFN0Q7Lf4Tml5LCP5QSZYhSubawJtTYiBHzDi/MiToPrKH4RC/m5E89ZRH5jU tdyZAeebkg1s2NLCsOjAHIvQeDfIPhSkSI2owohXsN5DKeTYiyr01kNBjUcKPvWSo7uY3iS/c+n XxZ1BngQKjkypP61QtPYFwMmCdQiUavIGzJjcoZqDpwtKY5PTqHRSa4gVq/qQKGkJU6apVxVAqT /vcXaMQbhVFtAybcYXDc5XA6RylEDxRrXAQs3Aq5h44F63bvgj3JuoJQcvtdt8ZZc1pHKDVlK7G cyrP5BdT2PG4G/75YTb43w== X-Received: by 2002:a05:600c:6b6c:b0:43d:fa59:be39 with SMTP id 5b1f17b1804b1-43dfa59bf9fmr83046245e9.33.1743523930234; Tue, 01 Apr 2025 09:12:10 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEZXiJ8c1MKAD59oM+jxw4s6wIAOa62pt3LsarDDoqS1UAAl1mtYiWot9iqnkG352qXMDvHFg== X-Received: by 2002:a05:600c:6b6c:b0:43d:fa59:be39 with SMTP id 5b1f17b1804b1-43dfa59bf9fmr83045935e9.33.1743523929800; Tue, 01 Apr 2025 09:12:09 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d8fbbfef2sm160662985e9.11.2025.04.01.09.12.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:08 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 22/29] KVM: x86: implement initial plane support Date: Tue, 1 Apr 2025 18:10:59 +0200 Message-ID: <20250401161106.790710-23-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement more of the shared state, namely the PIO emulation area and ioctl(KVM_RUN). Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ebdbd08a840b..d2b43d9b6543 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11567,7 +11567,7 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) trace_kvm_fpu(0); } =20 -int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) +static int kvm_vcpu_ioctl_run_plane(struct kvm_vcpu *vcpu) { struct kvm_queued_exception *ex =3D &vcpu->arch.exception; struct kvm_run *kvm_run =3D vcpu->run; @@ -11585,7 +11585,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) =20 kvm_vcpu_srcu_read_lock(vcpu); if (unlikely(vcpu->arch.mp_state =3D=3D KVM_MP_STATE_UNINITIALIZED)) { - if (!vcpu->wants_to_run) { + if (!vcpu->plane0->wants_to_run) { r =3D -EINTR; goto out; } @@ -11664,7 +11664,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) WARN_ON_ONCE(vcpu->mmio_needed); } =20 - if (!vcpu->wants_to_run) { + if (!vcpu->plane0->wants_to_run) { r =3D -EINTR; goto out; } @@ -11687,6 +11687,25 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) return r; } =20 +int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) +{ + int plane_id =3D READ_ONCE(vcpu->run->plane); + struct kvm_plane *plane =3D vcpu->kvm->planes[plane_id]; + int r; + + if (plane_id) { + vcpu =3D kvm_get_plane_vcpu(plane, vcpu->vcpu_id); + mutex_lock_nested(&vcpu->mutex, 1); + } + + r =3D kvm_vcpu_ioctl_run_plane(vcpu); + + if (plane_id) + mutex_unlock(&vcpu->mutex); + + return r; +} + static void __get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { if (vcpu->arch.emulate_regs_need_sync_to_vcpu) { @@ -12366,7 +12385,7 @@ static int kvm_init_guest_fpstate(struct kvm_vcpu *= vcpu, struct kvm_vcpu *plane0 =20 int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { - struct page *page; + struct page *page =3D NULL; int r; =20 vcpu->arch.last_vmentry_cpu =3D -1; @@ -12390,10 +12409,15 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, s= truct kvm_plane *plane) =20 r =3D -ENOMEM; =20 - page =3D alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); - if (!page) - goto fail_free_lapic; - vcpu->arch.pio_data =3D page_address(page); + if (plane->plane) { + page =3D NULL; + vcpu->arch.pio_data =3D vcpu->plane0->arch.pio_data; + } else { + page =3D alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); + if (!page) + goto fail_free_lapic; + vcpu->arch.pio_data =3D page_address(page); + } =20 vcpu->arch.mce_banks =3D kcalloc(KVM_MAX_MCE_BANKS * 4, sizeof(u64), GFP_KERNEL_ACCOUNT); @@ -12451,7 +12475,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, str= uct kvm_plane *plane) fail_free_mce_banks: kfree(vcpu->arch.mce_banks); kfree(vcpu->arch.mci_ctl2_banks); - free_page((unsigned long)vcpu->arch.pio_data); + __free_page(page); fail_free_lapic: kvm_free_lapic(vcpu); fail_mmu_destroy: @@ -12500,7 +12524,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) idx =3D srcu_read_lock(&vcpu->kvm->srcu); kvm_mmu_destroy(vcpu); srcu_read_unlock(&vcpu->kvm->srcu, idx); - free_page((unsigned long)vcpu->arch.pio_data); + if (!vcpu->plane) + free_page((unsigned long)vcpu->arch.pio_data); kvfree(vcpu->arch.cpuid_entries); } =20 --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 8728822256C for ; Tue, 1 Apr 2025 16:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523938; cv=none; b=fAOyPMTVIP3STj364roePd0oSJELJ/KdyUmnrv+SU71+qRi2GUs8f3eYGh/zAUobVWl/nmnSI2Lc+IPvv5Wq7saZkBUjBuyI0pebnwKvKDhd3Am4L7gcS9Qso8pFqHQhm+Zmxe7v2YyB/iKCttvpBPKhJl2g9o+JriIItSOR9QI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523938; c=relaxed/simple; bh=rEEG/JqTWYMnquhcA1NsEvfPwDFWFVv9Eii5wJCc9Lk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S8/cMvm1U/7dyNBpqcg8tGLtcAKnEFFUGyfS10QhzNse/5VjLRS4cWJsfG9Yuae66pIQJObi7U8h57gcEPyZsTxErybNbDpfTm43XVzsPonOjHXqscijTN2aT+tU8Ya+LJg5E/nmZKFL+Lxr0kHYZ6EM23NQrfrRaZ1GVp3JcYA= 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=fdcRZeMp; arc=none smtp.client-ip=170.10.129.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="fdcRZeMp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523935; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=clEaJtGkNoCtPvE/vwlOxKGgMTuZLXXi/afw5Ojz1dw=; b=fdcRZeMp+6Cv7Rqo498oJ1QBv8fQH+8f8F/eGvNd4cxAQnIJEDk332GaZb8EqursOYf6Dr HVOeeEF7vypGM+KSX5Nn8FXH4WhddoYHnJ2/WcO2Vnv+V0wkM25YKGIvyuTcTdGUpFSZf9 P0TNN3VOD5yHNlKfQGgWlpN/u1u+U68= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-183-V-7GX5gmOzily_rnOgwy1w-1; Tue, 01 Apr 2025 12:12:14 -0400 X-MC-Unique: V-7GX5gmOzily_rnOgwy1w-1 X-Mimecast-MFC-AGG-ID: V-7GX5gmOzily_rnOgwy1w_1743523933 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43d0830c3f7so47373945e9.2 for ; Tue, 01 Apr 2025 09:12:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523932; x=1744128732; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=clEaJtGkNoCtPvE/vwlOxKGgMTuZLXXi/afw5Ojz1dw=; b=iBxhICRZ/j7alBtQGadG+ZxYLc4f77+vFesQFOnbltc9BcRZ+hHIup78Kdkqt2rC5E aBPfbnPCNZuC04XIkhqwXrhVAhdKny0Z/i+rO/YpR6P6hfiV+aU8w3ukW2YxwCLpOLCo LCjTzrXncXwtsm0mRRPgIOvkFe/RyGpiFHZsG+MkKAXGd2IGGM6pmCCqurd+OJ5hxK3B fGRVvccbcElVOUg0BkriMy5KWilqyvOFR0K3RF0tsmkBTg+5nV/74NPMp6BPzLwhZDoB rmiAfRk8o82DNXHy5hgukOi/DVK9opbjqfgOEud/xWGpaGBgAmJU3Nas2zD4BBJo0cBE aYsw== X-Gm-Message-State: AOJu0YzMU2qLc5nWqOOiwfwAZn+5A0HRr1Hq0I9DQkaWUHWvRI9Cv/0l oJe2Q99aLJgCliJbgHI/As+ZyzOfKUAT0FpFDpA0bJYIxK4uWnJI9JIJZ8f8K0/3dKpSn3nP4zg AEF44/2KmmNMEvh6fftQmYyDVIVdu97ml8aMtnmnJZmydY342QLgqUY0QWLt4yI1aw8qcS3v5lP ag09ORwRwk4UOtvLkA1zq0eAJqeEjUkOeRcDYm9Du37vgPcw== X-Gm-Gg: ASbGncvd8AU6WBSUWGZ17Zx647XZYLxNythYjoM3GgO8ReEtqw8vzzKIxFIo7KwmdzO ayzSSKQQj+IkWRw5a5AMs8twHJ0y4fbAy9cJSpQZwZDe15qqJ7HhaD5O9q/4LzybIpLzPJNouXr rur/UKk3NYbES1h6QP2xXlEKFvGHC+ATkcjletgawdqW697Oeb1eG1oWAIRhzK0IGjApGr1SgPJ +QHk6+OrOLIeSEHJgs94nkxZd65lVhNrcI0QhPwWTA4OyordjzTPTLhzU6eTfGFVdr2Mw7GQLbh e80iTayoz1FbVV8PPFJ0Pg== X-Received: by 2002:a05:600c:3584:b0:439:6118:c188 with SMTP id 5b1f17b1804b1-43db62b7c5emr104954935e9.19.1743523932590; Tue, 01 Apr 2025 09:12:12 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGcsGAEYE+5PwlQjdEBXjpJ/Slimxfn6OxxsnrMh8halxw+3MQX3DryS9bQZc9lJ/fr1kYiAQ== X-Received: by 2002:a05:600c:3584:b0:439:6118:c188 with SMTP id 5b1f17b1804b1-43db62b7c5emr104954555e9.19.1743523932128; Tue, 01 Apr 2025 09:12:12 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d8fba3b13sm165471445e9.3.2025.04.01.09.12.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:10 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 23/29] KVM: x86: extract kvm_post_set_cpuid Date: Tue, 1 Apr 2025 18:11:00 +0200 Message-ID: <20250401161106.790710-24-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" CPU state depends on CPUID info and is initialized by KVM_SET_CPUID2, but KVM_SET_CPUID2 does not exist for non-default planes. Instead, they just copy over the CPUID info of plane 0. Extract the tail of KVM_SET_CPUID2 so that it can be executed as part of KVM_CREATE_VCPU_PLANE. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/cpuid.c | 38 ++++++++++++++++++++++++-------------- arch/x86/kvm/cpuid.h | 1 + 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index f760a8a5d719..142decb3a736 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -488,6 +488,29 @@ u64 kvm_vcpu_reserved_gpa_bits_raw(struct kvm_vcpu *vc= pu) return rsvd_bits(cpuid_maxphyaddr(vcpu), 63); } =20 +int kvm_post_set_cpuid(struct kvm_vcpu *vcpu) +{ + int r; + +#ifdef CONFIG_KVM_HYPERV + if (kvm_cpuid_has_hyperv(vcpu)) { + r =3D kvm_hv_vcpu_init(vcpu); + if (r) + return r; + } +#endif + + r =3D kvm_check_cpuid(vcpu); + if (r) + return r; + +#ifdef CONFIG_KVM_XEN + vcpu->arch.xen.cpuid =3D kvm_get_hypervisor_cpuid(vcpu, XEN_SIGNATURE); +#endif + kvm_vcpu_after_set_cpuid(vcpu); + return 0; +} + static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e= 2, int nent) { @@ -529,23 +552,10 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struc= t kvm_cpuid_entry2 *e2, goto success; } =20 -#ifdef CONFIG_KVM_HYPERV - if (kvm_cpuid_has_hyperv(vcpu)) { - r =3D kvm_hv_vcpu_init(vcpu); - if (r) - goto err; - } -#endif - - r =3D kvm_check_cpuid(vcpu); + r =3D kvm_post_set_cpuid(vcpu); if (r) goto err; =20 -#ifdef CONFIG_KVM_XEN - vcpu->arch.xen.cpuid =3D kvm_get_hypervisor_cpuid(vcpu, XEN_SIGNATURE); -#endif - kvm_vcpu_after_set_cpuid(vcpu); - success: kvfree(e2); return 0; diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index d3f5ae15a7ca..05cc1245f570 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -42,6 +42,7 @@ static inline struct kvm_cpuid_entry2 *kvm_find_cpuid_ent= ry(struct kvm_vcpu *vcp int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, struct kvm_cpuid_entry2 __user *entries, unsigned int type); +int kvm_post_set_cpuid(struct kvm_vcpu *vcpu); int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid *cpuid, struct kvm_cpuid_entry __user *entries); --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 17115223302 for ; Tue, 1 Apr 2025 16:12:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523941; cv=none; b=CkEyMYcAWVFzhweXPTBApcN8DjYKWYmLqpXuarRD0+MuqwwmimVFDA4Kp6EbN8wQorPMh6inAFahwmGuUigPoH3vJAhY582ZJ2EbKkzu6E9HpogrO0ZQrNB8U1tm0yiQ8MXKMdgr97iAqLbl4vVZc6RvHAWkMNxYzJ3ZKXMkRF8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523941; c=relaxed/simple; bh=RqolX2nBYsBB1RvK+C0gqm089aXRe/tRZbLNpfcHISU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JZkAU/AYqGJIqG6ORFQlMoSpDb4EclhW32WNaQwHVOlQPZnDQe5MKOBtd212phAPKK9SRTauO1uei16lVM3oVxlKaFz7lgaQq2yTWTTiIySCei7qW37UumM0rqyq0FTb2DumOYQ81sidXTeijwrAzjH+E/4UoNkpcVr2ic6qSeM= 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=Dc2W41nH; arc=none smtp.client-ip=170.10.129.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="Dc2W41nH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523939; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/yWeFqVMRebyIXvHSXUhfNNjcs9eft8Ib/p8yK7977Q=; b=Dc2W41nHSEpM3R/JcFIqM/Fudz3NBvc1pZmdk4NJ40Ytb8NWD1x/IpCGZjYg6PMttHVRbo y+4AjwUXsZbmoUK/Kvkxw/yEQLXeptGKkFCOC3G2z0Q3iRJ6EDoDGH2ttYxqs0QtIYrigD C4q4ehB5fRYLucn7mxKiXxGDfIj1XA4= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-453-bhNLah-jNseIdseRh-r5vQ-1; Tue, 01 Apr 2025 12:12:17 -0400 X-MC-Unique: bhNLah-jNseIdseRh-r5vQ-1 X-Mimecast-MFC-AGG-ID: bhNLah-jNseIdseRh-r5vQ_1743523936 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-391425471d6so2541278f8f.3 for ; Tue, 01 Apr 2025 09:12:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523935; x=1744128735; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/yWeFqVMRebyIXvHSXUhfNNjcs9eft8Ib/p8yK7977Q=; b=rb6X7wB5Bxw3xFYeF1FxklGtfm6ju7T78bgnbUYsTK2Li/v17+6jPvoUUnc9VVIkAA 59hmsSGmUsVfuav6cuFVDzEdUfxRs5cOFOj/ThOc08NffdydxAL11l8R9lvzo8vzfpTf J8McSLbqGHQQJkIzGk4RfSm8Msl9/oWnjmle4RWD7wkFn54K76h9f4n/g6cfsUQU0bpk 7VpnC2WXHZ0MyG+YzKGp0g7KAQhIxS4kPxyRRqQvNZhnLC3J1+Hh1aRpKJ875+sWTBhf ltgETaxjKSXGsxttk27KLcrDElFLRT1VkVsZ/TEufEmHlX3z7Vf142kaAgYp05Q+IaT6 h6zw== X-Gm-Message-State: AOJu0YwnH3/ZApbiZsKoYemu1N5GK71khxrTHfZvMPQNEQm/B0u9kozc jiPfwWv/mDKW4gbaNqe4F6Sp/rlv7hDDP1rksGrDkoFYscSMzT1KAlpZijfCBVFpSk3X83mNqZQ wt/jM/M8/A9VztR2uwa624ZKVvTclG4XIb97t+JieEpPSOLQ1RH9NAJLpz3G4tzsZgZU3r/MSb2 q2w5JzFhmpyinDuH+FYtDvEfT9xLYWFGek2qrDKNIs8gBncQ== X-Gm-Gg: ASbGncuPHtXqifKhFrL95a6WekBV6mkrne70GUfR11iCBNxFCdRE3XBkGHsYRuXgyov tuyz/ZChJU/4fdK2xme+wMKyWJfh5NxKINAnfq4IU1s4oVEJOTRSVQLdbtZIrxN3FnkDWYhiin2 jw3OStwfZnggAquMOBaPq+ZEn/8Ga04xdYLi9p8n4MBa2SlfI2eyJV1LXEUyAk6tvNYX2CoVDxC gSG5sYIG3OBIXoNcWlt0QrGlds0rclAuikSheveOgQS/yj0q4eEyn08qnHEHFMpAGf/ipHWbcaI hNASqc58BV9h5yxWhdNZOw== X-Received: by 2002:a5d:584c:0:b0:391:4559:8761 with SMTP id ffacd0b85a97d-39c1211394bmr11532851f8f.36.1743523935379; Tue, 01 Apr 2025 09:12:15 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFdiNekii4PSYbxjvDp66z82YdwPHoAMXYlQUesXdMmLvzhLibRLalKupSShxNYAuhAEstwpw== X-Received: by 2002:a5d:584c:0:b0:391:4559:8761 with SMTP id ffacd0b85a97d-39c1211394bmr11532793f8f.36.1743523934852; Tue, 01 Apr 2025 09:12:14 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d900008d8sm158223435e9.33.2025.04.01.09.12.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:13 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 24/29] KVM: x86: initialize CPUID for non-default planes Date: Tue, 1 Apr 2025 18:11:01 +0200 Message-ID: <20250401161106.790710-25-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Copy the initial CPUID from plane 0. To avoid mismatches, block KVM_SET_CPUID{,2} after KVM_CREATE_VCPU_PLANE similar to how it is blocked after KVM_RUN; this is handled by a tiny bit of architecture independent code. Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/api.rst | 4 +++- arch/x86/kvm/cpuid.c | 19 ++++++++++++++++++- arch/x86/kvm/cpuid.h | 1 + arch/x86/kvm/x86.c | 7 ++++++- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 1 + 6 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 16d836b954dc..3739d16b7164 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -736,7 +736,9 @@ Caveat emptor: configuration (if there is) is not corrupted. Userspace can get a copy of the resulting CPUID configuration through KVM_GET_CPUID2 in case. - Using KVM_SET_CPUID{,2} after KVM_RUN, i.e. changing the guest vCPU mo= del - after running the guest, may cause guest instability. + after running the guest, is forbidden; so is using the ioctls after + KVM_CREATE_VCPU_PLANE, because all planes must have the same CPU + capabilities. - Using heterogeneous CPUID configurations, modulo APIC IDs, topology, e= tc... may cause guest instability. =20 diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 142decb3a736..44e6d4989bdd 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -545,7 +545,7 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct = kvm_cpuid_entry2 *e2, * KVM_SET_CPUID{,2} again. To support this legacy behavior, check * whether the supplied CPUID data is equal to what's already set. */ - if (kvm_vcpu_has_run(vcpu)) { + if (kvm_vcpu_has_run(vcpu) || vcpu->has_planes) { r =3D kvm_cpuid_check_equal(vcpu, e2, nent); if (r) goto err; @@ -567,6 +567,23 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct= kvm_cpuid_entry2 *e2, return r; } =20 +int kvm_dup_cpuid(struct kvm_vcpu *vcpu, struct kvm_vcpu *source) +{ + if (WARN_ON_ONCE(vcpu->arch.cpuid_entries || vcpu->arch.cpuid_nent)) + return -EEXIST; + + vcpu->arch.cpuid_entries =3D kmemdup(source->arch.cpuid_entries, + source->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2), + GFP_KERNEL_ACCOUNT); + if (!vcpu->arch.cpuid_entries) + return -ENOMEM; + + memcpy(vcpu->arch.cpu_caps, source->arch.cpu_caps, sizeof(source->arch.cp= u_caps)); + vcpu->arch.cpuid_nent =3D source->arch.cpuid_nent; + + return 0; +} + /* when an old userspace process fills a new kernel module */ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid *cpuid, diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index 05cc1245f570..a5983c635a70 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -42,6 +42,7 @@ static inline struct kvm_cpuid_entry2 *kvm_find_cpuid_ent= ry(struct kvm_vcpu *vcp int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, struct kvm_cpuid_entry2 __user *entries, unsigned int type); +int kvm_dup_cpuid(struct kvm_vcpu *vcpu, struct kvm_vcpu *source); int kvm_post_set_cpuid(struct kvm_vcpu *vcpu); int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid *cpuid, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d2b43d9b6543..be4d7b97367b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -12412,6 +12412,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, st= ruct kvm_plane *plane) if (plane->plane) { page =3D NULL; vcpu->arch.pio_data =3D vcpu->plane0->arch.pio_data; + r =3D kvm_dup_cpuid(vcpu, vcpu->plane0); + if (r < 0) + goto fail_free_lapic; + + r =3D -ENOMEM; } else { page =3D alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!page) @@ -12459,7 +12464,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, str= uct kvm_plane *plane) =20 kvm_xen_init_vcpu(vcpu); vcpu_load(vcpu); - kvm_vcpu_after_set_cpuid(vcpu); + WARN_ON_ONCE(kvm_post_set_cpuid(vcpu)); kvm_set_tsc_khz(vcpu, vcpu->kvm->arch.default_tsc_khz); kvm_vcpu_reset(vcpu, false); kvm_init_mmu(vcpu); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 5cade1c04646..0b764951f461 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -344,6 +344,7 @@ struct kvm_vcpu { struct mutex mutex; =20 /* Only valid on plane 0 */ + bool has_planes; bool wants_to_run; =20 /* Shared for all planes */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index db38894f6fa3..3a04fdf0865d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4182,6 +4182,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm_plane = *plane, struct kvm_vcpu *pl if (plane->plane) { page =3D NULL; vcpu->run =3D plane0_vcpu->run; + plane0_vcpu->has_planes =3D true; } else { WARN_ON(plane0_vcpu !=3D NULL); plane0_vcpu =3D vcpu; --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 D0B5C223336 for ; Tue, 1 Apr 2025 16:12:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523944; cv=none; b=N+29Ikokn9uHS2f08/beDxd77zyHveMG9C8a6rEI+okMlmkQ8VehWVBFX+zeQuX0e76dW9WYlnIW/4UE8L0rEEM+ikFMW6WyADlZ4i1oVmtjcaXMK+m0sECBo2T0BJRXTK9pD9gGhIl+xXU6PHXLJKfVaDQnJKwkPB9T3i+kF2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523944; c=relaxed/simple; bh=pn8er/Ns1V0RvexqIaqaUyOMfeX7VOy6D1cEZq4AgVs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZdbdMiNOGAv8QYhY9ENHOR6sMSDQdXpKzX2sIGdl9JHLEBdYNAiAdA6F3cg5gu9cm4w+1Msqkxn9Y3D1agzeeEQPfVwbE4yh2f2GqXRecixbuhVd7Que+ukFDzh32x1Jn1FgYgxLDXi+RWDCzLfPWFVql9x7gelRtwYN/S0QM8M= 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=RCWXG1rt; arc=none smtp.client-ip=170.10.129.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="RCWXG1rt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523942; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=STKQiGVrBKxKXPgyW50q0lNwcXD/6o7OaldUCF+7vOE=; b=RCWXG1rtgHMePJw7uS/ExMTF3nZWX6k1rdfCyEsPzfNI0gtrbb/bUAokDBexcKBrzVxoZQ I21aQ5tk7/0JCQrdvtmrpP8PhwCKGcit5CQ02jXRFh1/Ezd0rrihv1UZqFJgrbitXIvrW8 T/j1TvJvU/mBmRZ/iGY87933L8KGR78= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-179-2V_gTDd9OZK-zObAwPVxDg-1; Tue, 01 Apr 2025 12:12:19 -0400 X-MC-Unique: 2V_gTDd9OZK-zObAwPVxDg-1 X-Mimecast-MFC-AGG-ID: 2V_gTDd9OZK-zObAwPVxDg_1743523939 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-39131851046so2760175f8f.0 for ; Tue, 01 Apr 2025 09:12:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523938; x=1744128738; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=STKQiGVrBKxKXPgyW50q0lNwcXD/6o7OaldUCF+7vOE=; b=DSdYr2fLujEuxmzIS7+x3V/4GJ1JKDTaJqYX7wzkhVPdu1dCYGHEiJiuaBb53e52AK szktkj1x4GO6mPEegldDINytpQgxvNxUgSMF5F9VEGO9+SEQyNI9xwK3xy2xJ5LABA6d 79aAD1/nIZNyzVDEgaCozbGzWeFND2l+LtMAwibvyDKlXZ2EYleWG1Lm/sQ6RcqmNQWm FNXpylS2S8NjUOa08AF4S6Ha+soJfWXb3urk5IcKsZpWQ5LDYn/SoCc7+taoQTF+uIoq tBCaluw7uGUoCDFhmexVvDTZc0QaAwWrAZL4vMHijS4TRm3ID2jhBzQyaZ5bdIlm8AT+ Utrw== X-Gm-Message-State: AOJu0YwuLiUF689R2cat2Vvz4K92kurlJyT/f7UZOjiYT07oi/sjitSs CuTvDhCe3C7DN+bdaww6BjdvUgo+lS8WUf8E+2H8catA//3w0FZDCz1f00+QYuWpTy9QzJ21VC5 qCYX4zfM2Mqsyy8Q/o6A8Er/nG/QikYI2K4dgP1cvGBEVPj5DTmif5bqlcPwScPsWFnzr2K61hw ee2RUVC8MHjuh2BcsFZ3C7GZAsym5kvV61OWzsIwyC5bnNmA== X-Gm-Gg: ASbGnctmHEIp88vlB3OfYKO0e7jcee4VExAXG8qWiHxpzF6TqX8O5P0keLu1SvYb8Nn 3nl9cEoLgWwaaNkyfKhmboRdEoeHxi0E/iiVv9dMGvQveQFiPonpYv/pepSM5PFVI+RNFA88gtm BBQt4Xwaf9cO+uUhc52G7G26bwjkcskTtPav9ixSZY0SzcALbJvQ3ttudIk4wplo1QS7+AANJzU xIbr2n9HovLt0FKdg5IrEYeB/PPO5sGZTkb1e97tnO9b3UEs2aPWkskD27BTG6bSLsmME7eFcip f0nCGinuedFFDfO4X+Q7pQ== X-Received: by 2002:a05:6000:40e1:b0:391:2ab1:d4c2 with SMTP id ffacd0b85a97d-39c12115daamr10848582f8f.37.1743523937566; Tue, 01 Apr 2025 09:12:17 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFixcIUQZovBxbTUqE5qYkRuf8yLn9S/Hc/iFsk0oOlWsNioebYuSesp4eyH3gSeVV6bFB72A== X-Received: by 2002:a05:6000:40e1:b0:391:2ab1:d4c2 with SMTP id ffacd0b85a97d-39c12115daamr10848526f8f.37.1743523937028; Tue, 01 Apr 2025 09:12:17 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d8fcceaaasm160266655e9.18.2025.04.01.09.12.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:15 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 25/29] KVM: x86: handle interrupt priorities for planes Date: Tue, 1 Apr 2025 18:11:02 +0200 Message-ID: <20250401161106.790710-26-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Force a userspace exit if an interrupt is delivered to a higher-priority plane, where priority is represented by vcpu->run->req_exit_planes. The set of planes with pending IRR are manipulated atomically and stored in the plane-0 vCPU, since it is handy to reach from the target vCPU. TODO: haven't put much thought into IPI virtualization. Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 7 +++++ arch/x86/kvm/lapic.c | 36 +++++++++++++++++++++++-- arch/x86/kvm/x86.c | 48 +++++++++++++++++++++++++++++++++ include/linux/kvm_host.h | 2 ++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 9ac39f128a53..0344e8bed319 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -125,6 +125,7 @@ #define KVM_REQ_HV_TLB_FLUSH \ KVM_ARCH_REQ_FLAGS(32, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) #define KVM_REQ_UPDATE_PROTECTED_GUEST_STATE KVM_ARCH_REQ(34) +#define KVM_REQ_PLANE_INTERRUPT KVM_ARCH_REQ(35) =20 #define CR0_RESERVED_BITS \ (~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \ @@ -864,6 +865,12 @@ struct kvm_vcpu_arch { u64 xcr0; u64 guest_supported_xcr0; =20 + /* + * Only valid in plane0. The bitmask of planes that received + * an interrupt, to be checked against req_exit_planes. + */ + atomic_t irr_pending_planes; + struct kvm_pio_request pio; void *pio_data; void *sev_pio_data; diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 16a0e2387f2c..21dbc539cbe7 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1311,6 +1311,39 @@ bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, s= truct kvm_lapic_irq *irq, return ret; } =20 +static void kvm_lapic_deliver_interrupt(struct kvm_vcpu *vcpu, struct kvm_= lapic *apic, + int delivery_mode, int trig_mode, int vector) +{ + struct kvm_vcpu *plane0_vcpu =3D vcpu->plane0; + struct kvm_plane *running_plane; + u16 req_exit_planes; + + kvm_x86_call(deliver_interrupt)(apic, delivery_mode, trig_mode, vector); + + /* + * test_and_set_bit implies a memory barrier, so IRR is written before + * reading irr_pending_planes below... + */ + if (!test_and_set_bit(vcpu->plane, &plane0_vcpu->arch.irr_pending_planes)= ) { + /* + * ... and also running_plane and req_exit_planes are read after writing + * irr_pending_planes. Both barriers pair with kvm_arch_vcpu_ioctl_run(= ). + */ + smp_mb__after_atomic(); + + running_plane =3D READ_ONCE(plane0_vcpu->running_plane); + if (!running_plane) + return; + + req_exit_planes =3D READ_ONCE(plane0_vcpu->req_exit_planes); + if (!(req_exit_planes & BIT(vcpu->plane))) + return; + + kvm_make_request(KVM_REQ_PLANE_INTERRUPT, + kvm_get_plane_vcpu(running_plane, vcpu->vcpu_id)); + } +} + /* * Add a pending IRQ into lapic. * Return 1 if successfully added and 0 if discarded. @@ -1352,8 +1385,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, = int delivery_mode, apic->regs + APIC_TMR); } =20 - kvm_x86_call(deliver_interrupt)(apic, delivery_mode, - trig_mode, vector); + kvm_lapic_deliver_interrupt(vcpu, apic, delivery_mode, trig_mode, vector= ); break; =20 case APIC_DM_REMRD: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index be4d7b97367b..4546d1049f43 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10960,6 +10960,19 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) goto out; } } + if (kvm_check_request(KVM_REQ_PLANE_INTERRUPT, vcpu)) { + u16 irr_pending_planes =3D atomic_read(&vcpu->plane0->arch.irr_pending_= planes); + u16 target =3D irr_pending_planes & vcpu->plane0->req_exit_planes; + if (target) { + vcpu->run->exit_reason =3D KVM_EXIT_PLANE_EVENT; + vcpu->run->plane_event.cause =3D KVM_PLANE_EVENT_INTERRUPT; + vcpu->run->plane_event.flags =3D 0; + vcpu->run->plane_event.pending_event_planes =3D irr_pending_planes; + vcpu->run->plane_event.target =3D target; + r =3D 0; + goto out; + } + } } =20 if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win || @@ -11689,8 +11702,11 @@ static int kvm_vcpu_ioctl_run_plane(struct kvm_vcp= u *vcpu) =20 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) { + struct kvm_vcpu *plane0_vcpu =3D vcpu; int plane_id =3D READ_ONCE(vcpu->run->plane); struct kvm_plane *plane =3D vcpu->kvm->planes[plane_id]; + u16 req_exit_planes =3D READ_ONCE(vcpu->run->req_exit_planes) & ~BIT(plan= e_id); + u16 irr_pending_planes; int r; =20 if (plane_id) { @@ -11698,8 +11714,40 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) mutex_lock_nested(&vcpu->mutex, 1); } =20 + if (plane0_vcpu->has_planes) { + plane0_vcpu->req_exit_planes =3D req_exit_planes; + plane0_vcpu->running_plane =3D plane; + + /* + * Check for cross-plane interrupts that happened while outside KVM_RUN; + * write running_plane and req_exit_planes before reading irr_pending_pl= anes. + * If an interrupt hasn't set irr_pending_planes yet, it will trigger + * KVM_REQ_PLANE_INTERRUPT itself in kvm_lapic_deliver_interrupt(). + */ + smp_mb__before_atomic(); + + irr_pending_planes =3D atomic_fetch_and(~BIT(plane_id), &plane0_vcpu->ar= ch.irr_pending_planes); + if (req_exit_planes & irr_pending_planes) + kvm_make_request(KVM_REQ_PLANE_INTERRUPT, vcpu); + } + r =3D kvm_vcpu_ioctl_run_plane(vcpu); =20 + if (plane0_vcpu->has_planes) { + smp_store_release(&plane0_vcpu->running_plane, NULL); + + /* + * Clear irr_pending_planes before reading IRR; pairs with + * kvm_lapic_deliver_interrupt(). If this side doesn't see IRR set, + * the other side will certainly see the cleared bit irr_pending_planes + * and set it, and vice versa. + */ + clear_bit(plane_id, &plane0_vcpu->arch.irr_pending_planes); + smp_mb__after_atomic(); + if (kvm_lapic_find_highest_irr(vcpu)) + atomic_or(BIT(plane_id), &plane0_vcpu->arch.irr_pending_planes); + } + if (plane_id) mutex_unlock(&vcpu->mutex); =20 diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 0b764951f461..442aed2b9cc6 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -346,6 +346,8 @@ struct kvm_vcpu { /* Only valid on plane 0 */ bool has_planes; bool wants_to_run; + u16 req_exit_planes; + struct kvm_plane *running_plane; =20 /* Shared for all planes */ struct kvm_run *run; --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 32D0A2236F6 for ; Tue, 1 Apr 2025 16:12:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523945; cv=none; b=JyZbJFpSSSRJa9glip0eAhcgRiCDxdOBlEpYRsN6/lNuOwzo3sGjdP1sB5DD/fDhlSv9hJlgZ6sSeMQhnocneoyYECCjNo8GaDHAaYEea7C1mQvdKTudDJzJ+gYASukFByyRha1oolhokqZszv1J0wmg+bkzYj0zpKet6o3C9jM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523945; c=relaxed/simple; bh=Jr48n7DTkbCOMB/d0GEJ1ZQWRT8vQDsoeXOK//lT2/0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QMx6vUW7NEInjj4isWX1wWT+cQKndBQeK+HwyWUU/Hf+GAOJW0tSspXxCnXfotTPLKcgnJaa5QFkodkzzXSrh9/I+hMscOHo/Na/Lla369GVPv0t7Hw2WnQCqCDjyelwEfB+/d6f6VbHeJ+wDiqo4AiC1ZnKG5av5v9FMF2A87c= 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=eO8K3TFN; arc=none smtp.client-ip=170.10.129.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="eO8K3TFN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523943; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JMmSY+BAN+od5q2oN5V+h7YwfbF4XF3XqSY7nT/C4e4=; b=eO8K3TFNNyfFXoH8F8dWLrMwdH629XyAeyR4emBFCS4+bZ1MM8pRGGBmlgZsjtKoGr4Zcl oj8joZWqaZNoFHQy9xt/qBOEvFC/FHl69cyce/gpKt1nvk5M26c00J5/ksM216MnKgzLIr Fif5IBGNpsc7Y+QfkCQ3eMBG2u5PUwY= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-199-Ocxnm4yCMY2KPrUAnhTCQg-1; Tue, 01 Apr 2025 12:12:22 -0400 X-MC-Unique: Ocxnm4yCMY2KPrUAnhTCQg-1 X-Mimecast-MFC-AGG-ID: Ocxnm4yCMY2KPrUAnhTCQg_1743523941 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-39abdadb0f0so2996989f8f.0 for ; Tue, 01 Apr 2025 09:12:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523940; x=1744128740; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JMmSY+BAN+od5q2oN5V+h7YwfbF4XF3XqSY7nT/C4e4=; b=sE5emEoUogAsyk333E6dy/9FU9emsNWeNP1VWJDM+wntCSujK+eka3ATJdPGbTqZQ/ YX7hjT+FJj7IuBL39wfrbSZSyzeHHKTfCPOZcw4Rn7SJYgEsPm9Hchho34QJjegkzXoL ++aS//MWwZWO/R8N6vw0eEFXm3a8pAgcB4ff8/wBVZuqBx+PJuAa+qxd35ZBHmE7m4Oh dSZY4VlQbAXEFvEmx5NqDoeEjWTwrGPFjfV4u18u1h5TSzc9txatrf1hS+ZMe7+oquJO R29RDcWGYHwpRmwZVAc/BPI5iYuw+cLT2kP8nWSVtwE99xgEM18GOwH81NJAE9gyHIv4 fotQ== X-Gm-Message-State: AOJu0YwnLZL2KF5KHDLlJBcRo+QXRze4ZWgXuueblSWcYduPMkAWn0EO OO/pMT5MCPYS1ms42VyKHtMASfp768uXogVB6SCpW5xS5dRpPeSAZEvqBh/Y7crNWJ5OXBJqe+n bglGi6dYyLcKvAonjhvoIuxiPZvxASxvm9T5KCYxzMB4i5OOKo9eVjn/drMyM77jKeoyIAh15q0 2HckHwMDnNMs+uieVE1rjdtl2IbbuljArk1mJXVBS+3drubQ== X-Gm-Gg: ASbGncu8k/K7o7lWfihyn8dEMcmH6Y3gScexk0yHDLJorHQfnpby9D4MN/fnPkp1AfY +l8+Gi0oVVorwMdA2BnMB8SWQD3zas2XdNz91OOnAMN3w+PpEt/7sfg+sp6TZzblpFqNgDHTSxK dE/mDgqBi3ZooF+ypbfB9pXW2XE6F3ccBRs+Gtwzfx4TzwPI7Jrok53wxI6lY9rRJ2+/N0+ifNT YzekyRV3Iq3b9STHw5OMp2B+NnVoyrYyvs1yNpc2nxQHYHS/0k28qPm6DNEaL31BC12Zzex3Ew0 i4e/pOm3XLuWGcfrCvd4uA== X-Received: by 2002:a05:6000:188b:b0:391:20ef:62d6 with SMTP id ffacd0b85a97d-39c120cb835mr10465222f8f.11.1743523940245; Tue, 01 Apr 2025 09:12:20 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFFwlHiQzmqyX2anRC0qQyOVR2lkXQfjeA/y3ngR7h2MBX/VCdz2HKMdJUXOZo8Odrhhl0ySQ== X-Received: by 2002:a05:6000:188b:b0:391:20ef:62d6 with SMTP id ffacd0b85a97d-39c120cb835mr10465179f8f.11.1743523939799; Tue, 01 Apr 2025 09:12:19 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d8fbc1716sm158501095e9.15.2025.04.01.09.12.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:17 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 26/29] KVM: x86: enable up to 16 planes Date: Tue, 1 Apr 2025 18:11:03 +0200 Message-ID: <20250401161106.790710-27-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow up to 16 VM planes, it's a nice round number. FIXME: online_vcpus is used by x86 code that deals with TSC synchronization. Maybe kvmclock should be moved to planex. Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/x86.c | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 0344e8bed319..d0cb177b6f52 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2339,6 +2339,8 @@ enum { # define kvm_memslots_for_spte_role(kvm, role) __kvm_memslots(kvm, 0) #endif =20 +#define KVM_MAX_VCPU_PLANES 16 + int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v); int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); int kvm_cpu_has_extint(struct kvm_vcpu *v); @@ -2455,6 +2457,7 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, = unsigned long npages); */ #define KVM_EXIT_HYPERCALL_MBZ GENMASK_ULL(31, 1) =20 +int kvm_arch_nr_vcpu_planes(struct kvm *kvm); bool kvm_arch_planes_share_fpu(struct kvm *kvm); =20 #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4546d1049f43..86d1a567f62e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -13989,6 +13989,12 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsi= gned long type, gva_t gva) } EXPORT_SYMBOL_GPL(kvm_handle_invpcid); =20 +int kvm_arch_nr_vcpu_planes(struct kvm *kvm) +{ + /* TODO: use kvm_x86_ops so that SNP can use planes for VTPLs. */ + return kvm->arch.has_protected_state ? 1 : KVM_MAX_VCPU_PLANES; +} + bool kvm_arch_planes_share_fpu(struct kvm *kvm) { return !kvm || kvm->arch.planes_share_fpu; --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 9D98B224240 for ; Tue, 1 Apr 2025 16:12:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523949; cv=none; b=AtjJVBgaMuiFjp4LvP9SbsVD28Ls000NrktMxgYxY8U2Amas3JCXeIlFqkYdiyvkHMd5ampTB1CmaNM/OhJ5HhOtRTdLpopuLm34y+wGb6I9bm51YKoWJw/NqczS7seKp5o2qCAjy6cQqLOaojs/2VmvcjIuvuP1iB3USFUigVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523949; c=relaxed/simple; bh=7h29/HU5sdApjkYIeGF2/5ZLb/HC0XBAWZ+vi6Cv12I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sTY8q0SNDWckkYqqDafREyFra/4n+mA6IR3TrDVrweb6c7igg2tsbyAnntL00LkcSUgtFn2+FBlfPl3xOnMTS7lh0Efnw4EZ04QI0yxk67SHY3+iKexAg6WXUvfRzb+Sz2wl/XqlQi+EuxxOIM8GW7gQE+BxgNb/E1eB9eJ5lK8= 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=bEoFSHjk; arc=none smtp.client-ip=170.10.129.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="bEoFSHjk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523946; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Za9UhBdtRl20IVd/exE7AzVdA7LtofpEuC+6DQ+7Q1I=; b=bEoFSHjkUKo+Y8QWRGVzO4tCShDz4UVZXB9vk6E0bisSB4i3TtYElCMgUcOXzJ9b+OZQSV f41n89zrSkx/64Ltoj7Kieyo2zi2CV6ntN3EnkvEYarXJE4ou/r6vT/1X1Udd3cvEEMc/t XrY1YhlFXBZR3z3oLg/lydXSgGhhpB0= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-103-h9dia9GOOZWt1kJyWt3xsA-1; Tue, 01 Apr 2025 12:12:25 -0400 X-MC-Unique: h9dia9GOOZWt1kJyWt3xsA-1 X-Mimecast-MFC-AGG-ID: h9dia9GOOZWt1kJyWt3xsA_1743523945 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43ceeaf1524so30161155e9.1 for ; Tue, 01 Apr 2025 09:12:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523943; x=1744128743; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Za9UhBdtRl20IVd/exE7AzVdA7LtofpEuC+6DQ+7Q1I=; b=JO5cXAHX6ulZtWUWY8gYlUFnQciryExhXxwIgnFJy/bD94AYE1GKQPN/AhvbwOR9Y6 c/0gTY0PGhBaCLc39frtaalm/Ml190nhlB1vl9IVDQ/a4cSCyMKF92LTe/Gt279RMAaS Xe8Ne6vZ33vsbUBAH9hgFG4yHRX860b4dgNQ1Vy8A4nPfST7ShrLbLGo3fXaBOHN9HO5 Cvg9ucUMJP6qPcocKyf+mrioPk4n3wuB8TfDtTVyxiqkiO8bHCL+50ltktwddudAPdUQ 3uVaCQgxFhaCVgyckldvMy3bMwGct1bJlBz9fU3FwfwhRWoBwKgthC/RxP77cvSzpkmz UOpw== X-Gm-Message-State: AOJu0YxG1WDlBHKEWw6qLWs9X9RXCY914qzsSs9+rQyNnBDUYFUVlhSw DkqS5LIDRxoVgtJ9Ze6n7fzRuISxb1mymlAQzn5r7sRLnalfxCWc8QU3oC7WEmXEDyfVcWMihom fYTsXULIM0guNCM88jtn71+vd82LplKW3B+vTnI/JQlp74GlhAaNzw1ILWCdNlBAqwgIVny88zA JF3OONBoMJAJvE1Mmx9x6sfxIJjkJ258VvKaium5/QfJBSsg== X-Gm-Gg: ASbGncvbqZ/cKm8aaJh11+htH0+ZovVvt3DuI29ywN/swt+rlpdJBFYzAMQXCcJ5ov2 mi+6Nd5StbedK7BOYpP6+YiDv5V3hOUGDXFgCQcBdyAEsN93A5bs5tHZe1eLI1Ns+ZrzGFFSHfh WqmrLvizZuqKqA6ErB7HNgeOMmEh1hexutXYTycNMbyhIYr+X3Hrou0kZjb28Cqwn9Y+ALAJRHH j68gBmWQf53PM2ElHMY06oAigF0sbRV8wUUxdCgZLJWMlvp+f6IgfLhhPY2IbAZTvxdYqRB2UCp DXcF6o7Hg7cvUhnaHfEnsg== X-Received: by 2002:a05:600c:198e:b0:43c:f3e1:a729 with SMTP id 5b1f17b1804b1-43eb05bd475mr6791875e9.12.1743523943510; Tue, 01 Apr 2025 09:12:23 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHgj2ZbCQGfmVhz6lrnJ+5wyjIJ9OaWTHSb2mNQbdBcNI3fX/rNQGWp16Y3i8t/HcaXbmtslA== X-Received: by 2002:a05:600c:198e:b0:43c:f3e1:a729 with SMTP id 5b1f17b1804b1-43eb05bd475mr6791375e9.12.1743523943004; Tue, 01 Apr 2025 09:12:23 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39c0b6588dbsm14265870f8f.2.2025.04.01.09.12.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:20 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 27/29] selftests: kvm: introduce basic test for VM planes Date: Tue, 1 Apr 2025 18:11:04 +0200 Message-ID: <20250401161106.790710-28-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check a few error cases and ensure that a vCPU can have a second plane added to it. For now, all interactions happen through the bare __vm_ioctl() interface or even directly through the ioctl() system call. Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/Makefile.kvm | 1 + tools/testing/selftests/kvm/plane_test.c | 108 +++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 tools/testing/selftests/kvm/plane_test.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index f62b0a5aba35..b1d0b410cc03 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -57,6 +57,7 @@ TEST_GEN_PROGS_COMMON +=3D guest_print_test TEST_GEN_PROGS_COMMON +=3D kvm_binary_stats_test TEST_GEN_PROGS_COMMON +=3D kvm_create_max_vcpus TEST_GEN_PROGS_COMMON +=3D kvm_page_table_test +TEST_GEN_PROGS_COMMON +=3D plane_test TEST_GEN_PROGS_COMMON +=3D set_memory_region_test =20 # Compiled test targets diff --git a/tools/testing/selftests/kvm/plane_test.c b/tools/testing/selft= ests/kvm/plane_test.c new file mode 100644 index 000000000000..43c8de13490a --- /dev/null +++ b/tools/testing/selftests/kvm/plane_test.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Red Hat, Inc. + * + * Test for architecture-neutral VM plane functionality + */ +#include +#include +#include +#include + +#include "test_util.h" + +#include "kvm_util.h" +#include "asm/kvm.h" +#include "linux/kvm.h" + +void test_create_plane_errors(int max_planes) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + int planefd, plane_vcpufd; + + vm =3D vm_create_barebones(); + vcpu =3D __vm_vcpu_add(vm, 0); + + planefd =3D __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)0); + TEST_ASSERT(planefd =3D=3D -1 && errno =3D=3D EEXIST, + "Creating existing plane, expecting EEXIST. ret: %d, errno: %d", + planefd, errno); + + planefd =3D __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)max_p= lanes); + TEST_ASSERT(planefd =3D=3D -1 && errno =3D=3D EINVAL, + "Creating plane %d, expecting EINVAL. ret: %d, errno: %d", + max_planes, planefd, errno); + + plane_vcpufd =3D __vm_ioctl(vm, KVM_CREATE_VCPU_PLANE, (void *)(unsigned = long)vcpu->fd); + TEST_ASSERT(plane_vcpufd =3D=3D -1 && errno =3D=3D ENOTTY, + "Creating vCPU for plane 0, expecting ENOTTY. ret: %d, errno: %d", + plane_vcpufd, errno); + + kvm_vm_free(vm); + ksft_test_result_pass("error conditions\n"); +} + +void test_create_plane(void) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + int r, planefd, plane_vcpufd; + + vm =3D vm_create_barebones(); + vcpu =3D __vm_vcpu_add(vm, 0); + + planefd =3D __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)1); + TEST_ASSERT(planefd >=3D 0, "Creating new plane, got error: %d", + errno); + + r =3D ioctl(planefd, KVM_CHECK_EXTENSION, KVM_CAP_PLANES); + TEST_ASSERT(r =3D=3D 0, + "Checking KVM_CHECK_EXTENSION(KVM_CAP_PLANES). ret: %d", r); + + r =3D ioctl(planefd, KVM_CHECK_EXTENSION, KVM_CAP_CHECK_EXTENSION_VM); + TEST_ASSERT(r =3D=3D 1, + "Checking KVM_CHECK_EXTENSION(KVM_CAP_CHECK_EXTENSION_VM). ret: %d",= r); + + r =3D __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)1); + TEST_ASSERT(r =3D=3D -1 && errno =3D=3D EEXIST, + "Creating existing plane, expecting EEXIST. ret: %d, errno: %d", + r, errno); + + plane_vcpufd =3D ioctl(planefd, KVM_CREATE_VCPU_PLANE, (void *)(unsigned = long)vcpu->fd); + TEST_ASSERT(plane_vcpufd >=3D 0, "Creating vCPU for plane 1, got error: %= d", errno); + + r =3D ioctl(planefd, KVM_CREATE_VCPU_PLANE, (void *)(unsigned long)vcpu->= fd); + TEST_ASSERT(r =3D=3D -1 && errno =3D=3D EEXIST, + "Creating vCPU again for plane 1. ret: %d, errno: %d", + r, errno); + + r =3D ioctl(planefd, KVM_RUN, (void *)(unsigned long)0); + TEST_ASSERT(r =3D=3D -1 && errno =3D=3D ENOTTY, + "Running plane vCPU again for plane 1. ret: %d, errno: %d", + r, errno); + + close(plane_vcpufd); + close(planefd); + + kvm_vm_free(vm); + ksft_test_result_pass("basic planefd and plane_vcpufd operation\n"); +} + +int main(int argc, char *argv[]) +{ + int cap_planes =3D kvm_check_cap(KVM_CAP_PLANES); + TEST_REQUIRE(cap_planes); + + ksft_print_header(); + ksft_set_plan(2); + + pr_info("# KVM_CAP_PLANES: %d\n", cap_planes); + + test_create_plane_errors(cap_planes); + + if (cap_planes > 1) + test_create_plane(); + + ksft_finished(); +} --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 F0726224243 for ; Tue, 1 Apr 2025 16:12:29 +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=1743523951; cv=none; b=MHrkFNYGD1O0ZVF89wtR2gNCLmFkMWUg/odoeaRp95jX4YQxHO8sLglwJhyvTsMDl8TCVFXNTPXJCSNEpO8kCCTm2Mv8nVjG3eqmm+hTSDwmaqz2Rk2J8Lqg47CMTjdh107yie85CrhDGElE8vVb/7CrtrTlOSuHUC8pTMMks44= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523951; c=relaxed/simple; bh=IzgYPa9TLRk/unXxPit+XhBgPDXmtIE8BQwrHks1a1I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X7F0ZnqqWX+T1/hrhJ3IOJ2h8RxjAPiK5j795z5Ta+TY8/bQcXYlCeAQSnn1IWAQcJfy7hD0uYlUarTI99EPV9qoJLQjMcByO6SAVeecl4yr6LhRRWjrj6e5Ti7lYA+m/VmDRYb+9D6S0JNwz1eQ6X5XRwyJBClZShUHMBo5sk0= 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=FskCZzmj; 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="FskCZzmj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523949; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ThjFpyMC5Hp17v5ZX3gmbcUwmxsf/SI/3VCI26Zru1Q=; b=FskCZzmjo+biTgYld/gpiRMW4B2e+sWznDvvJVRCIvziwmnB3QKsy9mCsAlXScE629cxVF S4+ESB1xsk5/2ZJjZSx3CbH41qf1YybYW8ci4LOnm2VR8Z9FOeiXwm64kxVkbKlPLBCL4Y 80i3NnAkJxHEo/zphfUKEWla89n1HMw= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-56-onhNahw8Ozedos648IqU4Q-1; Tue, 01 Apr 2025 12:12:27 -0400 X-MC-Unique: onhNahw8Ozedos648IqU4Q-1 X-Mimecast-MFC-AGG-ID: onhNahw8Ozedos648IqU4Q_1743523947 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-3912e4e2033so2464164f8f.0 for ; Tue, 01 Apr 2025 09:12:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523946; x=1744128746; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ThjFpyMC5Hp17v5ZX3gmbcUwmxsf/SI/3VCI26Zru1Q=; b=KQNYI5C4vbL+6vZsOz8cUCOhMan9F5vE0Kyb0s3aImkmOpMYyEskzcQSWw7sNkxKCS tm+nw7VdtV8Ll/9uVV5O+FhdfcRvmaemWLTzFSLeNXds09pvVxP7oD40q8KEJnMDtqvU YDxEXs11onh3YiAETC2zM5ChFXLlvzEHkSVzwJ/VrG6HdTuhGPMmJrJxKnRCRhKExdam UTLJxrJFotwzdUDBINU8crhAdKp5v8bYegrn7PnF24n4aXAL3ZspgPZtqE66ITZKwcsW H5gGhQ2mp2+71VQRDvplGgAkhRrVr2lC5ihmLtGve1qHBUwPTFPq61HbmSbuO9TTEjgq ohZw== X-Gm-Message-State: AOJu0YwdzovWGZhqverwmsqGH2KRJ0JgljPtXQPkkn5hjRHFwf1ZybiB u97oUMtL/KTDUi0IL9+Np7k/XKpYZv3V7S3ZHBZjEe9lxrnYxLRmSSWkfjNMagidBgc99cAuGiz C+uaC+yT2E7pouyqTK/1vTfIMptde/mPmMNLgPgIHJdEvebqzH5ai+kdI+nsAVa3XafXYfwQPAQ TVA5SrO7zLd5ob4lk9H71NmfOu8mrYtgmSEyrkeke34KRZYg== X-Gm-Gg: ASbGnctEk5BXvFWWKzwGj3cz7f/sTWbRUfAWJUHZD9SNi8h6uigXd/uaRa5YPlM6IwJ LLFhNshUk1iCSGdvcIOBE9rtVaeEAXREq9sxeulNVegijSYe0jZhWpoPjNsFl7veUDEBLj67rgD W/mLwcLkD8TuLEm/2XKCdseBsy8/Xi37iPmjV7bO4vm+VcN370ZEHOAOqBCfbengndyJAR5eLPt pD1RgYag98FQFr59xS3AKjOV5XI4w9vWug6rCTSzZuk3x/JX4XSWXx2yd9auHmgdPH56DCcFgD+ ThlAWITR2RGl8jZjdXfIAQ== X-Received: by 2002:a5d:5984:0:b0:391:4095:49b7 with SMTP id ffacd0b85a97d-39c120e079amr11107187f8f.25.1743523946174; Tue, 01 Apr 2025 09:12:26 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEBwtO/kXcEsLY7KXcPjFkl0MSW5C3pyJQtoPcatQB9sVIkAZFxi2d3eLTTZNav5W8Iob3Pfw== X-Received: by 2002:a5d:5984:0:b0:391:4095:49b7 with SMTP id ffacd0b85a97d-39c120e079amr11107136f8f.25.1743523945640; Tue, 01 Apr 2025 09:12:25 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d830f5ea4sm206316555e9.25.2025.04.01.09.12.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:23 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 28/29] selftests: kvm: add plane infrastructure Date: Tue, 1 Apr 2025 18:11:05 +0200 Message-ID: <20250401161106.790710-29-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow creating plane and vCPU-plane file descriptors, and close them when the VM is freed. Rewrite the previous test using the new infrastructure (separate for easier review). Signed-off-by: Paolo Bonzini --- .../testing/selftests/kvm/include/kvm_util.h | 48 ++++++++++++++ tools/testing/selftests/kvm/lib/kvm_util.c | 65 ++++++++++++++++++- tools/testing/selftests/kvm/plane_test.c | 21 +++--- 3 files changed, 119 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index 373912464fb4..c1dfe071357e 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -67,6 +67,20 @@ struct kvm_vcpu { uint32_t dirty_gfns_count; }; =20 +struct kvm_plane { + struct list_head list; + uint32_t id; + int fd; + struct kvm_vm *vm; +}; + +struct kvm_plane_vcpu { + struct list_head list; + uint32_t id; + int fd; + struct kvm_vcpu *plane0; +}; + struct userspace_mem_regions { struct rb_root gpa_tree; struct rb_root hva_tree; @@ -93,6 +107,8 @@ struct kvm_vm { unsigned int va_bits; uint64_t max_gfn; struct list_head vcpus; + struct list_head planes; + struct list_head plane_vcpus; struct userspace_mem_regions regions; struct sparsebit *vpages_valid; struct sparsebit *vpages_mapped; @@ -338,6 +354,21 @@ do { \ __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, vm); \ }) =20 +static __always_inline void static_assert_is_plane(struct kvm_plane *plane= ) { } + +#define __plane_ioctl(plane, cmd, arg) \ +({ \ + static_assert_is_plane(plane); \ + kvm_do_ioctl((plane)->fd, cmd, arg); \ +}) + +#define plane_ioctl(plane, cmd, arg) \ +({ \ + int ret =3D __plane_ioctl(plane, cmd, arg); \ + \ + __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (plane)->vm); \ +}) + static __always_inline void static_assert_is_vcpu(struct kvm_vcpu *vcpu) {= } =20 #define __vcpu_ioctl(vcpu, cmd, arg) \ @@ -353,6 +384,21 @@ static __always_inline void static_assert_is_vcpu(stru= ct kvm_vcpu *vcpu) { } __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (vcpu)->vm); \ }) =20 +static __always_inline void static_assert_is_plane_vcpu(struct kvm_plane_v= cpu *plane_vcpu) { } + +#define __plane_vcpu_ioctl(plane_vcpu, cmd, arg) \ +({ \ + static_assert_is_plane_vcpu(plane_vcpu); \ + kvm_do_ioctl((plane_vcpu)->fd, cmd, arg); \ +}) + +#define plane_vcpu_ioctl(plane_vcpu, cmd, arg) \ +({ \ + int ret =3D __plane_vcpu_ioctl(plane_vcpu, cmd, arg); \ + \ + __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (plane_vcpu)->plane0->vm); \ +}) + /* * Looks up and returns the value corresponding to the capability * (KVM_CAP_*) given by cap. @@ -601,6 +647,8 @@ void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_= t slot, uint32_t flags); void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa= ); void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot); struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id); +struct kvm_plane *vm_plane_add(struct kvm_vm *vm, int plane_id); +struct kvm_plane_vcpu *__vm_plane_vcpu_add(struct kvm_vcpu *vcpu, struct k= vm_plane *plane); void vm_populate_vaddr_bitmap(struct kvm_vm *vm); vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz, vm_vaddr_t va= ddr_min); vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_m= in); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 815bc45dd8dc..a2f233945e1c 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -279,6 +279,8 @@ struct kvm_vm *____vm_create(struct vm_shape shape) TEST_ASSERT(vm !=3D NULL, "Insufficient Memory"); =20 INIT_LIST_HEAD(&vm->vcpus); + INIT_LIST_HEAD(&vm->planes); + INIT_LIST_HEAD(&vm->plane_vcpus); vm->regions.gpa_tree =3D RB_ROOT; vm->regions.hva_tree =3D RB_ROOT; hash_init(vm->regions.slot_hash); @@ -757,10 +759,22 @@ static void vm_vcpu_rm(struct kvm_vm *vm, struct kvm_= vcpu *vcpu) =20 void kvm_vm_release(struct kvm_vm *vmp) { - struct kvm_vcpu *vcpu, *tmp; + struct kvm_vcpu *vcpu, *tmp_vcpu; + struct kvm_plane_vcpu *plane_vcpu, *tmp_plane_vcpu; + struct kvm_plane *plane, *tmp_plane; int ret; =20 - list_for_each_entry_safe(vcpu, tmp, &vmp->vcpus, list) + list_for_each_entry_safe(plane_vcpu, tmp_plane_vcpu, &vmp->plane_vcpus, l= ist) { + close(plane_vcpu->fd); + free(plane_vcpu); + } + + list_for_each_entry_safe(plane, tmp_plane, &vmp->planes, list) { + close(plane->fd); + free(plane); + } + + list_for_each_entry_safe(vcpu, tmp_vcpu, &vmp->vcpus, list) vm_vcpu_rm(vmp, vcpu); =20 ret =3D close(vmp->fd); @@ -1314,6 +1328,52 @@ static bool vcpu_exists(struct kvm_vm *vm, uint32_t = vcpu_id) return false; } =20 +/* + * Adds a virtual CPU to the VM specified by vm with the ID given by vcpu_= id. + * No additional vCPU setup is done. Returns the vCPU. + */ +struct kvm_plane *vm_plane_add(struct kvm_vm *vm, int plane_id) +{ + struct kvm_plane *plane; + + /* Allocate and initialize new vcpu structure. */ + plane =3D calloc(1, sizeof(*plane)); + TEST_ASSERT(plane !=3D NULL, "Insufficient Memory"); + + plane->fd =3D __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)pla= ne_id); + TEST_ASSERT_VM_VCPU_IOCTL(plane->fd >=3D 0, KVM_CREATE_PLANE, plane->fd, = vm); + plane->vm =3D vm; + plane->id =3D plane_id; + + /* Add to linked-list of extra-plane VCPUs. */ + list_add(&plane->list, &vm->planes); + + return plane; +} + +/* + * Adds a virtual CPU to the VM specified by vm with the ID given by vcpu_= id. + * No additional vCPU setup is done. Returns the vCPU. + */ +struct kvm_plane_vcpu *__vm_plane_vcpu_add(struct kvm_vcpu *vcpu, struct k= vm_plane *plane) +{ + struct kvm_plane_vcpu *plane_vcpu; + + /* Allocate and initialize new vcpu structure. */ + plane_vcpu =3D calloc(1, sizeof(*plane_vcpu)); + TEST_ASSERT(plane_vcpu !=3D NULL, "Insufficient Memory"); + + plane_vcpu->fd =3D __plane_ioctl(plane, KVM_CREATE_VCPU_PLANE, (void *)(u= nsigned long)vcpu->fd); + TEST_ASSERT_VM_VCPU_IOCTL(plane_vcpu->fd >=3D 0, KVM_CREATE_VCPU_PLANE, p= lane_vcpu->fd, plane->vm); + plane_vcpu->id =3D vcpu->id; + plane_vcpu->plane0 =3D vcpu; + + /* Add to linked-list of extra-plane VCPUs. */ + list_add(&plane_vcpu->list, &plane->vm->plane_vcpus); + + return plane_vcpu; +} + /* * Adds a virtual CPU to the VM specified by vm with the ID given by vcpu_= id. * No additional vCPU setup is done. Returns the vCPU. @@ -2021,6 +2081,7 @@ static struct exit_reason { KVM_EXIT_STRING(NOTIFY), KVM_EXIT_STRING(LOONGARCH_IOCSR), KVM_EXIT_STRING(MEMORY_FAULT), + KVM_EXIT_STRING(PLANE_EVENT), }; =20 /* diff --git a/tools/testing/selftests/kvm/plane_test.c b/tools/testing/selft= ests/kvm/plane_test.c index 43c8de13490a..9cf3ab76b3cd 100644 --- a/tools/testing/selftests/kvm/plane_test.c +++ b/tools/testing/selftests/kvm/plane_test.c @@ -47,20 +47,19 @@ void test_create_plane(void) { struct kvm_vm *vm; struct kvm_vcpu *vcpu; - int r, planefd, plane_vcpufd; + struct kvm_plane *plane; + int r; =20 vm =3D vm_create_barebones(); vcpu =3D __vm_vcpu_add(vm, 0); =20 - planefd =3D __vm_ioctl(vm, KVM_CREATE_PLANE, (void *)(unsigned long)1); - TEST_ASSERT(planefd >=3D 0, "Creating new plane, got error: %d", - errno); + plane =3D vm_plane_add(vm, 1); =20 - r =3D ioctl(planefd, KVM_CHECK_EXTENSION, KVM_CAP_PLANES); + r =3D __plane_ioctl(plane, KVM_CHECK_EXTENSION, (void *)(unsigned long)KV= M_CAP_PLANES); TEST_ASSERT(r =3D=3D 0, "Checking KVM_CHECK_EXTENSION(KVM_CAP_PLANES). ret: %d", r); =20 - r =3D ioctl(planefd, KVM_CHECK_EXTENSION, KVM_CAP_CHECK_EXTENSION_VM); + r =3D __plane_ioctl(plane, KVM_CHECK_EXTENSION, (void *)(unsigned long)KV= M_CAP_CHECK_EXTENSION_VM); TEST_ASSERT(r =3D=3D 1, "Checking KVM_CHECK_EXTENSION(KVM_CAP_CHECK_EXTENSION_VM). ret: %d",= r); =20 @@ -69,22 +68,18 @@ void test_create_plane(void) "Creating existing plane, expecting EEXIST. ret: %d, errno: %d", r, errno); =20 - plane_vcpufd =3D ioctl(planefd, KVM_CREATE_VCPU_PLANE, (void *)(unsigned = long)vcpu->fd); - TEST_ASSERT(plane_vcpufd >=3D 0, "Creating vCPU for plane 1, got error: %= d", errno); + __vm_plane_vcpu_add(vcpu, plane); =20 - r =3D ioctl(planefd, KVM_CREATE_VCPU_PLANE, (void *)(unsigned long)vcpu->= fd); + r =3D __plane_ioctl(plane, KVM_CREATE_VCPU_PLANE, (void *)(unsigned long)= vcpu->fd); TEST_ASSERT(r =3D=3D -1 && errno =3D=3D EEXIST, "Creating vCPU again for plane 1. ret: %d, errno: %d", r, errno); =20 - r =3D ioctl(planefd, KVM_RUN, (void *)(unsigned long)0); + r =3D __plane_ioctl(plane, KVM_RUN, (void *)(unsigned long)0); TEST_ASSERT(r =3D=3D -1 && errno =3D=3D ENOTTY, "Running plane vCPU again for plane 1. ret: %d, errno: %d", r, errno); =20 - close(plane_vcpufd); - close(planefd); - kvm_vm_free(vm); ksft_test_result_pass("basic planefd and plane_vcpufd operation\n"); } --=20 2.49.0 From nobody Thu Apr 10 18:58:27 2025 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 EFB1A2248A8 for ; Tue, 1 Apr 2025 16:12:32 +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=1743523954; cv=none; b=KAFb0MRXYV6bV2Kh63OPUrwHEbwU3VWpreT8k8jxTV1o4YxuUViEE9i9LL2jB+Tt4h0lVcv4owi550XWBd94uuHTPz616NHcKCEKiqRMYYs/TX3Oy5tAb5bIsWFNsUFx4/SflkdFY0XmBNb6qlTuV3WwVfjUNyt7OrIYXdcQ0wU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743523954; c=relaxed/simple; bh=qiOLED8BkRze4KF+KMmrHA+MJ7cag8ndXy7QMTI4Sw0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=afEhdOCC2dvo0TCxk5xyc4NVAP0mzw5HhgqprbKPJZCEqqKq2lcZEOW7wzxtt9SzrvWNA7ZiyQ5n76fkMEwGtYv0NTPutUa73zCqx3GVh1lzPMzm2RxpTPVCV3LpwBYym4ydMywrsCGd7Lb3q3DXx2P9mr+NZgvSCcgtutMtamA= 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=e8ltetUC; 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="e8ltetUC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743523951; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tPLDTEU28EVlLVRImtt+kppWrpwzBYCScgMp8fqLlvI=; b=e8ltetUCCmMGBy/1mpEaWFftDwNG9z4/kkdfB+8Cv+M8SLU7KESbJFUHmCS6cfg3P4h94Y In4/2KWLQOOCKu2U/p1HRrJqoudu3nduG/jWcU6WGvZj+XLRqzbk5JBk1f6kD3os456DXM LNosIUg9Lp/u8iP5bBfydTso8VShbS8= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-668-wT1Mo0l-Nki21hqXOOh8OQ-1; Tue, 01 Apr 2025 12:12:30 -0400 X-MC-Unique: wT1Mo0l-Nki21hqXOOh8OQ-1 X-Mimecast-MFC-AGG-ID: wT1Mo0l-Nki21hqXOOh8OQ_1743523949 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-3913aaf1e32so3298653f8f.0 for ; Tue, 01 Apr 2025 09:12:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743523949; x=1744128749; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tPLDTEU28EVlLVRImtt+kppWrpwzBYCScgMp8fqLlvI=; b=nnc5wqt1s5BMbOHxVkFuky6vO5hIz2KTp8M551rWWbsKPeJ6WI+vmSFy3Gy1dcS6Yy 3LijgFkUld0/g5hqoEytCKJrJneMnqpOMkMw77zqhbMXw2X3j0kM9n40GWwa2bFybwZS cnq08FBPLYXZIQFJU50TeIA75PQG9JyC1J+IuFTjlmZ5ar616/rC6f0FCtVasyiElSij shK7Ba2hxvNpKZravXV/TmgsLUx1IUdUgXpb3vrhfVfW2sYa4gklKIa040DP+JrH/Ypw vFOtAQVXhwWZKDy2O/JXPGPkocBi5Qo5R9q+IrKT0vLmq2qa5kqHiDA7ASzmUSsw85yi 3vRg== X-Gm-Message-State: AOJu0Yzl1ZzwemtH6bBPorHce3gQMvL8UMrzNHkU9/+M0wAFePaHfCm3 s/rWCfVVzWgNhHHmYSmk93VffC1jSWcKOXq18gB1/gSbWhCL33Gch1pTwV9NY5G+4rp44Qdv7op Lcd6JZPNxx2WM5XAsKspm2/YxVDK2nZ9OiW+LdZ5Ch03hjBVJfcW2BaQORyW0VI5++Vo2Gagum9 UNk9Kk1ssvGGkDQGcVquPUaDdUBtBk2dnOJ59J0+myzfV3xA== X-Gm-Gg: ASbGncv8BHzArJsqxDmo++CNWsq7CZYcKevnkbGwFdw+pONmSpfS95Ta5t8BOB/6oyp RScBMrCDrmT0DzXNyJz4raa4H0L6a/dWsePoxbYKDzZIApE5hH6vWF9KYCRFj8kqxUBsq/R1TCm +UHUDeVLwmojphc/sNqEROJrmDdyUsajlhBZVUVhOjdvr2nLOf0qeIFWSjNmFZ10fMpFDqAsFfr hgcKWyb9JIvNE2RtCQU4WtnL8ThFoCwMZ5K6LPuIPEtpjj4IqrL/gZxOORP4uN5It2U4qb+dx9G JlJWNmVTlHXyHgBfrLEYDg== X-Received: by 2002:a05:6000:2913:b0:391:122c:8b2 with SMTP id ffacd0b85a97d-39c120e1566mr11925050f8f.31.1743523948584; Tue, 01 Apr 2025 09:12:28 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEEasAFSdvxOC3yWEZX6iq1LZ/fATrSFrxZYBcxLlTIQzYSIpNJNzx61Lq79fmq0JTbS0oYjw== X-Received: by 2002:a05:6000:2913:b0:391:122c:8b2 with SMTP id ffacd0b85a97d-39c120e1566mr11924994f8f.31.1743523948129; Tue, 01 Apr 2025 09:12:28 -0700 (PDT) Received: from [192.168.10.48] ([176.206.111.201]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43ea8d2bc7fsm13944985e9.0.2025.04.01.09.12.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 09:12:26 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: roy.hopkins@suse.com, seanjc@google.com, thomas.lendacky@amd.com, ashish.kalra@amd.com, michael.roth@amd.com, jroedel@suse.de, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com Subject: [PATCH 29/29] selftests: kvm: add x86-specific plane test Date: Tue, 1 Apr 2025 18:11:06 +0200 Message-ID: <20250401161106.790710-30-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250401161106.790710-1-pbonzini@redhat.com> References: <20250401161106.790710-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-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new test for x86-specific behavior such as vCPU state sharing and interrupts. Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../selftests/kvm/include/x86/processor.h | 1 + .../testing/selftests/kvm/lib/x86/processor.c | 15 + tools/testing/selftests/kvm/x86/plane_test.c | 270 ++++++++++++++++++ 4 files changed, 287 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86/plane_test.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index b1d0b410cc03..9d94db9d750f 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -82,6 +82,7 @@ TEST_GEN_PROGS_x86 +=3D x86/kvm_pv_test TEST_GEN_PROGS_x86 +=3D x86/monitor_mwait_test TEST_GEN_PROGS_x86 +=3D x86/nested_emulation_test TEST_GEN_PROGS_x86 +=3D x86/nested_exceptions_test +TEST_GEN_PROGS_x86 +=3D x86/plane_test TEST_GEN_PROGS_x86 +=3D x86/platform_info_test TEST_GEN_PROGS_x86 +=3D x86/pmu_counters_test TEST_GEN_PROGS_x86 +=3D x86/pmu_event_filter_test diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/te= sting/selftests/kvm/include/x86/processor.h index 32ab6ca7ec32..cf2095f3a7d5 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -1106,6 +1106,7 @@ static inline void vcpu_clear_cpuid_feature(struct kv= m_vcpu *vcpu, =20 uint64_t vcpu_get_msr(struct kvm_vcpu *vcpu, uint64_t msr_index); int _vcpu_set_msr(struct kvm_vcpu *vcpu, uint64_t msr_index, uint64_t msr_= value); +int _plane_vcpu_set_msr(struct kvm_plane_vcpu *plane_vcpu, uint64_t msr_in= dex, uint64_t msr_value); =20 /* * Assert on an MSR access(es) and pretty print the MSR name when possible. diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testin= g/selftests/kvm/lib/x86/processor.c index bd5a802fa7a5..b4431ca7fbca 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -917,6 +917,21 @@ uint64_t vcpu_get_msr(struct kvm_vcpu *vcpu, uint64_t = msr_index) return buffer.entry.data; } =20 +int _plane_vcpu_set_msr(struct kvm_plane_vcpu *plane_vcpu, uint64_t msr_in= dex, uint64_t msr_value) +{ + struct { + struct kvm_msrs header; + struct kvm_msr_entry entry; + } buffer =3D {}; + + memset(&buffer, 0, sizeof(buffer)); + buffer.header.nmsrs =3D 1; + buffer.entry.index =3D msr_index; + buffer.entry.data =3D msr_value; + + return __plane_vcpu_ioctl(plane_vcpu, KVM_SET_MSRS, &buffer.header); +} + int _vcpu_set_msr(struct kvm_vcpu *vcpu, uint64_t msr_index, uint64_t msr_= value) { struct { diff --git a/tools/testing/selftests/kvm/x86/plane_test.c b/tools/testing/s= elftests/kvm/x86/plane_test.c new file mode 100644 index 000000000000..0fdd8a066723 --- /dev/null +++ b/tools/testing/selftests/kvm/x86/plane_test.c @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Red Hat, Inc. + * + * Test for x86-specific VM plane functionality + */ +#include +#include +#include +#include + +#include "test_util.h" + +#include "kvm_util.h" +#include "processor.h" +#include "apic.h" +#include "asm/kvm.h" +#include "linux/kvm.h" + +static void test_plane_regs(void) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + struct kvm_plane *plane; + struct kvm_plane_vcpu *plane_vcpu; + + struct kvm_regs regs0, regs1; + + vm =3D vm_create_barebones(); + vcpu =3D __vm_vcpu_add(vm, 0); + plane =3D vm_plane_add(vm, 1); + plane_vcpu =3D __vm_plane_vcpu_add(vcpu, plane); + + vcpu_ioctl(vcpu, KVM_GET_REGS, ®s0); + plane_vcpu_ioctl(plane_vcpu, KVM_GET_REGS, ®s1); + regs0.rax =3D 0x12345678; + regs1.rax =3D 0x87654321; + + vcpu_ioctl(vcpu, KVM_SET_REGS, ®s0); + plane_vcpu_ioctl(plane_vcpu, KVM_SET_REGS, ®s1); + + vcpu_ioctl(vcpu, KVM_GET_REGS, ®s0); + plane_vcpu_ioctl(plane_vcpu, KVM_GET_REGS, ®s1); + TEST_ASSERT_EQ(regs0.rax, 0x12345678); + TEST_ASSERT_EQ(regs1.rax, 0x87654321); + + kvm_vm_free(vm); + ksft_test_result_pass("get/set regs for planes\n"); +} + +/* Offset of XMM0 in the legacy XSAVE area. */ +#define XSTATE_BV_OFFSET (0x200/4) +#define XMM_OFFSET (0xa0/4) +#define PKRU_OFFSET (0xa80/4) + +static void test_plane_fpu_nonshared(void) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + struct kvm_plane *plane; + struct kvm_plane_vcpu *plane_vcpu; + + struct kvm_xsave xsave0, xsave1; + + vm =3D vm_create_barebones(); + TEST_ASSERT_EQ(vm_check_cap(vm, KVM_CAP_PLANES_FPU), false); + + vcpu =3D __vm_vcpu_add(vm, 0); + vcpu_init_cpuid(vcpu, kvm_get_supported_cpuid()); + vcpu_set_cpuid(vcpu); + + plane =3D vm_plane_add(vm, 1); + plane_vcpu =3D __vm_plane_vcpu_add(vcpu, plane); + + vcpu_ioctl(vcpu, KVM_GET_XSAVE, &xsave0); + xsave0.region[XSTATE_BV_OFFSET] |=3D XFEATURE_MASK_FP | XFEATURE_MASK_SSE; + xsave0.region[XMM_OFFSET] =3D 0x12345678; + vcpu_ioctl(vcpu, KVM_SET_XSAVE, &xsave0); + + plane_vcpu_ioctl(plane_vcpu, KVM_GET_XSAVE, &xsave1); + xsave1.region[XSTATE_BV_OFFSET] |=3D XFEATURE_MASK_FP | XFEATURE_MASK_SSE; + xsave1.region[XMM_OFFSET] =3D 0x87654321; + plane_vcpu_ioctl(plane_vcpu, KVM_SET_XSAVE, &xsave1); + + memset(&xsave0, 0, sizeof(xsave0)); + vcpu_ioctl(vcpu, KVM_GET_XSAVE, &xsave0); + TEST_ASSERT_EQ(xsave0.region[XMM_OFFSET], 0x12345678); + + memset(&xsave1, 0, sizeof(xsave0)); + plane_vcpu_ioctl(plane_vcpu, KVM_GET_XSAVE, &xsave1); + TEST_ASSERT_EQ(xsave1.region[XMM_OFFSET], 0x87654321); + + ksft_test_result_pass("get/set FPU not shared across planes\n"); +} + +static void test_plane_fpu_shared(void) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + struct kvm_plane *plane; + struct kvm_plane_vcpu *plane_vcpu; + + struct kvm_xsave xsave0, xsave1; + + vm =3D vm_create_barebones(); + vm_enable_cap(vm, KVM_CAP_PLANES_FPU, 1ul); + TEST_ASSERT_EQ(vm_check_cap(vm, KVM_CAP_PLANES_FPU), true); + + vcpu =3D __vm_vcpu_add(vm, 0); + vcpu_init_cpuid(vcpu, kvm_get_supported_cpuid()); + vcpu_set_cpuid(vcpu); + + plane =3D vm_plane_add(vm, 1); + plane_vcpu =3D __vm_plane_vcpu_add(vcpu, plane); + + vcpu_ioctl(vcpu, KVM_GET_XSAVE, &xsave0); + + xsave0.region[XSTATE_BV_OFFSET] |=3D XFEATURE_MASK_FP | XFEATURE_MASK_SSE; + xsave0.region[XMM_OFFSET] =3D 0x12345678; + vcpu_ioctl(vcpu, KVM_SET_XSAVE, &xsave0); + plane_vcpu_ioctl(plane_vcpu, KVM_GET_XSAVE, &xsave1); + TEST_ASSERT_EQ(xsave1.region[XMM_OFFSET], 0x12345678); + + xsave1.region[XSTATE_BV_OFFSET] |=3D XFEATURE_MASK_FP | XFEATURE_MASK_SSE; + xsave1.region[XMM_OFFSET] =3D 0x87654321; + plane_vcpu_ioctl(plane_vcpu, KVM_SET_XSAVE, &xsave1); + vcpu_ioctl(vcpu, KVM_GET_XSAVE, &xsave0); + TEST_ASSERT_EQ(xsave0.region[XMM_OFFSET], 0x87654321); + + ksft_test_result_pass("get/set FPU shared across planes\n"); + + if (!this_cpu_has(X86_FEATURE_PKU)) { + ksft_test_result_skip("get/set PKRU with shared FPU\n"); + goto exit; + } + + xsave0.region[XSTATE_BV_OFFSET] =3D XFEATURE_MASK_PKRU; + xsave0.region[PKRU_OFFSET] =3D 0xffffffff; + vcpu_ioctl(vcpu, KVM_SET_XSAVE, &xsave0); + plane_vcpu_ioctl(plane_vcpu, KVM_GET_XSAVE, &xsave0); + + xsave0.region[XSTATE_BV_OFFSET] =3D XFEATURE_MASK_PKRU; + xsave0.region[PKRU_OFFSET] =3D 0xaaaaaaaa; + vcpu_ioctl(vcpu, KVM_SET_XSAVE, &xsave0); + plane_vcpu_ioctl(plane_vcpu, KVM_GET_XSAVE, &xsave1); + assert(xsave1.region[PKRU_OFFSET] =3D=3D 0xffffffff); + + xsave1.region[XSTATE_BV_OFFSET] =3D XFEATURE_MASK_PKRU; + xsave1.region[PKRU_OFFSET] =3D 0x55555555; + plane_vcpu_ioctl(plane_vcpu, KVM_SET_XSAVE, &xsave1); + vcpu_ioctl(vcpu, KVM_GET_XSAVE, &xsave0); + assert(xsave0.region[PKRU_OFFSET] =3D=3D 0xaaaaaaaa); + + ksft_test_result_pass("get/set PKRU with shared FPU\n"); + +exit: + kvm_vm_free(vm); +} + +#define APIC_SPIV 0xF0 +#define APIC_IRR 0x200 + +#define MYVEC 192 + +#define MAKE_MSI(cpu, vector) ((struct kvm_msi){ \ + .address_lo =3D APIC_DEFAULT_GPA + (((cpu) & 0xff) << 8), \ + .address_hi =3D (cpu) & ~0xff, \ + .data =3D (vector), \ +}) + +static bool has_irr(struct kvm_lapic_state *apic, int vector) +{ + int word =3D vector >> 5; + int bit_in_word =3D vector & 31; + int bit =3D (APIC_IRR + word * 16) * CHAR_BIT + (bit_in_word & 31); + + return apic->regs[bit >> 3] & (1 << (bit & 7)); +} + +static void do_enable_lapic(struct kvm_lapic_state *apic) +{ + /* set bit 8 */ + apic->regs[APIC_SPIV + 1] |=3D 1; +} + +static void test_plane_msi(void) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + struct kvm_plane *plane; + struct kvm_plane_vcpu *plane_vcpu; + int r; + + struct kvm_msi msi =3D MAKE_MSI(0, MYVEC); + struct kvm_lapic_state lapic0, lapic1; + + vm =3D __vm_create(VM_SHAPE_DEFAULT, 1, 0); + + vcpu =3D __vm_vcpu_add(vm, 0); + vcpu_init_cpuid(vcpu, kvm_get_supported_cpuid()); + vcpu_set_cpuid(vcpu); + + plane =3D vm_plane_add(vm, 1); + plane_vcpu =3D __vm_plane_vcpu_add(vcpu, plane); + + vcpu_set_msr(vcpu, MSR_IA32_APICBASE, + APIC_DEFAULT_GPA | MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE); + vcpu_ioctl(vcpu, KVM_GET_LAPIC, &lapic0); + do_enable_lapic(&lapic0); + vcpu_ioctl(vcpu, KVM_SET_LAPIC, &lapic0); + + _plane_vcpu_set_msr(plane_vcpu, MSR_IA32_APICBASE, + APIC_DEFAULT_GPA | MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE); + plane_vcpu_ioctl(plane_vcpu, KVM_GET_LAPIC, &lapic1); + do_enable_lapic(&lapic1); + plane_vcpu_ioctl(plane_vcpu, KVM_SET_LAPIC, &lapic1); + + r =3D __plane_ioctl(plane, KVM_SIGNAL_MSI, &msi); + TEST_ASSERT(r =3D=3D 1, + "Delivering interrupt to plane 1. ret: %d, errno: %d", r, errno); + + vcpu_ioctl(vcpu, KVM_GET_LAPIC, &lapic0); + TEST_ASSERT(!has_irr(&lapic0, MYVEC), "Vector clear in plane 0"); + plane_vcpu_ioctl(plane_vcpu, KVM_GET_LAPIC, &lapic1); + TEST_ASSERT(has_irr(&lapic1, MYVEC), "Vector set in plane 1"); + + /* req_exit_planes always has priority */ + vcpu->run->req_exit_planes =3D (1 << 1); + vcpu_run(vcpu); + TEST_ASSERT_EQ(vcpu->run->exit_reason, KVM_EXIT_PLANE_EVENT); + TEST_ASSERT_EQ(vcpu->run->plane_event.cause, KVM_PLANE_EVENT_INTERRUPT); + TEST_ASSERT_EQ(vcpu->run->plane_event.pending_event_planes, (1 << 1)); + TEST_ASSERT_EQ(vcpu->run->plane_event.target, (1 << 1)); + + r =3D __vm_ioctl(vm, KVM_SIGNAL_MSI, &msi); + TEST_ASSERT(r =3D=3D 1, + "Delivering interrupt to plane 0. ret: %d, errno: %d", r, errno); + vcpu_ioctl(vcpu, KVM_GET_LAPIC, &lapic0); + TEST_ASSERT(has_irr(&lapic0, MYVEC), "Vector set in plane 0"); + + /* req_exit_planes ignores current plane; current plane is cleared */ + vcpu->run->plane =3D 1; + vcpu->run->req_exit_planes =3D (1 << 0) | (1 << 1); + vcpu_run(vcpu); + TEST_ASSERT_EQ(vcpu->run->exit_reason, KVM_EXIT_PLANE_EVENT); + TEST_ASSERT_EQ(vcpu->run->plane_event.cause, KVM_PLANE_EVENT_INTERRUPT); + TEST_ASSERT_EQ(vcpu->run->plane_event.pending_event_planes, (1 << 0)); + TEST_ASSERT_EQ(vcpu->run->plane_event.target, (1 << 0)); + + kvm_vm_free(vm); + ksft_test_result_pass("signal MSI for planes\n"); +} + +int main(int argc, char *argv[]) +{ + int cap_planes =3D kvm_check_cap(KVM_CAP_PLANES); + TEST_REQUIRE(cap_planes && cap_planes > 1); + + ksft_print_header(); + ksft_set_plan(5); + + pr_info("# KVM_CAP_PLANES: %d\n", cap_planes); + + test_plane_regs(); + test_plane_fpu_nonshared(); + test_plane_fpu_shared(); + test_plane_msi(); + + ksft_finished(); +} --=20 2.49.0