From nobody Sun Feb 8 10:04:37 2026 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C16C1332ECB for ; Thu, 5 Feb 2026 21:43:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327819; cv=none; b=rTGRG07mATR9tJJUiIz1v5gZ1/baTBHFpi0GyaupgREF0QTN6fawOh0NreozwulUuVZskFp+4/Nn87130whHG7vnU9wYBsR6ZOZg+3pu+CujpUarp4mH/+dSOKqFv1OBtHQxfMoh9HhHULyK6lIAIlrYzAu8g4Dak2LkIxlfrDI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327819; c=relaxed/simple; bh=t1FZ6K9ff28bBOACRhPauD3zpbu3dX1mvB0UDejh2tQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=aa986Jw6rG1nM7BxsLUOoM1RpfO6IPjylKFLN2uf1kMI7wtXW/+co1A350imZoEupx3lUevoYBQKt18ha6SglOPRV02QFRHzJAikQub7PCHZuGEGVNxcEbqQbQ6bKdmwpGU7VmuY86dr7USa956dugVF9xQNljBNVvRIqgjm8b0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=1Z287AkG; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="1Z287AkG" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-34c38781efcso1296872a91.2 for ; Thu, 05 Feb 2026 13:43:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770327819; x=1770932619; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=e7mnOr8u/WACBhY+jlevmvNnx0GAYmKuXG5gmX/ekFE=; b=1Z287AkGgGNbX+gUUETm5ThLj4gN9fZrIVmciDtcRGJ7qr1zKYRnggvEad3U6eKpQg 269Kx/rW4UYRIXzIg1URpUfWn3zYRm2vPPcEyP/b38dJ2lNq0VDY2AJmb12rBubu82hQ C5HiV3VGwrnpcvfK/9qgcTpMzqJ5Z4NB98cx+FjyIUTmX0yPbAnhND5IQT7JY3vN7YBI wl74uh2ns0SSEPkn/nNBqKkOxiadgHLTK4oBors/75mv7nEOY0YT7C5ItipwWiV3VqmC LBTzyYfB1o7mQ5mm2A8d2JItbHI4yXDnZ/9I5g95qEyB1FmaE1IWvfjVDHn5j3CAmtsM BAhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770327819; x=1770932619; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=e7mnOr8u/WACBhY+jlevmvNnx0GAYmKuXG5gmX/ekFE=; b=bcs/sl/aUSBUyb/4fiaY2VVh6xeABnx/fZL5E1GNexTeCUmEsxVswgADS+XPSbdoID tXvkJDRAOOC3RgjsIBjY3Ga0Q5Xh6QRIcF5pJfXaHhrZK16sZ8aQGgxifi5FBhKbHlsz gGQwl+tAPXeYCSwnEL9mGHYuPWmt5YGzUboyRFjTuPR9kYRSwLxvgOferCmqJFucmxei gzpdgZsDK21teV8Ko77YbdZf99/nLV4tpLh7EBSiklhYCXLkdZwIT+NfwHjGBQ3nIL1Y VkckDGtk32DPQQlUN9I4XCDTD9gfOrarAoXpFRpT9I/B0z8PKwtWwcsmf/S6WuNaGuLI xOzQ== X-Forwarded-Encrypted: i=1; AJvYcCUDuthxy315uJhlaihvVqLG8G1hdc/4gT36tqlUkhLXg31oDpkP7Ao89MGiTy2vodx8Zgeh/v6V4foP4oM=@vger.kernel.org X-Gm-Message-State: AOJu0Yz0EQcF0Usu8BWZ0hAIERKiW0CBUik8HVcepKjUkGO2pxvvPWv0 J0G4LVMIs5gR9cikdhnDaifxVoyTdfQZLkD9d0XOwo2S3Hu3P5CWR4x9/TJ4BeYjpSMthE1DjHl GYZfZH0qCh868Iw== X-Received: from pjkk4.prod.google.com ([2002:a17:90b:57e4:b0:352:de4e:4039]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3901:b0:354:a57c:65dd with SMTP id 98e67ed59e1d1-354b3cae0d0mr362193a91.24.1770327819173; Thu, 05 Feb 2026 13:43:39 -0800 (PST) Date: Thu, 5 Feb 2026 13:43:01 -0800 In-Reply-To: <20260205214326.1029278-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260205214326.1029278-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260205214326.1029278-2-jmattson@google.com> Subject: [PATCH v3 1/8] KVM: x86: nSVM: Clear VMCB_NPT clean bit when updating g_pat in L2 From: Jim Mattson To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yosry Ahmed Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When running an L2 guest and writing to MSR_IA32_CR_PAT, the host PAT value is stored in vmcb01.ptr->save.g_pat, but the clean bit was only being cleared for svm->vmcb, which points to vmcb02 in guest mode. Introduce the helper svm_set_vmcb_gpat() which sets vmcb->save.g_pat and marks the VMCB dirty for VMCB_NPT. Use this helper in both svm_set_msr() for updating vmcb01 and in nested_vmcb02_compute_g_pat() for updating vmcb02, ensuring both VMCBs are properly marked dirty. Fixes: 4995a3685f1b ("KVM: SVM: Use a separate vmcb for the nested L2 guest= ") Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/nested.c | 2 +- arch/x86/kvm/svm/svm.c | 3 +-- arch/x86/kvm/svm/svm.h | 6 ++++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index de90b104a0dd..f72dbd10dcad 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -636,7 +636,7 @@ void nested_vmcb02_compute_g_pat(struct vcpu_svm *svm) return; =20 /* FIXME: merge g_pat from vmcb01 and vmcb12. */ - svm->nested.vmcb02.ptr->save.g_pat =3D svm->vmcb01.ptr->save.g_pat; + svm_set_vmcb_gpat(svm->nested.vmcb02.ptr, svm->vmcb01.ptr->save.g_pat); } =20 static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *= vmcb12) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 5f0136dbdde6..08f145eb9215 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2939,10 +2939,9 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct= msr_data *msr) if (ret) break; =20 - svm->vmcb01.ptr->save.g_pat =3D data; + svm_set_vmcb_gpat(svm->vmcb01.ptr, data); if (is_guest_mode(vcpu)) nested_vmcb02_compute_g_pat(svm); - vmcb_mark_dirty(svm->vmcb, VMCB_NPT); break; case MSR_IA32_SPEC_CTRL: if (!msr->host_initiated && diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index ebd7b36b1ceb..986d90f2d4ca 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -420,6 +420,12 @@ static inline bool vmcb_is_dirty(struct vmcb *vmcb, in= t bit) return !test_bit(bit, (unsigned long *)&vmcb->control.clean); } =20 +static inline void svm_set_vmcb_gpat(struct vmcb *vmcb, u64 data) +{ + vmcb->save.g_pat =3D data; + vmcb_mark_dirty(vmcb, VMCB_NPT); +} + static __always_inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) { return container_of(vcpu, struct vcpu_svm, vcpu); --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sun Feb 8 10:04:37 2026 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 53C4A33375B for ; Thu, 5 Feb 2026 21:43:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327821; cv=none; b=Ib+QEE4X1W+H+4CmWOBOqx1VqojCR1+E2vRVOsI4kvK4vgHlY7iJdfRNjW7yg436oiMcIymCQnZ0Ec1nbXEYyHZob+F68tjwi+u1aeDv532hngY/T5cMyZmBcQkGO9aWh1rkQirm8dcWqBlax9wt2sMPV14LyKhe2/9ZCiSLlMk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327821; c=relaxed/simple; bh=//1gJ9AADdkcXusZWlVgojFG22OU4StZISH4Uz81e5w=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Vf3CQ47/sLQYoBB0SE2z7pKaM+zBW7tSQ3CKZUg5GtC91msg59xX27Pv+srjzAd9afD4vTyUcekWV7ObNrSuO+A+5y/x2naEsT3QZz25umXplV8xk9E5ljtpmv86LRw8OdZb6ZPs/43v8HAhE++AKXiimn0BKbyEd9nE7o+cvCw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=PQJ+eijR; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="PQJ+eijR" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-34c43f8ef9bso2807207a91.1 for ; Thu, 05 Feb 2026 13:43:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770327821; x=1770932621; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=zeNAWI4t8RbEksTte5HEam/g+zHUdM8Hnj9AjmiEzPY=; b=PQJ+eijRx4H8jK6nVyGF6gJGPv8IVrMjwgn+MFAfrWOvVSYwXXsnZfiMFOfXHxw8zZ o1N/HLrqJTHsSjxcSRQoyW3IVvZxFLmyJcmBXTiQcxrejuXSjcCH7ByYnRqQOLFNdx0b VSh5CaCS4Qnxe1PwFu3528IgeyA7734s/FBMHiM0oPIPmflcyi2Nv/W6WbSzMDY2yezE zgKnhm6+yrHs4sNFuA7Nirv7sd+NaPCE2hU0x7dkiIt9Y41tpVw9iv4+LL6bBAeupBYh vT9QvAE4YYCXL2XNdVnTbsB3kBOuNNTGkJVbQzIG5AN5se4opiiDwivR3jmrNwkSlp50 4DhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770327821; x=1770932621; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=zeNAWI4t8RbEksTte5HEam/g+zHUdM8Hnj9AjmiEzPY=; b=O7jXekZPGD3NQL6q/NVbweuTKtHRxuGe/EPFUfqxGYW/EEYcwsRtsEXQDILuS/5Joy WpSx+1jM2qjU7MAYK20Qtup4sXBNKJWFr8r7lDtj+NqNOxUAuCw17gzOUabUUCo714/W zc10tPz7b9FUsVuo8JwbK0XNNDIlaExIkJW5VwOKeKud5nEMZGNFFheuJnVYdFg2wS7s DfCD0PZHXp+xDjiRLQOUICkJ3DtnRTKNDYyi5/xmcLs98tAJ2l+6L8JAahVblexNTkKI VOpBitvh9p4eE4hMRhCBFReWWQzS3jHAsQQ4+9EmpaExmyPNg4Xay88fvIW0bb+EOMRj ZN3g== X-Forwarded-Encrypted: i=1; AJvYcCWEInMTUkMHKl1gRckNagwb1SiMFCTh1aBfUgVnbi3VoaVdsjsx4g8hMRE3dFI5vN4q9wFrTC6IR+Tpa28=@vger.kernel.org X-Gm-Message-State: AOJu0YyRK8stXQcz7ABO7JmuyZfL1CSe6hX+WcvLw4o+rdYCLjGrpL4o 0M5hDKR7SJF3pRKTM0cEuYFevz88fsyFHl20ls8Svif/q0PxO6M34Obw272qTgjXNpSir5ez9f3 QVTIza59t2JY7Xw== X-Received: from pjbqe9.prod.google.com ([2002:a17:90b:4f89:b0:352:de4e:4038]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:28cc:b0:352:dbcc:d74c with SMTP id 98e67ed59e1d1-354b30ace04mr594953a91.15.1770327820720; Thu, 05 Feb 2026 13:43:40 -0800 (PST) Date: Thu, 5 Feb 2026 13:43:02 -0800 In-Reply-To: <20260205214326.1029278-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260205214326.1029278-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260205214326.1029278-3-jmattson@google.com> Subject: [PATCH v3 2/8] KVM: x86: nSVM: Cache and validate vmcb12 g_pat From: Jim Mattson To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yosry Ahmed Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Cache g_pat from vmcb12 in svm->nested.gpat to avoid TOCTTOU issues, and add a validity check so that when nested paging is enabled for vmcb12, an invalid g_pat causes an immediate VMEXIT with exit code VMEXIT_INVALID, as specified in the APM, volume 2: "Nested Paging and VMRUN/VMEXIT." Fixes: 3d6368ef580a ("KVM: SVM: Add VMRUN handler") Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/nested.c | 4 +++- arch/x86/kvm/svm/svm.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index f72dbd10dcad..1d4ff6408b34 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1027,9 +1027,11 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) =20 nested_copy_vmcb_control_to_cache(svm, &vmcb12->control); nested_copy_vmcb_save_to_cache(svm, &vmcb12->save); + svm->nested.gpat =3D vmcb12->save.g_pat; =20 if (!nested_vmcb_check_save(vcpu) || - !nested_vmcb_check_controls(vcpu)) { + !nested_vmcb_check_controls(vcpu) || + (nested_npt_enabled(svm) && !kvm_pat_valid(svm->nested.gpat))) { vmcb12->control.exit_code =3D SVM_EXIT_ERR; vmcb12->control.exit_info_1 =3D 0; vmcb12->control.exit_info_2 =3D 0; diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 986d90f2d4ca..42a4bf83b3aa 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -208,6 +208,9 @@ struct svm_nested_state { */ struct vmcb_save_area_cached save; =20 + /* Cached guest PAT from vmcb12.save.g_pat */ + u64 gpat; + bool initialized; =20 /* --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sun Feb 8 10:04:37 2026 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C91AF334372 for ; Thu, 5 Feb 2026 21:43:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327822; cv=none; b=EIlgzHjfD3Jx5h6qxf3VvoS3K964bGIfVR/yUlxJfru/WfZsV4FpqhkWKh8apcYpcVtjstWUH3jTxA9pMdYp+Y7YdDq1D3G2jVK1aQ/u8c8Qgat1lEdudEytXDwpgPDEf1c+kUJh/bQVVvespcFNNavoJDkLkF0IBkDvvBcNNyw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327822; c=relaxed/simple; bh=/RX4mCH35HZdkO8HyVbrveLVnRTbZa+1vh8oTPb28F8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=L5Abs/VIWGXBoeJ6d73CbUcjutO9jZS9WT6smlfoUUHe7GWdfcuZlryQ74pPk0B0VZntPS5OI8Dfw9rjxQS09Nx2DecePRKiEG9CSmxYknNCHTP0RqFVMH7ozbhH8XfgWU2xPVQpqmwWU/gW8Sqz/EWSXvhz9o57GpKc29RRSHE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=PzElm3RG; arc=none smtp.client-ip=209.85.214.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="PzElm3RG" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2a07fa318fdso14634125ad.0 for ; Thu, 05 Feb 2026 13:43:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770327822; x=1770932622; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Vzh3iLHAfWUF+ni0XgKYTYRZaX8q/MuSJjdjzVEy2HI=; b=PzElm3RGGIe7FaErGMIOiEXp6nZ4slLg/mnY4AHOYO2jEy4jlgRBXsBT3q6U3NQOzb y19GgpPmv9R93CFzhmpTmhYMvCVhRQx/FudrcbRX3a2WfR3rb763RWntTlC562t1TXNQ Yf9R3fbj94z4Lgi6ROTAW+jB0lXeshvyKmx9jGpJj3lluKskZX8tCm14HGiKYTJNYnCu uYLHL4UCoWkBD+q76gXuua3C9f7uwHkgiKcmCe4vDudOxjDvK8uphtA4+irSNpMsYOdd /G7rGOZ8gcpMcsoXjxTt/UGNlm1zApNTwX/ac6XUg5o/7CuK29hqAuk2FX4OClKYXK/l bcJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770327822; x=1770932622; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Vzh3iLHAfWUF+ni0XgKYTYRZaX8q/MuSJjdjzVEy2HI=; b=tVzeFDmKv7+6a8Ar2aw2UXo4dBELqt3+FeBDrZVbh6itcCSWt94ODyjtWd+6NVRMMf q069MPjmDe4xtDGMrAIZ7NowUB30GzYuVvH50YJ38SFxg313UgSNts14iNG5jnNyxw3N /DgXM+0RtrwmpE6pDV17+Q4lcsnAZTb45dVB0kdrpR5J95jAoxrEsizBIpvH+iAbnTBR 3mRpDyIv9JfFoWiecoyqZ7u76Ua2cIFBz8llLGMwPl8GRcx2JhLyCxSPaujUZX+qk9RR EwOAPEeRsUXoNlsXUdOUAYsC7GYpHVMJfOqPD/F7Kk3Yh3GRLqm9Y3jA1clA4HVIiFul LD/A== X-Forwarded-Encrypted: i=1; AJvYcCWkybTPPAdxoZ/LaEgRqS35VKjTYDfAMcz3n5WMEbqVThqMOElnkT3NmIsw64WIj7ckkMsJ58tEr0M9GcE=@vger.kernel.org X-Gm-Message-State: AOJu0YyBny0oXuD5TpUffzwlm4wxS2NTB7toWny8cxNhFMo5bQI5Rt0v 9B/RfYEbyqHwDIxBLhg9taoZ2T8cgpklTC9xfv1b73BHd9ZsEY2HH2GmQ7TO/mkisyl/jq2q1oa N4s2pcGLK+B1lTQ== X-Received: from pjq16.prod.google.com ([2002:a17:90b:5610:b0:34c:2778:11c5]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:517:b0:38b:eeb9:cbb5 with SMTP id adf61e73a8af0-393af0da032mr246446637.39.1770327822187; Thu, 05 Feb 2026 13:43:42 -0800 (PST) Date: Thu, 5 Feb 2026 13:43:03 -0800 In-Reply-To: <20260205214326.1029278-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260205214326.1029278-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260205214326.1029278-4-jmattson@google.com> Subject: [PATCH v3 3/8] KVM: x86: nSVM: Set vmcb02.g_pat correctly for nested NPT From: Jim Mattson To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yosry Ahmed Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When nested NPT is enabled in vmcb12, copy the (cached and validated) vmcb12 g_pat field to the guest PAT register. Under KVM, the guest PAT register lives in the vmcb02 g_pat field. When NPT is enabled, but nested NPT is disabled, copy L1's IA32_PAT MSR to the vmcb02 g_pat field, since L2 shares the IA32_PAT MSR with L1. When NPT is disabled, the vmcb02 g_pat field is ignored by hardware. Fixes: 15038e147247 ("KVM: SVM: obey guest PAT") Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/nested.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 1d4ff6408b34..1ff2ede96094 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -646,9 +646,6 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm = *svm, struct vmcb *vmcb12 struct vmcb *vmcb02 =3D svm->nested.vmcb02.ptr; struct kvm_vcpu *vcpu =3D &svm->vcpu; =20 - nested_vmcb02_compute_g_pat(svm); - vmcb_mark_dirty(vmcb02, VMCB_NPT); - /* Load the nested guest state */ if (svm->nested.vmcb12_gpa !=3D svm->nested.last_vmcb12_gpa) { new_vmcb12 =3D true; @@ -656,6 +653,19 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm= *svm, struct vmcb *vmcb12 svm->nested.force_msr_bitmap_recalc =3D true; } =20 + if (npt_enabled) { + if (nested_npt_enabled(svm)) { + if (unlikely(new_vmcb12 || + vmcb_is_dirty(vmcb12, VMCB_NPT))) { + vmcb02->save.g_pat =3D svm->nested.gpat; + vmcb_mark_dirty(vmcb02, VMCB_NPT); + } + } else { + vmcb02->save.g_pat =3D vcpu->arch.pat; + vmcb_mark_dirty(vmcb02, VMCB_NPT); + } + } + if (unlikely(new_vmcb12 || vmcb_is_dirty(vmcb12, VMCB_SEG))) { vmcb02->save.es =3D vmcb12->save.es; vmcb02->save.cs =3D vmcb12->save.cs; --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sun Feb 8 10:04:37 2026 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23F533358BB for ; Thu, 5 Feb 2026 21:43:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327824; cv=none; b=JNQywFowHnQNM6wgfOVi9yYNXC1tdTMj7eKVcuOBqZTLVvGG7OViKGcdwB76cY+jN8ZCvMJcGAoAe2uShK4veFdMOxAvU4gGo+yoFRGTFTpJbC1YufQRRnTGi/XqN22OthTgk/dVnxB11PcrePqbRRtgW9u2snNR+YNfRftwjlI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327824; c=relaxed/simple; bh=1D+Rg0RzamaZWrQGwQog0TMlHq2s25Z6R2jx9QWiAkk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=YtDjFsmd37pOrhLbn7aLHq4HUGQjNC+6ZFVeFcQju++QwDk75iDndy/1gtxTKwlkdFvRz3poBOqe8eD14xLZY4Sc+NSCvItyhuWKliJZVHSikehQhZneVbLvjpWkL7m11pI4rZK4ARdiPkrTxlQlC4XZ6YsaDOIq8ajGSfY/wr8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=CpJIfaxZ; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="CpJIfaxZ" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-c56848e6f53so819663a12.0 for ; Thu, 05 Feb 2026 13:43:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770327823; x=1770932623; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=3S+CqfjZPLDswkTpiM7Jj+iI7z0lBAQUqin93RB1oEY=; b=CpJIfaxZ/QjO5cL/fD0sezoL1e2K0t8oPb/l7xJIBGsxBkSkiJOKkgkpXA401XJ2gs RWxVR8lMzQOF2ADHK08dRJ4aZqAaHoYg/d3YFWsXEBK3K99XaGOuUrPX+RsHlBiDfYyO Bw0z/9L4St6naokiO3BLcGKAAGAPCbZSUWlV6c0bD3oumrn9tVqSpYRocXLRwUzepDY3 Hd8e8QH/A9F7Y2k8wDcixZxj5tgo5SvInAU6D0YXUiX3qCssj/CNPf9MMIYHKZXHbJPt VRlp8M9IrZRa04wjdpi76veYyF9Ips4HkPUNn/IjlXoFdQARAVo8ZH4ZfJKlWt0lfA9u Uw1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770327823; x=1770932623; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3S+CqfjZPLDswkTpiM7Jj+iI7z0lBAQUqin93RB1oEY=; b=gwr7pMDeyO/SfsCjp/DLcakpazggcoTmSE3//j78xqJ9d39VlKGnkb+DHmBBlpFGmk T+ug1YrYTZoz+CSwJhEjHG8dVt9n6OvzGkLzD0gT4eZmEgDPDrb3mCc7WVGDrsVrPLHt y3hTqbBA9MrXplZev7Oerg+rR1DgAOvdT4ItnDU7Z1kGSN+g4mqMXH9DNethqCFKXxa5 PyXsLiYwH/gsWKrfqOXG7Qu/CqXRqGPEHQ5Gy5fzTAtWOSeEcZ2bL3IHQ+HAhbOZVquP 2UKN1v0F6iX847Wh34X4ZZ4DFu75rczsuKm+YBxK9vZsHY4xqBEGM3DLab6kqUkyeclu qDmg== X-Forwarded-Encrypted: i=1; AJvYcCV22W7dkag27xgwGVhgQwWUY5FPP6Eq/eUqhfU4BJpUoKDr8s/fKZhObFzhIDCk4BqkWi9CYXCaJtHspkA=@vger.kernel.org X-Gm-Message-State: AOJu0YxIZlOuBHRfrBjSMo2iwVesasp20037uum4eIPCyZSVi9t4dUBf digVxALHvxZOKO8H0GcK97xMYu6F6VFN30kfJ5yFkZY0RK0jHGVfnHa77kHYeVNwFni5t5prh7q Etwzbt6pVvBGxKg== X-Received: from pgbdo4.prod.google.com ([2002:a05:6a02:e84:b0:c63:53c3:c03a]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:3c8e:b0:341:d5f3:f1ac with SMTP id adf61e73a8af0-393af0c8604mr331317637.41.1770327823550; Thu, 05 Feb 2026 13:43:43 -0800 (PST) Date: Thu, 5 Feb 2026 13:43:04 -0800 In-Reply-To: <20260205214326.1029278-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260205214326.1029278-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260205214326.1029278-5-jmattson@google.com> Subject: [PATCH v3 4/8] KVM: x86: nSVM: Redirect IA32_PAT accesses to either hPAT or gPAT From: Jim Mattson To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yosry Ahmed Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When the vCPU is in guest mode with nested NPT enabled, guest accesses to IA32_PAT are redirected to the gPAT register, which is stored in vmcb02->save.g_pat. Non-guest accesses (e.g. from userspace) to IA32_PAT are always redirected to hPAT, which is stored in vcpu->arch.pat. This is architected behavior. It also makes it possible to restore a new checkpoint on an old kernel with reasonable semantics. After the restore, gPAT will be lost, and L2 will run on L1's PAT. Note that the old kernel would have always run L2 on L1's PAT. Fixes: 15038e147247 ("KVM: SVM: obey guest PAT") Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/nested.c | 9 --------- arch/x86/kvm/svm/svm.c | 34 ++++++++++++++++++++++++++++------ arch/x86/kvm/svm/svm.h | 17 ++++++++++++++++- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 1ff2ede96094..08844bc51b3c 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -630,15 +630,6 @@ static int nested_svm_load_cr3(struct kvm_vcpu *vcpu, = unsigned long cr3, return 0; } =20 -void nested_vmcb02_compute_g_pat(struct vcpu_svm *svm) -{ - if (!svm->nested.vmcb02.ptr) - return; - - /* FIXME: merge g_pat from vmcb01 and vmcb12. */ - svm_set_vmcb_gpat(svm->nested.vmcb02.ptr, svm->vmcb01.ptr->save.g_pat); -} - static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *= vmcb12) { bool new_vmcb12 =3D false; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 08f145eb9215..b62c32c3942d 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2852,6 +2852,20 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct= msr_data *msr_info) case MSR_AMD64_DE_CFG: msr_info->data =3D svm->msr_decfg; break; + case MSR_IA32_CR_PAT: + /* + * When nested NPT is enabled, L2 has a separate PAT from L1. + * Guest accesses to IA32_PAT while running L2 target L2's gPAT; + * host-initiated accesses always target L1's hPAT for backward + * and forward KVM_GET_MSRS compatibility with older kernels. + */ + WARN_ON_ONCE(msr_info->host_initiated && vcpu->wants_to_run); + if (!msr_info->host_initiated && is_guest_mode(vcpu) && + nested_npt_enabled(svm)) + msr_info->data =3D svm->nested.gpat; + else + msr_info->data =3D vcpu->arch.pat; + break; default: return kvm_get_msr_common(vcpu, msr_info); } @@ -2935,13 +2949,21 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struc= t msr_data *msr) =20 break; case MSR_IA32_CR_PAT: - ret =3D kvm_set_msr_common(vcpu, msr); - if (ret) - break; + if (!kvm_pat_valid(data)) + return 1; =20 - svm_set_vmcb_gpat(svm->vmcb01.ptr, data); - if (is_guest_mode(vcpu)) - nested_vmcb02_compute_g_pat(svm); + /* + * When nested NPT is enabled, L2 has a separate PAT from L1. + * Guest accesses to IA32_PAT while running L2 target L2's gPAT; + * host-initiated accesses always target L1's hPAT for backward + * and forward KVM_SET_MSRS compatibility with older kernels. + */ + WARN_ON_ONCE(msr->host_initiated && vcpu->wants_to_run); + if (!msr->host_initiated && is_guest_mode(vcpu) && + nested_npt_enabled(svm)) + svm_set_gpat(svm, data); + else + svm_set_hpat(svm, data); break; case MSR_IA32_SPEC_CTRL: if (!msr->host_initiated && diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 42a4bf83b3aa..a0e94a2c51a1 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -590,6 +590,22 @@ static inline bool nested_npt_enabled(struct vcpu_svm = *svm) return svm->nested.ctl.nested_ctl & SVM_NESTED_CTL_NP_ENABLE; } =20 +static inline void svm_set_gpat(struct vcpu_svm *svm, u64 data) +{ + svm->nested.gpat =3D data; + svm_set_vmcb_gpat(svm->nested.vmcb02.ptr, data); +} + +static inline void svm_set_hpat(struct vcpu_svm *svm, u64 data) +{ + svm->vcpu.arch.pat =3D data; + if (npt_enabled) { + svm_set_vmcb_gpat(svm->vmcb01.ptr, data); + if (is_guest_mode(&svm->vcpu) && !nested_npt_enabled(svm)) + svm_set_vmcb_gpat(svm->nested.vmcb02.ptr, data); + } +} + static inline bool nested_vnmi_enabled(struct vcpu_svm *svm) { return guest_cpu_cap_has(&svm->vcpu, X86_FEATURE_VNMI) && @@ -816,7 +832,6 @@ void nested_copy_vmcb_control_to_cache(struct vcpu_svm = *svm, void nested_copy_vmcb_save_to_cache(struct vcpu_svm *svm, struct vmcb_save_area *save); void nested_sync_control_from_vmcb02(struct vcpu_svm *svm); -void nested_vmcb02_compute_g_pat(struct vcpu_svm *svm); void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vm= cb); =20 extern struct kvm_x86_nested_ops svm_nested_ops; --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sun Feb 8 10:04:37 2026 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2562336EFD for ; Thu, 5 Feb 2026 21:43:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327825; cv=none; b=Mi4aP76p3kFeM6MYyTXzEVL1vbAEsWeLlcNklZ2oUEmSi+/NseIv9EdQ1NPmiDTfGYRDec3QSu7k3kGvXu0DGsUt0pDL43XtbF58u4hNTzBXlFK+kXUF8TC2w8Z2kDQhOrniUr1X+b1M9UZet9muUWSbuVwYe9aQ14uldFCRPxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327825; c=relaxed/simple; bh=VKK3FI5CznSAk7yWaDS4FKTM94PMhdrLBqenb/UE3CU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=r/hSiFri/TqeydODJojvmUb2xebedsJ1Ng9hrCDrjYHhJUwQrKFer+eg/A0vDWdPqh/oNmR/wbREDEqHD38WiPvOntC+h+TA7v0ECAN44iYS0b3B9sh7JlvJr3t9s7hYrIX0hE9VnzQbYKU3DTcIv4VAFo0Ck0ZCuJvPFwkyqJc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=yN34Ik7Q; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="yN34Ik7Q" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2a0f0c7a06eso13284715ad.2 for ; Thu, 05 Feb 2026 13:43:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770327825; x=1770932625; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=/y42SgBvf8dyV9xojnKcBJj98e4MjkxOU4lKNEYjtnI=; b=yN34Ik7QD3KL5yHDFPMvYywOYoh5TyfWVj++g6IoN2BDRMLrOItTWJqLJEPHjaetWe TkqQEARIDPbH75UO7AWCWF7HRnrXhgPjhywqCzglhIISD1KYp+1qn6WHS8x+jAgUZKPU 8is009BGMGPbt0KIWkjlYtbhvFpnCfeHV+I01zsmWrNW5Fn1aBaBVYnPIeEDsfOWMTdg 5dc5X0Y5UBVXVz8x4wuERTKGW43d0KIlgk1SNGN6/g8xTgT2xIhz4Dd9Ms7h2Xb1LteB fCmDLNzLhu+mL6KtECSmLArE9QBuuM4s9iIt1fDiIlOKisMLhNIRoJYA16KAFsy9vPen RonA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770327825; x=1770932625; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=/y42SgBvf8dyV9xojnKcBJj98e4MjkxOU4lKNEYjtnI=; b=fFZ7RxTrDtUnQXJAQI+gr9qD9Fy39qIKXQm2FUwpRhocYVOMPm3Pbj+uLPi3UVt0BC e0YBEiDCd3n8V65YFxooVE9CdAYuBWrc2TpXEVdb9R/E3M5tstV/wgpsBfj5n33EUSHD w6kKt6VYiE1BcMiN9oOVdZZBR9tHgFmsLg74VwrRU3CxgHDhUinqeiIejPm+wi37557j qRKViZxTWudb/nlfeOGaub27FOTZrUprQ0Nuhk8TBuvIVzsMoO3FIqabe6n0EEVcSaWC ptG4RNwvHix/wlpsLNKvjc+sE+oUlN4Mw2AINU2ssnqFKWqJw4KQ7HF/ovhqAZ3JKLRw mNhw== X-Forwarded-Encrypted: i=1; AJvYcCWLB1t6zHu24tptPZhyy4P9eaq5ra5/ksxptkmtgJKEcP1bDL+IAAZJln62z6QBkKJC3+XymWYbbGxcqlo=@vger.kernel.org X-Gm-Message-State: AOJu0Yz4gn4Cx9hT+DlvKexBF3jeNyCZZ1hkiA55EeD1dN8BWFJ5Cy8m 9QjCySq2aishOVIB6GARfYGrkPN7D1zjIwUnM9v6Rdk7nkuoN+dGZWJjO+pJlXYcD+ts0Oeyy8Q ncJ8b2QWarkmKhw== X-Received: from pge15.prod.google.com ([2002:a05:6a02:2d0f:b0:c64:8baa:4f1b]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:ce4d:b0:366:14ac:e200 with SMTP id adf61e73a8af0-393af250deamr354321637.62.1770327825224; Thu, 05 Feb 2026 13:43:45 -0800 (PST) Date: Thu, 5 Feb 2026 13:43:05 -0800 In-Reply-To: <20260205214326.1029278-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260205214326.1029278-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260205214326.1029278-6-jmattson@google.com> Subject: [PATCH v3 5/8] KVM: x86: nSVM: Save gPAT to vmcb12.g_pat on VMEXIT From: Jim Mattson To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yosry Ahmed Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" According to the APM volume 3 pseudo-code for "VMRUN," when nested paging is enabled in the vmcb, the guest PAT register (gPAT) is saved to the vmcb on emulated VMEXIT. Under KVM, the guest PAT register lives in the vmcb02 g_pat field. Save this value to the vmcb12 g_pat field on emulated VMEXIT. Fixes: 15038e147247 ("KVM: SVM: obey guest PAT") Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/nested.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 08844bc51b3c..0b95ae1e864b 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1169,6 +1169,9 @@ int nested_svm_vmexit(struct vcpu_svm *svm) vmcb12->save.dr6 =3D svm->vcpu.arch.dr6; vmcb12->save.cpl =3D vmcb02->save.cpl; =20 + if (nested_npt_enabled(svm)) + vmcb12->save.g_pat =3D vmcb02->save.g_pat; + if (guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK)) { vmcb12->save.s_cet =3D vmcb02->save.s_cet; vmcb12->save.isst_addr =3D vmcb02->save.isst_addr; --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sun Feb 8 10:04:37 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1BDF3376AC for ; Thu, 5 Feb 2026 21:43:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327827; cv=none; b=P1Reuoi7FPgRQPVhzvQnTPUcp8y9/zRKTkSz0GXQy9d9G6/4SIUsngBKfvUbtas9L5kNnpMQcbsbSK64pNkf0o5MUbUFSS7p5HBN2C6NesKreZklvHDT6cvqs/IVABc9VX2cmy9yLLGPo1h4DZ/jogRLrN9HrpJEOPyhNrDrUMw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327827; c=relaxed/simple; bh=REMk7MsNEK46ltVnyaD2qUn2Wq3i1H3LHfd2I6/ePAo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mTRnE97wWilao3kREI4OhqSSpiIHuLJ0ftjHWMiwAn8Qj0sh8tiG+v/PqSG7Srg7MgFp2WKvMIUw51QK7VPnFvK8+LgyTVAgSBDJhCIpOC39uuLUBjF+bOawgXbVJxN09MDCQKr5Rkts55ZZwRler1YwaHJuo77/ZvYxnLYzCxU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=VrkP8LCG; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="VrkP8LCG" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-c636238ec57so903050a12.1 for ; Thu, 05 Feb 2026 13:43:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770327826; x=1770932626; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=S4KbIplwSpOgL8y77jJIQF/6UFPYYOp7aggt19vghWY=; b=VrkP8LCG4GKYYzkmPlZ9/1Y+U6sAc/Alv8yMlTxscyNXD8QqKNjjJ0NXbeIRWscEKF nF19crYtRaMYwTMJsgQt44O7WuE4m6FVDiHXyeeJ38KfHhYOfm5LesKIOJn9fg9ECYpa MioRdoBZ+Qv2kUovJLYnjUYEj/zD+0Ec796gJ4079L0is2x08tPCi8kbjFnWaWDpSIuQ XbIrc0Hyvwy+eOVW+0FIJnliupj+5Qs71V4/sKh3fiXNrI4RlRU7EbJBUGdbQ4NM/4SX x4TOL/aPYsvGZ8wIFVAB4pkzQYWZ2P3IiFGdg6NTP/u0vpwUgpz0oCCfePAG1dhZZBTU W8EQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770327826; x=1770932626; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=S4KbIplwSpOgL8y77jJIQF/6UFPYYOp7aggt19vghWY=; b=rwKte8r7WzK5c5dRL8S7tPesOIAv3LEZvqr6zmou/9zuxJqW+K0cPjD8Qnb9o+FUJd l0rSZCGBmu45zJJHRiOoP/arMWRbd0QWatulxlaXSx2CR2WoqI9DFvOGvYQ2JfwY0sVK rJfTZOPWufWF8S1wn1biw1OW6vakJ33fGaE8+QxPiXCNHsHQkibs8NGNDU0SFg6XuQIm XlkrkiYduww0LLAgDaDZiCzqZNK5Qb39WnH2f4swKPhv2dxn7ZKuG5XPqqp6Tr1fY8I7 NShNWgSMnGg4StLmr5/Snyb7LgjmfyD+CTWYBoteoKl2v8+CQ0h9eoI4TGC49fGBlnoZ EhWQ== X-Forwarded-Encrypted: i=1; AJvYcCU0rOZloRClHWihiBYO1y0QQLfgwTWpZZJImxFLSMujWrLw8iuhfKiokNceDD5SVZUpPu9tJPDWIvprk+E=@vger.kernel.org X-Gm-Message-State: AOJu0YyuAoCzF2ECWYtlmyiRjQP514+iVSDwL/EvuDVqy0eLhIFKZ+F3 NqJ5WFjkn2xzmXuSIQU4tQEQqED2pAhEMwNUYfo7ym0o2GQ8WzXPc6Q5U8HVPcTN5GWSc/+5bb9 /3ScbQYrjYvWR4A== X-Received: from pjup21.prod.google.com ([2002:a17:90a:d315:b0:354:a065:ec58]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:69b:b0:38d:f084:e351 with SMTP id adf61e73a8af0-393af2a9b96mr335204637.80.1770327826507; Thu, 05 Feb 2026 13:43:46 -0800 (PST) Date: Thu, 5 Feb 2026 13:43:06 -0800 In-Reply-To: <20260205214326.1029278-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260205214326.1029278-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260205214326.1029278-7-jmattson@google.com> Subject: [PATCH v3 6/8] KVM: x86: nSVM: Save/restore gPAT with KVM_{GET,SET}_NESTED_STATE From: Jim Mattson To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yosry Ahmed Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a 'flags' field to the SVM nested state header, and use bit 0 of the flags to indicate that gPAT is stored in the nested state. If in guest mode with NPT enabled, store the current vmcb->save.g_pat value into the header of the nested state, and set the flag. Note that struct kvm_svm_nested_state_hdr is included in a union padded to 120 bytes, so there is room to add the flags field and the gpt field without changing any offsets. Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET= _NESTED_STATE") Signed-off-by: Jim Mattson --- arch/x86/include/uapi/asm/kvm.h | 5 +++++ arch/x86/kvm/svm/nested.c | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kv= m.h index 846a63215ce1..664d04d1db3f 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -495,6 +495,8 @@ struct kvm_sync_regs { =20 #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001 =20 +#define KVM_STATE_SVM_VALID_GPAT 0x00000001 + /* vendor-independent attributes for system fd (group 0) */ #define KVM_X86_GRP_SYSTEM 0 # define KVM_X86_XCOMP_GUEST_SUPP 0 @@ -531,6 +533,9 @@ struct kvm_svm_nested_state_data { =20 struct kvm_svm_nested_state_hdr { __u64 vmcb_pa; + __u32 flags; + __u32 reserved; + __u64 gpat; }; =20 /* for KVM_CAP_NESTED_STATE */ diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 0b95ae1e864b..3f512fb630db 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1764,6 +1764,10 @@ static int svm_get_nested_state(struct kvm_vcpu *vcp= u, /* First fill in the header and copy it out. */ if (is_guest_mode(vcpu)) { kvm_state.hdr.svm.vmcb_pa =3D svm->nested.vmcb12_gpa; + if (nested_npt_enabled(svm)) { + kvm_state.hdr.svm.flags |=3D KVM_STATE_SVM_VALID_GPAT; + kvm_state.hdr.svm.gpat =3D svm->nested.gpat; + } kvm_state.size +=3D KVM_STATE_NESTED_SVM_VMCB_SIZE; kvm_state.flags |=3D KVM_STATE_NESTED_GUEST_MODE; =20 @@ -1889,6 +1893,12 @@ static int svm_set_nested_state(struct kvm_vcpu *vcp= u, !__nested_vmcb_check_save(vcpu, &save_cached)) goto out_free; =20 + /* + * Validate gPAT, if provided. + */ + if ((kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT) && + !kvm_pat_valid(kvm_state->hdr.svm.gpat)) + goto out_free; =20 /* * All checks done, we can enter guest mode. Userspace provides @@ -1926,6 +1936,10 @@ static int svm_set_nested_state(struct kvm_vcpu *vcp= u, if (ret) goto out_free; =20 + if (nested_npt_enabled(svm) && + (kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT)) + svm_set_gpat(svm, kvm_state->hdr.svm.gpat); + svm->nested.force_msr_bitmap_recalc =3D true; =20 kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sun Feb 8 10:04:37 2026 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 74BC0337B99 for ; Thu, 5 Feb 2026 21:43:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327828; cv=none; b=RYHTi0pjXMg+8jB6pYculNWa7ZBeY8ZmcGaU1BPcJnWleFFMzueDn/+hmS18D3/YtFE/Zi18onjjVRKKxBl1QBLyjSL1djfAWfAnJ3FOmkg5iTluqNxv2EZ77HhEY2E4UFU0EFzYXX4bFj/oy190R7gC54COiRWSKsqbSpTa8Tw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327828; c=relaxed/simple; bh=MekaBo4sf17xgGY9W1J8mQajBnaq5uK/pQ/wy1TwC7A=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=YIS3HvibWxxGhDsp6pz1BUXON2MS+IKbuaCmkTLRx5mKYllKxVhnVaFyscDCN/YIKKcTS5z9Ul3ZzOK2hr0RHCDJIAhgPBDDDCyT168kAkMbEjZ+aoaLdMiJYHd9YbzmTu19qwCZPingQ9FRidiGHWS+gTtkjle7o+YsUvAIASY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=TNbVf3Vz; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="TNbVf3Vz" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2a8c54bbe46so32903605ad.2 for ; Thu, 05 Feb 2026 13:43:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770327828; x=1770932628; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=43/5MPyJUuLlvxAVOINMUPcXPK41vsmXFa7nB5Y5I2U=; b=TNbVf3Vzy4UmZYIeScvgt0I7YPk97440u/F9plyESJkWLVuhLygfR24Ic9sKd1VhWz 844DuQWjTowOSCB2jaVOVIv1Il5Vzbap7gcY1v3WDGPFUZby2CV37fAaMotm9baaf7wU d+XNg9vsNAwPoRmm/2MKxZDDnURFvbYmCqZahW/EK6QLMdRFT2twyg9g/S169sgsgyoZ GWAC9lIeJWhIpBK6xZqAgIO2QgA1kUT1mf7QfzNEG4e9phz4k4tLD9UtVpTpLnljVu02 +rS2/xahXdEFodUwhN2D2V5T+WGp5pRAi4CeSl0/jyLRvwKpglP+3uPIjdwrGUtVs+eN Y+3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770327828; x=1770932628; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=43/5MPyJUuLlvxAVOINMUPcXPK41vsmXFa7nB5Y5I2U=; b=nkc8XgHx7C0Vsbo9V33WwCQ+LOtml6Mt1cqdmbQfKC2ju/VdVrwyuDz5FiCSzhHrlW hB63V/Pxs+yjgH59LgQr8JMWbbYmBiqy+lmUSYaIrC49UyLqYPLD+SKJWfUmdJtJSmdC CUC3AFG52kbeEv6CBfdUDGThMM5+vnFENJ4XNprc6+eYmTywdxEzH6pkZcbMfWljbJg6 5KgTLPJbVX1nKqpQSJwyaa7+E0/KizwfW0IGEYuK7JI6T3VYd1W5aBdEewx6tb0e7OWk 44uHklo6ZBC5dNSyxdQ+ZztGaWYkzGnEXz33x1bKcffH4CZJsAmo/6shW/xuptn43SFG CmPw== X-Forwarded-Encrypted: i=1; AJvYcCVVtN4vmUC+WAHk3jS74b//oeVzOA5nJFV6j0sY7vo/b4Y83Me9ZNNu9lUbl7FE26J6nEhwl6AvlMtmlsY=@vger.kernel.org X-Gm-Message-State: AOJu0YzG6/VYV1eRSpWTvatSZtxgamhQog47FPjqXvc2mTP18YbZBVoy SkmuxpCx4g7NqOnGVTcF9duGlXz7dmAcPCdrBmA95aimtvOoO/U+Z2/t+vsTr1XXl2VpSm9Y0KJ PwlmnV57G2lLVBw== X-Received: from plpr14.prod.google.com ([2002:a17:903:3e2e:b0:29f:2b44:973b]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:eb14:b0:2a3:bf9d:9399 with SMTP id d9443c01a7336-2a9516d4f31mr4351265ad.35.1770327827905; Thu, 05 Feb 2026 13:43:47 -0800 (PST) Date: Thu, 5 Feb 2026 13:43:07 -0800 In-Reply-To: <20260205214326.1029278-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260205214326.1029278-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260205214326.1029278-8-jmattson@google.com> Subject: [PATCH v3 7/8] KVM: x86: nSVM: Handle restore of legacy nested state From: Jim Mattson To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yosry Ahmed Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When nested NPT is enabled and KVM_SET_NESTED_STATE is used to restore an old checkpoint (without a valid gPAT), the current IA32_PAT value must be used as L2's gPAT. The current IA32_PAT value may be restored by KVM_SET_MSRS after KVM_SET_NESTED_STATE. Furthermore, there may be a KVM_GET_NESTED_STATE before the first KVM_RUN. Introduce a new boolean, svm->nested.legacy_gpat_semantics. When set, hPAT updates are also applied to gPAT, preserving the old behavior where L2 shared L1's PAT. svm_vcpu_pre_run() clears this boolean at the first KVM_RUN. Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/nested.c | 11 ++++++++--- arch/x86/kvm/svm/svm.c | 2 ++ arch/x86/kvm/svm/svm.h | 9 +++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 3f512fb630db..a7d6fc1382a7 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1936,9 +1936,14 @@ static int svm_set_nested_state(struct kvm_vcpu *vcp= u, if (ret) goto out_free; =20 - if (nested_npt_enabled(svm) && - (kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT)) - svm_set_gpat(svm, kvm_state->hdr.svm.gpat); + if (nested_npt_enabled(svm)) { + if (kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT) { + svm_set_gpat(svm, kvm_state->hdr.svm.gpat); + } else { + svm_set_gpat(svm, vcpu->arch.pat); + svm->nested.legacy_gpat_semantics =3D true; + } + } =20 svm->nested.force_msr_bitmap_recalc =3D true; =20 diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index b62c32c3942d..a6a44deec82b 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4239,6 +4239,8 @@ static int svm_vcpu_pre_run(struct kvm_vcpu *vcpu) if (to_kvm_sev_info(vcpu->kvm)->need_init) return -EINVAL; =20 + to_svm(vcpu)->nested.legacy_gpat_semantics =3D false; + return 1; } =20 diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index a0e94a2c51a1..a559cd45c8a9 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -221,6 +221,13 @@ struct svm_nested_state { * on its side. */ bool force_msr_bitmap_recalc; + + /* + * Indicates that a legacy nested state was restored (without a + * valid gPAT). In this mode, updates to hPAT are also applied to + * gPAT, preserving the old behavior where L2 shared L1's PAT. + */ + bool legacy_gpat_semantics; }; =20 struct vcpu_sev_es_state { @@ -604,6 +611,8 @@ static inline void svm_set_hpat(struct vcpu_svm *svm, u= 64 data) if (is_guest_mode(&svm->vcpu) && !nested_npt_enabled(svm)) svm_set_vmcb_gpat(svm->nested.vmcb02.ptr, data); } + if (svm->nested.legacy_gpat_semantics) + svm_set_gpat(svm, data); } =20 static inline bool nested_vnmi_enabled(struct vcpu_svm *svm) --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sun Feb 8 10:04:37 2026 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 232A533970F for ; Thu, 5 Feb 2026 21:43:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327830; cv=none; b=HQQlU1FxwLSQ1yHbJt4FP2tLa3idODMIwjzr5faTfopMSi8rT8ihZdhyKxDs4/LRw/7Z89xv/4SpZ3bgecqlaTvZ3mME8TohljziwRoSTTfBs2wyJ0MIJRXoCmp3XzlojIa11wMp/6t7NiHrSrW2VB3HKgdt1CSjdYNeD9fVe40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770327830; c=relaxed/simple; bh=JZ5ruax6Fqre5VIwRYbUJVDDyy/C2tkKudh0Pd6yX/M=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BgdBJz77TiOZIe0GF0u7xv3HtLvan4oFzDGXejovUVzimVSYjb3hkjXxXPNTRfNJIGMAv1Ijm1qwwDCziMV1+UTSgyz/8hrFwQiwCE/sCbW70B7vAYzHLhgFEUbPOI5+5XSn1XSVtwg0pCyKdGo7SLm8k1YkyCNJFEzyXf0/aXM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=2CXF8Ou8; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jmattson.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="2CXF8Ou8" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-34c2f670a06so1065052a91.3 for ; Thu, 05 Feb 2026 13:43:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770327829; x=1770932629; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=1yRMb4qc+aRpKM0YfgdxkNe0DvJ7aTkEuu9+gYbrEts=; b=2CXF8Ou81t60wqGx1B4aiqHvpCDSZJPGD4UK0Vv1Lp1U64bZPb7pONh+KURj9HBich jAAdrY0MpXemYjgwUW5vJgVZdXKUaOSObVR/tGefyhuZmt71LK3YiAMRnF/FmsJAivuk sb5DW7FTyY+XwKWgNzVmJxhSmTxPyuxO24E7QkOErCwY0DsAZ47Cd8ely5CxQpvw/9Hv tocZYNj/zsL7PUiXa4LjFS8NG0CLgLNRw8SuFXyDdQgpMCUGg7h/jvh56Xtg/Fi3cCRw zErIPnRZFunXl6QozOmFznrR9FqLseyFaJsnMjVVJbM++YCqdNhP4Mb9QFlcL9wQDyUI T4fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770327829; x=1770932629; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=1yRMb4qc+aRpKM0YfgdxkNe0DvJ7aTkEuu9+gYbrEts=; b=hYo4hxPXBm+lEV1ddHW9JSzRneHkDGEBJWidTPuWwTP8f2CU0hzDEXReZPx3DnlAEf IJSp85KLPwTojw1zRPI94A84dsUel7iUfolxWVd7bQZWII5TPiTo3/ugMHaLyjYrAGhF h0xSCGoNscNG/w9UoOePjbNx+Vkt858uqA1TgDmMjphtpTtCTyIzqqa94ek8eGvwd5OM sIyDfOKbf3MIvmJooEJhaua336Ddb8h0+leaCbSj7IJC12ScPsrxkOc59e5RBj6rpc+M 1i88q8h2SDSBHd8UaFsrrnC7xpusKCMil8QzcxLkIeK4yLq1r3C6UCk7lxJwGMxYBVfG sG0g== X-Forwarded-Encrypted: i=1; AJvYcCXD/2kaHhlJP2rnl12/R0kw4303ls8CBEVFeDSyk5M9CuNVTN3p7Nmiz25a6nThlyJtk2Eg37PCv9jbfSQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwianCBM+A+m6v0oCKrARX8EPOGtuO7J9YserpNIiI2uuMNwIcZ jwkjVohb2eYyNG4GUocJmJImG41cG+hfqAMMLuEcqr0pqOwh3ClW8Kj8WDsVY1+9raqwK5sz+0a EdZIBRlWf/tuLcw== X-Received: from pjbqd12.prod.google.com ([2002:a17:90b:3ccc:b0:352:b687:3b20]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4f45:b0:343:7714:4cab with SMTP id 98e67ed59e1d1-354b3e2f162mr294708a91.22.1770327829498; Thu, 05 Feb 2026 13:43:49 -0800 (PST) Date: Thu, 5 Feb 2026 13:43:08 -0800 In-Reply-To: <20260205214326.1029278-1-jmattson@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260205214326.1029278-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260205214326.1029278-9-jmattson@google.com> Subject: [PATCH v3 8/8] KVM: selftests: nSVM: Add svm_nested_pat test From: Jim Mattson To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Yosry Ahmed Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Verify that when nested NPT is enabled, L1 and L2 have independent PATs, and changes to the PAT by either guest are not visible to the other. Signed-off-by: Jim Mattson --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../selftests/kvm/x86/svm_nested_pat_test.c | 298 ++++++++++++++++++ 2 files changed, 299 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86/svm_nested_pat_test.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 58eee0474db6..dddaaa6ac157 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -110,6 +110,7 @@ TEST_GEN_PROGS_x86 +=3D x86/state_test TEST_GEN_PROGS_x86 +=3D x86/vmx_preemption_timer_test TEST_GEN_PROGS_x86 +=3D x86/svm_vmcall_test TEST_GEN_PROGS_x86 +=3D x86/svm_int_ctl_test +TEST_GEN_PROGS_x86 +=3D x86/svm_nested_pat_test TEST_GEN_PROGS_x86 +=3D x86/svm_nested_shutdown_test TEST_GEN_PROGS_x86 +=3D x86/svm_nested_soft_inject_test TEST_GEN_PROGS_x86 +=3D x86/tsc_scaling_sync diff --git a/tools/testing/selftests/kvm/x86/svm_nested_pat_test.c b/tools/= testing/selftests/kvm/x86/svm_nested_pat_test.c new file mode 100644 index 000000000000..08c1428969b0 --- /dev/null +++ b/tools/testing/selftests/kvm/x86/svm_nested_pat_test.c @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * KVM nested SVM PAT test + * + * Copyright (C) 2026, Google LLC. + * + * Test that KVM correctly virtualizes the PAT MSR and VMCB g_pat field + * for nested SVM guests: + * + * o With nested NPT disabled: + * - L1 and L2 share the same PAT + * - The vmcb12.g_pat is ignored + * o With nested NPT enabled: + * - Invalid g_pat in vmcb12 should cause VMEXIT_INVALID + * - L2 should see vmcb12.g_pat via RDMSR, not L1's PAT + * - L2's writes to PAT should be saved to vmcb12 on exit + * - L1's PAT should be restored after #VMEXIT from L2 + * - State save/restore should preserve both L1's and L2's PAT values + */ +#include +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" +#include "svm_util.h" + +#define L2_GUEST_STACK_SIZE 256 + +#define PAT_DEFAULT 0x0007040600070406ULL +#define L1_PAT_VALUE 0x0007040600070404ULL /* Change PA0 to WT */ +#define L2_VMCB12_PAT 0x0606060606060606ULL /* All WB */ +#define L2_PAT_MODIFIED 0x0606060606060604ULL /* Change PA0 to WT */ +#define INVALID_PAT_VALUE 0x0808080808080808ULL /* 8 is reserved */ + +/* + * Shared state between L1 and L2 for verification. + */ +struct pat_test_data { + uint64_t l2_pat_read; + uint64_t l2_pat_after_write; + uint64_t l1_pat_after_vmexit; + uint64_t vmcb12_gpat_after_exit; + bool l2_done; +}; + +static struct pat_test_data *pat_data; + +static void l2_guest_code(void) +{ + pat_data->l2_pat_read =3D rdmsr(MSR_IA32_CR_PAT); + wrmsr(MSR_IA32_CR_PAT, L2_PAT_MODIFIED); + pat_data->l2_pat_after_write =3D rdmsr(MSR_IA32_CR_PAT); + pat_data->l2_done =3D true; + vmmcall(); +} + +static void l2_guest_code_saverestoretest(void) +{ + pat_data->l2_pat_read =3D rdmsr(MSR_IA32_CR_PAT); + + GUEST_SYNC(1); + GUEST_ASSERT_EQ(rdmsr(MSR_IA32_CR_PAT), pat_data->l2_pat_read); + + wrmsr(MSR_IA32_CR_PAT, L2_PAT_MODIFIED); + pat_data->l2_pat_after_write =3D rdmsr(MSR_IA32_CR_PAT); + + GUEST_SYNC(2); + GUEST_ASSERT_EQ(rdmsr(MSR_IA32_CR_PAT), L2_PAT_MODIFIED); + + pat_data->l2_done =3D true; + vmmcall(); +} + +static void l2_guest_code_multi_vmentry(void) +{ + pat_data->l2_pat_read =3D rdmsr(MSR_IA32_CR_PAT); + wrmsr(MSR_IA32_CR_PAT, L2_PAT_MODIFIED); + pat_data->l2_pat_after_write =3D rdmsr(MSR_IA32_CR_PAT); + vmmcall(); + + pat_data->l2_pat_read =3D rdmsr(MSR_IA32_CR_PAT); + pat_data->l2_done =3D true; + vmmcall(); +} + +static struct vmcb *l1_common_setup(struct svm_test_data *svm, + struct pat_test_data *data, + void *l2_guest_code, + void *l2_guest_stack) +{ + struct vmcb *vmcb =3D svm->vmcb; + + pat_data =3D data; + + wrmsr(MSR_IA32_CR_PAT, L1_PAT_VALUE); + GUEST_ASSERT_EQ(rdmsr(MSR_IA32_CR_PAT), L1_PAT_VALUE); + + generic_svm_setup(svm, l2_guest_code, l2_guest_stack); + + vmcb->save.g_pat =3D L2_VMCB12_PAT; + vmcb->control.intercept &=3D ~(1ULL << INTERCEPT_MSR_PROT); + + return vmcb; +} + +static void l1_assert_l2_state(struct pat_test_data *data, uint64_t expect= ed_pat_read) +{ + GUEST_ASSERT(data->l2_done); + GUEST_ASSERT_EQ(data->l2_pat_read, expected_pat_read); + GUEST_ASSERT_EQ(data->l2_pat_after_write, L2_PAT_MODIFIED); +} + +static void l1_svm_code_npt_disabled(struct svm_test_data *svm, + struct pat_test_data *data) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + struct vmcb *vmcb; + + vmcb =3D l1_common_setup(svm, data, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + run_guest(vmcb, svm->vmcb_gpa); + + GUEST_ASSERT_EQ(vmcb->control.exit_code, SVM_EXIT_VMMCALL); + l1_assert_l2_state(data, L1_PAT_VALUE); + + data->l1_pat_after_vmexit =3D rdmsr(MSR_IA32_CR_PAT); + GUEST_ASSERT_EQ(data->l1_pat_after_vmexit, L2_PAT_MODIFIED); + + GUEST_DONE(); +} + +static void l1_svm_code_invalid_gpat(struct svm_test_data *svm, + struct pat_test_data *data) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + struct vmcb *vmcb; + + vmcb =3D l1_common_setup(svm, data, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + vmcb->save.g_pat =3D INVALID_PAT_VALUE; + + run_guest(vmcb, svm->vmcb_gpa); + + GUEST_ASSERT_EQ(vmcb->control.exit_code, SVM_EXIT_ERR); + GUEST_ASSERT(!data->l2_done); + + GUEST_DONE(); +} + +static void l1_svm_code_npt_enabled(struct svm_test_data *svm, + struct pat_test_data *data) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + struct vmcb *vmcb; + + vmcb =3D l1_common_setup(svm, data, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + run_guest(vmcb, svm->vmcb_gpa); + + GUEST_ASSERT_EQ(vmcb->control.exit_code, SVM_EXIT_VMMCALL); + l1_assert_l2_state(data, L2_VMCB12_PAT); + + data->vmcb12_gpat_after_exit =3D vmcb->save.g_pat; + GUEST_ASSERT_EQ(data->vmcb12_gpat_after_exit, L2_PAT_MODIFIED); + + data->l1_pat_after_vmexit =3D rdmsr(MSR_IA32_CR_PAT); + GUEST_ASSERT_EQ(data->l1_pat_after_vmexit, L1_PAT_VALUE); + + GUEST_DONE(); +} + +static void l1_svm_code_saverestore(struct svm_test_data *svm, + struct pat_test_data *data) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + struct vmcb *vmcb; + + vmcb =3D l1_common_setup(svm, data, l2_guest_code_saverestoretest, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + run_guest(vmcb, svm->vmcb_gpa); + + GUEST_ASSERT_EQ(vmcb->control.exit_code, SVM_EXIT_VMMCALL); + GUEST_ASSERT(data->l2_done); + + GUEST_ASSERT_EQ(rdmsr(MSR_IA32_CR_PAT), L1_PAT_VALUE); + GUEST_ASSERT_EQ(vmcb->save.g_pat, L2_PAT_MODIFIED); + + GUEST_DONE(); +} + +static void l1_svm_code_multi_vmentry(struct svm_test_data *svm, + struct pat_test_data *data) +{ + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + struct vmcb *vmcb; + + vmcb =3D l1_common_setup(svm, data, l2_guest_code_multi_vmentry, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + run_guest(vmcb, svm->vmcb_gpa); + GUEST_ASSERT_EQ(vmcb->control.exit_code, SVM_EXIT_VMMCALL); + + GUEST_ASSERT_EQ(data->l2_pat_after_write, L2_PAT_MODIFIED); + GUEST_ASSERT_EQ(vmcb->save.g_pat, L2_PAT_MODIFIED); + GUEST_ASSERT_EQ(rdmsr(MSR_IA32_CR_PAT), L1_PAT_VALUE); + + vmcb->save.rip +=3D 3; /* vmmcall */ + run_guest(vmcb, svm->vmcb_gpa); + + GUEST_ASSERT_EQ(vmcb->control.exit_code, SVM_EXIT_VMMCALL); + GUEST_ASSERT(data->l2_done); + GUEST_ASSERT_EQ(data->l2_pat_read, L2_PAT_MODIFIED); + GUEST_ASSERT_EQ(rdmsr(MSR_IA32_CR_PAT), L1_PAT_VALUE); + + GUEST_DONE(); +} + +static void run_test(void *l1_code, const char *test_name, bool npt_enable= d, + bool do_save_restore) +{ + struct pat_test_data *data_hva; + vm_vaddr_t svm_gva, data_gva; + struct kvm_x86_state *state; + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + struct ucall uc; + + pr_info("Testing: %s\n", test_name); + + vm =3D vm_create_with_one_vcpu(&vcpu, l1_code); + if (npt_enabled) + vm_enable_npt(vm); + + vcpu_alloc_svm(vm, &svm_gva); + + data_gva =3D vm_vaddr_alloc_page(vm); + data_hva =3D addr_gva2hva(vm, data_gva); + memset(data_hva, 0, sizeof(*data_hva)); + + if (npt_enabled) + tdp_identity_map_default_memslots(vm); + + vcpu_args_set(vcpu, 2, svm_gva, data_gva); + + for (;;) { + vcpu_run(vcpu); + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); + + switch (get_ucall(vcpu, &uc)) { + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + /* NOT REACHED */ + case UCALL_SYNC: + if (do_save_restore) { + pr_info(" Save/restore at sync point %ld\n", + uc.args[1]); + state =3D vcpu_save_state(vcpu); + kvm_vm_release(vm); + vcpu =3D vm_recreate_with_one_vcpu(vm); + vcpu_load_state(vcpu, state); + kvm_x86_state_cleanup(state); + } + break; + case UCALL_DONE: + pr_info(" PASSED\n"); + kvm_vm_free(vm); + return; + default: + TEST_FAIL("Unknown ucall %lu", uc.cmd); + } + } +} + +int main(int argc, char *argv[]) +{ + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM)); + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_NPT)); + TEST_REQUIRE(kvm_has_cap(KVM_CAP_NESTED_STATE)); + + run_test(l1_svm_code_npt_disabled, "nested NPT disabled", false, false); + + run_test(l1_svm_code_invalid_gpat, "invalid g_pat", true, false); + + run_test(l1_svm_code_npt_enabled, "nested NPT enabled", true, false); + + run_test(l1_svm_code_saverestore, "save/restore", true, true); + + run_test(l1_svm_code_multi_vmentry, "multiple entries", true, false); + + return 0; +} --=20 2.53.0.rc2.204.g2597b5adb4-goog