From nobody Mon Jun 15 06:29:31 2026 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 82A093D34BB for ; Wed, 8 Apr 2026 15:42:25 +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=1775662946; cv=none; b=Itl8BVGjtnY2PF+11zsg3/8GGlvIZxcEipAx3gimAlbTOg2+766uP+U6TIS9JtMMXylM3qVHrlZyQJsbRyl3NBZ2UEktCgZsB0UTeZaZobaKXawIfrHw5jFHXl9PiJ3GyixroySY0o0H9poim89OaPwdOUIFsSvIEmhLXhAhd5c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662946; c=relaxed/simple; bh=Jn8Zpr+9SPV38i77yJC1Vrp1M0wvghEqTByVTsybKns=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YBVlwGn7qmCJaGy6VRb8JfMA6dtWsqi32RwQOCLgkuohd+6iPVDnaMT8x037F36Oica0tRQh6shTAJP8kgakElfiyeDELFr7ytcd/VSa36ZFpFt7F+RdDPEsPR+rg7sJcbChmVN1/lpkdHY3cYTlXZKo5ijr4q/regRz9S5pZTU= 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=Tm1nTW+f; 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="Tm1nTW+f" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662944; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kS5ozYk6KNxR0FIyk66ZQPFelQuS9JAUm9NEDE/X1KY=; b=Tm1nTW+fqh0v5V8LcipWxehbCM7mq1tb7Y7YnUGtdjGO/OFFEhtxpXdIdYaGaQTANmf+JL p1BNeM1Io9ScTgal1aYIfA0rj2NoU564zTVct+HziFHha2Au7xx1mM35M2lbhwqUeQ6v+m srI/RUmm0xkGVK+O6E/51jav+dsl+H8= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-404-IRpSGD2gOISX1tX8doGTsw-1; Wed, 08 Apr 2026 11:42:22 -0400 X-MC-Unique: IRpSGD2gOISX1tX8doGTsw-1 X-Mimecast-MFC-AGG-ID: IRpSGD2gOISX1tX8doGTsw_1775662939 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C88E51800618; Wed, 8 Apr 2026 15:42:19 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EF603180036E; Wed, 8 Apr 2026 15:42:18 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 01/27] KVM: TDX/VMX: rework EPT_VIOLATION_EXEC_FOR_RING3_LIN into PROT_MASK Date: Wed, 8 Apr 2026 11:41:51 -0400 Message-ID: <20260408154217.458420-2-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" From: Jon Kohler EPT exit qualification bit 6 is used when mode-based execute control is enabled, and reflects user executable addresses. Rework name to reflect the intention and add to EPT_VIOLATION_PROT_MASK, which allows simplifying the return evaluation in tdx_is_sept_violation_unexpected_pending a pinch. Rework handling in __vmx_handle_ept_violation to unconditionally clear EPT_VIOLATION_PROT_USER_EXEC until MBEC is implemented, as suggested by Sean [1]. Note: Intel SDM Table 29-7 defines bit 6 as: If the "mode-based execute control" VM-execution control is 0, the value of this bit is undefined. If that control is 1, this bit is the logical-AND of bit 10 in the EPT paging-structure entries used to translate the guest-physical address of the access causing the EPT violation. In this case, it indicates whether the guest-physical address was executable for user-mode linear addresses. [1] https://lore.kernel.org/all/aCJDzU1p_SFNRIJd@google.com/ Suggested-by: Sean Christopherson Signed-off-by: Jon Kohler Message-ID: <20251223054806.1611168-2-jon@nutanix.com> Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/include/asm/vmx.h | 5 +++-- arch/x86/kvm/vmx/common.h | 9 +++++++-- arch/x86/kvm/vmx/tdx.c | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index b92ff87e3560..7fdc6b787d70 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -597,10 +597,11 @@ enum vm_entry_failure_code { #define EPT_VIOLATION_PROT_READ BIT(3) #define EPT_VIOLATION_PROT_WRITE BIT(4) #define EPT_VIOLATION_PROT_EXEC BIT(5) -#define EPT_VIOLATION_EXEC_FOR_RING3_LIN BIT(6) +#define EPT_VIOLATION_PROT_USER_EXEC BIT(6) #define EPT_VIOLATION_PROT_MASK (EPT_VIOLATION_PROT_READ | \ EPT_VIOLATION_PROT_WRITE | \ - EPT_VIOLATION_PROT_EXEC) + EPT_VIOLATION_PROT_EXEC | \ + EPT_VIOLATION_PROT_USER_EXEC) #define EPT_VIOLATION_GVA_IS_VALID BIT(7) #define EPT_VIOLATION_GVA_TRANSLATED BIT(8) =20 diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h index 412d0829d7a2..adf925500b9e 100644 --- a/arch/x86/kvm/vmx/common.h +++ b/arch/x86/kvm/vmx/common.h @@ -94,8 +94,13 @@ static inline int __vmx_handle_ept_violation(struct kvm_= vcpu *vcpu, gpa_t gpa, /* Is it a fetch fault? */ error_code |=3D (exit_qualification & EPT_VIOLATION_ACC_INSTR) ? PFERR_FETCH_MASK : 0; - /* ept page table entry is present? */ - error_code |=3D (exit_qualification & EPT_VIOLATION_PROT_MASK) + /* + * ept page table entry is present? + * note: unconditionally clear USER_EXEC until mode-based + * execute control is implemented + */ + error_code |=3D (exit_qualification & + (EPT_VIOLATION_PROT_MASK & ~EPT_VIOLATION_PROT_USER_EXEC)) ? PFERR_PRESENT_MASK : 0; =20 if (exit_qualification & EPT_VIOLATION_GVA_IS_VALID) diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index c5065f84b78b..fa740f70ee75 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -1855,7 +1855,7 @@ static inline bool tdx_is_sept_violation_unexpected_p= ending(struct kvm_vcpu *vcp if (eeq_type !=3D TDX_EXT_EXIT_QUAL_TYPE_PENDING_EPT_VIOLATION) return false; =20 - return !(eq & EPT_VIOLATION_PROT_MASK) && !(eq & EPT_VIOLATION_EXEC_FOR_R= ING3_LIN); + return !(eq & EPT_VIOLATION_PROT_MASK); } =20 static int tdx_handle_ept_violation(struct kvm_vcpu *vcpu) --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 BAF273A1CEA for ; Wed, 8 Apr 2026 15:42:27 +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=1775662949; cv=none; b=C0jUtdkKOchk01U2PI5dh5iniohWY3iwm6sj6/qPSD7RgcImSeMRRNTlx3L+pOaxS7WKnjq8sf6FrG9PTznUrbpg3iAy0uzwA9K1nqFTFdpTMR9BpU+ZFegfVI/pvbwrvW0+BqYR2lLtG2d4kIT4wZpCZmtYb67HTWfXsBLwXrQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662949; c=relaxed/simple; bh=OsoBbys/U3JoK7PZoOWLKYmL+wqziYV87FX4CgqrO/g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=V7+JBiI3SQ6ilgYDSVfPF6FysDbzjl4H/NmZZjCaD08r5WpCJX25kIhfSQvAaJTGoGpvPUWu/GTBtuSesqr7JrwPQOqpUjwkRUAz4fqXE4HdFb5PAkHPnxjgUurJwvIUfPxz9kQ3Vs5WPf6c3CJwEfLsTPys1aNXEQMr3IMCzqo= 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=JU7ijN+f; 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="JU7ijN+f" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662946; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3v/GdFslNs0T9M87HJLS4SJi834jsEHlSo4L+T5jf0c=; b=JU7ijN+fMPrseSgsJF7F+M9t2pf8YQQL1TDE2FIPqosvLKXqA5ISBYnKrIVoXCqGuYVUAt NBR9luCo2FFAb4bFrRjt0ekJGeV6005hxsbPU8Zzd2GSty2r+jiwgag7JSiN2RTYgJ7V3/ 4d5mGVenxYC476v/i1su8ddgSGbj1n4= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-248-3LZPVAaaPiKEzlnG4humTw-1; Wed, 08 Apr 2026 11:42:23 -0400 X-MC-Unique: 3LZPVAaaPiKEzlnG4humTw-1 X-Mimecast-MFC-AGG-ID: 3LZPVAaaPiKEzlnG4humTw_1775662941 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D45F31955F6A; Wed, 8 Apr 2026 15:42:20 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F0B69180036E; Wed, 8 Apr 2026 15:42:19 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 02/27] KVM: x86/mmu: remove SPTE_PERM_MASK Date: Wed, 8 Apr 2026 11:41:52 -0400 Message-ID: <20260408154217.458420-3-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" From: Jon Kohler SPTE_PERM_MASK is no longer referenced by anything in the kernel. Signed-off-by: Jon Kohler Message-ID: <20251223054806.1611168-3-jon@nutanix.com> Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/spte.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 91ce29fd6f1b..28086fa86fe0 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -42,9 +42,6 @@ static_assert(SPTE_TDP_AD_ENABLED =3D=3D 0); #define SPTE_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) #endif =20 -#define SPTE_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | shadow_user_m= ask \ - | shadow_x_mask | shadow_nx_mask | shadow_me_mask) - #define ACC_EXEC_MASK 1 #define ACC_WRITE_MASK PT_WRITABLE_MASK #define ACC_USER_MASK PT_USER_MASK --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 D16553D3485 for ; Wed, 8 Apr 2026 15:42:28 +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=1775662950; cv=none; b=UgjdQRNLGNGBF0vgY/AZsHrxcOugHvoyBN4CGiqUEDC2NFo1VdacoK24xzPgYfCm60S5L0/eErYoOssbas24QV/mrz5TCtGIt76Gq74cEnZ75o7noYSnxZvBusYKs3oz84S8h9oZEHt1ynZBmYtFS/zgDdR3mXvW4RQ58b2+jA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662950; c=relaxed/simple; bh=+oNPlRVWZkPXNPyQBbr8Bs8ziBH4mjuHj8KiiOvpCFg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Xgi5fP4IQYeBBdfK7MNR116a2KBQJ8KIYN4zjW+2iiU5rpgEMzGLUaSMshY/AmtesHpZIlDljQwIeMubu+LkV+CeVfUnYaU1N5I61AmTznlPGM2c3FfVsZfaixPJdXVKx2PbCCwfMXLIZYWV1SHefzEySA7/hR+KAjFsUGnKy3M= 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=jSRXEaz8; 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="jSRXEaz8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662948; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zTA3xMak32jLEQHD7hiPfKVXSQGkH1mA3EyLnAnQwvk=; b=jSRXEaz8mqW4/620oqN7N4CqZRwWH5SHAIbT3Gj1ULQY784lj9YsCltpa0vHw0Bgks/mcz MR1Ix47GDA16HqqVJ30uU88HTwZOehc7AFV7viGQnLpHaYWIgQvANWBiy0cnke9mt4Q4Se u1GJPakO6qG8HtS+V/C3jtXn6g3RgDA= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-361-8Jls90JsNNqk3006-tNJIQ-1; Wed, 08 Apr 2026 11:42:24 -0400 X-MC-Unique: 8Jls90JsNNqk3006-tNJIQ-1 X-Mimecast-MFC-AGG-ID: 8Jls90JsNNqk3006-tNJIQ_1775662942 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id ED039195608E; Wed, 8 Apr 2026 15:42:21 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 07B35180036E; Wed, 8 Apr 2026 15:42:20 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti , Kai Huang Subject: [PATCH 03/27] KVM: x86/mmu: free up bit 10 of PTEs in preparation for MBEC Date: Wed, 8 Apr 2026 11:41:53 -0400 Message-ID: <20260408154217.458420-4-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" From: Jon Kohler Update SPTE_MMIO_ALLOWED_MASK to allow EPT user executable (bit 10) to be treated like EPT RWX bit2:0, as when mode-based execute control is enabled, bit 10 can act like a "present" bit. Likewise do not include it in FROZEN_SPTE. No functional changes intended, other than the reduction of the maximum MMIO generation that is stored in page tables. Cc: Kai Huang Signed-off-by: Jon Kohler Message-ID: <20251223054806.1611168-4-jon@nutanix.com> Signed-off-by: Paolo Bonzini Reviewed-by: Kai Huang Tested-by: David Riley --- arch/x86/include/asm/vmx.h | 2 ++ arch/x86/kvm/mmu/spte.h | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 7fdc6b787d70..59e3b095a315 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -549,10 +549,12 @@ enum vmcs_field { #define VMX_EPT_ACCESS_BIT (1ull << 8) #define VMX_EPT_DIRTY_BIT (1ull << 9) #define VMX_EPT_SUPPRESS_VE_BIT (1ull << 63) + #define VMX_EPT_RWX_MASK (VMX_EPT_READABLE_MASK | = \ VMX_EPT_WRITABLE_MASK | \ VMX_EPT_EXECUTABLE_MASK) #define VMX_EPT_MT_MASK (7ull << VMX_EPT_MT_EPTE_SHIFT) +#define VMX_EPT_USER_EXECUTABLE_MASK (1ull << 10) =20 static inline u8 vmx_eptp_page_walk_level(u64 eptp) { diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 28086fa86fe0..4283cea3e66c 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -96,11 +96,11 @@ static_assert(!(EPT_SPTE_MMU_WRITABLE & SHADOW_ACC_TRAC= K_SAVED_MASK)); #undef SHADOW_ACC_TRACK_SAVED_MASK =20 /* - * Due to limited space in PTEs, the MMIO generation is a 19 bit subset of + * Due to limited space in PTEs, the MMIO generation is an 18 bit subset of * the memslots generation and is derived as follows: * - * Bits 0-7 of the MMIO generation are propagated to spte bits 3-10 - * Bits 8-18 of the MMIO generation are propagated to spte bits 52-62 + * Bits 0-6 of the MMIO generation are propagated to spte bits 3-9 + * Bits 7-17 of the MMIO generation are propagated to spte bits 52-62 * * The KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS flag is intentionally not includ= ed in * the MMIO generation number, as doing so would require stealing a bit fr= om @@ -111,7 +111,7 @@ static_assert(!(EPT_SPTE_MMU_WRITABLE & SHADOW_ACC_TRAC= K_SAVED_MASK)); */ =20 #define MMIO_SPTE_GEN_LOW_START 3 -#define MMIO_SPTE_GEN_LOW_END 10 +#define MMIO_SPTE_GEN_LOW_END 9 =20 #define MMIO_SPTE_GEN_HIGH_START 52 #define MMIO_SPTE_GEN_HIGH_END 62 @@ -133,7 +133,8 @@ static_assert(!(SPTE_MMU_PRESENT_MASK & * and so they're off-limits for generation; additional checks ensure the = mask * doesn't overlap legal PA bits), and bit 63 (carved out for future usage= ). */ -#define SPTE_MMIO_ALLOWED_MASK (BIT_ULL(63) | GENMASK_ULL(51, 12) | GENMAS= K_ULL(2, 0)) +#define SPTE_MMIO_ALLOWED_MASK (BIT_ULL(63) | GENMASK_ULL(51, 12) | \ + BIT_ULL(10) | GENMASK_ULL(2, 0)) static_assert(!(SPTE_MMIO_ALLOWED_MASK & (SPTE_MMU_PRESENT_MASK | MMIO_SPTE_GEN_LOW_MASK | MMIO_SPTE_GEN_HIGH_MAS= K))); =20 @@ -141,7 +142,7 @@ static_assert(!(SPTE_MMIO_ALLOWED_MASK & #define MMIO_SPTE_GEN_HIGH_BITS (MMIO_SPTE_GEN_HIGH_END - MMIO_SPTE_GEN_H= IGH_START + 1) =20 /* remember to adjust the comment above as well if you change these */ -static_assert(MMIO_SPTE_GEN_LOW_BITS =3D=3D 8 && MMIO_SPTE_GEN_HIGH_BITS = =3D=3D 11); +static_assert(MMIO_SPTE_GEN_LOW_BITS =3D=3D 7 && MMIO_SPTE_GEN_HIGH_BITS = =3D=3D 11); =20 #define MMIO_SPTE_GEN_LOW_SHIFT (MMIO_SPTE_GEN_LOW_START - 0) #define MMIO_SPTE_GEN_HIGH_SHIFT (MMIO_SPTE_GEN_HIGH_START - MMIO_SPTE_GEN= _LOW_BITS) @@ -217,10 +218,11 @@ extern u64 __read_mostly shadow_nonpresent_or_rsvd_ma= sk; * * Only used by the TDP MMU. */ -#define FROZEN_SPTE (SHADOW_NONPRESENT_VALUE | 0x5a0ULL) +#define FROZEN_SPTE (SHADOW_NONPRESENT_VALUE | 0x1a0ULL) =20 -/* Frozen SPTEs must not be misconstrued as shadow present PTEs. */ -static_assert(!(FROZEN_SPTE & SPTE_MMU_PRESENT_MASK)); +/* Frozen SPTEs must not be misconstrued as shadow or MMU present PTEs. */ +static_assert(!(FROZEN_SPTE & (SPTE_MMU_PRESENT_MASK | + VMX_EPT_RWX_MASK | VMX_EPT_USER_EXECUTABLE_MASK))); =20 static inline bool is_frozen_spte(u64 spte) { --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 2C6EB3793BF for ; Wed, 8 Apr 2026 15:42:28 +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=1775662949; cv=none; b=GPTAha5fHeR/42v6eQDNKKmUFVSlO69zlQMwRfTpiM3IeJEn7IiNK/FFGpJgIaOyS6xbArOrsIvyybyQsxTYs9cbdXDKV2AcC0GuBMORCJ4MSSxRCKAvNC54NLEP46jjliz772CFLVpyfZzSJh1fugvtdDvJnExzF62ziMSfxOk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662949; c=relaxed/simple; bh=lcSCQhvgV13mrQnwNDpyMIm8Qtw3Tg7NXo9VIB4oKEI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rH7xgoGry4AgTwH/BmgCbu+XR4lljlG1Xnypy2yZI2AaaK1aBgDNjk4qBM2UFX3dFxvgbV6OlQs5ULRwSf9Z4AIljpT/V2ZLOBBV4b8i7nM+vKpCi11UsPO56kCB1D3J313HTC6DQFQBlqs89Y9Qxdjp39feQk7f2QUWBHQZKWM= 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=iz9i+ndB; 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="iz9i+ndB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662947; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ggsR5mD/t7F3g58B8WA467weQ2q8K4Vnkyfxm48B1Nc=; b=iz9i+ndBSDWVcqsvZuuRmmDs1cUkGCW4c3lxgF4DXkaG0BU38IOXOIHruvNODAeJ2/nvsV 74LOzcpuUKwnaBcOiKX6NEMvS3PTRxHkD7bN89s+mDczFNPXiadu8Fg5FfgX4ewZgEdjyO 2ZWXG6wviHbEg6tlEg1ltmfrZoSTvoI= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-427-Ue7Hg-A_ONeDM9LL52CRjw-1; Wed, 08 Apr 2026 11:42:24 -0400 X-MC-Unique: Ue7Hg-A_ONeDM9LL52CRjw-1 X-Mimecast-MFC-AGG-ID: Ue7Hg-A_ONeDM9LL52CRjw_1775662943 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id EB7791956053; Wed, 8 Apr 2026 15:42:22 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1FE61180036E; Wed, 8 Apr 2026 15:42:22 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 04/27] KVM: x86/mmu: shuffle high bits of SPTEs in preparation for MBEC Date: Wed, 8 Apr 2026 11:41:54 -0400 Message-ID: <20260408154217.458420-5-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" Access tracking will need to save bit 10 when MBEC is enabled. Right now it is simply shifting the R and X bits into bits 54 and 56, but bit 10 would not fit with the same scheme. Reorganize the high bits so that access tracking will use bits 52, 54 and 62. As a side effect, the free bits are compacted slightly, with 56-59 still unused. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/spte.h | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 4283cea3e66c..317b9cd1537c 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -17,10 +17,20 @@ */ #define SPTE_MMU_PRESENT_MASK BIT_ULL(11) =20 +/* + * The ignored high bits are allocated as follows: + * - bits 52, 54: saved X-R bits for access tracking when EPT does not hav= e A/D + * - bits 53 (EPT only): host writable + * - bits 55 (EPT only): MMU-writable + * - bits 56-59: unused + * - bits 60-61: type of A/D tracking + * - bits 62: unused + */ + /* * TDP SPTES (more specifically, EPT SPTEs) may not have A/D bits, and may= also * be restricted to using write-protection (for L2 when CPU dirty logging,= i.e. - * PML, is enabled). Use bits 52 and 53 to hold the type of A/D tracking = that + * PML, is enabled). Use bits 60 and 61 to hold the type of A/D tracking = that * is must be employed for a given TDP SPTE. * * Note, the "enabled" mask must be '0', as bits 62:52 are _reserved_ for = PAE @@ -29,7 +39,7 @@ * TDP with CPU dirty logging (PML). If NPT ever gains PML-like support, = it * must be restricted to 64-bit KVM. */ -#define SPTE_TDP_AD_SHIFT 52 +#define SPTE_TDP_AD_SHIFT 60 #define SPTE_TDP_AD_MASK (3ULL << SPTE_TDP_AD_SHIFT) #define SPTE_TDP_AD_ENABLED (0ULL << SPTE_TDP_AD_SHIFT) #define SPTE_TDP_AD_DISABLED (1ULL << SPTE_TDP_AD_SHIFT) @@ -65,7 +75,7 @@ static_assert(SPTE_TDP_AD_ENABLED =3D=3D 0); */ #define SHADOW_ACC_TRACK_SAVED_BITS_MASK (SPTE_EPT_READABLE_MASK | \ SPTE_EPT_EXECUTABLE_MASK) -#define SHADOW_ACC_TRACK_SAVED_BITS_SHIFT 54 +#define SHADOW_ACC_TRACK_SAVED_BITS_SHIFT 52 #define SHADOW_ACC_TRACK_SAVED_MASK (SHADOW_ACC_TRACK_SAVED_BITS_MASK << \ SHADOW_ACC_TRACK_SAVED_BITS_SHIFT) static_assert(!(SPTE_TDP_AD_MASK & SHADOW_ACC_TRACK_SAVED_MASK)); @@ -84,8 +94,8 @@ static_assert(!(SPTE_TDP_AD_MASK & SHADOW_ACC_TRACK_SAVED= _MASK)); * to not overlap the A/D type mask or the saved access bits of access-tra= cked * SPTEs when A/D bits are disabled. */ -#define EPT_SPTE_HOST_WRITABLE BIT_ULL(57) -#define EPT_SPTE_MMU_WRITABLE BIT_ULL(58) +#define EPT_SPTE_HOST_WRITABLE BIT_ULL(53) +#define EPT_SPTE_MMU_WRITABLE BIT_ULL(55) =20 static_assert(!(EPT_SPTE_HOST_WRITABLE & SPTE_TDP_AD_MASK)); static_assert(!(EPT_SPTE_MMU_WRITABLE & SPTE_TDP_AD_MASK)); --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 6B6913D75AB for ; Wed, 8 Apr 2026 15:42:29 +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=1775662951; cv=none; b=BWvdtTrjMIi6TUDL79Ic6x/QdflJPZPexxzWrDyUbtVDdsuw2qGtKUFuL01136C0tFoInRx3+NTb1QMVju+hO7bkQXgZi09+nijUvZrsdoW7aFvDA3O2rqr7nfg8a+Cfus63MTHgnn6iZ2SS9XjWL6uWSxGqIWghJo1iY31zrQM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662951; c=relaxed/simple; bh=fqHT1pnDK6DwfEr0ptaleAeSYZJjpkW+GH1PZpbZuGE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UuA7QG+M2nbP/Gi3dGih1rf361Q4YCrjXE545o7q/OSPXmENtChQICyRFqE513wsDKdL/ohOaOJrfy0OevopBmEayAoyZxAVZF8GRwxsTD0qKTxjW6zNtFSDDds6ffD/Bf/iPrOSK3hbRfQzBZWFkjXrmmRyOkfweCDfoex4c7A= 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=TV+N44z6; 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="TV+N44z6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662948; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mFUzE5NcTOnpssdGYeZVSDjozPCtHCC7XohYQ1HLmGA=; b=TV+N44z6jrLCNnTbQx4IcMvcTmCoRM6V5wUex3EvzPeqGsbMIQjGjxJNsG6QcBocOiHysU ZC2Cx2THIwI7To8Ae8Wyc2Vqoj/1kqGc7Fg7774qfzJV5xqL8zhE6XWonc29Sfr+6hC3cO ZttCWiAOLmND7rEA9sv7NsVP1sh7mFc= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-383-Luvj13zoPcuv1-3JW2O0zA-1; Wed, 08 Apr 2026 11:42:25 -0400 X-MC-Unique: Luvj13zoPcuv1-3JW2O0zA-1 X-Mimecast-MFC-AGG-ID: Luvj13zoPcuv1-3JW2O0zA_1775662944 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E9A70180028B; Wed, 8 Apr 2026 15:42:23 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1F170180036E; Wed, 8 Apr 2026 15:42:23 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 05/27] KVM: x86/mmu: remove SPTE_EPT_* Date: Wed, 8 Apr 2026 11:41:55 -0400 Message-ID: <20260408154217.458420-6-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" spte.h is already including vmx.h, use the constants it defines. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/spte.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 317b9cd1537c..bc02a2e89a31 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -57,10 +57,6 @@ static_assert(SPTE_TDP_AD_ENABLED =3D=3D 0); #define ACC_USER_MASK PT_USER_MASK #define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) =20 -/* The mask for the R/X bits in EPT PTEs */ -#define SPTE_EPT_READABLE_MASK 0x1ull -#define SPTE_EPT_EXECUTABLE_MASK 0x4ull - #define SPTE_LEVEL_BITS 9 #define SPTE_LEVEL_SHIFT(level) __PT_LEVEL_SHIFT(level, SPTE_LEVEL_BITS) #define SPTE_INDEX(address, level) __PT_INDEX(address, level, SPTE_LEVEL_B= ITS) @@ -73,8 +69,8 @@ static_assert(SPTE_TDP_AD_ENABLED =3D=3D 0); * restored only when a write is attempted to the page. This mask obvious= ly * must not overlap the A/D type mask. */ -#define SHADOW_ACC_TRACK_SAVED_BITS_MASK (SPTE_EPT_READABLE_MASK | \ - SPTE_EPT_EXECUTABLE_MASK) +#define SHADOW_ACC_TRACK_SAVED_BITS_MASK (VMX_EPT_READABLE_MASK | \ + VMX_EPT_EXECUTABLE_MASK) #define SHADOW_ACC_TRACK_SAVED_BITS_SHIFT 52 #define SHADOW_ACC_TRACK_SAVED_MASK (SHADOW_ACC_TRACK_SAVED_BITS_MASK << \ SHADOW_ACC_TRACK_SAVED_BITS_SHIFT) --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 DFD2C3D7D7A for ; Wed, 8 Apr 2026 15:42:30 +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=1775662952; cv=none; b=NPhPGr4dMriwAQIknSxykuCgHFY8d/U7y/ekvMjsUU40Ku09uuZG+3y4BXKf3c+6Em3+q8BUr/HoXrzfB1OuQMiG4MsYxch+fVBYpNjfQm3thxNaWlOiZPBy6fZmMLLoBBk5UgBBYPBU+SqpoAuK1f/N+ffK1NF6KetyFjoGQ0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662952; c=relaxed/simple; bh=S3iQPXqoQDIe9OxHjVNJIMjqmhKDoBtB2TbMtubeBTs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pmBuIv5xUX3RNMK5tDDoLH88A2kTtDCY7hHM6FHqyL7MxKL6RNtxWEGgFJMRCun3cy8IasOK5l1NFf1qvX/r++PIxnzdFcS3p7qY5zIeWFd3P07/EOrJzQgfHG5lE9d5sibOwOB8g3Bv1rnLUSb/wi2apEBjixW5wLqZLn5Nt5s= 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=LJPruODr; 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="LJPruODr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662950; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=K/iezNRC4ybfGq5UaIZ4cXDIi/YuE1XIEGu/2CdlosI=; b=LJPruODrI7CBcCXxi0oHJuHoGDSPizy5U2ZlVbM3BIAb1VHzXlcaLKMjTUqEfQ4CdyeBEX URbvda7Fi4ucGBxtf90YNTYdIQpYekqEcPpVZ31iFyer3Id3QVSUHpb7taEzzuI6tTZWY1 rmXPSqpbYrRM+BVALhh8pMb+Zhs4I0Q= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-205-CUP3YElbPyWws1TVDj59Mw-1; Wed, 08 Apr 2026 11:42:26 -0400 X-MC-Unique: CUP3YElbPyWws1TVDj59Mw-1 X-Mimecast-MFC-AGG-ID: CUP3YElbPyWws1TVDj59Mw_1775662945 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id F2E0B1956051; Wed, 8 Apr 2026 15:42:24 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1E4A5180036E; Wed, 8 Apr 2026 15:42:24 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 06/27] KVM: x86/mmu: merge make_spte_{non,}executable Date: Wed, 8 Apr 2026 11:41:56 -0400 Message-ID: <20260408154217.458420-7-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" As the logic will become more complicated with the introduction of MBEC, at least write it only once. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/spte.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index 85a0473809b0..e9dc0ae44274 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -317,14 +317,16 @@ static u64 modify_spte_protections(u64 spte, u64 set,= u64 clear) return spte; } =20 -static u64 make_spte_executable(u64 spte) +static u64 make_spte_executable(u64 spte, u8 access) { - return modify_spte_protections(spte, shadow_x_mask, shadow_nx_mask); -} + u64 set, clear; =20 -static u64 make_spte_nonexecutable(u64 spte) -{ - return modify_spte_protections(spte, shadow_nx_mask, shadow_x_mask); + if (access & ACC_EXEC_MASK) + set =3D shadow_x_mask; + else + set =3D shadow_nx_mask; + clear =3D set ^ (shadow_nx_mask | shadow_x_mask); + return modify_spte_protections(spte, set, clear); } =20 /* @@ -356,8 +358,8 @@ u64 make_small_spte(struct kvm *kvm, u64 huge_spte, * the page executable as the NX hugepage mitigation no longer * applies. */ - if ((role.access & ACC_EXEC_MASK) && is_nx_huge_page_enabled(kvm)) - child_spte =3D make_spte_executable(child_spte); + if (is_nx_huge_page_enabled(kvm)) + child_spte =3D make_spte_executable(child_spte, role.access); } =20 return child_spte; @@ -379,7 +381,7 @@ u64 make_huge_spte(struct kvm *kvm, u64 small_spte, int= level) huge_spte &=3D KVM_HPAGE_MASK(level) | ~PAGE_MASK; =20 if (is_nx_huge_page_enabled(kvm)) - huge_spte =3D make_spte_nonexecutable(huge_spte); + huge_spte =3D make_spte_executable(huge_spte, 0); =20 return huge_spte; } --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 677693D810D for ; Wed, 8 Apr 2026 15:42:31 +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=1775662953; cv=none; b=jD96A7Govj/YXmCriHKkzBpipc+PSmSLQ9l6BC4sTu9Y35/A7DM9RvrFgwNvKRK4zmCTUspTDAqwqi5hH9af2Qr/pNecKAhE/2f2aJZPBrDqVZ4SYS3P+5MgdIkxYxiZfUTqdhW/g9yn0I4ieQbrp0uo2fzsot7dDsQMrX+SQhI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662953; c=relaxed/simple; bh=xEYy5dAYYS2A2/VZh1lSZF372/3b8XaObXPJLU+7krk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bajPAgiVbWe9D2LHOKVYl2I77MGNpQ9T7hu36DF1fRLIYz5GisbMamytPgeLrY/xHcMkQVhFMqENBhF9rzQue0MlS7ylEGpjza+YtbbKJ+Gos7X+7qxysw9j8a2624rJcnlKfBF7NallRrCMvLiSOtMzEDF0Ubp4vC5o+efVQYg= 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=P8+ePmET; 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="P8+ePmET" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662950; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=T6bknSVJlYMJRJsVKlIB214gfQ9ySZOyYvJd1kpHdpY=; b=P8+ePmETh1FIPI7bf3iDx19ZA2DJz3LEhh+OyHB3xYP7neuMz7wmMHhwEGUNyDyTZmeVTG 1VRKTTzri9Oe9n3IOxnGscZ0mv1eE7Z4RJNQ0F2M3XIIKyOBbPcP3ljX4KZl68cO+VCXSF GbLm93lFBAi9ISc+soI7Mqx0BQeYsCA= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-5-wCIx5at7P1iuQs8UeNZZqw-1; Wed, 08 Apr 2026 11:42:27 -0400 X-MC-Unique: wCIx5at7P1iuQs8UeNZZqw-1 X-Mimecast-MFC-AGG-ID: wCIx5at7P1iuQs8UeNZZqw_1775662946 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0633D19560B2; Wed, 8 Apr 2026 15:42:26 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 25F5E1800764; Wed, 8 Apr 2026 15:42:25 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 07/27] KVM: x86/mmu: rename and clarify BYTE_MASK Date: Wed, 8 Apr 2026 11:41:57 -0400 Message-ID: <20260408154217.458420-8-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" The BYTE_MASK macro is the central point of the black magic in update_permission_bitmask(). Rename it to something that relates to how it is used, and add a comment explaining how it works. Using shifts instead of powers of two was actually suggested by David Hildenbrand back in 2017 for clarity[1] but I evidently forgot his suggestion when applying to kvm.git. [1] https://lore.kernel.org/kvm/e4b5df86-31ae-2f4e-0666-393753e256df@redhat= .com/ Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/mmu.c | 55 ++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index dd06453d5b72..d4bb693b3555 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5520,29 +5520,53 @@ reset_ept_shadow_zero_bits_mask(struct kvm_mmu *con= text, bool execonly) max_huge_page_level); } =20 -#define BYTE_MASK(access) \ - ((1 & (access) ? 2 : 0) | \ - (2 & (access) ? 4 : 0) | \ - (3 & (access) ? 8 : 0) | \ - (4 & (access) ? 16 : 0) | \ - (5 & (access) ? 32 : 0) | \ - (6 & (access) ? 64 : 0) | \ - (7 & (access) ? 128 : 0)) - +/* + * Build a mask with all combinations of PTE access rights that + * include the given access bit. The mask can be queried with + * "mask & (1 << access)", where access is a combination of + * ACC_* bits. + * + * By mixing and matching multiple masks returned by ACC_BITS_MASK, + * update_permission_bitmask() builds what is effectively a + * two-dimensional array of bools. The second dimension is + * provided by individual bits of permissions[pfec >> 1], and + * logical &, | and ~ operations operate on all the 8 possible + * combinations of ACC_* bits. + */ +#define ACC_BITS_MASK(access) \ + ((1 & (access) ? 1 << 1 : 0) | \ + (2 & (access) ? 1 << 2 : 0) | \ + (3 & (access) ? 1 << 3 : 0) | \ + (4 & (access) ? 1 << 4 : 0) | \ + (5 & (access) ? 1 << 5 : 0) | \ + (6 & (access) ? 1 << 6 : 0) | \ + (7 & (access) ? 1 << 7 : 0)) =20 static void update_permission_bitmask(struct kvm_mmu *mmu, bool ept) { unsigned byte; =20 - const u8 x =3D BYTE_MASK(ACC_EXEC_MASK); - const u8 w =3D BYTE_MASK(ACC_WRITE_MASK); - const u8 u =3D BYTE_MASK(ACC_USER_MASK); + const u8 x =3D ACC_BITS_MASK(ACC_EXEC_MASK); + const u8 w =3D ACC_BITS_MASK(ACC_WRITE_MASK); + const u8 u =3D ACC_BITS_MASK(ACC_USER_MASK); =20 bool cr4_smep =3D is_cr4_smep(mmu); bool cr4_smap =3D is_cr4_smap(mmu); bool cr0_wp =3D is_cr0_wp(mmu); bool efer_nx =3D is_efer_nx(mmu); =20 + /* + * In hardware, page fault error codes are generated (as the name + * suggests) on any kind of page fault. permission_fault() and + * paging_tmpl.h already use the same bits after a successful page + * table walk, to indicate the kind of access being performed. + * + * However, PFERR_PRESENT_MASK and PFERR_RSVD_MASK are never set here, + * exactly because the page walk is successful. PFERR_PRESENT_MASK is + * removed by the shift, while PFERR_RSVD_MASK is repurposed in + * permission_fault() to indicate accesses that are *not* subject to + * SMAP restrictions. + */ for (byte =3D 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) { unsigned pfec =3D byte << 1; =20 @@ -5589,10 +5613,9 @@ static void update_permission_bitmask(struct kvm_mmu= *mmu, bool ept) * - The access is supervisor mode * - If implicit supervisor access or X86_EFLAGS_AC is clear * - * Here, we cover the first four conditions. - * The fifth is computed dynamically in permission_fault(); - * PFERR_RSVD_MASK bit will be set in PFEC if the access is - * *not* subject to SMAP restrictions. + * Here, we cover the first four conditions. The fifth + * is computed dynamically in permission_fault() and + * communicated by setting PFERR_RSVD_MASK. */ if (cr4_smap) smapf =3D (pfec & (PFERR_RSVD_MASK|PFERR_FETCH_MASK)) ? 0 : kf; --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 BDC6F3D6486 for ; Wed, 8 Apr 2026 15:42: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=1775662955; cv=none; b=GupCdzMuJ3HKXOCEV6ZmMB3GV/jllkLe11o/OmcNUkTo7VF86zoCZ6tv3pudF+Ypfp4wgps+OUasgQDwEAlI9IAYqVOyQnhAI03B9TmJtHXUYlHUtUM4mrVeK3Z2fP1O6am+HgponsamiLeSm9jb6aF5WFwARltB/Un9gZJorag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662955; c=relaxed/simple; bh=/AWjYIgK+REIHHDLylWG6tkHoU5WOZeRVdS4QFdpNKQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UsHcIY34gvuC+KZ/bXJvw7m1IeHNqIkdAYyWgfBFCtz1NFgsRTPnHGBTdoWj03Q491SoltHC8TMPEk8kUUvLwboKfi2kCsjJEiR/tbMAavxQONPzsPaDWcMGM59BIcFVGCiHR9peN84kPE2ZLQgpTNkIyiTYyeSqzsnNwjWzWIk= 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=EIqZPsRL; 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="EIqZPsRL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662950; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=I9X9htpo4rk5wdV7xeEeWKkKrBagez0UVEeKPXajVEA=; b=EIqZPsRLN6oS/8m8cDz9/Tpuw9o03EWb/GLsXOGC9inczMrASAPU1K9Hy2WnRcQe2LEmoh u/Rg1y+gstWPHTFAw858TYxUdJYieL3a+dENxC1lxnoLAdTjciaRQ23WTTCjnaOgP/izoa QdkkscpA+9wct8pQB+3bs/OHwIQYTDg= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-490-UuXxMU3oOuu_I1RGTHZF-A-1; Wed, 08 Apr 2026 11:42:28 -0400 X-MC-Unique: UuXxMU3oOuu_I1RGTHZF-A-1 X-Mimecast-MFC-AGG-ID: UuXxMU3oOuu_I1RGTHZF-A_1775662947 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 058EF180034F; Wed, 8 Apr 2026 15:42:27 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2D610180036E; Wed, 8 Apr 2026 15:42:26 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 08/27] KVM: x86/mmu: introduce ACC_READ_MASK Date: Wed, 8 Apr 2026 11:41:58 -0400 Message-ID: <20260408154217.458420-9-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" Read permissions so far were only needed for EPT, which does not need ACC_USER_MASK. Therefore, for EPT page tables ACC_USER_MASK was repurposed as a read permission bit. In order to implement nested MBEC, EPT will genuinely have four kinds of accesses, and there will be no room for such hacks; bite the bullet at last, enlarging ACC_ALL to four bits and permissions[] to 2^4 bits (u16). The new code does not enforce that the XWR bits on non-execonly processors have their R bit set, even when running nested: none of the shadow_*_mask values have bit 0 set, and make_spte() genuinely relies on ACC_READ_MASK being requested! This works because, if execonly is not supported by the processor, shadow EPT will generate an EPT misconfig vmexit if the XWR bits represent a non-readable page, and therefore the pte_access argument to make_spte() will also always have ACC_READ_MASK set. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/include/asm/kvm_host.h | 12 +++++----- arch/x86/kvm/mmu.h | 2 +- arch/x86/kvm/mmu/mmu.c | 39 +++++++++++++++++++++------------ arch/x86/kvm/mmu/mmutrace.h | 3 ++- arch/x86/kvm/mmu/paging_tmpl.h | 35 +++++++++++++++++------------ arch/x86/kvm/mmu/spte.c | 18 ++++++--------- arch/x86/kvm/mmu/spte.h | 5 +++-- arch/x86/kvm/vmx/capabilities.h | 5 ----- arch/x86/kvm/vmx/common.h | 5 +---- arch/x86/kvm/vmx/vmx.c | 3 +-- 10 files changed, 67 insertions(+), 60 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 6e4e3ef9b8c7..65671d3769f0 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -327,11 +327,11 @@ struct kvm_kernel_irq_routing_entry; * the number of unique SPs that can theoretically be created is 2^n, wher= e n * is the number of bits that are used to compute the role. * - * But, even though there are 20 bits in the mask below, not all combinati= ons + * But, even though there are 21 bits in the mask below, not all combinati= ons * of modes and flags are possible: * * - invalid shadow pages are not accounted, mirror pages are not shadow= ed, - * so the bits are effectively 18. + * so the bits are effectively 19. * * - quadrant will only be used if has_4_byte_gpte=3D1 (non-PAE paging); * execonly and ad_disabled are only used for nested EPT which has @@ -346,7 +346,7 @@ struct kvm_kernel_irq_routing_entry; * cr0_wp=3D0, therefore these three bits only give rise to 5 possibil= ities. * * Therefore, the maximum number of possible upper-level shadow pages for a - * single gfn is a bit less than 2^13. + * single gfn is a bit less than 2^14. */ union kvm_mmu_page_role { u32 word; @@ -355,7 +355,7 @@ union kvm_mmu_page_role { unsigned has_4_byte_gpte:1; unsigned quadrant:2; unsigned direct:1; - unsigned access:3; + unsigned access:4; unsigned invalid:1; unsigned efer_nx:1; unsigned cr0_wp:1; @@ -365,7 +365,7 @@ union kvm_mmu_page_role { unsigned guest_mode:1; unsigned passthrough:1; unsigned is_mirror:1; - unsigned :4; + unsigned:3; =20 /* * This is left at the top of the word so that @@ -491,7 +491,7 @@ struct kvm_mmu { * Byte index: page fault error code [4:1] * Bit index: pte permissions in ACC_* format */ - u8 permissions[16]; + u16 permissions[16]; =20 u64 *pae_root; u64 *pml4_root; diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 830f46145692..23f37535c0ce 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -81,7 +81,7 @@ u8 kvm_mmu_get_max_tdp_level(void); void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_= mask); void kvm_mmu_set_mmio_spte_value(struct kvm *kvm, u64 mmio_value); void kvm_mmu_set_me_spte_mask(u64 me_value, u64 me_mask); -void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_exec_only); +void kvm_mmu_set_ept_masks(bool has_ad_bits); =20 void kvm_init_mmu(struct kvm_vcpu *vcpu); void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index d4bb693b3555..72c0e2c806c3 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -2033,7 +2033,7 @@ static bool kvm_sync_page_check(struct kvm_vcpu *vcpu= , struct kvm_mmu_page *sp) */ const union kvm_mmu_page_role sync_role_ign =3D { .level =3D 0xf, - .access =3D 0x7, + .access =3D ACC_ALL, .quadrant =3D 0x3, .passthrough =3D 0x1, }; @@ -5530,7 +5530,7 @@ reset_ept_shadow_zero_bits_mask(struct kvm_mmu *conte= xt, bool execonly) * update_permission_bitmask() builds what is effectively a * two-dimensional array of bools. The second dimension is * provided by individual bits of permissions[pfec >> 1], and - * logical &, | and ~ operations operate on all the 8 possible + * logical &, | and ~ operations operate on all the 16 possible * combinations of ACC_* bits. */ #define ACC_BITS_MASK(access) \ @@ -5540,15 +5540,24 @@ reset_ept_shadow_zero_bits_mask(struct kvm_mmu *con= text, bool execonly) (4 & (access) ? 1 << 4 : 0) | \ (5 & (access) ? 1 << 5 : 0) | \ (6 & (access) ? 1 << 6 : 0) | \ - (7 & (access) ? 1 << 7 : 0)) + (7 & (access) ? 1 << 7 : 0) | \ + (8 & (access) ? 1 << 8 : 0) | \ + (9 & (access) ? 1 << 9 : 0) | \ + (10 & (access) ? 1 << 10 : 0) | \ + (11 & (access) ? 1 << 11 : 0) | \ + (12 & (access) ? 1 << 12 : 0) | \ + (13 & (access) ? 1 << 13 : 0) | \ + (14 & (access) ? 1 << 14 : 0) | \ + (15 & (access) ? 1 << 15 : 0)) =20 static void update_permission_bitmask(struct kvm_mmu *mmu, bool ept) { unsigned byte; =20 - const u8 x =3D ACC_BITS_MASK(ACC_EXEC_MASK); - const u8 w =3D ACC_BITS_MASK(ACC_WRITE_MASK); - const u8 u =3D ACC_BITS_MASK(ACC_USER_MASK); + const u16 x =3D ACC_BITS_MASK(ACC_EXEC_MASK); + const u16 w =3D ACC_BITS_MASK(ACC_WRITE_MASK); + const u16 u =3D ACC_BITS_MASK(ACC_USER_MASK); + const u16 r =3D ACC_BITS_MASK(ACC_READ_MASK); =20 bool cr4_smep =3D is_cr4_smep(mmu); bool cr4_smap =3D is_cr4_smap(mmu); @@ -5571,24 +5580,26 @@ static void update_permission_bitmask(struct kvm_mm= u *mmu, bool ept) unsigned pfec =3D byte << 1; =20 /* - * Each "*f" variable has a 1 bit for each UWX value + * Each "*f" variable has a 1 bit for each ACC_* combo * that causes a fault with the given PFEC. */ =20 + /* Faults from reads to non-readable pages */ + u16 rf =3D (pfec & (PFERR_WRITE_MASK|PFERR_FETCH_MASK)) ? 0 : (u16)~r; /* Faults from writes to non-writable pages */ - u8 wf =3D (pfec & PFERR_WRITE_MASK) ? (u8)~w : 0; + u16 wf =3D (pfec & PFERR_WRITE_MASK) ? (u16)~w : 0; /* Faults from user mode accesses to supervisor pages */ - u8 uf =3D (pfec & PFERR_USER_MASK) ? (u8)~u : 0; + u16 uf =3D (pfec & PFERR_USER_MASK) ? (u16)~u : 0; /* Faults from fetches of non-executable pages*/ - u8 ff =3D (pfec & PFERR_FETCH_MASK) ? (u8)~x : 0; + u16 ff =3D (pfec & PFERR_FETCH_MASK) ? (u16)~x : 0; /* Faults from kernel mode fetches of user pages */ - u8 smepf =3D 0; + u16 smepf =3D 0; /* Faults from kernel mode accesses of user pages */ - u8 smapf =3D 0; + u16 smapf =3D 0; =20 if (!ept) { /* Faults from kernel mode accesses to user pages */ - u8 kf =3D (pfec & PFERR_USER_MASK) ? 0 : u; + u16 kf =3D (pfec & PFERR_USER_MASK) ? 0 : u; =20 /* Not really needed: !nx will cause pte.nx to fault */ if (!efer_nx) @@ -5621,7 +5632,7 @@ static void update_permission_bitmask(struct kvm_mmu = *mmu, bool ept) smapf =3D (pfec & (PFERR_RSVD_MASK|PFERR_FETCH_MASK)) ? 0 : kf; } =20 - mmu->permissions[byte] =3D ff | uf | wf | smepf | smapf; + mmu->permissions[byte] =3D ff | uf | wf | rf | smepf | smapf; } } =20 diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h index 764e3015d021..dcfdfedfc4e9 100644 --- a/arch/x86/kvm/mmu/mmutrace.h +++ b/arch/x86/kvm/mmu/mmutrace.h @@ -25,7 +25,8 @@ #define KVM_MMU_PAGE_PRINTK() ({ \ const char *saved_ptr =3D trace_seq_buffer_ptr(p); \ static const char *access_str[] =3D { \ - "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" \ + "----", "r---", "-w--", "rw--", "--u-", "r-u-", "-wu-", "rwu-", \ + "---x", "r--x", "-w-x", "rw-x", "--ux", "r-ux", "-wux", "rwux" \ }; \ union kvm_mmu_page_role role; \ \ diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 901cd2bd40b8..fb1b5d8b23e5 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -170,25 +170,24 @@ static bool FNAME(prefetch_invalid_gpte)(struct kvm_v= cpu *vcpu, return true; } =20 -/* - * For PTTYPE_EPT, a page table can be executable but not readable - * on supported processors. Therefore, set_spte does not automatically - * set bit 0 if execute only is supported. Here, we repurpose ACC_USER_MASK - * to signify readability since it isn't used in the EPT case - */ static inline unsigned FNAME(gpte_access)(u64 gpte) { unsigned access; #if PTTYPE =3D=3D PTTYPE_EPT access =3D ((gpte & VMX_EPT_WRITABLE_MASK) ? ACC_WRITE_MASK : 0) | ((gpte & VMX_EPT_EXECUTABLE_MASK) ? ACC_EXEC_MASK : 0) | - ((gpte & VMX_EPT_READABLE_MASK) ? ACC_USER_MASK : 0); + ((gpte & VMX_EPT_READABLE_MASK) ? ACC_READ_MASK : 0); #else - BUILD_BUG_ON(ACC_EXEC_MASK !=3D PT_PRESENT_MASK); - BUILD_BUG_ON(ACC_EXEC_MASK !=3D 1); + /* + * P is set here, so the page is always readable and W/U/!NX represent + * allowed accesses. + */ + BUILD_BUG_ON(ACC_READ_MASK !=3D PT_PRESENT_MASK); + BUILD_BUG_ON(ACC_WRITE_MASK !=3D PT_WRITABLE_MASK); + BUILD_BUG_ON(ACC_USER_MASK !=3D PT_USER_MASK); + BUILD_BUG_ON(ACC_EXEC_MASK & (PT_WRITABLE_MASK | PT_USER_MASK | PT_PRESEN= T_MASK)); access =3D gpte & (PT_WRITABLE_MASK | PT_USER_MASK | PT_PRESENT_MASK); - /* Combine NX with P (which is set here) to get ACC_EXEC_MASK. */ - access ^=3D (gpte >> PT64_NX_SHIFT); + access |=3D gpte & PT64_NX_MASK ? 0 : ACC_EXEC_MASK; #endif =20 return access; @@ -501,10 +500,18 @@ static int FNAME(walk_addr_generic)(struct guest_walk= er *walker, =20 if (write_fault) walker->fault.exit_qualification |=3D EPT_VIOLATION_ACC_WRITE; - if (user_fault) - walker->fault.exit_qualification |=3D EPT_VIOLATION_ACC_READ; - if (fetch_fault) + else if (fetch_fault) walker->fault.exit_qualification |=3D EPT_VIOLATION_ACC_INSTR; + else + walker->fault.exit_qualification |=3D EPT_VIOLATION_ACC_READ; + + /* + * Accesses to guest paging structures are either "reads" or + * "read+write" accesses, so consider them the latter if write_fault + * is true. + */ + if (access & PFERR_GUEST_PAGE_MASK) + walker->fault.exit_qualification |=3D EPT_VIOLATION_ACC_READ; =20 /* * Note, pte_access holds the raw RWX bits from the EPTE, not diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index e9dc0ae44274..7b5f118ae211 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -194,12 +194,6 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_p= age *sp, int is_host_mmio =3D -1; bool wrprot =3D false; =20 - /* - * For the EPT case, shadow_present_mask has no RWX bits set if - * exec-only page table entries are supported. In that case, - * ACC_USER_MASK and shadow_user_mask are used to represent - * read access. See FNAME(gpte_access) in paging_tmpl.h. - */ WARN_ON_ONCE((pte_access | shadow_present_mask) =3D=3D SHADOW_NONPRESENT_= VALUE); =20 if (sp->role.ad_disabled) @@ -228,6 +222,9 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_pa= ge *sp, pte_access &=3D ~ACC_EXEC_MASK; } =20 + if (pte_access & ACC_READ_MASK) + spte |=3D PT_PRESENT_MASK; /* or VMX_EPT_READABLE_MASK */ + if (pte_access & ACC_EXEC_MASK) spte |=3D shadow_x_mask; else @@ -391,6 +388,7 @@ u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled) u64 spte =3D SPTE_MMU_PRESENT_MASK; =20 spte |=3D __pa(child_pt) | shadow_present_mask | PT_WRITABLE_MASK | + PT_PRESENT_MASK /* or VMX_EPT_READABLE_MASK */ | shadow_user_mask | shadow_x_mask | shadow_me_value; =20 if (ad_disabled) @@ -491,18 +489,16 @@ void kvm_mmu_set_me_spte_mask(u64 me_value, u64 me_ma= sk) } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_mmu_set_me_spte_mask); =20 -void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_exec_only) +void kvm_mmu_set_ept_masks(bool has_ad_bits) { kvm_ad_enabled =3D has_ad_bits; =20 - shadow_user_mask =3D VMX_EPT_READABLE_MASK; + shadow_user_mask =3D 0; shadow_accessed_mask =3D VMX_EPT_ACCESS_BIT; shadow_dirty_mask =3D VMX_EPT_DIRTY_BIT; shadow_nx_mask =3D 0ull; shadow_x_mask =3D VMX_EPT_EXECUTABLE_MASK; - /* VMX_EPT_SUPPRESS_VE_BIT is needed for W or X violation. */ - shadow_present_mask =3D - (has_exec_only ? 0ull : VMX_EPT_READABLE_MASK) | VMX_EPT_SUPPRESS_VE_BIT; + shadow_present_mask =3D VMX_EPT_SUPPRESS_VE_BIT; =20 shadow_acc_track_mask =3D VMX_EPT_RWX_MASK; shadow_host_writable_mask =3D EPT_SPTE_HOST_WRITABLE; diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index bc02a2e89a31..121bfb2217e8 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -52,10 +52,11 @@ static_assert(SPTE_TDP_AD_ENABLED =3D=3D 0); #define SPTE_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) #endif =20 -#define ACC_EXEC_MASK 1 +#define ACC_READ_MASK PT_PRESENT_MASK #define ACC_WRITE_MASK PT_WRITABLE_MASK #define ACC_USER_MASK PT_USER_MASK -#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) +#define ACC_EXEC_MASK 8 +#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK |= ACC_READ_MASK) =20 #define SPTE_LEVEL_BITS 9 #define SPTE_LEVEL_SHIFT(level) __PT_LEVEL_SHIFT(level, SPTE_LEVEL_BITS) diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilitie= s.h index 4e371c93ae16..609477f190e8 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -300,11 +300,6 @@ static inline bool cpu_has_vmx_flexpriority(void) cpu_has_vmx_virtualize_apic_accesses(); } =20 -static inline bool cpu_has_vmx_ept_execute_only(void) -{ - return vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT; -} - static inline bool cpu_has_vmx_ept_4levels(void) { return vmx_capability.ept & VMX_EPT_PAGE_WALK_4_BIT; diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h index adf925500b9e..1afbf272efae 100644 --- a/arch/x86/kvm/vmx/common.h +++ b/arch/x86/kvm/vmx/common.h @@ -85,11 +85,8 @@ static inline int __vmx_handle_ept_violation(struct kvm_= vcpu *vcpu, gpa_t gpa, { u64 error_code; =20 - /* Is it a read fault? */ - error_code =3D (exit_qualification & EPT_VIOLATION_ACC_READ) - ? PFERR_USER_MASK : 0; /* Is it a write fault? */ - error_code |=3D (exit_qualification & EPT_VIOLATION_ACC_WRITE) + error_code =3D (exit_qualification & EPT_VIOLATION_ACC_WRITE) ? PFERR_WRITE_MASK : 0; /* Is it a fetch fault? */ error_code |=3D (exit_qualification & EPT_VIOLATION_ACC_INSTR) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 8b24e682535b..e27868fa4eb7 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8798,8 +8798,7 @@ __init int vmx_hardware_setup(void) set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */ =20 if (enable_ept) - kvm_mmu_set_ept_masks(enable_ept_ad_bits, - cpu_has_vmx_ept_execute_only()); + kvm_mmu_set_ept_masks(enable_ept_ad_bits); else vt_x86_ops.get_mt_mask =3D NULL; =20 --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 890D73D8126 for ; Wed, 8 Apr 2026 15:42:31 +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=1775662953; cv=none; b=mMn52GaLKGq5O6GFAlyOGQwMgIciqv5589DQrW0NYzRCDq0lVeVDPZL7d+XI4C3ErrGJBVEgGO058mMz4Ga8KKCquAKmPNBW/btYSBGNrVrYObVT8DbWjp/xrnXUf/pfAxxeykw4/B3l8nxTQPbPLWqm8EB3rQDXo24NmXnNHH0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662953; c=relaxed/simple; bh=8LTLy6DT42dvHRcsH/96CGZY5DRMWaGV/APUyPrYTqg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=K4QaSGXELTOvGEpSAOPbzxYpv/FNfKOpjPDiHi/xXNsoSz4BfyjT9LgyHQcPrzR/q174MA6zbway9znuBG6DoKQASBS8zPE2XCAk6PuE/9x/1c3qQBqM3AkYg4EzmRp5EqijY25MuTGGd2eR++bWOM14WFDbzIv92fQs/EYIrEw= 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=BUWGAKAr; 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="BUWGAKAr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662950; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qiimktwqNsIGErSNPDPMCTHd/htbVzYQ3m8IYarxywE=; b=BUWGAKArhORs9kkzhpW9bYR3e62mZHtrxeloHSwUQnYaOjaao66q8/7ZEWtXRVhN8rPdXj JiLmttcAd4LzIZxzaxseW4TL0JTLeaOb45M8WBcrigBero08WMly9E2/PZgjgmwl6fYNrE M0903ARuchTZhsoeiPBMcLRkg84/CDE= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-339-d3SVXM9IOgmDcsn3HFzwTQ-1; Wed, 08 Apr 2026 11:42:29 -0400 X-MC-Unique: d3SVXM9IOgmDcsn3HFzwTQ-1 X-Mimecast-MFC-AGG-ID: d3SVXM9IOgmDcsn3HFzwTQ_1775662948 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0307C18002E3; Wed, 8 Apr 2026 15:42:28 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2C8941800765; Wed, 8 Apr 2026 15:42:27 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 09/27] KVM: x86/mmu: separate more EPT/non-EPT permission_fault() Date: Wed, 8 Apr 2026 11:41:59 -0400 Message-ID: <20260408154217.458420-10-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" Now that EPT is not abusing anymore ACC_USER_MASK, move its handling entirely in the !ept branch. Merge smepf and ff into a single variable because EPT's "SMEP" (actually MBEC) is defined differently. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/mmu.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 72c0e2c806c3..a26514124fe5 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5556,7 +5556,6 @@ static void update_permission_bitmask(struct kvm_mmu = *mmu, bool ept) =20 const u16 x =3D ACC_BITS_MASK(ACC_EXEC_MASK); const u16 w =3D ACC_BITS_MASK(ACC_WRITE_MASK); - const u16 u =3D ACC_BITS_MASK(ACC_USER_MASK); const u16 r =3D ACC_BITS_MASK(ACC_READ_MASK); =20 bool cr4_smep =3D is_cr4_smep(mmu); @@ -5589,21 +5588,24 @@ static void update_permission_bitmask(struct kvm_mm= u *mmu, bool ept) /* Faults from writes to non-writable pages */ u16 wf =3D (pfec & PFERR_WRITE_MASK) ? (u16)~w : 0; /* Faults from user mode accesses to supervisor pages */ - u16 uf =3D (pfec & PFERR_USER_MASK) ? (u16)~u : 0; - /* Faults from fetches of non-executable pages*/ - u16 ff =3D (pfec & PFERR_FETCH_MASK) ? (u16)~x : 0; - /* Faults from kernel mode fetches of user pages */ - u16 smepf =3D 0; + u16 uf =3D 0; + /* Faults from fetches of non-executable pages */ + u16 ff =3D 0; /* Faults from kernel mode accesses of user pages */ u16 smapf =3D 0; =20 - if (!ept) { + if (ept) { + ff =3D (pfec & PFERR_FETCH_MASK) ? (u16)~x : 0; + } else { + const u16 u =3D ACC_BITS_MASK(ACC_USER_MASK); + /* Faults from kernel mode accesses to user pages */ u16 kf =3D (pfec & PFERR_USER_MASK) ? 0 : u; =20 - /* Not really needed: !nx will cause pte.nx to fault */ - if (!efer_nx) - ff =3D 0; + uf =3D (pfec & PFERR_USER_MASK) ? (u16)~u : 0; + + if (efer_nx) + ff =3D (pfec & PFERR_FETCH_MASK) ? (u16)~x : 0; =20 /* Allow supervisor writes if !cr0.wp */ if (!cr0_wp) @@ -5611,7 +5613,7 @@ static void update_permission_bitmask(struct kvm_mmu = *mmu, bool ept) =20 /* Disallow supervisor fetches of user code if cr4.smep */ if (cr4_smep) - smepf =3D (pfec & PFERR_FETCH_MASK) ? kf : 0; + ff |=3D (pfec & PFERR_FETCH_MASK) ? kf : 0; =20 /* * SMAP:kernel-mode data accesses from user-mode @@ -5632,7 +5634,7 @@ static void update_permission_bitmask(struct kvm_mmu = *mmu, bool ept) smapf =3D (pfec & (PFERR_RSVD_MASK|PFERR_FETCH_MASK)) ? 0 : kf; } =20 - mmu->permissions[byte] =3D ff | uf | wf | rf | smepf | smapf; + mmu->permissions[byte] =3D ff | uf | wf | rf | smapf; } } =20 --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 F17913D902E for ; Wed, 8 Apr 2026 15:42:32 +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=1775662955; cv=none; b=Ut2etp/I8of00CtFW7HMZpw/nGrShigXmeqdrs9q6WN86Avk3cX7g5MZEic4xWvUM/YihLB8WGhPT9Q3BsCGnJWg+BwE7rKlDTzedV84nuMkx7c2n212zo3lvlRZDp8Npylh2AioGdJoL6ncXa6cNGDZFNlhVyj0TJZKvqstilg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662955; c=relaxed/simple; bh=NAuDkuAAn6io9oRaMeoPjSzScOQbFqvRr3rpmrc7qGk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=c+4/bmUpJt4GEr+srbAo6VboD1Kx36Ny8XIOlSZYBSaoLgXSRHEdsFGmhGE/NbxnB6duhqHizYFXhhQNE4TtGK9b4Xj2SMs1QQh2mUJmdekWDCgZkp0dtoYsHiB3spbi4VF6cIvXb4twh5TZmTX6y6iZoLbNYqKn3tXzN1heUMg= 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=AoY7k0le; 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="AoY7k0le" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yUssvVav5wds3GZewe4BtC/nqJ4wE7HKSL0kQHrTWMA=; b=AoY7k0leJEH5mLO0SoOh1q5XmRjlxAhuxEogSjMS9QuXuVC7rDRccAJJZMgn8bTNig1FEN 19pSgNCggU1Uemd1wqKims8mmnLEedHyTX99/gmkDUyEVzuIkUGUZCR9hSSguJAieY2xvb dhl6iSQp9UZlrIHOkKJ/Ey7qAmV1rWo= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-491-SD5hsPFeP3aXOAY5Ld9H9w-1; Wed, 08 Apr 2026 11:42:31 -0400 X-MC-Unique: SD5hsPFeP3aXOAY5Ld9H9w-1 X-Mimecast-MFC-AGG-ID: SD5hsPFeP3aXOAY5Ld9H9w_1775662949 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 89A471955F04; Wed, 8 Apr 2026 15:42:29 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B48EF1955F2B; Wed, 8 Apr 2026 15:42:28 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 10/27] KVM: x86/mmu: pass PFERR_GUEST_PAGE/FINAL_MASK to kvm_translate_gpa Date: Wed, 8 Apr 2026 11:42:00 -0400 Message-ID: <20260408154217.458420-11-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" The XS/XU bit for EPT are only applied to final accesses, and use the U bit from the page walk itself. While strictly speaking not necessary (any value of PFERR_USER_MASK would be the same for page table accesses, because they're reads and writes only), it is clearer and less hackish to only apply MBEC to PFERR_GUEST_FINAL_MASK. Allow kvm-intel.ko to distinguish the two cases. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/hyperv.c | 3 ++- arch/x86/kvm/mmu/mmu.c | 3 ++- arch/x86/kvm/mmu/paging_tmpl.h | 7 +++++-- arch/x86/kvm/x86.c | 3 ++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 9b140bbdc1d8..cf9dd565b894 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2041,7 +2041,8 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, st= ruct kvm_hv_hcall *hc) * read with kvm_read_guest(). */ if (!hc->fast && is_guest_mode(vcpu)) { - hc->ingpa =3D translate_nested_gpa(vcpu, hc->ingpa, 0, NULL); + hc->ingpa =3D translate_nested_gpa(vcpu, hc->ingpa, + PFERR_GUEST_FINAL_MASK, NULL); if (unlikely(hc->ingpa =3D=3D INVALID_GPA)) return HV_STATUS_INVALID_HYPERCALL_INPUT; } diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index a26514124fe5..a459177c0480 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4339,7 +4339,8 @@ static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vc= pu, struct kvm_mmu *mmu, { if (exception) exception->error_code =3D 0; - return kvm_translate_gpa(vcpu, mmu, vaddr, access, exception); + return kvm_translate_gpa(vcpu, mmu, vaddr, access | PFERR_GUEST_FINAL_MAS= K, + exception); } =20 static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direc= t) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index fb1b5d8b23e5..567f8b77ffe0 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -376,7 +376,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, walker->pte_gpa[walker->level - 1] =3D pte_gpa; =20 real_gpa =3D kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(table_gfn), - nested_access, &walker->fault); + nested_access | PFERR_GUEST_PAGE_MASK, + &walker->fault); =20 /* * FIXME: This can happen if emulation (for of an INS/OUTS @@ -444,7 +445,9 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, gfn +=3D pse36_gfn_delta(pte); #endif =20 - real_gpa =3D kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), access, &walke= r->fault); + real_gpa =3D kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), + access | PFERR_GUEST_FINAL_MASK, + &walker->fault); if (real_gpa =3D=3D INVALID_GPA) return 0; =20 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fd1c4a36b593..bbafd10fd72c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1070,7 +1070,8 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long = cr3) * to an L1 GPA. */ real_gpa =3D kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(pdpt_gfn), - PFERR_USER_MASK | PFERR_WRITE_MASK, NULL); + PFERR_USER_MASK | PFERR_WRITE_MASK | + PFERR_GUEST_PAGE_MASK, NULL); if (real_gpa =3D=3D INVALID_GPA) return 0; =20 --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 467393DA7C7 for ; Wed, 8 Apr 2026 15:42:36 +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=1775662958; cv=none; b=E8pXscX1HPkiKWpKjJTcYV/hf3DHHzwjAvFsTPHQZyzGooM3AEKg07KCpY0F9qWaW39zONN5rwzgS4s5jzG3OeWUNGEJ83yMn4MDlNGW20XqEsyD4LpnI6+rbxmFqlU+rbOYTm8qCjvX9rd8i+rYBH4ZzHZY1Eddk/uJx+sM1AA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662958; c=relaxed/simple; bh=NiRZK1nPPOCZT4FFid68MW2Wp17mhjcEsXxPGHuPx4Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=f4t/U+XJkzoytXgHvdh2vwfmLpBJZZLSawxPjuWc62nHDvm9wdIi6oD7Uksn1CRoAQ07PZmY+CW1R5c/0La/cf9SYWIoiVZ/dOp0XGZAVSSvuKsD8sZMjmdI+6wJNScUJIoStLQtfW6NSXJnnbza4pKaPnY0dBcDR5DHCJXLbYc= 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=aDwbUQN6; 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="aDwbUQN6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662955; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QhhfEg8cV5pxvhe06bPCmyR/4KDcczdkiCXxWkqEfHA=; b=aDwbUQN6ajPs0lN2g5A5+oF6LY7gvihYkSF3G+VTmSjbmGceo+ATNV6xgQGcxax7Q163Kk 5VlSTg8i6xtPf7YqTl9HW5NZbiIbiGCCDRyTf4S3J9J1Ez+clyuSKdHN/0oVb6fviP7Bav tpnGvlppnqZMXLcJXjJj7RPmsByobq4= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-547-ppbdECukNtypJLFtDtn3Pg-1; Wed, 08 Apr 2026 11:42:31 -0400 X-MC-Unique: ppbdECukNtypJLFtDtn3Pg-1 X-Mimecast-MFC-AGG-ID: ppbdECukNtypJLFtDtn3Pg_1775662950 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 83B4318002FC; Wed, 8 Apr 2026 15:42:30 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id AF6841955F2B; Wed, 8 Apr 2026 15:42:29 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 11/27] KVM: x86/mmu: pass pte_access for final nGPA->GPA walk Date: Wed, 8 Apr 2026 11:42:01 -0400 Message-ID: <20260408154217.458420-12-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" The XS/XU bit for EPT are only applied to final accesses, and use the U bit from the page walk itself. This is available in the page walker as pte_access & ACC_USER_MASK but not available to translate_nested_gpa, so pass it down. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/hyperv.c | 2 +- arch/x86/kvm/mmu.h | 15 ++++++++++++--- arch/x86/kvm/mmu/mmu.c | 2 +- arch/x86/kvm/mmu/paging_tmpl.h | 4 ++-- arch/x86/kvm/mmu/spte.h | 6 ------ arch/x86/kvm/x86.c | 5 +++-- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index cf9dd565b894..53688f7b76eb 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2042,7 +2042,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, st= ruct kvm_hv_hcall *hc) */ if (!hc->fast && is_guest_mode(vcpu)) { hc->ingpa =3D translate_nested_gpa(vcpu, hc->ingpa, - PFERR_GUEST_FINAL_MASK, NULL); + PFERR_GUEST_FINAL_MASK, NULL, 0); if (unlikely(hc->ingpa =3D=3D INVALID_GPA)) return HV_STATUS_INVALID_HYPERCALL_INPUT; } diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 23f37535c0ce..635c2e5d8513 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -37,6 +37,12 @@ extern bool __read_mostly enable_mmio_caching; #define PT32_ROOT_LEVEL 2 #define PT32E_ROOT_LEVEL 3 =20 +#define ACC_READ_MASK PT_PRESENT_MASK +#define ACC_WRITE_MASK PT_WRITABLE_MASK +#define ACC_USER_MASK PT_USER_MASK +#define ACC_EXEC_MASK 8 +#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK |= ACC_READ_MASK) + #define KVM_MMU_CR4_ROLE_BITS (X86_CR4_PSE | X86_CR4_PAE | X86_CR4_LA57 | \ X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE) =20 @@ -289,16 +295,19 @@ static inline void kvm_update_page_stats(struct kvm *= kvm, int level, int count) } =20 gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, - struct x86_exception *exception); + struct x86_exception *exception, + u64 pte_access); =20 static inline gpa_t kvm_translate_gpa(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, gpa_t gpa, u64 access, - struct x86_exception *exception) + struct x86_exception *exception, + u64 pte_access) { if (mmu !=3D &vcpu->arch.nested_mmu) return gpa; - return translate_nested_gpa(vcpu, gpa, access, exception); + return translate_nested_gpa(vcpu, gpa, access, exception, + pte_access); } =20 static inline bool kvm_has_mirrored_tdp(const struct kvm *kvm) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index a459177c0480..f911f7578613 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4340,7 +4340,7 @@ static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vc= pu, struct kvm_mmu *mmu, if (exception) exception->error_code =3D 0; return kvm_translate_gpa(vcpu, mmu, vaddr, access | PFERR_GUEST_FINAL_MAS= K, - exception); + exception, ACC_ALL); } =20 static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direc= t) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 567f8b77ffe0..de8770d2fcfc 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -377,7 +377,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, =20 real_gpa =3D kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(table_gfn), nested_access | PFERR_GUEST_PAGE_MASK, - &walker->fault); + &walker->fault, 0); =20 /* * FIXME: This can happen if emulation (for of an INS/OUTS @@ -447,7 +447,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, =20 real_gpa =3D kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), access | PFERR_GUEST_FINAL_MASK, - &walker->fault); + &walker->fault, pte_access); if (real_gpa =3D=3D INVALID_GPA) return 0; =20 diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 121bfb2217e8..8a4c09c5cdbf 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -52,12 +52,6 @@ static_assert(SPTE_TDP_AD_ENABLED =3D=3D 0); #define SPTE_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) #endif =20 -#define ACC_READ_MASK PT_PRESENT_MASK -#define ACC_WRITE_MASK PT_WRITABLE_MASK -#define ACC_USER_MASK PT_USER_MASK -#define ACC_EXEC_MASK 8 -#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK |= ACC_READ_MASK) - #define SPTE_LEVEL_BITS 9 #define SPTE_LEVEL_SHIFT(level) __PT_LEVEL_SHIFT(level, SPTE_LEVEL_BITS) #define SPTE_INDEX(address, level) __PT_INDEX(address, level, SPTE_LEVEL_B= ITS) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bbafd10fd72c..15c1b2de3d93 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1071,7 +1071,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long = cr3) */ real_gpa =3D kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(pdpt_gfn), PFERR_USER_MASK | PFERR_WRITE_MASK | - PFERR_GUEST_PAGE_MASK, NULL); + PFERR_GUEST_PAGE_MASK, NULL, 0); if (real_gpa =3D=3D INVALID_GPA) return 0; =20 @@ -7824,7 +7824,8 @@ void kvm_get_segment(struct kvm_vcpu *vcpu, } =20 gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, - struct x86_exception *exception) + struct x86_exception *exception, + u64 pte_access) { struct kvm_mmu *mmu =3D vcpu->arch.mmu; gpa_t t_gpa; --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 E380A3DB62A for ; Wed, 8 Apr 2026 15:42:37 +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=1775662959; cv=none; b=kniYKBdVl99FVObUSi78g2mfWnjp6SVa67ISE19CSEpFfMAYMYZRrYxmr6ic7FYKQPk0whWC4Of5ZU8tfPVMLYQg9/thhLSDpqxesRqpgQtdtypI8KXd2jpZUCHYLsYSDSrLH1iDIsheDO8dCizV2UGrLc+Jfvqzn2KQI97O6G0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662959; c=relaxed/simple; bh=q+6QttVNMZBbjTG5ngEa9OPvoQpUiyXaXWaKjVh6B+Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=seCq5fwb1S0Kaur9oqsrn1y5/F8+2g3RaCrOYRJorB8VjbT7NfdnQk3Os9MnkxBIVC9G6TtBZAehSNZhVzTEv5P4Csn42boN4yX3T8LLvh1T4ms7WIcCGGXh+m9tE2yMXaDrLNQfYD0/++FqOwlRQ6dBE5fcVypeUL5lI4fuGsI= 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=PO+YrAOy; 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="PO+YrAOy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662956; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=olLPuuoE2IFdhLX8kg1UQdrgii1TPh/dluPSgqDT6L4=; b=PO+YrAOyN/O870EigINDDyqLlqOng121DzjSe3SNt0j/Q8DngynISXAkkyHSyeZitJzvD2 h5omaWIkDqsGWItRKQiOmxar8SN0ESRBchFbYze665tYQWc/0n+EOgL+nIjE/vixhXlPpK DgYoPBl8SPkvV13MF1N9u8U0MZhL6Ik= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-246-dOmSbm2rMZ6cfsM8K9Iw2A-1; Wed, 08 Apr 2026 11:42:33 -0400 X-MC-Unique: dOmSbm2rMZ6cfsM8K9Iw2A-1 X-Mimecast-MFC-AGG-ID: dOmSbm2rMZ6cfsM8K9Iw2A_1775662951 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7E15C18002F3; Wed, 8 Apr 2026 15:42:31 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id AA2A119560A6; Wed, 8 Apr 2026 15:42:30 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 12/27] KVM: x86: make translate_nested_gpa vendor-specific Date: Wed, 8 Apr 2026 11:42:02 -0400 Message-ID: <20260408154217.458420-13-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" EPT and NPT have different rules for passing PFERR_USER_MASK to the nested page table walk. In particular, for final addresses EPT uses the U bit of the guest (nGVA->nGPA) walk. While at it, remove PFERR_USER_MASK from the VMX version of the function, since it is actually ignored by the tables that update_permission_bitmask() generates for EPT. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/include/asm/kvm_host.h | 4 ++++ arch/x86/kvm/hyperv.c | 3 ++- arch/x86/kvm/mmu.h | 9 +++------ arch/x86/kvm/svm/nested.c | 15 +++++++++++++++ arch/x86/kvm/vmx/nested.c | 12 ++++++++++++ arch/x86/kvm/x86.c | 16 ---------------- 6 files changed, 36 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 65671d3769f0..a20263a4e727 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1979,6 +1979,10 @@ struct kvm_x86_nested_ops { struct kvm_nested_state *kvm_state); bool (*get_nested_state_pages)(struct kvm_vcpu *vcpu); int (*write_log_dirty)(struct kvm_vcpu *vcpu, gpa_t l2_gpa); + gpa_t (*translate_nested_gpa)(struct kvm_vcpu *vcpu, gpa_t gpa, + u64 access, + struct x86_exception *exception, + u64 pte_access); =20 int (*enable_evmcs)(struct kvm_vcpu *vcpu, uint16_t *vmcs_version); diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 53688f7b76eb..f35fae3a7b3d 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2041,7 +2041,8 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, st= ruct kvm_hv_hcall *hc) * read with kvm_read_guest(). */ if (!hc->fast && is_guest_mode(vcpu)) { - hc->ingpa =3D translate_nested_gpa(vcpu, hc->ingpa, + hc->ingpa =3D kvm_x86_ops.nested_ops->translate_nested_gpa( + vcpu, hc->ingpa, PFERR_GUEST_FINAL_MASK, NULL, 0); if (unlikely(hc->ingpa =3D=3D INVALID_GPA)) return HV_STATUS_INVALID_HYPERCALL_INPUT; diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 635c2e5d8513..63be5c5efed9 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -294,10 +294,6 @@ static inline void kvm_update_page_stats(struct kvm *k= vm, int level, int count) atomic64_add(count, &kvm->stat.pages[level - 1]); } =20 -gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, - struct x86_exception *exception, - u64 pte_access); - static inline gpa_t kvm_translate_gpa(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, gpa_t gpa, u64 access, @@ -306,8 +302,9 @@ static inline gpa_t kvm_translate_gpa(struct kvm_vcpu *= vcpu, { if (mmu !=3D &vcpu->arch.nested_mmu) return gpa; - return translate_nested_gpa(vcpu, gpa, access, exception, - pte_access); + return kvm_x86_ops.nested_ops->translate_nested_gpa(vcpu, gpa, access, + exception, + pte_access); } =20 static inline bool kvm_has_mirrored_tdp(const struct kvm *kvm) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index b36c33255bed..3b670ee4eb26 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1968,8 +1968,23 @@ static bool svm_get_nested_state_pages(struct kvm_vc= pu *vcpu) return true; } =20 +static gpa_t svm_translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, + u64 access, + struct x86_exception *exception, + u64 pte_access) +{ + struct kvm_mmu *mmu =3D vcpu->arch.mmu; + + BUG_ON(!mmu_is_nested(vcpu)); + + /* NPT walks are always user-walks */ + access |=3D PFERR_USER_MASK; + return mmu->gva_to_gpa(vcpu, mmu, gpa, access, exception); +} + struct kvm_x86_nested_ops svm_nested_ops =3D { .leave_nested =3D svm_leave_nested, + .translate_nested_gpa =3D svm_translate_nested_gpa, .is_exception_vmexit =3D nested_svm_is_exception_vmexit, .check_events =3D svm_check_nested_events, .triple_fault =3D nested_svm_triple_fault, diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 937aeb474af7..e4cb317807ab 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -7436,8 +7436,20 @@ __init int nested_vmx_hardware_setup(int (*exit_hand= lers[])(struct kvm_vcpu *)) return 0; } =20 +static gpa_t vmx_translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, + u64 access, + struct x86_exception *exception, + u64 pte_access) +{ + struct kvm_mmu *mmu =3D vcpu->arch.mmu; + + BUG_ON(!mmu_is_nested(vcpu)); + return mmu->gva_to_gpa(vcpu, mmu, gpa, access, exception); +} + struct kvm_x86_nested_ops vmx_nested_ops =3D { .leave_nested =3D vmx_leave_nested, + .translate_nested_gpa =3D vmx_translate_nested_gpa, .is_exception_vmexit =3D nested_vmx_is_exception_vmexit, .check_events =3D vmx_check_nested_events, .has_events =3D vmx_has_nested_events, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 15c1b2de3d93..0757b93e528d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7823,22 +7823,6 @@ void kvm_get_segment(struct kvm_vcpu *vcpu, kvm_x86_call(get_segment)(vcpu, var, seg); } =20 -gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access, - struct x86_exception *exception, - u64 pte_access) -{ - struct kvm_mmu *mmu =3D vcpu->arch.mmu; - gpa_t t_gpa; - - BUG_ON(!mmu_is_nested(vcpu)); - - /* NPT walks are always user-walks */ - access |=3D PFERR_USER_MASK; - t_gpa =3D mmu->gva_to_gpa(vcpu, mmu, gpa, access, exception); - - return t_gpa; -} - gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, struct x86_exception *exception) { --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 285E53DB652 for ; Wed, 8 Apr 2026 15:42:38 +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=1775662961; cv=none; b=Ud2xoCTf4WyOvyjTKl4tFV+QA1Mug2BvyrJt7/32/p/Bx2UUedZxpAEk8hr6kjYZn+1YTvl3QC1jvSzhSZY0jV1ySg5u5VCdoy0sjCio212gPmkHo3zJvuIpQ2cQFtBsaJiIS5+eciVf4tZ7S7KfjcbRZphbJpuzindpHaVzZ7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662961; c=relaxed/simple; bh=yTDdJDZAMyBIkLlDwYHDFovUdVITcy3kZiOQsrzOfBs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=aaVOnKIMSAwnl9FONNxxOZJQKKUnBNwYfTgpiqZUty8JIP3dytf7kPt24SbSoO2uwVgYRiYKs//ZEiCoIQ94DDU//OE3fG7M4tVB18/m847VpJisq9MlxbENKU39JQ4F6juVvC0E7eZeEjhJxQZvShnAWMGQGTnGtRyl9xxb4o8= 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=ftCHgkia; 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="ftCHgkia" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662958; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dEenS+pNViV5lCL0oy3TCnEINNWFZs/HabjzYitjLRU=; b=ftCHgkiaW7DHQkGtzrXKnB+fmQVs5ZZ3vYNmtkR/rhIIQus+KCA9uOm/RtEApTMyUUylqo OblTMcgFT6ocsI2HQcIBYk+KxPfALPqMhkmDdJgpFeKtRGWGIr4RQ8yLZh9PXiaS5105eg kTFMtFWWpdhK5h9tIJKe8HvMNj2Yd/M= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-613-Rf6UlWlsP6G6jtZQJcQuJQ-1; Wed, 08 Apr 2026 11:42:33 -0400 X-MC-Unique: Rf6UlWlsP6G6jtZQJcQuJQ-1 X-Mimecast-MFC-AGG-ID: Rf6UlWlsP6G6jtZQJcQuJQ_1775662952 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7A227180057B; Wed, 8 Apr 2026 15:42:32 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A4B9919560A6; Wed, 8 Apr 2026 15:42:31 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 13/27] KVM: x86/mmu: split XS/XU bits for EPT Date: Wed, 8 Apr 2026 11:42:03 -0400 Message-ID: <20260408154217.458420-14-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" When EPT is in use, replace ACC_USER_MASK with ACC_USER_EXEC_MASK, so that supervisor and user-mode execution can be controlled independently (ACC_USER_MASK would not allow a setting similar to XU=3D0 XS=3D1 W=3D1 R=3D1). Replace shadow_x_mask with shadow_xs_mask/shadow_xu_mask, to allow setting XS and XU bits separately in EPT entries. Note that ACC_USER_EXEC_MASK is already set through ACC_ALL in the kvm_mmu_page roles, but it does not propagate to the XU bit because (for now) shadow_xs_mask =3D=3D shadow_xu_mask. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu.h | 3 ++- arch/x86/kvm/mmu/mmu.c | 2 +- arch/x86/kvm/mmu/mmutrace.h | 6 ++--- arch/x86/kvm/mmu/spte.c | 44 +++++++++++++++++++++++-------------- arch/x86/kvm/mmu/spte.h | 11 ++++++++-- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 63be5c5efed9..d8c13e43c2d7 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -39,7 +39,8 @@ extern bool __read_mostly enable_mmio_caching; =20 #define ACC_READ_MASK PT_PRESENT_MASK #define ACC_WRITE_MASK PT_WRITABLE_MASK -#define ACC_USER_MASK PT_USER_MASK +#define ACC_USER_MASK PT_USER_MASK /* non EPT */ +#define ACC_USER_EXEC_MASK ACC_USER_MASK /* EPT only */ #define ACC_EXEC_MASK 8 #define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK |= ACC_READ_MASK) =20 diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index f911f7578613..ff87dca46cc6 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5476,7 +5476,7 @@ static void reset_shadow_zero_bits_mask(struct kvm_vc= pu *vcpu, static inline bool boot_cpu_is_amd(void) { WARN_ON_ONCE(!tdp_enabled); - return shadow_x_mask =3D=3D 0; + return shadow_xs_mask =3D=3D 0; } =20 /* diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h index dcfdfedfc4e9..3429c1413f42 100644 --- a/arch/x86/kvm/mmu/mmutrace.h +++ b/arch/x86/kvm/mmu/mmutrace.h @@ -357,8 +357,8 @@ TRACE_EVENT( __entry->sptep =3D virt_to_phys(sptep); __entry->level =3D level; __entry->r =3D shadow_present_mask || (__entry->spte & PT_PRESENT_MASK); - __entry->x =3D is_executable_pte(__entry->spte); - __entry->u =3D shadow_user_mask ? !!(__entry->spte & shadow_user_mask) := -1; + __entry->x =3D (__entry->spte & (shadow_xs_mask | shadow_nx_mask)) =3D= =3D shadow_xs_mask; + __entry->u =3D !!(__entry->spte & (shadow_xu_mask | shadow_user_mask)); ), =20 TP_printk("gfn %llx spte %llx (%s%s%s%s) level %d at %llx", @@ -366,7 +366,7 @@ TRACE_EVENT( __entry->r ? "r" : "-", __entry->spte & PT_WRITABLE_MASK ? "w" : "-", __entry->x ? "x" : "-", - __entry->u =3D=3D -1 ? "" : (__entry->u ? "u" : "-"), + __entry->u ? "u" : "-", __entry->level, __entry->sptep ) ); diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index 7b5f118ae211..779ee44893b0 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -29,8 +29,9 @@ bool __read_mostly kvm_ad_enabled; u64 __read_mostly shadow_host_writable_mask; u64 __read_mostly shadow_mmu_writable_mask; u64 __read_mostly shadow_nx_mask; -u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ u64 __read_mostly shadow_user_mask; +u64 __read_mostly shadow_xs_mask; /* mutual exclusive with nx_mask and use= r_mask */ +u64 __read_mostly shadow_xu_mask; /* mutual exclusive with nx_mask and use= r_mask */ u64 __read_mostly shadow_accessed_mask; u64 __read_mostly shadow_dirty_mask; u64 __read_mostly shadow_mmio_value; @@ -217,21 +218,26 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_= page *sp, * would tie make_spte() further to vCPU/MMU state, and add complexity * just to optimize a mode that is anything but performance critical. */ - if (level > PG_LEVEL_4K && (pte_access & ACC_EXEC_MASK) && - is_nx_huge_page_enabled(vcpu->kvm)) { + if (level > PG_LEVEL_4K && is_nx_huge_page_enabled(vcpu->kvm)) { pte_access &=3D ~ACC_EXEC_MASK; + if (shadow_xu_mask) + pte_access &=3D ~ACC_USER_EXEC_MASK; } =20 if (pte_access & ACC_READ_MASK) spte |=3D PT_PRESENT_MASK; /* or VMX_EPT_READABLE_MASK */ =20 - if (pte_access & ACC_EXEC_MASK) - spte |=3D shadow_x_mask; - else - spte |=3D shadow_nx_mask; - - if (pte_access & ACC_USER_MASK) - spte |=3D shadow_user_mask; + if (shadow_nx_mask) { + if (!(pte_access & ACC_EXEC_MASK)) + spte |=3D shadow_nx_mask; + if (pte_access & ACC_USER_MASK) + spte |=3D shadow_user_mask; + } else { + if (pte_access & ACC_EXEC_MASK) + spte |=3D shadow_xs_mask; + if (pte_access & ACC_USER_EXEC_MASK) + spte |=3D shadow_xu_mask; + } =20 if (level > PG_LEVEL_4K) spte |=3D PT_PAGE_SIZE_MASK; @@ -318,11 +324,13 @@ static u64 make_spte_executable(u64 spte, u8 access) { u64 set, clear; =20 - if (access & ACC_EXEC_MASK) - set =3D shadow_x_mask; + if (shadow_nx_mask) + set =3D (access & ACC_EXEC_MASK) ? 0 : shadow_nx_mask; else - set =3D shadow_nx_mask; - clear =3D set ^ (shadow_nx_mask | shadow_x_mask); + set =3D + (access & ACC_EXEC_MASK ? shadow_xs_mask : 0) | + (access & ACC_USER_EXEC_MASK ? shadow_xu_mask : 0); + clear =3D set ^ (shadow_nx_mask | shadow_xs_mask | shadow_xu_mask); return modify_spte_protections(spte, set, clear); } =20 @@ -389,7 +397,7 @@ u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled) =20 spte |=3D __pa(child_pt) | shadow_present_mask | PT_WRITABLE_MASK | PT_PRESENT_MASK /* or VMX_EPT_READABLE_MASK */ | - shadow_user_mask | shadow_x_mask | shadow_me_value; + shadow_user_mask | shadow_xs_mask | shadow_xu_mask | shadow_me_value; =20 if (ad_disabled) spte |=3D SPTE_TDP_AD_DISABLED; @@ -497,7 +505,8 @@ void kvm_mmu_set_ept_masks(bool has_ad_bits) shadow_accessed_mask =3D VMX_EPT_ACCESS_BIT; shadow_dirty_mask =3D VMX_EPT_DIRTY_BIT; shadow_nx_mask =3D 0ull; - shadow_x_mask =3D VMX_EPT_EXECUTABLE_MASK; + shadow_xs_mask =3D VMX_EPT_EXECUTABLE_MASK; + shadow_xu_mask =3D VMX_EPT_EXECUTABLE_MASK; shadow_present_mask =3D VMX_EPT_SUPPRESS_VE_BIT; =20 shadow_acc_track_mask =3D VMX_EPT_RWX_MASK; @@ -548,7 +557,8 @@ void kvm_mmu_reset_all_pte_masks(void) shadow_accessed_mask =3D PT_ACCESSED_MASK; shadow_dirty_mask =3D PT_DIRTY_MASK; shadow_nx_mask =3D PT64_NX_MASK; - shadow_x_mask =3D 0; + shadow_xs_mask =3D 0; + shadow_xu_mask =3D 0; shadow_present_mask =3D PT_PRESENT_MASK; =20 shadow_acc_track_mask =3D 0; diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 8a4c09c5cdbf..0ed690f78e17 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -178,8 +178,9 @@ extern bool __read_mostly kvm_ad_enabled; extern u64 __read_mostly shadow_host_writable_mask; extern u64 __read_mostly shadow_mmu_writable_mask; extern u64 __read_mostly shadow_nx_mask; -extern u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ extern u64 __read_mostly shadow_user_mask; +extern u64 __read_mostly shadow_xs_mask; /* mutual exclusive with nx_mask = and user_mask */ +extern u64 __read_mostly shadow_xu_mask; /* mutual exclusive with nx_mask = and user_mask */ extern u64 __read_mostly shadow_accessed_mask; extern u64 __read_mostly shadow_dirty_mask; extern u64 __read_mostly shadow_mmio_value; @@ -357,7 +358,13 @@ static inline bool is_last_spte(u64 pte, int level) =20 static inline bool is_executable_pte(u64 spte) { - return (spte & (shadow_x_mask | shadow_nx_mask)) =3D=3D shadow_x_mask; + /* + * For now, return true if either the XS or XU bit is set + * This function is only used for fast_page_fault, + * which never processes shadow EPT, and regular page + * tables always have XS=3D=3DXU. + */ + return (spte & (shadow_xs_mask | shadow_xu_mask | shadow_nx_mask)) !=3D s= hadow_nx_mask; } =20 static inline kvm_pfn_t spte_to_pfn(u64 pte) --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 706CA3DC4C2 for ; Wed, 8 Apr 2026 15:42:43 +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=1775662965; cv=none; b=LN4gCnRRdK6P6TBiCK80BFwMXCUt0A3IcAegTf+THvPf0FqkB3uVcUuiv7xrxo7gUY0uHGrJqFPlzV7RmLpxGraZbWVtJAaDKPA326ooBspTFs8evS3xqnAya8T3vZgxWj6VoEKX9OtmXowPmbEQZGC8kHfVwvX/B/PbG8kiVL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662965; c=relaxed/simple; bh=EVq7oL8uEMO231dsy+MPZQt2fG2+GObD3otZ38j/nm0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ADtv8/DZoukOQT85G3l+5x+hIaAEvK9ABUF2fJ/7VrOwAxn4A/lxb7NPaQ6lSVASGBSGlZVWRdLijfpDaobZkkMWKz6tiLzP8EjblYdS8B6JIwnAbDF5A7Wkph/QOhvUTyT28Vfuna2f3ZTU7izNmUSusckFwk+wUR1DnW2hZV0= 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=VPhBqkl8; 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="VPhBqkl8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662962; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vXT+GqnSDhFlo87FMfdObpuhhX2JHr2SghRG5EaXeTE=; b=VPhBqkl8iMM20Q038XaQYRG94IJOTQDc++Qg/8wBIBejU6VGIfy9dipVk+/A/CBMo+Zlyi RCRsuBwtrUGXwHBLESfa23FBWguT2KTHJi06m38ya2Y0DJot9N0BMFDs921wTmN9SrufSa V1z7YhKcpH491H2OiX8EtjG1nU8KhF4= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-595-VWX3loJoPTeq1UVPiLt6mg-1; Wed, 08 Apr 2026 11:42:35 -0400 X-MC-Unique: VWX3loJoPTeq1UVPiLt6mg-1 X-Mimecast-MFC-AGG-ID: VWX3loJoPTeq1UVPiLt6mg_1775662953 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 73F37180057C; Wed, 8 Apr 2026 15:42:33 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9FDF219560A6; Wed, 8 Apr 2026 15:42:32 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 14/27] KVM: x86/mmu: move cr4_smep to base role Date: Wed, 8 Apr 2026 11:42:04 -0400 Message-ID: <20260408154217.458420-15-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Guest page tables can be reused independent of the value of CR4.SMEP (at least if WP=3D1). However, this is not true of EPT MBEC pages, because presence of EPT entries is signaled by bits 0-2 when MBEC is off, and bits 0-2 + bit 10 when MBEC is on. In preparation for enabling MBEC, move cr4_smep to the base role. This makes the smep_andnot_wp bit redundant, so remove it. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- Documentation/virt/kvm/x86/mmu.rst | 10 ++++------ arch/x86/include/asm/kvm-x86-ops.h | 1 + arch/x86/include/asm/kvm_host.h | 23 +++++++++++++++-------- arch/x86/kvm/mmu/mmu.c | 6 +++--- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Documentation/virt/kvm/x86/mmu.rst b/Documentation/virt/kvm/x8= 6/mmu.rst index 2b3b6d442302..666aa179601a 100644 --- a/Documentation/virt/kvm/x86/mmu.rst +++ b/Documentation/virt/kvm/x86/mmu.rst @@ -184,10 +184,8 @@ Shadow pages contain the following information: Contains the value of efer.nx for which the page is valid. role.cr0_wp: Contains the value of cr0.wp for which the page is valid. - role.smep_andnot_wp: - Contains the value of cr4.smep && !cr0.wp for which the page is valid - (pages for which this is true are different from other pages; see the - treatment of cr0.wp=3D0 below). + role.cr4_smep: + Contains the value of cr4.smep for which the page is valid. role.smap_andnot_wp: Contains the value of cr4.smap && !cr0.wp for which the page is valid (pages for which this is true are different from other pages; see the @@ -435,8 +433,8 @@ from being written by the kernel after cr0.wp has chang= ed to 1, we make the value of cr0.wp part of the page role. This means that an spte created with one value of cr0.wp cannot be used when cr0.wp has a different value - it will simply be missed by the shadow page lookup code. A similar issue -exists when an spte created with cr0.wp=3D0 and cr4.smep=3D0 is used after -changing cr4.smep to 1. To avoid this, the value of !cr0.wp && cr4.smep +exists when an spte created with cr0.wp=3D0 and cr4.smap=3D0 is used after +changing cr4.smap to 1. To avoid this, the value of !cr0.wp && cr4.smap is also made a part of the page role. =20 Large pages diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-= x86-ops.h index de709fb5bd76..a02b486cc6fe 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -93,6 +93,7 @@ KVM_X86_OP_OPTIONAL(sync_pir_to_irr) KVM_X86_OP_OPTIONAL_RET0(set_tss_addr) KVM_X86_OP_OPTIONAL_RET0(set_identity_map_addr) KVM_X86_OP_OPTIONAL_RET0(get_mt_mask) +KVM_X86_OP_OPTIONAL_RET0(tdp_has_smep) KVM_X86_OP(load_mmu_pgd) KVM_X86_OP_OPTIONAL(link_external_spt) KVM_X86_OP_OPTIONAL(set_external_spte) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index a20263a4e727..8b4a55cc0918 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -342,8 +342,8 @@ struct kvm_kernel_irq_routing_entry; * paging has exactly one upper level, making level completely redunda= nt * when has_4_byte_gpte=3D1. * - * - on top of this, smep_andnot_wp and smap_andnot_wp are only set if - * cr0_wp=3D0, therefore these three bits only give rise to 5 possibil= ities. + * - on top of this, smap_andnot_wp is only set if cr0_wp=3D0, + * therefore these two bits only give rise to 3 possibilities. * * Therefore, the maximum number of possible upper-level shadow pages for a * single gfn is a bit less than 2^14. @@ -359,12 +359,19 @@ union kvm_mmu_page_role { unsigned invalid:1; unsigned efer_nx:1; unsigned cr0_wp:1; - unsigned smep_andnot_wp:1; unsigned smap_andnot_wp:1; unsigned ad_disabled:1; unsigned guest_mode:1; unsigned passthrough:1; unsigned is_mirror:1; + + /* + * cr4_smep is also set for EPT MBEC. Because it affects + * which pages are considered non-present (bit 10 additionally + * must be zero if MBEC is on) it has to be in the base role. + */ + unsigned cr4_smep:1; + unsigned:3; =20 /* @@ -391,10 +398,10 @@ union kvm_mmu_page_role { * tables (because KVM doesn't support Protection Keys with shadow paging)= , and * CR0.PG, CR4.PAE, and CR4.PSE are indirectly reflected in role.level. * - * Note, SMEP and SMAP are not redundant with sm*p_andnot_wp in the page r= ole. - * If CR0.WP=3D1, KVM can reuse shadow pages for the guest regardless of S= MEP and - * SMAP, but the MMU's permission checks for software walks need to be SME= P and - * SMAP aware regardless of CR0.WP. + * Note, SMAP is not redundant with smap_andnot_wp in the page role. If + * CR0.WP=3D1, KVM can reuse shadow pages for the guest regardless of SMAP, + * but the MMU's permission checks for software walks need to be SMAP + * aware regardless of CR0.WP. */ union kvm_mmu_extended_role { u32 word; @@ -404,7 +411,6 @@ union kvm_mmu_extended_role { unsigned int cr4_pse:1; unsigned int cr4_pke:1; unsigned int cr4_smap:1; - unsigned int cr4_smep:1; unsigned int cr4_la57:1; unsigned int efer_lma:1; }; @@ -1856,6 +1862,7 @@ struct kvm_x86_ops { int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr); u8 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); + bool (*tdp_has_smep)(struct kvm *kvm); =20 void (*load_mmu_pgd)(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index ff87dca46cc6..c4da7a42c77f 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -227,7 +227,7 @@ static inline bool __maybe_unused is_##reg##_##name(str= uct kvm_mmu *mmu) \ } BUILD_MMU_ROLE_ACCESSOR(base, cr0, wp); BUILD_MMU_ROLE_ACCESSOR(ext, cr4, pse); -BUILD_MMU_ROLE_ACCESSOR(ext, cr4, smep); +BUILD_MMU_ROLE_ACCESSOR(base, cr4, smep); BUILD_MMU_ROLE_ACCESSOR(ext, cr4, smap); BUILD_MMU_ROLE_ACCESSOR(ext, cr4, pke); BUILD_MMU_ROLE_ACCESSOR(ext, cr4, la57); @@ -5749,7 +5749,7 @@ static union kvm_cpu_role kvm_calc_cpu_role(struct kv= m_vcpu *vcpu, =20 role.base.efer_nx =3D ____is_efer_nx(regs); role.base.cr0_wp =3D ____is_cr0_wp(regs); - role.base.smep_andnot_wp =3D ____is_cr4_smep(regs) && !____is_cr0_wp(regs= ); + role.base.cr4_smep =3D ____is_cr4_smep(regs); role.base.smap_andnot_wp =3D ____is_cr4_smap(regs) && !____is_cr0_wp(regs= ); role.base.has_4_byte_gpte =3D !____is_cr4_pae(regs); =20 @@ -5761,7 +5761,6 @@ static union kvm_cpu_role kvm_calc_cpu_role(struct kv= m_vcpu *vcpu, else role.base.level =3D PT32_ROOT_LEVEL; =20 - role.ext.cr4_smep =3D ____is_cr4_smep(regs); role.ext.cr4_smap =3D ____is_cr4_smap(regs); role.ext.cr4_pse =3D ____is_cr4_pse(regs); =20 @@ -5820,6 +5819,7 @@ kvm_calc_tdp_mmu_root_page_role(struct kvm_vcpu *vcpu, =20 role.access =3D ACC_ALL; role.cr0_wp =3D true; + role.cr4_smep =3D kvm_x86_call(tdp_has_smep)(vcpu->kvm); role.efer_nx =3D true; role.smm =3D cpu_role.base.smm; role.guest_mode =3D cpu_role.base.guest_mode; --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 87F713D75DB for ; Wed, 8 Apr 2026 15:42:39 +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=1775662961; cv=none; b=IuBhlQ3/Z5SOyx0ZRKeNHcSAwZDJQVmWfntTQyiBHDYuirS3i9u28usmaSfIjw0zddgXKL5SwydOE0T6RKPkHaUIcmDLKPdU/KKZTqhZW9hYdNWdpExefJmS8d7Izy6UNjN3Dx7kgmExbaIlIMhI776IWYY1legvs8ValNvvLfE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662961; c=relaxed/simple; bh=jbTy/Li7PFdTAMbw3OzhrtT5zoFqsPNm0zcGo71lNzk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=m808i2BDP1gB8kseWh8AqeRt2WNiBtVvZNBcELhjM/0HRT2GNb3sGFj0ab87wE+ASbqypowfNrRX0DE/jgQjlh7g7zKK4qH81F0baz8Z1K+n+TRk3R3BX3LqEmbOXNPKkgX2j91ILmyAa78XEyIFa2DF3jH3hMpyH3GOh4c/ajE= 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=UgQVr++E; 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="UgQVr++E" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662958; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CeB6uVbhuSF7QBj63geywsNYZuaqFMdV23JyMmc+n8I=; b=UgQVr++E1i+AQxwo9AT3ANjUc/2gPh5X5liXnjn/QqzeIld70sc2dhZ6vtnFLLLazSe8cD r1uAAnXxciuJ7E4efBxpL4fBywBVwusQ728Kk7WRuF2++EeJBpG847bE/wxztGgwuKTu70 VWBdG/zLTKgO6T68JLyMTn7a9/qgNU8= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-286-_M1iKQglNqO1MbGQHPXwtQ-1; Wed, 08 Apr 2026 11:42:36 -0400 X-MC-Unique: _M1iKQglNqO1MbGQHPXwtQ-1 X-Mimecast-MFC-AGG-ID: _M1iKQglNqO1MbGQHPXwtQ_1775662954 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6ED2C180059C; Wed, 8 Apr 2026 15:42:34 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9A3871955D6B; Wed, 8 Apr 2026 15:42:33 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 15/27] KVM: VMX: enable use of MBEC Date: Wed, 8 Apr 2026 11:42:05 -0400 Message-ID: <20260408154217.458420-16-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" If available, set SECONDARY_EXEC_MODE_BASED_EPT_EXEC in the secondary execution controls and configure XS and XU separately (even if they are always used together). Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/include/asm/vmx.h | 3 +++ arch/x86/kvm/mmu.h | 7 ++++++- arch/x86/kvm/mmu/spte.c | 6 +++--- arch/x86/kvm/mmu/spte.h | 5 +++-- arch/x86/kvm/vmx/capabilities.h | 7 +++++++ arch/x86/kvm/vmx/common.h | 10 +++++----- arch/x86/kvm/vmx/main.c | 9 +++++++++ arch/x86/kvm/vmx/nested.c | 1 + arch/x86/kvm/vmx/vmx.c | 16 +++++++++++++++- arch/x86/kvm/vmx/vmx.h | 1 + arch/x86/kvm/vmx/x86_ops.h | 1 + 11 files changed, 54 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 59e3b095a315..2b449a3948d3 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -608,9 +608,12 @@ enum vm_entry_failure_code { #define EPT_VIOLATION_GVA_TRANSLATED BIT(8) =20 #define EPT_VIOLATION_RWX_TO_PROT(__epte) (((__epte) & VMX_EPT_RWX_MASK) <= < 3) +#define EPT_VIOLATION_USER_EXEC_TO_PROT(__epte) (((__epte) & VMX_EPT_USER_= EXECUTABLE_MASK) >> 4) =20 static_assert(EPT_VIOLATION_RWX_TO_PROT(VMX_EPT_RWX_MASK) =3D=3D (EPT_VIOLATION_PROT_READ | EPT_VIOLATION_PROT_WRITE | EPT_VIOLATION= _PROT_EXEC)); +static_assert(EPT_VIOLATION_USER_EXEC_TO_PROT(VMX_EPT_USER_EXECUTABLE_MASK= ) =3D=3D + (EPT_VIOLATION_PROT_USER_EXEC)); =20 /* * Exit Qualifications for NOTIFY VM EXIT diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index d8c13e43c2d7..d15f908d048f 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -83,12 +83,17 @@ static inline gfn_t kvm_mmu_max_gfn(void) return (1ULL << (max_gpa_bits - PAGE_SHIFT)) - 1; } =20 +static inline bool mmu_has_mbec(struct kvm_mmu *mmu) +{ + return mmu->root_role.cr4_smep; +} + u8 kvm_mmu_get_max_tdp_level(void); =20 void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_= mask); void kvm_mmu_set_mmio_spte_value(struct kvm *kvm, u64 mmio_value); void kvm_mmu_set_me_spte_mask(u64 me_value, u64 me_mask); -void kvm_mmu_set_ept_masks(bool has_ad_bits); +void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_mbec); =20 void kvm_init_mmu(struct kvm_vcpu *vcpu); void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c index 779ee44893b0..6da5c73d1004 100644 --- a/arch/x86/kvm/mmu/spte.c +++ b/arch/x86/kvm/mmu/spte.c @@ -497,7 +497,7 @@ void kvm_mmu_set_me_spte_mask(u64 me_value, u64 me_mask) } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_mmu_set_me_spte_mask); =20 -void kvm_mmu_set_ept_masks(bool has_ad_bits) +void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_mbec) { kvm_ad_enabled =3D has_ad_bits; =20 @@ -506,10 +506,10 @@ void kvm_mmu_set_ept_masks(bool has_ad_bits) shadow_dirty_mask =3D VMX_EPT_DIRTY_BIT; shadow_nx_mask =3D 0ull; shadow_xs_mask =3D VMX_EPT_EXECUTABLE_MASK; - shadow_xu_mask =3D VMX_EPT_EXECUTABLE_MASK; + shadow_xu_mask =3D has_mbec ? VMX_EPT_USER_EXECUTABLE_MASK : VMX_EPT_EXE= CUTABLE_MASK; shadow_present_mask =3D VMX_EPT_SUPPRESS_VE_BIT; =20 - shadow_acc_track_mask =3D VMX_EPT_RWX_MASK; + shadow_acc_track_mask =3D VMX_EPT_RWX_MASK | shadow_xu_mask; shadow_host_writable_mask =3D EPT_SPTE_HOST_WRITABLE; shadow_mmu_writable_mask =3D EPT_SPTE_MMU_WRITABLE; =20 diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 0ed690f78e17..f5261d993eac 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -24,7 +24,7 @@ * - bits 55 (EPT only): MMU-writable * - bits 56-59: unused * - bits 60-61: type of A/D tracking - * - bits 62: unused + * - bits 62 (EPT only): saved XU bit for disabled AD */ =20 /* @@ -65,7 +65,8 @@ static_assert(SPTE_TDP_AD_ENABLED =3D=3D 0); * must not overlap the A/D type mask. */ #define SHADOW_ACC_TRACK_SAVED_BITS_MASK (VMX_EPT_READABLE_MASK | \ - VMX_EPT_EXECUTABLE_MASK) + VMX_EPT_EXECUTABLE_MASK | \ + VMX_EPT_USER_EXECUTABLE_MASK) #define SHADOW_ACC_TRACK_SAVED_BITS_SHIFT 52 #define SHADOW_ACC_TRACK_SAVED_MASK (SHADOW_ACC_TRACK_SAVED_BITS_MASK << \ SHADOW_ACC_TRACK_SAVED_BITS_SHIFT) diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilitie= s.h index 609477f190e8..83d68028d414 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -15,6 +15,7 @@ extern bool __read_mostly enable_ept; extern bool __read_mostly enable_unrestricted_guest; extern bool __read_mostly enable_ept_ad_bits; extern bool __read_mostly enable_pml; +extern bool __read_mostly enable_mbec; extern int __read_mostly pt_mode; =20 #define PT_MODE_SYSTEM 0 @@ -406,4 +407,10 @@ static inline bool cpu_has_notify_vmexit(void) SECONDARY_EXEC_NOTIFY_VM_EXITING; } =20 +static inline bool cpu_has_ept_mbec(void) +{ + return vmcs_config.cpu_based_2nd_exec_ctrl & + SECONDARY_EXEC_MODE_BASED_EPT_EXEC; +} + #endif /* __KVM_X86_VMX_CAPS_H */ diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h index 1afbf272efae..40fa72f31fc7 100644 --- a/arch/x86/kvm/vmx/common.h +++ b/arch/x86/kvm/vmx/common.h @@ -91,15 +91,15 @@ static inline int __vmx_handle_ept_violation(struct kvm= _vcpu *vcpu, gpa_t gpa, /* Is it a fetch fault? */ error_code |=3D (exit_qualification & EPT_VIOLATION_ACC_INSTR) ? PFERR_FETCH_MASK : 0; - /* - * ept page table entry is present? - * note: unconditionally clear USER_EXEC until mode-based - * execute control is implemented - */ + /* ept page table entry is present? */ error_code |=3D (exit_qualification & (EPT_VIOLATION_PROT_MASK & ~EPT_VIOLATION_PROT_USER_EXEC)) ? PFERR_PRESENT_MASK : 0; =20 + if (mmu_has_mbec(vcpu->arch.mmu)) + error_code |=3D (exit_qualification & EPT_VIOLATION_PROT_USER_EXEC) + ? PFERR_PRESENT_MASK : 0; + if (exit_qualification & EPT_VIOLATION_GVA_IS_VALID) error_code |=3D (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) ? PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK; diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index a46ccd670785..c0dd506bed64 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -750,6 +750,14 @@ static int vt_set_identity_map_addr(struct kvm *kvm, u= 64 ident_addr) return vmx_set_identity_map_addr(kvm, ident_addr); } =20 +static bool vt_tdp_has_smep(struct kvm *kvm) +{ + if (is_td(kvm)) + return false; + + return vmx_tdp_has_smep(kvm); +} + static u64 vt_get_l2_tsc_offset(struct kvm_vcpu *vcpu) { /* TDX doesn't support L2 guest at the moment. */ @@ -961,6 +969,7 @@ struct kvm_x86_ops vt_x86_ops __initdata =3D { .set_tss_addr =3D vt_op(set_tss_addr), .set_identity_map_addr =3D vt_op(set_identity_map_addr), .get_mt_mask =3D vmx_get_mt_mask, + .tdp_has_smep =3D vt_op(tdp_has_smep), =20 .get_exit_info =3D vt_op(get_exit_info), .get_entry_info =3D vt_op(get_entry_info), diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index e4cb317807ab..cdc35a2728d9 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2440,6 +2440,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx= , struct loaded_vmcs *vmcs0 SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_ENABLE_VMFUNC | + SECONDARY_EXEC_MODE_BASED_EPT_EXEC | SECONDARY_EXEC_DESC); =20 if (nested_cpu_has(vmcs12, diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e27868fa4eb7..3905bc85a46c 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -113,6 +113,9 @@ module_param(emulate_invalid_guest_state, bool, 0444); static bool __read_mostly fasteoi =3D 1; module_param(fasteoi, bool, 0444); =20 +bool __read_mostly enable_mbec =3D 1; +module_param_named(mbec, enable_mbec, bool, 0444); + module_param(enable_apicv, bool, 0444); module_param(enable_ipiv, bool, 0444); =20 @@ -2809,6 +2812,7 @@ static int setup_vmcs_config(struct vmcs_config *vmcs= _conf, return -EIO; =20 vmx_cap->ept =3D 0; + _cpu_based_2nd_exec_control &=3D ~SECONDARY_EXEC_MODE_BASED_EPT_EXEC; _cpu_based_2nd_exec_control &=3D ~SECONDARY_EXEC_EPT_VIOLATION_VE; } if (!(_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_VPID) && @@ -4844,6 +4848,9 @@ static u32 vmx_secondary_exec_control(struct vcpu_vmx= *vmx) */ exec_control &=3D ~SECONDARY_EXEC_ENABLE_VMFUNC; =20 + if (!enable_mbec) + exec_control &=3D ~SECONDARY_EXEC_MODE_BASED_EPT_EXEC; + /* SECONDARY_EXEC_DESC is enabled/disabled on writes to CR4.UMIP, * in vmx_set_cr4. */ exec_control &=3D ~SECONDARY_EXEC_DESC; @@ -7932,6 +7939,11 @@ u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn,= bool is_mmio) return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT); } =20 +bool vmx_tdp_has_smep(struct kvm *kvm) +{ + return enable_mbec; +} + static void vmcs_set_secondary_exec_control(struct vcpu_vmx *vmx, u32 new_= ctl) { /* @@ -8779,6 +8791,8 @@ __init int vmx_hardware_setup(void) ple_window_shrink =3D 0; } =20 + if (!cpu_has_ept_mbec()) + enable_mbec =3D 0; if (!cpu_has_vmx_apicv()) enable_apicv =3D 0; if (!enable_apicv) @@ -8798,7 +8812,7 @@ __init int vmx_hardware_setup(void) set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */ =20 if (enable_ept) - kvm_mmu_set_ept_masks(enable_ept_ad_bits); + kvm_mmu_set_ept_masks(enable_ept_ad_bits, enable_mbec); else vt_x86_ops.get_mt_mask =3D NULL; =20 diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 70bfe81dea54..594717e619d9 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -570,6 +570,7 @@ static inline u8 vmx_get_rvi(void) SECONDARY_EXEC_ENABLE_VMFUNC | \ SECONDARY_EXEC_BUS_LOCK_DETECTION | \ SECONDARY_EXEC_NOTIFY_VM_EXITING | \ + SECONDARY_EXEC_MODE_BASED_EPT_EXEC | \ SECONDARY_EXEC_ENCLS_EXITING | \ SECONDARY_EXEC_EPT_VIOLATION_VE) =20 diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h index d09abeac2b56..69cf276be88e 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -103,6 +103,7 @@ void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *e= oi_exit_bitmap); int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr); int vmx_set_identity_map_addr(struct kvm *kvm, u64 ident_addr); u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); +bool vmx_tdp_has_smep(struct kvm *kvm); =20 void vmx_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, u64 *info1, u64 *info2, u32 *intr_info, u32 *error_code); --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 A383E3DC4D2 for ; Wed, 8 Apr 2026 15:42:43 +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=1775662965; cv=none; b=Rlm7NHuDjfJOWTADg1Oj1YJGV+7YQltLYYukdf7oIIo6slxOJY81P0AjHV47/jKUko2DjoOglXo5P+VZlgFn4iHwlg2rjO+UbwApSIoPbc9DGIKFsratVKCuqPtJTmuFF9W2JotdHVMSbhkGmwr6wxDZRuR46q+9Ki2c8JrnC3A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662965; c=relaxed/simple; bh=rPRdRLWg8htFM6ROgNGlDPkhA17nR+qayALDPyMV+Vo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZigdPCJpoDftA7gok+EA+/js38ZUTc1pJNuBzrzZtAO4x77pYZEuLilWItZU5k+w3UXsOL/B+xHxIrTWkQy6Wn2/OBEO81h8z1d/c7kuPJaMeDqrppuVzzsgu4xsXbzi4xmWUdeP+uHjAMjl3ioySW3fY7zIAamJ20mEJ3ql4Bo= 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=IsXPBD/z; 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="IsXPBD/z" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662962; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=izbJAGJGsnpYGt8ulJkjqisiCiGregx4QgYg2m66Fn0=; b=IsXPBD/z/w/EZK5v1zKQ0p8Bl1lBLVLsAQwVlEtrl/aPIVqkHcfHXXsfoHDLywcnU+qtFX s0aQA28EcUeEvA885XnFQ6m9klY8zmiQ6jMd1+nRkR/WbHIjVxl1IyT7MsaJUo4FqW5/35 SiX6fTxSWACVBTRyoimwDXBU+kx8gg8= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-661-Z3QMmR3gP92qlGJCYYA4dA-1; Wed, 08 Apr 2026 11:42:37 -0400 X-MC-Unique: Z3QMmR3gP92qlGJCYYA4dA-1 X-Mimecast-MFC-AGG-ID: Z3QMmR3gP92qlGJCYYA4dA_1775662955 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 69C7618002EA; Wed, 8 Apr 2026 15:42:35 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 952061955D6B; Wed, 8 Apr 2026 15:42:34 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 16/27] KVM: nVMX: pass advanced EPT violation vmexit info to guest Date: Wed, 8 Apr 2026 11:42:06 -0400 Message-ID: <20260408154217.458420-17-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" KVM will use advanced vmexit information for EPT violations to virtualize MBEC. Pass it to the guest since it is easy and allows testing nested nested. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/include/asm/vmx.h | 4 ++++ arch/x86/kvm/mmu/paging_tmpl.h | 2 +- arch/x86/kvm/vmx/nested.c | 13 +++++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 2b449a3948d3..fcd623719334 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -524,6 +524,7 @@ enum vmcs_field { #define VMX_EPT_1GB_PAGE_BIT (1ull << 17) #define VMX_EPT_INVEPT_BIT (1ull << 20) #define VMX_EPT_AD_BIT (1ull << 21) +#define VMX_EPT_ADVANCED_VMEXIT_INFO_BIT (1ull << 22) #define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) #define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) =20 @@ -606,6 +607,9 @@ enum vm_entry_failure_code { EPT_VIOLATION_PROT_USER_EXEC) #define EPT_VIOLATION_GVA_IS_VALID BIT(7) #define EPT_VIOLATION_GVA_TRANSLATED BIT(8) +#define EPT_VIOLATION_GVA_USER BIT(9) +#define EPT_VIOLATION_GVA_WRITABLE BIT(10) +#define EPT_VIOLATION_GVA_NX BIT(11) =20 #define EPT_VIOLATION_RWX_TO_PROT(__epte) (((__epte) & VMX_EPT_RWX_MASK) <= < 3) #define EPT_VIOLATION_USER_EXEC_TO_PROT(__epte) (((__epte) & VMX_EPT_USER_= EXECUTABLE_MASK) >> 4) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index de8770d2fcfc..f5f9e745f21d 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -494,7 +494,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, * [2:0] - Derive from the access bits. The exit_qualification might be * out of date if it is serving an EPT misconfiguration. * [5:3] - Calculated by the page walk of the guest EPT page tables - * [7:8] - Derived from [7:8] of real exit_qualification + * [7:11] - Derived from [7:11] of real exit_qualification * * The other bits are set to 0. */ diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index cdc35a2728d9..e0ef2cb8f2cd 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -443,10 +443,14 @@ static void nested_ept_inject_page_fault(struct kvm_v= cpu *vcpu, vm_exit_reason =3D EXIT_REASON_EPT_MISCONFIG; exit_qualification =3D 0; } else { + u64 mask =3D EPT_VIOLATION_GVA_IS_VALID | + EPT_VIOLATION_GVA_TRANSLATED; + if (vmx->nested.msrs.ept_caps & VMX_EPT_ADVANCED_VMEXIT_INFO_BIT) + mask |=3D EPT_VIOLATION_GVA_USER | + EPT_VIOLATION_GVA_WRITABLE | + EPT_VIOLATION_GVA_NX; exit_qualification =3D fault->exit_qualification; - exit_qualification |=3D vmx_get_exit_qual(vcpu) & - (EPT_VIOLATION_GVA_IS_VALID | - EPT_VIOLATION_GVA_TRANSLATED); + exit_qualification |=3D vmx_get_exit_qual(vcpu) & mask; vm_exit_reason =3D EXIT_REASON_EPT_VIOLATION; } =20 @@ -7238,7 +7242,8 @@ static void nested_vmx_setup_secondary_ctls(u32 ept_c= aps, VMX_EPT_PAGE_WALK_5_BIT | VMX_EPTP_WB_BIT | VMX_EPT_INVEPT_BIT | - VMX_EPT_EXECUTE_ONLY_BIT; + VMX_EPT_EXECUTE_ONLY_BIT | + VMX_EPT_ADVANCED_VMEXIT_INFO_BIT; =20 msrs->ept_caps &=3D ept_caps; msrs->ept_caps |=3D VMX_EPT_EXTENT_GLOBAL_BIT | --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 CB8673DBD6A for ; Wed, 8 Apr 2026 15:42:41 +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=1775662963; cv=none; b=nZ29oWppC4/z9AxKUQZ2y37PvMO1pdDkij/artCmOqdMW/FFHdXKNaQqRhot8j0L6a3Zb0+suyJ1/l5rJNsSNCdRE0lvB5LxOFUC35plat/LfT5XvPqDM5yHqGbPrDxr0mHCH4zzjyMJwqZEq6pWeaIacN3Hhd0P8vglbvv5vK8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662963; c=relaxed/simple; bh=jNuXJ8kroXJRvPlG8Og3ilixZUP6vHWT25/bPVthaVw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=M3P3vQ6p7umLR/CRmy6ADREkQepXmCNtdiekbILzqnjQHOT871z021QsHnYp/e/ELGIzP5z7jkCqvtT0vkCCzj/UOHl2hpsjFX41Aq5tfs0AkmPd3oBReCRrg1NqTuVvdtEElONc6rbY6iy+Zve3Vg1in2P7FflOVM8Rs6vJSpg= 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=YAaU+0CG; 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="YAaU+0CG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662961; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bIo6Zoa8TZfbO15UPe+dFfMCRInDcKBHx42OS7/xjaU=; b=YAaU+0CGCf3xT0+htIBhlzLSSrM6bgHVZxlogLF7ylASXjjbeq8VOW+fDB5rmGtAG868Kg vY46oSVYJqLxgrx3hKvu+SBwNqFozv4bCllU/fb85xxo0QUHNDPpvpXfudbsdbpW31Xk5F 4q8T0RvjkJiES5JLc2mwP6gRVYEFJNQ= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-652-p9Rg4GaZNay2QFyfkBKQfA-1; Wed, 08 Apr 2026 11:42:39 -0400 X-MC-Unique: p9Rg4GaZNay2QFyfkBKQfA-1 X-Mimecast-MFC-AGG-ID: p9Rg4GaZNay2QFyfkBKQfA_1775662956 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 65812195608D; Wed, 8 Apr 2026 15:42:36 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8FAC11955D70; Wed, 8 Apr 2026 15:42:35 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 17/27] KVM: nVMX: pass PFERR_USER_MASK to MMU on EPT violations Date: Wed, 8 Apr 2026 11:42:07 -0400 Message-ID: <20260408154217.458420-18-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" For EPT, PFERR_USER_MASK refers not to the CPL of the guest, but to the AND of the U bits encountered while walking guest page tables; this is consistent with how MBEC differentiates between XS and XU. This is available through the "advanced vmexit information for EPT violations" feature. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/vmx/common.h | 6 +++++- arch/x86/kvm/vmx/vmx.c | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h index 40fa72f31fc7..48520fa1c8e8 100644 --- a/arch/x86/kvm/vmx/common.h +++ b/arch/x86/kvm/vmx/common.h @@ -100,9 +100,13 @@ static inline int __vmx_handle_ept_violation(struct kv= m_vcpu *vcpu, gpa_t gpa, error_code |=3D (exit_qualification & EPT_VIOLATION_PROT_USER_EXEC) ? PFERR_PRESENT_MASK : 0; =20 - if (exit_qualification & EPT_VIOLATION_GVA_IS_VALID) + if (exit_qualification & EPT_VIOLATION_GVA_IS_VALID) { error_code |=3D (exit_qualification & EPT_VIOLATION_GVA_TRANSLATED) ? PFERR_GUEST_FINAL_MASK : PFERR_GUEST_PAGE_MASK; + if ((exit_qualification & (EPT_VIOLATION_GVA_TRANSLATED|EPT_VIOLATION_GV= A_USER)) + =3D=3D (EPT_VIOLATION_GVA_TRANSLATED|EPT_VIOLATION_GVA_USER)) + error_code |=3D PFERR_USER_MASK; + } =20 if (vt_is_tdx_private_gpa(vcpu->kvm, gpa)) error_code |=3D PFERR_PRIVATE_ACCESS; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 3905bc85a46c..53dc78066650 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2826,6 +2826,16 @@ static int setup_vmcs_config(struct vmcs_config *vmc= s_conf, vmx_cap->vpid =3D 0; } =20 + /* + * Virtualizing MBEC requires advanced vmexit information in order to + * distinguish supervisor and user accesses. For simplicity and clarity + * disable MBEC entirely if advanced vmexit information is not available, + * this way mbec=3D1 in the kvm_intel module parameters implies availabil= ity + * to nested guests as well. + */ + if (!(vmx_cap->ept & VMX_EPT_ADVANCED_VMEXIT_INFO_BIT)) + _cpu_based_2nd_exec_control &=3D ~SECONDARY_EXEC_MODE_BASED_EPT_EXEC; + if (!cpu_has_sgx()) _cpu_based_2nd_exec_control &=3D ~SECONDARY_EXEC_ENCLS_EXITING; =20 --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 5D0B03DD514 for ; Wed, 8 Apr 2026 15:42:45 +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=1775662967; cv=none; b=uWVZjlc2gq1X0ysqXKTgwiBCYCB6eARZu99h80D0+iy8JVEdwWXYG7M0j9AK+6U2MHE0fugNRvj23WIZ0dELK9kXzax0kdhC634SM1gVTawoI63QuPqXeddLbztQNK9kPc0NCV3gfevXp6EcICKvywB8GX6N/3C85DW7mkJeNGM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662967; c=relaxed/simple; bh=Vi2h6wgXSqS0Z3npITZpTKJzqvGpkE+E7w8apfBRHU0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rTLe4QLHD3WUCz3u7aPJEdUKWizGrE93Mr7W3JZQgRoK0MVz4DMiJ32f4zfteN0mSegJ9BwG+CsmCT7aHk4Rxm36lhFonW1qJol2hnGLR6hPftFddRdocvEw33JK9TnJ+NCkcWUlKI+j6+hR7zK3kwbwy6XLqDrQ6wHiAuPxZbE= 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=FgLs291H; 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="FgLs291H" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662964; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2s/gpUseP+WPonCcnkk3uiS88opdY1tg3pny2c7juOg=; b=FgLs291HZH01mxxDj6IIeC2d+zgGrxCxMXndS5ZK44YMc6feWDhdwZzkGIOH+IZKXHoK3u ujxKTfaCsmm+i+YNcebRHkNDINa15SzgBiv9JY9ZEiVB+p/fvoQ+L7EKY/KhdEJn5nQdaV epFp6xGXtk5BQ6DB4OO3nUAd7b/+ftA= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-683-EgcAuF1sMauVfa5NI_ietw-1; Wed, 08 Apr 2026 11:42:39 -0400 X-MC-Unique: EgcAuF1sMauVfa5NI_ietw-1 X-Mimecast-MFC-AGG-ID: EgcAuF1sMauVfa5NI_ietw_1775662957 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5F74F1955D79; Wed, 8 Apr 2026 15:42:37 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8A45C19560A6; Wed, 8 Apr 2026 15:42:36 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 18/27] KVM: x86/mmu: add support for MBEC to EPT page table walks Date: Wed, 8 Apr 2026 11:42:08 -0400 Message-ID: <20260408154217.458420-19-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Extend the page walker to support moving bit 10 of the PTEs into ACC_USER_EXEC_MASK and bit 6 of the exit qualification of EPT violation VM exits. Note that while mmu_has_mbec()/cr4_smep affect the interpretation of ACC_USER_EXEC_MASK and add bit 10 as a "present bit" in guest EPT page table entries, they do not affect how KVM operates on SPTEs. That's because the MMU uses explicit ACC_USER_EXEC_MASK/shadow_xu_mask even for the non-nested EPT; the only difference is that ACC_USER_EXEC_MASK and ACC_EXEC_MASK will always be set in tandem outside the nested scenario. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/mmu.c | 13 +++++++++++-- arch/x86/kvm/mmu/paging_tmpl.h | 27 +++++++++++++++++++++------ arch/x86/kvm/mmu/spte.h | 2 ++ arch/x86/kvm/vmx/nested.c | 9 +++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index c4da7a42c77f..07bdc8f9b0cb 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5555,7 +5555,6 @@ static void update_permission_bitmask(struct kvm_mmu = *mmu, bool ept) { unsigned byte; =20 - const u16 x =3D ACC_BITS_MASK(ACC_EXEC_MASK); const u16 w =3D ACC_BITS_MASK(ACC_WRITE_MASK); const u16 r =3D ACC_BITS_MASK(ACC_READ_MASK); =20 @@ -5596,8 +5595,18 @@ static void update_permission_bitmask(struct kvm_mmu= *mmu, bool ept) u16 smapf =3D 0; =20 if (ept) { - ff =3D (pfec & PFERR_FETCH_MASK) ? (u16)~x : 0; + const u16 xs =3D ACC_BITS_MASK(ACC_EXEC_MASK); + const u16 xu =3D ACC_BITS_MASK(ACC_USER_EXEC_MASK); + + if (pfec & PFERR_FETCH_MASK) { + /* Ignore XU unless MBEC is enabled. */ + if (cr4_smep) + ff =3D pfec & PFERR_USER_MASK ? (u16)~xu : (u16)~xs; + else + ff =3D (u16)~xs; + } } else { + const u16 x =3D ACC_BITS_MASK(ACC_EXEC_MASK); const u16 u =3D ACC_BITS_MASK(ACC_USER_MASK); =20 /* Faults from kernel mode accesses to user pages */ diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index f5f9e745f21d..7d7c617885fa 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -124,12 +124,17 @@ static inline void FNAME(protect_clean_gpte)(struct k= vm_mmu *mmu, unsigned *acce *access &=3D mask; } =20 -static inline int FNAME(is_present_gpte)(unsigned long pte) +static inline int FNAME(is_present_gpte)(struct kvm_mmu *mmu, + unsigned long pte) { #if PTTYPE !=3D PTTYPE_EPT return pte & PT_PRESENT_MASK; #else - return pte & 7; + /* + * For EPT, an entry is present if any of bits 2:0 are set. + * With mode-based execute control, bit 10 also indicates presence. + */ + return pte & (7 | (mmu_has_mbec(mmu) ? VMX_EPT_USER_EXECUTABLE_MASK : 0)); #endif } =20 @@ -152,7 +157,7 @@ static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcp= u *vcpu, struct kvm_mmu_page *sp, u64 *spte, u64 gpte) { - if (!FNAME(is_present_gpte)(gpte)) + if (!FNAME(is_present_gpte)(vcpu->arch.mmu, gpte)) goto no_present; =20 /* Prefetch only accessed entries (unless A/D bits are disabled). */ @@ -173,10 +178,17 @@ static bool FNAME(prefetch_invalid_gpte)(struct kvm_v= cpu *vcpu, static inline unsigned FNAME(gpte_access)(u64 gpte) { unsigned access; + /* + * Set bits in ACC_*_MASK even if they might not be used in the + * actual checks. For example, if EFER.NX is clear permission_fault() + * will ignore ACC_EXEC_MASK, and if MBEC is disabled it will + * ignore ACC_USER_EXEC_MASK. + */ #if PTTYPE =3D=3D PTTYPE_EPT access =3D ((gpte & VMX_EPT_WRITABLE_MASK) ? ACC_WRITE_MASK : 0) | ((gpte & VMX_EPT_EXECUTABLE_MASK) ? ACC_EXEC_MASK : 0) | - ((gpte & VMX_EPT_READABLE_MASK) ? ACC_READ_MASK : 0); + ((gpte & VMX_EPT_READABLE_MASK) ? ACC_READ_MASK : 0) | + ((gpte & VMX_EPT_USER_EXECUTABLE_MASK) ? ACC_USER_EXEC_MASK : 0); #else /* * P is set here, so the page is always readable and W/U/!NX represent @@ -331,7 +343,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, if (walker->level =3D=3D PT32E_ROOT_LEVEL) { pte =3D mmu->get_pdptr(vcpu, (addr >> 30) & 3); trace_kvm_mmu_paging_element(pte, walker->level); - if (!FNAME(is_present_gpte)(pte)) + if (!FNAME(is_present_gpte)(mmu, pte)) goto error; --walker->level; } @@ -414,7 +426,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, */ pte_access =3D pt_access & (pte ^ walk_nx_mask); =20 - if (unlikely(!FNAME(is_present_gpte)(pte))) + if (unlikely(!FNAME(is_present_gpte)(mmu, pte))) goto error; =20 if (unlikely(FNAME(is_rsvd_bits_set)(mmu, pte, walker->level))) { @@ -521,6 +533,9 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, * ACC_*_MASK flags! */ walker->fault.exit_qualification |=3D EPT_VIOLATION_RWX_TO_PROT(pte_acce= ss); + if (mmu_has_mbec(mmu)) + walker->fault.exit_qualification |=3D + EPT_VIOLATION_USER_EXEC_TO_PROT(pte_access); } #endif walker->fault.address =3D addr; diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index f5261d993eac..fe9571837fee 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -395,6 +395,8 @@ static inline bool __is_rsvd_bits_set(struct rsvd_bits_= validate *rsvd_check, static inline bool __is_bad_mt_xwr(struct rsvd_bits_validate *rsvd_check, u64 pte) { + if (pte & VMX_EPT_USER_EXECUTABLE_MASK) + pte |=3D VMX_EPT_EXECUTABLE_MASK; return rsvd_check->bad_mt_xwr & BIT_ULL(pte & 0x3f); } =20 diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index e0ef2cb8f2cd..925dfa7f54df 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -7450,6 +7450,15 @@ static gpa_t vmx_translate_nested_gpa(struct kvm_vcp= u *vcpu, gpa_t gpa, struct kvm_mmu *mmu =3D vcpu->arch.mmu; =20 BUG_ON(!mmu_is_nested(vcpu)); + + /* + * MBEC differentiates based on the effective U/S bit of + * the guest page tables; not the processor CPL. + */ + access &=3D ~PFERR_USER_MASK; + if ((pte_access & ACC_USER_MASK) && (access & PFERR_GUEST_FINAL_MASK)) + access |=3D PFERR_USER_MASK; + return mmu->gva_to_gpa(vcpu, mmu, gpa, access, exception); } =20 --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 2AD523DD51F for ; Wed, 8 Apr 2026 15:42:45 +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=1775662969; cv=none; b=Y+HTMs9cm0BS2Hch/i9qFQAvHdVyMWiWO/TVhqXtp+82WDmfG9+ljQ51bP4UZ94jKWYvbMXBr7DwX34gMKiW5SVAB5IGtTdRovK8m9x2agxHjnuvZ0YcUsugmgr99qNE2+IxBsvZa2RlGmC3uynd7tA+CQ5myxQ7rD6ElpaUnnI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662969; c=relaxed/simple; bh=BMiY9SiICmWSoHzZVLcNnq8HoiYaPMGBivIEdIwdKrI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NpG+7jlgOZOuQK+PIgrHjzpiNA5LFYLi/8KsAPwLOfPuXzaCgGFCGxCQImAqhdkmIUvhinTRWFNYIFw20s9Oru66+u6fcRbPiLAPRa62zS5DcPjo5vJDhX4MZzXlRlwkIz7oazPRAJx8wwt17QvseHj9Mr5hO0ncDh5dsXlxwMc= 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=KBXpB2UZ; 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="KBXpB2UZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662965; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+yvyFVMIPBwVIFiykHWuVesiCmwNgYaaVARbhRufRic=; b=KBXpB2UZxGKPZqwFY2nn2aEDAueYbz7OfCgpgJ1GvJFFhTCMyGvJyC2PRChPflRggRWCvv T4xNN+gzEby4RMewr/3b5Evek8/30gp4O+CNwy7h3Xlcp0tY+KI16Kk4jRL9wwCFu5KB0V EbSrlj0SkRnlIc/6w3SqwYzwdJSjCjY= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-689-uEkhpNdtMaKajM5X1QU0iQ-1; Wed, 08 Apr 2026 11:42:42 -0400 X-MC-Unique: uEkhpNdtMaKajM5X1QU0iQ-1 X-Mimecast-MFC-AGG-ID: uEkhpNdtMaKajM5X1QU0iQ_1775662958 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 682D0180034E; Wed, 8 Apr 2026 15:42:38 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 850C319560A6; Wed, 8 Apr 2026 15:42:37 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 19/27] KVM: nVMX: advertise MBEC to nested guests Date: Wed, 8 Apr 2026 11:42:09 -0400 Message-ID: <20260408154217.458420-20-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" From: Jon Kohler Advertise SECONDARY_EXEC_MODE_BASED_EPT_EXEC (MBEC) to userspace, which allows userspace to expose and advertise the feature to the guest. When MBEC is enabled by the guest, it is passed to the MMU via cr4_smep, and to the processor by the merging of vmcs12->secondary_vm_exec_control into the VMCS02's secondary VM execution controls. Signed-off-by: Jon Kohler Message-ID: <20251223054806.1611168-9-jon@nutanix.com> Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu.h | 2 +- arch/x86/kvm/mmu/mmu.c | 7 ++++--- arch/x86/kvm/vmx/nested.c | 11 +++++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index d15f908d048f..9031f7ef8e4e 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -100,7 +100,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, uns= igned long cr0, unsigned long cr4, u64 efer, gpa_t nested_cr3); void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly, int huge_page_level, bool accessed_dirty, - gpa_t new_eptp); + bool mbec, gpa_t new_eptp); bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu); int kvm_handle_page_fault(struct kvm_vcpu *vcpu, u64 error_code, u64 fault_address, char *insn, int insn_len); diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 07bdc8f9b0cb..3ecc571a1de0 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5944,7 +5944,7 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_init_shadow_npt_mm= u); =20 static union kvm_cpu_role kvm_calc_shadow_ept_root_page_role(struct kvm_vcpu *vcpu, bool accessed_di= rty, - bool execonly, u8 level) + bool execonly, u8 level, bool mbec) { union kvm_cpu_role role =3D {0}; =20 @@ -5954,6 +5954,7 @@ kvm_calc_shadow_ept_root_page_role(struct kvm_vcpu *v= cpu, bool accessed_dirty, */ WARN_ON_ONCE(is_smm(vcpu)); role.base.level =3D level; + role.base.cr4_smep =3D mbec; role.base.has_4_byte_gpte =3D false; role.base.direct =3D false; role.base.ad_disabled =3D !accessed_dirty; @@ -5969,13 +5970,13 @@ kvm_calc_shadow_ept_root_page_role(struct kvm_vcpu = *vcpu, bool accessed_dirty, =20 void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly, int huge_page_level, bool accessed_dirty, - gpa_t new_eptp) + bool mbec, gpa_t new_eptp) { struct kvm_mmu *context =3D &vcpu->arch.guest_mmu; u8 level =3D vmx_eptp_page_walk_level(new_eptp); union kvm_cpu_role new_mode =3D kvm_calc_shadow_ept_root_page_role(vcpu, accessed_dirty, - execonly, level); + execonly, level, mbec); =20 if (new_mode.as_u64 !=3D context->cpu_role.as_u64) { /* EPT, and thus nested EPT, does not consume CR0, CR4, nor EFER. */ diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 925dfa7f54df..564165262073 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -469,6 +469,13 @@ static void nested_ept_inject_page_fault(struct kvm_vc= pu *vcpu, vmcs12->guest_physical_address =3D fault->address; } =20 +static inline bool nested_ept_mbec_enabled(struct kvm_vcpu *vcpu) +{ + struct vmcs12 *vmcs12 =3D get_vmcs12(vcpu); + + return nested_cpu_has2(vmcs12, SECONDARY_EXEC_MODE_BASED_EPT_EXEC); +} + static void nested_ept_new_eptp(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx =3D to_vmx(vcpu); @@ -477,6 +484,7 @@ static void nested_ept_new_eptp(struct kvm_vcpu *vcpu) =20 kvm_init_shadow_ept_mmu(vcpu, execonly, ept_lpage_level, nested_ept_ad_enabled(vcpu), + nested_ept_mbec_enabled(vcpu), nested_ept_get_eptp(vcpu)); } =20 @@ -7255,6 +7263,9 @@ static void nested_vmx_setup_secondary_ctls(u32 ept_c= aps, msrs->ept_caps |=3D VMX_EPT_AD_BIT; } =20 + if (enable_mbec) + msrs->secondary_ctls_high |=3D + SECONDARY_EXEC_MODE_BASED_EPT_EXEC; /* * Advertise EPTP switching irrespective of hardware support, * KVM emulates it in software so long as VMFUNC is supported. --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 5CD703DD513 for ; Wed, 8 Apr 2026 15:42:45 +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=1775662967; cv=none; b=B3hT4uVxmUjnKhVB+zAgCzseBQ4S7KBA51ESB3rdiYWt2lNs3/8Hhgv6wBAu2X4v8+6NK4ERz8zxvwG2jc2pp2cZu4Mo0Pqj5iZ6/I5LBfdtOEsGXxIZ/CkzXtnMw014EI93fxJp6t9x/yXVrLOHpCtW9NZE1X882hweJ7HaJyc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662967; c=relaxed/simple; bh=ZC6NCvnfM7WpBsDvG2b0UXeZTe7aYsSUmPg1AtwNUgo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hfGwQw/dgFgJF6p7WBJ0OALP7+7BpzPV8GGBobK6edPO0b9QKjq1UtiexCmhu8u4TAovtc7f4L+ztlv3aAmB/axOPaDA7qFkdk83SUPdug6xa4ujWFwqAAoKJzrpbSaL4w6+lgAai1+qp35MoC1l/X0OgA2JrQ/e4R2fpk2cB8U= 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=Y9NPh1hF; 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="Y9NPh1hF" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662964; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7JkpVhW/sTdXQFvSvpTCG+JUTud5ztAXKsP5roiWk5Y=; b=Y9NPh1hFEYa12m0tt0JkEcU400DLDcs6GLnPbm1mM1ZsWW0xRWJe1+d8nh6Pp3g0LT6mw9 670Bj9pCftHNRUYAFujy/jevuzMdO07NduBwuK+2kQOqa54nZ7X9Gp3w3taNaK3qX2je2I bzoY/HYOhNBkKg9s6P0DLiMI6k/KU38= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-99-w2Gtgh6-NZiQYMG6lisMrw-1; Wed, 08 Apr 2026 11:42:41 -0400 X-MC-Unique: w2Gtgh6-NZiQYMG6lisMrw-1 X-Mimecast-MFC-AGG-ID: w2Gtgh6-NZiQYMG6lisMrw_1775662959 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C3F4E1800620; Wed, 8 Apr 2026 15:42:39 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EEC9A300019F; Wed, 8 Apr 2026 15:42:38 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 20/27] KVM: nVMX: allow MBEC with EVMCS Date: Wed, 8 Apr 2026 11:42:10 -0400 Message-ID: <20260408154217.458420-21-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" From: Jon Kohler Extend EVMCS1_SUPPORTED_2NDEXEC to allow MBEC and EVMCS to coexist. Presenting both EVMCS and MBEC simultaneously causes KVM to filter out MBEC and not present it as a supported control to the guest, preventing performance gains from MBEC when Windows HVCI is enabled. The guest may choose not to use MBEC (e.g., if the admin does not enable Windows HVCI / Memory Integrity), but if they use traditional nested virt (Hyper-V, WSL2, etc.), having EVMCS exposed is important for improving nested guest performance. IOW allowing MBEC and EVMCS to coexist provides maximum optionality to Windows users without overcomplicating VM administration. Signed-off-by: Jon Kohler Message-ID: <20251223054806.1611168-8-jon@nutanix.com> Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/vmx/hyperv_evmcs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/vmx/hyperv_evmcs.h b/arch/x86/kvm/vmx/hyperv_evmc= s.h index fc7c4e7bd1bf..bc08fe40590e 100644 --- a/arch/x86/kvm/vmx/hyperv_evmcs.h +++ b/arch/x86/kvm/vmx/hyperv_evmcs.h @@ -87,6 +87,7 @@ SECONDARY_EXEC_PT_CONCEAL_VMX | \ SECONDARY_EXEC_BUS_LOCK_DETECTION | \ SECONDARY_EXEC_NOTIFY_VM_EXITING | \ + SECONDARY_EXEC_MODE_BASED_EPT_EXEC | \ SECONDARY_EXEC_ENCLS_EXITING) =20 #define EVMCS1_SUPPORTED_3RDEXEC (0ULL) --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 EA3463DDDAE for ; Wed, 8 Apr 2026 15:42:47 +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=1775662970; cv=none; b=dNRAlsBiE8FEMu7YixbqhP8TmF9MX3OfU7qTh0z4xCQ7pdU3LqGwbqrMr8z1h6EicgMZjiRhpQucGOjx54de7S9OYl/48sTE8s4H5HEoFFdPseagXVCDCL9FRGtBDEU2UPRLy1Tec6TQYYMkIfIjTOpJCOv5vqYu6go7n2rE3aU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662970; c=relaxed/simple; bh=JVCAcwJQQN4bQ6fP3Y2WluN95G+sotLsTGjHahOAE7M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JJHN1DDrUNBfoBUBiYRHeZ/ErW0JvhWBTurrts1GirttmnlsRs8iWfHTiMZ+lmhXXOf++g5lflGriQGXWuD+6I+Qs/fwKagi8RLT+cW68IL30rOYUKvbp/gVJWI3MciSr1Tqcii2cqPxWBINzFF+de+fg3DY2r8prtD99juWkS4= 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=IhIfRH3d; 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="IhIfRH3d" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662967; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1HfZFcQZChj41h3Tp2pq4sA5RxV8tgAmfI8S3vj9zYk=; b=IhIfRH3di8uT712gnmrx9asIZot5i0aVCznY/4fH8R5oLxjad0wn1h2RSIMhYKUfgjdcJf b21jfy9zU9jceVDLt9SO2bjT1fAn0SpeUcKIDk/GMHLilrnczq9eHAnMXy00d9zGHwdcBC wBYQ2KnEpjEqhe6TRp4bSM6djHDvaUY= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-175-d7F4wT2wN3OFgiPZ0sKNfQ-1; Wed, 08 Apr 2026 11:42:43 -0400 X-MC-Unique: d7F4wT2wN3OFgiPZ0sKNfQ-1 X-Mimecast-MFC-AGG-ID: d7F4wT2wN3OFgiPZ0sKNfQ_1775662960 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C078D18002D7; Wed, 8 Apr 2026 15:42:40 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EA74A300019F; Wed, 8 Apr 2026 15:42:39 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 21/27] KVM: x86/mmu: propagate access mask from root pages down Date: Wed, 8 Apr 2026 11:42:11 -0400 Message-ID: <20260408154217.458420-22-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" Until now, all SPTEs have had all kinds of access allowed; however, for GMET to be enabled all the pages have to have ACC_USER_MASK disabled. By marking them as supervisor pages, the processor allows execution from either user or supervisor mode (unlike for normal paging, NPT ignores the U bit for reads and writes). That will mean that the root page's role has ACC_USER_MASK cleared and that has to be propagated down through the kvm_mmu_page tree. Do that, and pass the required access to the kvm_mmu_spte_requested tracepoint since it's not ACC_ALL anymore. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/mmu.c | 9 +++++---- arch/x86/kvm/mmu/mmutrace.h | 10 ++++++---- arch/x86/kvm/mmu/paging_tmpl.h | 2 +- arch/x86/kvm/mmu/tdp_mmu.c | 6 +++--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 3ecc571a1de0..4374784f1154 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3437,12 +3437,13 @@ static int direct_map(struct kvm_vcpu *vcpu, struct= kvm_page_fault *fault) { struct kvm_shadow_walk_iterator it; struct kvm_mmu_page *sp; - int ret; + int ret, access; gfn_t base_gfn =3D fault->gfn; =20 kvm_mmu_hugepage_adjust(vcpu, fault); =20 - trace_kvm_mmu_spte_requested(fault); + access =3D vcpu->arch.mmu->root_role.access; + trace_kvm_mmu_spte_requested(fault, access); for_each_shadow_entry(vcpu, fault->addr, it) { /* * We cannot overwrite existing page tables with an NX @@ -3455,7 +3456,7 @@ static int direct_map(struct kvm_vcpu *vcpu, struct k= vm_page_fault *fault) if (it.level =3D=3D fault->goal_level) break; =20 - sp =3D kvm_mmu_get_child_sp(vcpu, it.sptep, base_gfn, true, ACC_ALL); + sp =3D kvm_mmu_get_child_sp(vcpu, it.sptep, base_gfn, true, access); if (sp =3D=3D ERR_PTR(-EEXIST)) continue; =20 @@ -3468,7 +3469,7 @@ static int direct_map(struct kvm_vcpu *vcpu, struct k= vm_page_fault *fault) if (WARN_ON_ONCE(it.level !=3D fault->goal_level)) return -EFAULT; =20 - ret =3D mmu_set_spte(vcpu, fault->slot, it.sptep, ACC_ALL, + ret =3D mmu_set_spte(vcpu, fault->slot, it.sptep, access, base_gfn, fault->pfn, fault); if (ret =3D=3D RET_PF_SPURIOUS) return ret; diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h index 3429c1413f42..fa01719baf8d 100644 --- a/arch/x86/kvm/mmu/mmutrace.h +++ b/arch/x86/kvm/mmu/mmutrace.h @@ -373,23 +373,25 @@ TRACE_EVENT( =20 TRACE_EVENT( kvm_mmu_spte_requested, - TP_PROTO(struct kvm_page_fault *fault), - TP_ARGS(fault), + TP_PROTO(struct kvm_page_fault *fault, u8 access), + TP_ARGS(fault, access), =20 TP_STRUCT__entry( __field(u64, gfn) __field(u64, pfn) __field(u8, level) + __field(u8, access) ), =20 TP_fast_assign( __entry->gfn =3D fault->gfn; __entry->pfn =3D fault->pfn | (fault->gfn & (KVM_PAGES_PER_HPAGE(fault->= goal_level) - 1)); __entry->level =3D fault->goal_level; + __entry->access =3D access; ), =20 - TP_printk("gfn %llx pfn %llx level %d", - __entry->gfn, __entry->pfn, __entry->level + TP_printk("gfn %llx pfn %llx level %d access %x", + __entry->gfn, __entry->pfn, __entry->level, __entry->access ) ); =20 diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 7d7c617885fa..9ad2b05a0f44 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -734,7 +734,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct k= vm_page_fault *fault, */ kvm_mmu_hugepage_adjust(vcpu, fault); =20 - trace_kvm_mmu_spte_requested(fault); + trace_kvm_mmu_spte_requested(fault, gw->pte_access); =20 for (; shadow_walk_okay(&it); shadow_walk_next(&it)) { /* diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 9c26038f6b77..25e557de99d6 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1185,9 +1185,9 @@ static int tdp_mmu_map_handle_target_level(struct kvm= _vcpu *vcpu, } =20 if (unlikely(!fault->slot)) - new_spte =3D make_mmio_spte(vcpu, iter->gfn, ACC_ALL); + new_spte =3D make_mmio_spte(vcpu, iter->gfn, sp->role.access); else - wrprot =3D make_spte(vcpu, sp, fault->slot, ACC_ALL, iter->gfn, + wrprot =3D make_spte(vcpu, sp, fault->slot, sp->role.access, iter->gfn, fault->pfn, iter->old_spte, fault->prefetch, false, fault->map_writable, &new_spte); =20 @@ -1272,7 +1272,7 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm= _page_fault *fault) =20 kvm_mmu_hugepage_adjust(vcpu, fault); =20 - trace_kvm_mmu_spte_requested(fault); + trace_kvm_mmu_spte_requested(fault, root->role.access); =20 rcu_read_lock(); =20 --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 9E6723DDDA6 for ; Wed, 8 Apr 2026 15:42:47 +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=1775662970; cv=none; b=t68VyGdiNaYjjmVi+Kr0EbPDQLt5ie6GDihQCBVG0nIwcmVOmElz6iwEMhHMSh7Z2kMNfP6nckY9LPK2eL5W1698IleHF7wv8yoiXKBBl9qyegtXLnsWzvrEIx+OeMwsdiBq5o+On7BiLxEOizKD8wbc3gufbrir/XchKLKzsaU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662970; c=relaxed/simple; bh=hcs/cCShvVSFWUEielIenwF1plhGW01uLgpk5qBMrAA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Eo5GPf3g6sk6wDr4BpxEndWcQn4/NZ74HC/Icvsx64xIx1/HovFlTe+h87NHN34a3fIdSN8MEBwBeaG2B3YE0mH9jZ//QeCmTNeaWnQkWmXLlOWjA7xXkgYZKWLLQ4yQmhya5IpTrcg55qPll7jvtBccHVPh7Im2KjK8yqSF6wE= 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=IZTYx8TG; 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="IZTYx8TG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662966; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=htdHEzNxZVx0urLlhtk3SLmGjAoqKwgtxTQYw/MvVdE=; b=IZTYx8TGT63/vHi39k7qTwr8fickGKtvJ08HwshRGCRws/lVEM5bdOtYFkeF5veneHTwVJ lka4TXbSOxi4vvh2S7dbEmdffUsxYNXruSqaFFesvEGrsUONLJV0bs/miCYDGj/8VHfbN4 Ogmqw+pEHd0mJUZo+xCdOPoXD4baimw= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-82-LKUr8K8HPfmLjBV1AQbhAQ-1; Wed, 08 Apr 2026 11:42:43 -0400 X-MC-Unique: LKUr8K8HPfmLjBV1AQbhAQ-1 X-Mimecast-MFC-AGG-ID: LKUr8K8HPfmLjBV1AQbhAQ_1775662961 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id BAD1A180035D; Wed, 8 Apr 2026 15:42:41 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E5C783000210; Wed, 8 Apr 2026 15:42:40 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 22/27] KVM: x86/mmu: introduce cpu_role bit for availability of PFEC.I/D Date: Wed, 8 Apr 2026 11:42:12 -0400 Message-ID: <20260408154217.458420-23-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" While GMET looks a lot like SMEP, it has several annoying differences. The main one is that the availability of the I/D bit in the page fault error code still depends on the host CR4.SMEP and EFER.NXE bits. If the base.cr4_smep bit of the cpu_role is (ab)used to enable GMET, there needs to be another place where the host CR4.SMEP is read from; just merge it with EFER.NXE into a new cpu_role bit that tells paging_tmpl.h whether to set the I/D bit at all. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/include/asm/kvm_host.h | 7 +++++++ arch/x86/kvm/mmu/mmu.c | 8 ++++++++ arch/x86/kvm/mmu/paging_tmpl.h | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 8b4a55cc0918..e20f729f6eb2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -413,6 +413,13 @@ union kvm_mmu_extended_role { unsigned int cr4_smap:1; unsigned int cr4_la57:1; unsigned int efer_lma:1; + + /* + * True if either CR4.SMEP or EFER.NXE are set. For AMD NPT + * this is the "real" host CR4.SMEP whereas cr4_smep is + * actually GMET. + */ + unsigned int has_pferr_fetch:1; }; }; =20 diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 4374784f1154..290537b0f36c 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -234,6 +234,11 @@ BUILD_MMU_ROLE_ACCESSOR(ext, cr4, la57); BUILD_MMU_ROLE_ACCESSOR(base, efer, nx); BUILD_MMU_ROLE_ACCESSOR(ext, efer, lma); =20 +static inline bool has_pferr_fetch(struct kvm_mmu *mmu) +{ + return mmu->cpu_role.ext.has_pferr_fetch; +} + static inline bool is_cr0_pg(struct kvm_mmu *mmu) { return mmu->cpu_role.base.level > 0; @@ -5778,6 +5783,8 @@ static union kvm_cpu_role kvm_calc_cpu_role(struct kv= m_vcpu *vcpu, role.ext.cr4_pke =3D ____is_efer_lma(regs) && ____is_cr4_pke(regs); role.ext.cr4_la57 =3D ____is_efer_lma(regs) && ____is_cr4_la57(regs); role.ext.efer_lma =3D ____is_efer_lma(regs); + + role.ext.has_pferr_fetch =3D role.base.efer_nx | role.base.cr4_smep; return role; } =20 @@ -5931,6 +5938,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, u= nsigned long cr0, =20 /* NPT requires CR0.PG=3D1. */ WARN_ON_ONCE(cpu_role.base.direct || !cpu_role.base.guest_mode); + cpu_role.base.cr4_smep =3D false; =20 root_role =3D cpu_role.base; root_role.level =3D kvm_mmu_get_tdp_level(vcpu); diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 9ad2b05a0f44..ad0e5f43b8ad 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -489,7 +489,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker= *walker, =20 error: errcode |=3D write_fault | user_fault; - if (fetch_fault && (is_efer_nx(mmu) || is_cr4_smep(mmu))) + if (fetch_fault && has_pferr_fetch(mmu)) errcode |=3D PFERR_FETCH_MASK; =20 walker->fault.vector =3D PF_VECTOR; --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 AFD663DCD84 for ; Wed, 8 Apr 2026 15:42: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=1775662971; cv=none; b=deSWNjlMoAE+4OiRaFk4wnLpg03P6OMAgYzUzBZxgcMEatOrh0G6YXGTiIhVIz0ye7lugEqsS2o1PncDIFg02ffndH/sPwZKRbmM4c5a5H1iHzztqXPJX0mr+NpEgjSjZLUE9gKjCEiNYGCojhN2xjqm64nXje7LZFJDWDC50BQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662971; c=relaxed/simple; bh=loYcaHXhbwfkT+ynvn8BmMOZPhoFzSC/PDHxiwVweDQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MS1FTFClDfrn/Nd+ftmDaCsH+F0WoUMQOSmV58UhUIdHbzcmAP2R8OGH+w/yrbVIlPDhWNTjWiorm2NRmcPwOiRj0suJrYSe6KaQLbK3Y6UyKXM3yQXdSkAV/l6k0q0o9jgwbPBSe49VlSCl1pT3EEExG8EiNIw54+5x1DOQrlc= 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=M16/zdNR; 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="M16/zdNR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662968; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VaDJcUGr4YUbHYQecogVrtm7L7GpWha0RMvCGYtANgE=; b=M16/zdNRQX0ZKRyaUT5g6ZPmm4htN/DXkwy7Z2RjJasjlAukR6f8b08HmX4hOG+Ft3peoD DczMsp/zReJ11hy5zpbzWr3NqV1JxABiPyEOp1I0JGomKUtihVMSqBr+qkSvDJJGezwNbx mWEgo20UJckDGn/i2bAnq3N0w+PpvJk= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-684-c61CkDa5M8CdYJDrg3cloA-1; Wed, 08 Apr 2026 11:42:44 -0400 X-MC-Unique: c61CkDa5M8CdYJDrg3cloA-1 X-Mimecast-MFC-AGG-ID: c61CkDa5M8CdYJDrg3cloA_1775662963 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 559CA195608B; Wed, 8 Apr 2026 15:42:43 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E0E83300019F; Wed, 8 Apr 2026 15:42:41 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti , "Borislav Petkov (AMD)" Subject: [PATCH 23/27] KVM: SVM: add GMET bit definitions Date: Wed, 8 Apr 2026 11:42:13 -0400 Message-ID: <20260408154217.458420-24-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" GMET (Guest Mode Execute Trap) is an AMD virtualization feature, essentially the nested paging version of SMEP. Hyper-V uses it; add it in preparation for making it available to hypervisors running under KVM. Acked-by: Borislav Petkov (AMD) Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/svm.h | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpuf= eatures.h index dbe104df339b..9f876fbdcc3a 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -379,6 +379,7 @@ #define X86_FEATURE_AVIC (15*32+13) /* "avic" Virtual Interrupt Controlle= r */ #define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* "v_vmsave_vmload" Virtua= l VMSAVE VMLOAD */ #define X86_FEATURE_VGIF (15*32+16) /* "vgif" Virtual GIF */ +#define X86_FEATURE_GMET (15*32+17) /* Guest Mode Execution Trap */ #define X86_FEATURE_X2AVIC (15*32+18) /* "x2avic" Virtual x2apic */ #define X86_FEATURE_V_SPEC_CTRL (15*32+20) /* "v_spec_ctrl" Virtual SPEC_= CTRL */ #define X86_FEATURE_VNMI (15*32+25) /* "vnmi" Virtual NMI */ diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index edde36097ddc..03e9e0112b10 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -242,6 +242,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define SVM_NESTED_CTL_NP_ENABLE BIT(0) #define SVM_NESTED_CTL_SEV_ENABLE BIT(1) #define SVM_NESTED_CTL_SEV_ES_ENABLE BIT(2) +#define SVM_NESTED_CTL_GMET_ENABLE BIT(3) =20 =20 #define SVM_TSC_RATIO_RSVD 0xffffff0000000000ULL --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 22E343D88F6 for ; Wed, 8 Apr 2026 15:42: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=1775662974; cv=none; b=kJ9HlzjwqEBQ9o2PRxJV4r7o1tXxtY1DXisL/MPOh0xBRDGar7euoRnDhN9yDkz7QPnvfkm1LoTzI2JXbzZhs+9BCb2hZUQBWKAhq/xpfxgXkqZipzReHuSQGlr2OOeXsvFv5uiuapAbORC/g4GbURPQLt+xV2Uy0EfF2Q/DgEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662974; c=relaxed/simple; bh=GdkdUmN2SZOgqFPse1j8klG3cXf2CgXMerkjHlHAHl0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=h0GaP04rgKcf1oFsT9cjbNQs6YO1UysNTJIYibMjCR+4EtOogypmsw7cpH/0pPuQ4S+cnguMMooI7MSUpwqTfN8FyRHif2+sWm4qp+AZc2ChGxCwqx5YlG9bVSKfUqodW+6ekYlOZ/ODVCknrzyz5Q5iXnX7Pa7Touf1+T7pB0s= 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=OJESF66c; 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="OJESF66c" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662972; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=63vtfR1XnXTmtYcQt+S7PbSdNk24tkQ2sDonVo3agFg=; b=OJESF66cL7Xv1aBefZIfzadKt9rStdvbsoTQET/fv+DtOsGPwMPeBn89bPeFvOcRX/skXi 9YFETtFSooJuEHpwDM0IaUQH9sqO5xoOoAFCOQDYRn5aKyU9M14pNpmyHWDdfwkpavR36E 9Xu0ZGnFm1Z9ZpzspoqVhAI5QHTVvUc= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-30-dmYgJcZON4WAIfnXo2nokw-1; Wed, 08 Apr 2026 11:42:47 -0400 X-MC-Unique: dmYgJcZON4WAIfnXo2nokw-1 X-Mimecast-MFC-AGG-ID: dmYgJcZON4WAIfnXo2nokw_1775662965 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id DF8F918002CB; Wed, 8 Apr 2026 15:42:44 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7AD77300019F; Wed, 8 Apr 2026 15:42:43 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 24/27] KVM: x86/mmu: add support for GMET to NPT page table walks Date: Wed, 8 Apr 2026 11:42:14 -0400 Message-ID: <20260408154217.458420-25-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" GMET allows page table entries to be created with U=3D0 in NPT. However, when GMET=3D1 U=3D0 only affects execution, not reads or writes. Ignore user faults on non-fetch accesses for NPT GMET. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/mmu.h | 3 ++- arch/x86/kvm/mmu/mmu.c | 19 +++++++++++++------ arch/x86/kvm/svm/nested.c | 10 +++++++--- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index e20f729f6eb2..99f37fc132ab 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -369,6 +369,8 @@ union kvm_mmu_page_role { * cr4_smep is also set for EPT MBEC. Because it affects * which pages are considered non-present (bit 10 additionally * must be zero if MBEC is on) it has to be in the base role. + * It also has to be in the base role for AMD GMET because + * kernel-executable pages need to have U=3D0 with GMET enabled. */ unsigned cr4_smep:1; =20 diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 9031f7ef8e4e..1677eb0b5588 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -97,7 +97,8 @@ void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_mbe= c); =20 void kvm_init_mmu(struct kvm_vcpu *vcpu); void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, - unsigned long cr4, u64 efer, gpa_t nested_cr3); + unsigned long cr4, u64 efer, gpa_t nested_cr3, + u64 nested_ctl); void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly, int huge_page_level, bool accessed_dirty, bool mbec, gpa_t new_eptp); diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 290537b0f36c..354f8af5d90a 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -55,6 +55,7 @@ #include #include #include +#include #include =20 #include "trace.h" @@ -5557,7 +5558,7 @@ reset_ept_shadow_zero_bits_mask(struct kvm_mmu *conte= xt, bool execonly) (14 & (access) ? 1 << 14 : 0) | \ (15 & (access) ? 1 << 15 : 0)) =20 -static void update_permission_bitmask(struct kvm_mmu *mmu, bool ept) +static void update_permission_bitmask(struct kvm_mmu *mmu, bool tdp, bool = ept) { unsigned byte; =20 @@ -5618,7 +5619,12 @@ static void update_permission_bitmask(struct kvm_mmu= *mmu, bool ept) /* Faults from kernel mode accesses to user pages */ u16 kf =3D (pfec & PFERR_USER_MASK) ? 0 : u; =20 - uf =3D (pfec & PFERR_USER_MASK) ? (u16)~u : 0; + /* + * For NPT GMET, U=3D0 does not affect reads and writes. Fetches + * are handled below via cr4_smep. + */ + if (!(tdp && cr4_smep)) + uf =3D (pfec & PFERR_USER_MASK) ? (u16)~u : 0; =20 if (efer_nx) ff =3D (pfec & PFERR_FETCH_MASK) ? (u16)~x : 0; @@ -5729,7 +5735,7 @@ static void reset_guest_paging_metadata(struct kvm_vc= pu *vcpu, return; =20 reset_guest_rsvds_bits_mask(vcpu, mmu); - update_permission_bitmask(mmu, false); + update_permission_bitmask(mmu, mmu =3D=3D &vcpu->arch.guest_mmu, false); update_pkru_bitmask(mmu); } =20 @@ -5925,7 +5931,8 @@ static void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, } =20 void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, - unsigned long cr4, u64 efer, gpa_t nested_cr3) + unsigned long cr4, u64 efer, gpa_t nested_cr3, + u64 nested_ctl) { struct kvm_mmu *context =3D &vcpu->arch.guest_mmu; struct kvm_mmu_role_regs regs =3D { @@ -5938,7 +5945,7 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, u= nsigned long cr0, =20 /* NPT requires CR0.PG=3D1. */ WARN_ON_ONCE(cpu_role.base.direct || !cpu_role.base.guest_mode); - cpu_role.base.cr4_smep =3D false; + cpu_role.base.cr4_smep =3D (nested_ctl & SVM_NESTED_CTL_GMET_ENABLE) !=3D= 0; =20 root_role =3D cpu_role.base; root_role.level =3D kvm_mmu_get_tdp_level(vcpu); @@ -5996,7 +6003,7 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, b= ool execonly, context->gva_to_gpa =3D ept_gva_to_gpa; context->sync_spte =3D ept_sync_spte; =20 - update_permission_bitmask(context, true); + update_permission_bitmask(context, true, true); context->pkru_mask =3D 0; reset_rsvds_bits_mask_ept(vcpu, context, execonly, huge_page_level); reset_ept_shadow_zero_bits_mask(context, execonly); diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 3b670ee4eb26..a76f2b8cbef9 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -95,7 +95,8 @@ static void nested_svm_init_mmu_context(struct kvm_vcpu *= vcpu) */ kvm_init_shadow_npt_mmu(vcpu, X86_CR0_PG, svm->vmcb01.ptr->save.cr4, svm->vmcb01.ptr->save.efer, - svm->nested.ctl.nested_cr3); + svm->nested.ctl.nested_cr3, + svm->nested.ctl.nested_ctl); vcpu->arch.mmu->get_guest_pgd =3D nested_svm_get_tdp_cr3; vcpu->arch.mmu->get_pdptr =3D nested_svm_get_tdp_pdptr; vcpu->arch.mmu->inject_page_fault =3D nested_svm_inject_npf_exit; @@ -1973,12 +1974,15 @@ static gpa_t svm_translate_nested_gpa(struct kvm_vc= pu *vcpu, gpa_t gpa, struct x86_exception *exception, u64 pte_access) { + struct vcpu_svm *svm =3D to_svm(vcpu); struct kvm_mmu *mmu =3D vcpu->arch.mmu; =20 BUG_ON(!mmu_is_nested(vcpu)); =20 - /* NPT walks are always user-walks */ - access |=3D PFERR_USER_MASK; + /* Non-GMET walks are always user-walks */ + if (!(svm->nested.ctl.nested_ctl & SVM_NESTED_CTL_GMET_ENABLE)) + access |=3D PFERR_USER_MASK; + return mmu->gva_to_gpa(vcpu, mmu, gpa, access, exception); } =20 --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 528093DFC6B for ; Wed, 8 Apr 2026 15:42:51 +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=1775662972; cv=none; b=pWbp8Mkandie+q/g2z5cfVg2sav43fNJvWvVp+tztaw7rPrfqh2z1pa6/hjDzmTQWppDmSzRyn1v6dGt5w5nhRPct2benea2tGuPA+DUmqWJW90/8rf9uZIulH1bIBQAnsNpavP1VenCTXhgIXDHEH3ESK7C+ztKnjXlFvjUe1E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662972; c=relaxed/simple; bh=KwfssTU0csEG8EFIv0YNsoktwPl9amvk7G4CBUf0tMs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Lurzdy6Y1Vrvlld8kwH2fNC/gbZRVa+IAlT0yg0o2jAJ0hcH/JthS0MA4BidFtv6DJ9UQ+dEgDU/LNyXYGRU+nb3I9jWsQR2BtX1PyB+w8UBhHr0zRAhXRoV08g48/mI5RVspxUBIHrwV+eESSomwcV2CoO3i/qwlHFisIftr/g= 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=Bhhc78EZ; 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="Bhhc78EZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662970; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jmv4vG8EdF+XHXSjT5PLH1s8XlJsY5LnBC8HBPikyXc=; b=Bhhc78EZXdpUDCjG6WBAh93Djv1vHB/VmfvQCivnz0iSueI3asUPKEWY3mAo+kXwZ0NzB0 O6Gc2LIH36HBZIKvuUGtI9kCng5Ms9Lb4ne+B9rp+C692QVeDiZPU683ir08uBbqQZBee0 N73k4rY6rLY5U6AzhTa5EHU0lPpljhA= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-48-9PubGUhHO-WN7ZbRXJQg_Q-1; Wed, 08 Apr 2026 11:42:47 -0400 X-MC-Unique: 9PubGUhHO-WN7ZbRXJQg_Q-1 X-Mimecast-MFC-AGG-ID: 9PubGUhHO-WN7ZbRXJQg_Q_1775662966 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id DA85C1956068; Wed, 8 Apr 2026 15:42:45 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 11CBB300019F; Wed, 8 Apr 2026 15:42:44 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 25/27] KVM: SVM: enable GMET and set it in MMU role Date: Wed, 8 Apr 2026 11:42:15 -0400 Message-ID: <20260408154217.458420-26-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" Set the GMET bit in the nested control field. This has effectively no impact as long as NPT page tables are changed to have U=3D0. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/mmu/mmu.c | 6 +++++- arch/x86/kvm/svm/nested.c | 7 +++++-- arch/x86/kvm/svm/svm.c | 16 ++++++++++++++++ arch/x86/kvm/svm/svm.h | 1 + 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 354f8af5d90a..14c0c2da75bb 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5840,7 +5840,6 @@ kvm_calc_tdp_mmu_root_page_role(struct kvm_vcpu *vcpu, { union kvm_mmu_page_role role =3D {0}; =20 - role.access =3D ACC_ALL; role.cr0_wp =3D true; role.cr4_smep =3D kvm_x86_call(tdp_has_smep)(vcpu->kvm); role.efer_nx =3D true; @@ -5851,6 +5850,11 @@ kvm_calc_tdp_mmu_root_page_role(struct kvm_vcpu *vcp= u, role.direct =3D true; role.has_4_byte_gpte =3D false; =20 + /* All TDP pages are supervisor-executable */ + role.access =3D ACC_ALL; + if (role.cr4_smep && shadow_user_mask) + role.access &=3D ~ACC_USER_MASK; + return role; } =20 diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index a76f2b8cbef9..863040ecec0e 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -829,9 +829,12 @@ static void nested_vmcb02_prepare_control(struct vcpu_= svm *svm, /* Also overwritten later if necessary. */ vmcb02->control.tlb_ctl =3D TLB_CONTROL_DO_NOTHING; =20 - /* nested_cr3. */ - if (nested_npt_enabled(svm)) + /* Use vmcb01 MMU and format if guest does not use nNPT */ + if (nested_npt_enabled(svm)) { + vmcb02->control.nested_ctl &=3D ~SVM_NESTED_CTL_GMET_ENABLE; + nested_svm_init_mmu_context(vcpu); + } =20 vcpu->arch.tsc_offset =3D kvm_calc_nested_tsc_offset( vcpu->arch.l1_tsc_offset, diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index e6477affac9a..1705e3cafcb0 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -135,6 +135,9 @@ module_param(pause_filter_count_max, ushort, 0444); bool npt_enabled =3D true; module_param_named(npt, npt_enabled, bool, 0444); =20 +bool gmet_enabled =3D true; +module_param_named(gmet, gmet_enabled, bool, 0444); + /* allow nested virtualization in KVM/SVM */ static int nested =3D true; module_param(nested, int, 0444); @@ -1170,6 +1173,10 @@ static void init_vmcb(struct kvm_vcpu *vcpu, bool in= it_event) save->g_pat =3D vcpu->arch.pat; save->cr3 =3D 0; } + + if (gmet_enabled) + control->nested_ctl |=3D SVM_NESTED_CTL_GMET_ENABLE; + svm->current_vmcb->asid_generation =3D 0; svm->asid =3D 0; =20 @@ -4475,6 +4482,11 @@ svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned = char *hypercall) hypercall[2] =3D 0xd9; } =20 +static bool svm_tdp_has_smep(struct kvm *kvm) +{ + return gmet_enabled; +} + /* * The kvm parameter can be NULL (module initialization, or invocation bef= ore * VM creation). Be sure to check the kvm parameter before using it. @@ -5224,6 +5236,7 @@ struct kvm_x86_ops svm_x86_ops __initdata =3D { .write_tsc_multiplier =3D svm_write_tsc_multiplier, =20 .load_mmu_pgd =3D svm_load_mmu_pgd, + .tdp_has_smep =3D svm_tdp_has_smep, =20 .check_intercept =3D svm_check_intercept, .handle_exit_irqoff =3D svm_handle_exit_irqoff, @@ -5464,6 +5477,9 @@ static __init int svm_hardware_setup(void) if (!boot_cpu_has(X86_FEATURE_NPT)) npt_enabled =3D false; =20 + if (!npt_enabled || !boot_cpu_has(X86_FEATURE_GMET)) + gmet_enabled =3D false; + /* Force VM NPT level equal to the host's paging level */ kvm_configure_mmu(npt_enabled, get_npt_level(), get_npt_level(), PG_LEVEL_1G); diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 6942e6b0eda6..41042379aa48 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -44,6 +44,7 @@ static inline struct page *__sme_pa_to_page(unsigned long= pa) #define IOPM_SIZE PAGE_SIZE * 3 #define MSRPM_SIZE PAGE_SIZE * 2 =20 +extern bool gmet_enabled; extern bool npt_enabled; extern int nrips; extern int vgif; --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 E86F13E121D for ; Wed, 8 Apr 2026 15:42:54 +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=1775662976; cv=none; b=WS0h+j4UzNSUM+iClIP/XH1q01ckvkAwhkcU9DCQdU73M+N7mEh9gx6afRWu98wRREt2I5zMwbHCFZXfzvqhYgQYJjWp55NZcHMY+zGyiDp03D/EHFA4P41FT3paLiAqB4WDGJ7DdP632FI1Biph+ldMeWxj7aM3sVb0PFaSr5c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662976; c=relaxed/simple; bh=yaea5/Ax4J38w1GFSJYJk465b/D+AB/xugPnx6/Ot1Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=F8o6dC08C/IQ9rwZR9llbMGQlco1XYCzLSmkPvfPJrt6df47K6ZGhHhnyPZDDH8ypzlk4UEqnbIUXCQxNlGwcEGQmIF9QYdIFsTcZSGO4EhdJ3/TjK3I6T+42MW2jlChfWCmy+coZvcl/oFMBDJX7QzOHcbavO07oDOoiWAUYm8= 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=FWH5CI3M; 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="FWH5CI3M" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662973; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0/7RM8AJFwrUCGR19kMuWKotXnXj9XWHFEGzBSeVvwc=; b=FWH5CI3MkvcArEbbCI/WlR8oXIdFWTTfrz/lLgJoZP9bZbNQaaSIDdGe3lK8fVw3qHnfdc uXeJgpqaHTAHeUbQvoG1ic7ZjA7mhjn80CEoDBwFeWP+woywYygxwKx0BL8hnU2MrvcEBc PHMU+Azn9l93kkPAOb3YnznTIfupuY0= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-367-FFCPhIw1N7K8uTsLKMPmEg-1; Wed, 08 Apr 2026 11:42:48 -0400 X-MC-Unique: FFCPhIw1N7K8uTsLKMPmEg-1 X-Mimecast-MFC-AGG-ID: FFCPhIw1N7K8uTsLKMPmEg_1775662967 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D6E941956065; Wed, 8 Apr 2026 15:42:46 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0D4EF300019F; Wed, 8 Apr 2026 15:42:45 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 26/27] KVM: SVM: work around errata 1218 Date: Wed, 8 Apr 2026 11:42:16 -0400 Message-ID: <20260408154217.458420-27-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" According to AMD, the hypervisor may not be able to determine whether a fault was a GMET fault or an NX fault based on EXITINFO1, and software "must read the relevant VMCB to determine whether a fault was a GMET fault or an NX fault". The APM further details that they meant the CPL field. KVM uses the page fault error code to distinguish the causes of a nested page fault, so recalculate the PFERR_USER_MASK bit of the vmexit information. Only do it for fetches and only if GMET is in use, because KVM does not differentiate based on PFERR_USER_MASK for other nested NPT page faults. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/svm/svm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 1705e3cafcb0..4957fa36890c 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1957,6 +1957,17 @@ static int npf_interception(struct kvm_vcpu *vcpu) } } =20 + if ((svm->vmcb->control.nested_ctl & SVM_NESTED_CTL_GMET_ENABLE) && + (error_code & PFERR_FETCH_MASK)) { + /* + * Work around errata 1218: EXITINFO1[2] May Be Incorrectly Set + * When GMET (Guest Mode Execute Trap extension) is Enabled + */ + error_code |=3D PFERR_USER_MASK; + if (svm_get_cpl(vcpu) !=3D 3) + error_code &=3D ~PFERR_USER_MASK; + } + if (sev_snp_guest(vcpu->kvm) && (error_code & PFERR_GUEST_ENC_MASK)) error_code |=3D PFERR_PRIVATE_ACCESS; =20 --=20 2.52.0 From nobody Mon Jun 15 06:29:31 2026 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 4AE303E1CF5 for ; Wed, 8 Apr 2026 15:42:56 +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=1775662977; cv=none; b=ue1aMe4wXEOnKsYSLsaqhXffQ2P/e6fPGyX8pLkf2R4gWJPsnikwsKEBOR6MO6ZRB+oCSaAtYm9hcSIcDCSJIlUDuwqfQneBNiRWxQfFIB/u52fBmU4v8UlKcX9LLR/OFcH7RWu4sx0ctI+aciwC3HQH1VRWgZVCB2VvNZmQUVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775662977; c=relaxed/simple; bh=ZsDJpj7MSSebIDfPfyhxOzylV0M1CI6/K0n6Hjt9nKQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=c5w2LCjBhnNz7Kh1h8p+k0yzxMzW5tdXR8g16Qh1J4jjYdT4CpT45nmiTrkADr/r+ED9uMbr7Nw1iV5Q2ivZKCQFq3theExAzMlSLXAfJs6II5mxz+1d25lXuuWignB/Sd6Afhy+DY6xcSZPEO+bWpXRndS8nIl0ggEvwJx0w10= 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=RihQV1+0; 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="RihQV1+0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775662975; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Xv7ZOujT48/Fy6/YhH8RYKG7tAQtoFH4Ofc00619ouo=; b=RihQV1+0qitju6PyyiAM/rTHylI4IC/qIdJWfxE2LPESm3XbHp1ABpCvF6QyvffTHP3pp4 6EFC9j0F8GSLSkL2AMjAABhr+N2R+fh4jnVeaIU+5s5b8VJiNzkl/sOYmYf997/J9TZkCf Dd/mJcXZNvlrckqc1M/zhHuvmry52nQ= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-479-vKJ__5ZZP0eJWUc6tkdTkQ-1; Wed, 08 Apr 2026 11:42:50 -0400 X-MC-Unique: vKJ__5ZZP0eJWUc6tkdTkQ-1 X-Mimecast-MFC-AGG-ID: vKJ__5ZZP0eJWUc6tkdTkQ_1775662967 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D178E1955F56; Wed, 8 Apr 2026 15:42:47 +0000 (UTC) Received: from virtlab1023.lab.eng.rdu2.redhat.lab.eng.rdu2.redhat.com (virtlab1023.lab.eng.rdu2.redhat.com [10.8.1.187]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 08CF5300019F; Wed, 8 Apr 2026 15:42:46 +0000 (UTC) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Jon Kohler , Nikunj A Dadhania , Amit Shah , Sean Christopherson , Marcelo Tosatti Subject: [PATCH 27/27] KVM: nSVM: enable GMET for guests Date: Wed, 8 Apr 2026 11:42:17 -0400 Message-ID: <20260408154217.458420-28-pbonzini@redhat.com> In-Reply-To: <20260408154217.458420-1-pbonzini@redhat.com> References: <20260408154217.458420-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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" All that needs to be done is moving the GMET bit from vmcs12 to vmcs02. The only new thing is that __nested_svm_check_controls now ensures that ignored-if-unavailable bits are zero in svm->nested.ctl. Signed-off-by: Paolo Bonzini Tested-by: David Riley --- arch/x86/kvm/svm/nested.c | 5 +++++ arch/x86/kvm/svm/svm.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 863040ecec0e..3c45adb70946 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -470,7 +470,11 @@ void __nested_copy_vmcb_control_to_cache(struct kvm_vc= pu *vcpu, to->exit_info_2 =3D from->exit_info_2; to->exit_int_info =3D from->exit_int_info; to->exit_int_info_err =3D from->exit_int_info_err; + to->nested_ctl =3D from->nested_ctl; + if (!gmet_enabled || !guest_cpu_cap_has(vcpu, X86_FEATURE_GMET)) + to->nested_ctl &=3D ~SVM_NESTED_CTL_GMET_ENABLE; + to->event_inj =3D from->event_inj; to->event_inj_err =3D from->event_inj_err; to->next_rip =3D from->next_rip; @@ -832,6 +836,7 @@ static void nested_vmcb02_prepare_control(struct vcpu_s= vm *svm, /* Use vmcb01 MMU and format if guest does not use nNPT */ if (nested_npt_enabled(svm)) { vmcb02->control.nested_ctl &=3D ~SVM_NESTED_CTL_GMET_ENABLE; + vmcb02->control.nested_ctl |=3D (svm->nested.ctl.nested_ctl & SVM_NESTED= _CTL_GMET_ENABLE); =20 nested_svm_init_mmu_context(vcpu); } diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 4957fa36890c..55baaf833e63 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -5372,6 +5372,9 @@ static __init void svm_set_cpu_caps(void) if (boot_cpu_has(X86_FEATURE_PFTHRESHOLD)) kvm_cpu_cap_set(X86_FEATURE_PFTHRESHOLD); =20 + if (gmet_enabled) + kvm_cpu_cap_set(X86_FEATURE_GMET); + if (vgif) kvm_cpu_cap_set(X86_FEATURE_VGIF); =20 --=20 2.52.0