From nobody Thu Apr 2 19:00:04 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 D3B2034BA42 for ; Thu, 26 Mar 2026 17:50:01 +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=1774547403; cv=none; b=AUNikc35Z8mkvrioIkcM4bUNEGDMhzXZi2ZcfQFN7L89PfOw4+a+wQ28RR/8PWRj35Cdf9Y6nlb4Me1zc3nLZlYN2SZEEuO8edDMkpRNr1QFQrE2OCGzCrIhVqINEfTThO0paoGPlf6gUcdKCFGOYg0N/k6tDfCQsEIFrb8EekE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547403; c=relaxed/simple; bh=4vsIq1VfSzTSyTEBFa61is6eowpApyT+KkPsKzqgDyU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PuuHyJZqD+yf++gW5XFis9CGkFFBwhg/wPJ2O7SWTHV6v4zX1spBG1im2rqy4Bbh7cQ4rR66MquJPXoHKhw4yoNqVvntw2Mzc7TC9+Lqg7UoY83WyDLLI77He0GIRDPbTQLij5s8Ajm727w7MJ4ULyfXLTAXcifGPi+4C86q8sE= 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=wlhT16vQ; 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="wlhT16vQ" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2b0c92ff4ebso4384095ad.2 for ; Thu, 26 Mar 2026 10:50:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547401; x=1775152201; 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=/fxWdpT8ek9U1KpozmfT6zoWQuFICVRwtG9anfQiaBI=; b=wlhT16vQgD0/vOyxsqQrq2oZxLcsnfv2TfuvSnBCMk3LPfsBD+s+NCG44F0BAxvbNW R4r9GVHCwz/u4u8PY3hT8Am+I7RLaED9c5aRCUnKVuPNpvpGnLDZ+q1BePR2NyN+PuCJ LxHXrkypm4IV0B1n/NtZjGTmukUlLE0B+aN9/+LLdYcsezIWbxeTyFisrU+Hr3gQ+jQr eX/c/yypz2mETFfmwYYvq1Gz9I3j9cASxrts/7IJzx8y51XxKJ1eidQZzULZl9tFBbZD ftWqIWEoq41mmZ4fQVzw7Qaimmwp9F06mPZu5L0ktm/6FvLsh+stEIuYIJAGvcxHGXaC CeIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547401; x=1775152201; 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=/fxWdpT8ek9U1KpozmfT6zoWQuFICVRwtG9anfQiaBI=; b=pSuzzbXd3rgbhlmMxYBgBGrlrwuqVgiGr9O6tT8iPhq461eICmIFwe1K0okvsux9+B +4PnvaNhksLdVX/mIqoJB78nAkoiZLy+sqLv7m3y+PcA18TzpMbQG6zly+26x+nxWfSd M8rMD7VlRknmorejcJVZeKlVHRMtnUbPkcY0RhojRK7gk7hTQg8IcNeIgsEGq2mIXgEV l7UXSDQQMvPNV312IK2gzIc+mbpveb4t4DysJFO9NbSo/UKmgtz45I8CPuVNe45SOWmt JqxQO3HjAW0y6fJfOVBkgmhIx0RvDaL4VQDrSdiYdHvaMzGDaQR9msiohwMDuWH2nxHL B00A== X-Forwarded-Encrypted: i=1; AJvYcCWHKrbJTqymahUpT/DjMYoIeTuxSYw6KyAr5vtNkSs7fBUdolqfLkK8pKKjznL+2Ux5/NSPrNwPzFs/Clg=@vger.kernel.org X-Gm-Message-State: AOJu0Yy0FFNQrA8PhvOWk1qpVdju/ywMY4Kx5NAmxxS5/qDLMBzybroA SvA+Du2QqGQelKm+V1OKUnGXYgCBr9jJ3YA0xmudVQZSugKs185bE5yf2stGQoBweZdzDeExxWw SyOzwwrNj5ius1w== X-Received: from plll4.prod.google.com ([2002:a17:902:d044:b0:2ae:5344:9e72]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:ebc2:b0:2aa:d5e5:b136 with SMTP id d9443c01a7336-2b0b0af3befmr101915535ad.38.1774547401035; Thu, 26 Mar 2026 10:50:01 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:19 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-2-jmattson@google.com> Subject: [PATCH v6 01/10] KVM: x86: Define KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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" Define a quirk to control whether nested SVM shares L1's PAT with L2 (legacy behavior) or gives L2 its own independent gPAT (correct behavior per the APM). When the quirk is enabled (default), L2 shares L1's PAT, preserving the legacy KVM behavior. When userspace disables the quirk, KVM correctly virtualizes the PAT for nested SVM guests, giving L2 a separate gPAT as specified in the AMD architecture. Signed-off-by: Jim Mattson --- Documentation/virt/kvm/api.rst | 14 ++++++++++++++ arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/kvm/svm/svm.h | 7 +++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 032516783e96..2d56f17e3760 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -8551,6 +8551,20 @@ KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM By defaul= t, KVM relaxes the consisten bit to be cleared. Note that t= he vmcs02 bit is still completely control= led by the host, regardless of the quirk s= etting. + +KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT By default, KVM for nested SVM = guests + shares the IA32_PAT MSR between= L1 and + L2. This is legacy behavior and= does + not match the AMD architecture + specification. When this quirk = is + disabled and nested paging (NPT= ) is + enabled for L2, KVM correctly + virtualizes a separate guest PAT + register for L2, using the g_pat + field in the VMCB. When NPT is + disabled for L2, L1 and L2 cont= inue + to share the IA32_PAT MSR regar= dless + of the quirk setting. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 7.32 KVM_CAP_MAX_VCPU_ID diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index d3bdc9828133..0809d8f28208 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2511,7 +2511,8 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, = unsigned long npages); KVM_X86_QUIRK_SLOT_ZAP_ALL | \ KVM_X86_QUIRK_STUFF_FEATURE_MSRS | \ KVM_X86_QUIRK_IGNORE_GUEST_PAT | \ - KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM) + KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM \ + KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT) =20 #define KVM_X86_CONDITIONAL_QUIRKS \ (KVM_X86_QUIRK_CD_NW_CLEARED | \ diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kv= m.h index 5f2b30d0405c..3ada2fa9ca86 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -477,6 +477,7 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8) #define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9) #define KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM (1 << 10) +#define KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT (1 << 11) =20 #define KVM_STATE_NESTED_FORMAT_VMX 0 #define KVM_STATE_NESTED_FORMAT_SVM 1 diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index ff1e4b4dc998..67aa5d34332e 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -616,6 +616,13 @@ static inline bool nested_npt_enabled(struct vcpu_svm = *svm) return svm->nested.ctl.misc_ctl & SVM_MISC_ENABLE_NP; } =20 +static inline bool l2_has_separate_pat(struct vcpu_svm *svm) +{ + return nested_npt_enabled(svm) && + !kvm_check_has_quirk(svm->vcpu.kvm, + KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT); +} + static inline bool nested_vnmi_enabled(struct vcpu_svm *svm) { return guest_cpu_cap_has(&svm->vcpu, X86_FEATURE_VNMI) && --=20 2.53.0.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 5BC9D30E85D for ; Thu, 26 Mar 2026 17:50:03 +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=1774547406; cv=none; b=ua1SJ4lNLwpysnAue6wNBu5HYmZon5MBg5bJj0Ml5v+302jzZN/GC+XOsYVZs5pMXz/Ad57ih65dYqQJTPyWjB9oDXBmF764YH8vffcMnfDY4an4ahVHQccqh3J1AP4/kHaHhYxNd4i0ss3KBY75g0upM04sMYLsMlyXpUOXvos= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547406; c=relaxed/simple; bh=tZ12QRR3FmdWK+NRPEzhTArwt9NG+814P1E0pPf9rCg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=K27VQX8NdV2+Y0SmnY90PzxAJR0LSgC+R64uJAsShiZQ49+C8s3L2Ls4+DrFodp9H3wjrek8nsXZAZmY9E0wiyjxbPkCxpVOVL5902m9Ql2aY4054Z5Y5LYYijhs00hzej+1h503uNpzgzNTjO6O07MzquhdE6UgogORhujQh3k= 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=YEj/gFP5; 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="YEj/gFP5" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-354bc535546so1413726a91.3 for ; Thu, 26 Mar 2026 10:50:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547403; x=1775152203; 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=/9d4uR3KG2j2870MKAm/vuBsQJvgm3m57WemQ0F9xCY=; b=YEj/gFP5cZnjK3nOOLceGPQlyqsnCT/PM3r+hdPDrWNio75hh3HugLZNJFDl66NPZA u/pe29ytxd95U6cL2oXxBxGXOjuOFV/v94zE8e/cr8AsaeElNG12HGTPCSqzZX+Rk1qB 3rjCQlJ3G5vaamxPFFur5EuIMuArvQDOW/Qf9+o5/nyW1fPcXAfKvlHwGzzM2x7Mwljv Mmut2jiiObt4f20A5C7pkS9v3KjZjVScieUT5jbp2zbdkpoBsIxagNvfNTYIwZWlLnd7 T1y0MvQhcmiPI1GdqkOFfe0zIPWWl5saEH3tlKkD3IzeC7qyGbYTL+bW4JWhpBVlAwFD VOmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547403; x=1775152203; 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=/9d4uR3KG2j2870MKAm/vuBsQJvgm3m57WemQ0F9xCY=; b=W55KCdlcmC8LOFMzSPWhrWKXW62TKbuLSp5aldAlZDJ10RsMAOoml9sNE+K4jf1/Hu KMbnpSAS3jRl29Zt5SugfaSnfcH5DGYFM05WwKwe64iBsJAc+4W+HZogeYBfIEgTjeh9 m/r65f8qhzYIplJYie4f4EkcCC0xS9/bAc5zvZn8ruHvl/8JstOPPZaAOUeDTZny+n78 xD2Ftkfxxu5rhINlhHiUSPJjBb4J++0x0cJ8S2HHTgC+aOUp5NmbcrMu87MQ5NOBIqwm houPHjSg+JYmMza/y+Pf2lXngbUeYQ+lx3/POoFT0+TFln5/7hv5Rx6OHyqn/g2LlwgF kRkA== X-Forwarded-Encrypted: i=1; AJvYcCVwdH8lS89akKZzWdEjpMEJ0KI1gnYqF8+KXWDM5fiRLD73a65Oq/dnwpj39CqekH7PN/3IWT5tTZf5xjs=@vger.kernel.org X-Gm-Message-State: AOJu0YwA+WEBiv9R4ReK9tgLw3yS5v+DTvBkb3AJpnyQYFDrYn9KGn8c Q0noSTCkmoekpmZnOQEBojiE1Tx9kMa8XTArJ73GtfNMIWILu7Pp+tNJXiRxB/pJRyHfc/ovLl3 VEzkv/vQg7NQzuw== X-Received: from pjbbb10.prod.google.com ([2002:a17:90b:8a:b0:35c:2d1e:7123]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90a:fc45:b0:340:25f0:a9b with SMTP id 98e67ed59e1d1-35c0ddaa96emr7892201a91.33.1774547402493; Thu, 26 Mar 2026 10:50:02 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:20 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-3-jmattson@google.com> Subject: [PATCH v6 02/10] KVM: x86: nSVM: Clear VMCB_NPT clean bit when updating hPAT from guest mode From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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 both vmcb01's g_pat field and vmcb02's g_pat field, but the clean bit was only being cleared for vmcb02. Introduce the helper vmcb_set_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' NPT fields 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 5ff01d2ac85e..32fa8e688c00 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -697,7 +697,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; + vmcb_set_gpat(svm->nested.vmcb02.ptr, svm->vmcb01.ptr->save.g_pat); } =20 static bool nested_vmcb12_has_lbrv(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index d2ca226871c2..af808e83173e 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2979,10 +2979,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; + vmcb_set_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 67aa5d34332e..0f0c08c5ce0c 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -439,6 +439,12 @@ static inline bool vmcb12_is_dirty(struct vmcb_ctrl_ar= ea_cached *control, int bi return !test_bit(bit, (unsigned long *)&control->clean); } =20 +static inline void vmcb_set_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.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 2C0EC3A545F for ; Thu, 26 Mar 2026 17:50:05 +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=1774547406; cv=none; b=uAgZEzt4ve1dfO2QNRr/tRo6Kblfo62EpD2eAv4/k+7MLa3+PNKvvD4RQRcHcVAmN9NrqKHpTU5z76J5ps3K5BWXfcRi6oLwmgiLsDd7KOsNE012hL9vCSRIEBB8qH7nxxgSLMdjfgMM878JX0fZD4mRg7IoLvPSJ46yVitbO1M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547406; c=relaxed/simple; bh=7SI+MHaHsHfhtgMbQHFaI8EaRKrXuYVzdDzUpM37mAE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=IgJI3a5TosF7NPHNBHUKXmHPqZJfouGarkXPqBM4Hko103VmOwh+jbVpoMrxOmTid33BMh2649Tp3ZTjKNbiv/oyZgE88Q8/dKNjlJrArUsw2xKeOsLJQSwWFjkoiEkrFuboFdnrAAJiRa9s8Q2GC+f6O95L9f782PSsRPFJlsw= 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=Njh/rOS/; 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="Njh/rOS/" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-35c1874336aso3788037a91.3 for ; Thu, 26 Mar 2026 10:50:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547404; x=1775152204; 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=dAH8qf9G0XQlUHg8hq3D+h8w7UbFbHHt2UywU7wF7JE=; b=Njh/rOS/DQpG/JBpBRz9hHreITlszVQxp/rdncGTtRmb9fwU2u6PMyXh6KulaEGX2r Ie0CICDKukhmEkKglwgB8ie7VC7Pr4+L5j5iYEx5t0rl0Tb1BAK3QJl0TYwI+BMzbyZm a3VzllUAi0FjlPL/v9XeXC3nwWLk0Z/VFmsxePXIuxmPg2mvFDmBFdzqedt0RZFcxc5L fKjsFeQ2+tC8MSD2eMz48qH5yGu1R3vnTyc7VsfhpkAtA4pvkuYF0DLkt09qJBmS7lHA cfzs0e3eIUpy4NVpHPKBQPhVXXtmcv1xMf4O0zdKMWSJb8gKf+jogcWcxym9QDMaaMZL zT/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547404; x=1775152204; 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=dAH8qf9G0XQlUHg8hq3D+h8w7UbFbHHt2UywU7wF7JE=; b=mz8XT73XM6IFIzknPzDg4XlV8OS/LcqJAwpx1i29ieE9O0G32IgULi7FWci0UglAV4 OHwT24R2oMLslDGN0kIQqwVBwqzd3MLRJTRiUTVcCTfiwQ7YFPc9zylp9m1hDjc6N1wD ahvEJgM6NlU8F0Q2vtoB6UkTIf+uLm8yLYVRVvVYqqSvs7FgptAKfM1UHGx7IAVYeCxj NlUbgLJXMrZX++79rlCtBYOjIgFZUqBBrXVoqA8B6dg238BkxsO6ixiAafSEKJCg31Gj R3/bp1Ik/3A6qfoCpJDj8wLXV7RRuGBkGgUqY4HGLnxBjvrpO+UsoUaZum32BVxRuG/h 8ZnA== X-Forwarded-Encrypted: i=1; AJvYcCWRnf8ghjituHXtdzQ2C/8ip7CKyXk6ZEkglaGns4kScA98hj2AYnzItWTWt0FuRkPP3THb8tx9qhuMAfk=@vger.kernel.org X-Gm-Message-State: AOJu0YxLawdV5SfHvckVuVXHVD46qCPx9zOQHGDktNUkRRO0+HgVeuFr 6AV+Fnz9emSPslmeYFdFGcBqiE9WUDOFFyfa9hkueZq3CpKV8p2O4C1iOgBWXnlfD+5nvZ8345p IYA6BFgJN9q8Fwg== X-Received: from pjbie10.prod.google.com ([2002:a17:90b:400a:b0:35a:294:ab56]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90a:e183:b0:35b:9d0c:a2f5 with SMTP id 98e67ed59e1d1-35c0ddf1215mr8406645a91.33.1774547404300; Thu, 26 Mar 2026 10:50:04 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:21 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-4-jmattson@google.com> Subject: [PATCH v6 03/10] KVM: x86: nSVM: Cache and validate vmcb12 g_pat From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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 KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT is disabled and nested paging is enabled in vmcb12, validate g_pat at emulated VMRUN and cause an immediate VMEXIT with exit code VMEXIT_INVALID if it is 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/include/asm/kvm_host.h | 2 +- arch/x86/kvm/svm/nested.c | 17 +++++++++++++---- arch/x86/kvm/svm/svm.h | 1 + 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 0809d8f28208..0b4ab141feae 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2511,7 +2511,7 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, = unsigned long npages); KVM_X86_QUIRK_SLOT_ZAP_ALL | \ KVM_X86_QUIRK_STUFF_FEATURE_MSRS | \ KVM_X86_QUIRK_IGNORE_GUEST_PAT | \ - KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM \ + KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM | \ KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT) =20 #define KVM_X86_CONDITIONAL_QUIRKS \ diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 32fa8e688c00..0ad1e0348492 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -410,7 +410,8 @@ static bool nested_vmcb_check_controls(struct kvm_vcpu = *vcpu, =20 /* Common checks that apply to both L1 and L2 state. */ static bool nested_vmcb_check_save(struct kvm_vcpu *vcpu, - struct vmcb_save_area_cached *save) + struct vmcb_save_area_cached *save, + bool check_gpat) { if (CC(!(save->efer & EFER_SVME))) return false; @@ -445,6 +446,9 @@ static bool nested_vmcb_check_save(struct kvm_vcpu *vcp= u, if (CC(!kvm_valid_efer(vcpu, save->efer))) return false; =20 + if (check_gpat && CC(!kvm_pat_valid(save->g_pat))) + return false; + return true; } =20 @@ -452,7 +456,8 @@ int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcp= u) { struct vcpu_svm *svm =3D to_svm(vcpu); =20 - if (!nested_vmcb_check_save(vcpu, &svm->nested.save) || + if (!nested_vmcb_check_save(vcpu, &svm->nested.save, + l2_has_separate_pat(svm)) || !nested_vmcb_check_controls(vcpu, &svm->nested.ctl)) return -EINVAL; =20 @@ -562,6 +567,7 @@ static void __nested_copy_vmcb_save_to_cache(struct vmc= b_save_area_cached *to, =20 to->rax =3D from->rax; to->cr2 =3D from->cr2; + to->g_pat =3D from->g_pat; =20 svm_copy_lbrs(to, from); } @@ -1971,13 +1977,16 @@ static int svm_set_nested_state(struct kvm_vcpu *vc= pu, =20 /* * Validate host state saved from before VMRUN (see - * nested_svm_check_permissions). + * nested_svm_check_permissions). Note that the g_pat field is not + * validated, because (a) it may have been clobbered by SMM before + * KVM_GET_NESTED_STATE, and (b) it is not loaded at emulated + * #VMEXIT. */ __nested_copy_vmcb_save_to_cache(&save_cached, save); if (!(save->cr0 & X86_CR0_PG) || !(save->cr0 & X86_CR0_PE) || (save->rflags & X86_EFLAGS_VM) || - !nested_vmcb_check_save(vcpu, &save_cached)) + !nested_vmcb_check_save(vcpu, &save_cached, false)) goto out_free; =20 =20 diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 0f0c08c5ce0c..3588f6d3fb9b 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -161,6 +161,7 @@ struct vmcb_save_area_cached { u64 isst_addr; u64 rax; u64 cr2; + u64 g_pat; u64 dbgctl; u64 br_from; u64 br_to; --=20 2.53.0.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 D54D23C661A for ; Thu, 26 Mar 2026 17:50:06 +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=1774547408; cv=none; b=cFh8Idl1qWPvuVX1+2d+InXyvCGnQwsns/1k/ZZ5NWGRjNp0injWFIMmS1zCYHzGCFF6P3DfSiEC6+t9BWGSaUNiTHxIpOtXbvzJQiI8PGtlktkAkWkVnjU6bOjk+s3KSnsIfyaVPza3XxU9pe5/vpRs12Zdb0ye9uP60vul5no= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547408; c=relaxed/simple; bh=yXQYjGUPut6PXkdfSl0YRjFdLTlF4PK0M5tnPbSrd0s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=o7m0Upc196rm3uDPQSeNtRv8rZ/pJLluHEgsGT4YJjJoh/ZjHOOyPJjv/fsXO0RRGiJntuAwZhbj4rXhdGOcatC2/S0OZklhrpnpkcq9E/VM7ypnKwiepMwbPdd0lAdqhX/3oPZiJni3XxkFpzGWqXD5/zT0GetaKJMCTLN1F1g= 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=ZY2Ci+rt; 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="ZY2Ci+rt" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2b0c92ff4ebso4385255ad.2 for ; Thu, 26 Mar 2026 10:50:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547406; x=1775152206; 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=A0q74nR0onjV0BK2f2Df6n+ntIHSSjqGFZqE9Y1ouTk=; b=ZY2Ci+rtjocYXKdoxe2xkSmkz5kEfJqCeT1H6LOHL1yxOjs1T8n8TV5VwH/c83JnzQ dkJ5ooEHVrsGIJkI+1n9cMDeVp+H6yglucu+lr4akKukEdYJpiEXx+/2jfR7GMJritu4 bU7+7v74FIYJ8dDMOE0aG/d8gXOVOOgMncafVWlgQSldedJAdTyKLGfgUWe/kVbJxlpK buOMAlX7hRZm6TZ0rxDFZUXWyzxXVQBpg00iDl2KOTTzHSf9N81jWwzA6r2F3/MmWpGG wYZ+W+olvRHL7m112O1cjtKK5vTBAajZDog14jcry0C22LiGvHR2nRc/Yfd5Pa6cCq3J /I3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547406; x=1775152206; 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=A0q74nR0onjV0BK2f2Df6n+ntIHSSjqGFZqE9Y1ouTk=; b=TmAku9b+vk6Lz2vKd0CEuYtcKWbjEqtHQzktCE/s/Jg5Zs4zkNpGxUkH4Cq+JszN8R inVxakhbdbpEdNCWSyT8ksFIC6U71S1toS/9vEF4tMK6u7q/x7FP4hQnmuh5fRs9sHQp 0EjcPNU+68vbn4lQLuKhZitORkS2D+uAvnuMomltJgsB0MuQ8KN7AeSFVpnBfsAhrR1M ovHQY3GWZmrbY1uQsBoSxgjgLUvwdq1NeIQ6P35tX5zkQnqiPBscZU/eNZlQfWjO7d6U w7TAC9cGfYkw87Ltbyan1oRQzMLrl737P09J+0cswOZfliArCfee+lbKVzOyfRoKQWwQ kkMA== X-Forwarded-Encrypted: i=1; AJvYcCXmAt8FYNK39C1Xq+cpRaPG33c0ys0/hXvMbnF+T6LV8SUETchKz77x6DagtsatSQEepX3QjjYe6QidYXI=@vger.kernel.org X-Gm-Message-State: AOJu0Ywz5VDGJ/eSqDxa5CuTHeePChkwhzXJXF1UGhLgqztgJ2eDtyZY vFHKKcwHdexLZV/Vuw5NMjl19Fjraon9aguNZFhujEGAgjT9f2PP5NdPZeRmhjCfxHfDEjQFGT6 W9JdOihQnHV8P9Q== X-Received: from plbku14.prod.google.com ([2002:a17:903:288e:b0:2b0:ae36:890]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1b45:b0:2b0:5fa5:a68c with SMTP id d9443c01a7336-2b0b09a0aafmr93375115ad.9.1774547406079; Thu, 26 Mar 2026 10:50:06 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:22 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-5-jmattson@google.com> Subject: [PATCH v6 04/10] KVM: x86: nSVM: Set vmcb02.g_pat correctly for nested NPT From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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 KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT is disabled and nested NPT is enabled in vmcb12, copy the (cached and validated) vmcb12 g_pat field to vmcb02's g_pat, giving L2 its own independent guest PAT register. When the quirk is enabled (default), or 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 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 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 0ad1e0348492..405209f8c4cd 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -721,9 +721,6 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm = *svm) 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; @@ -754,6 +751,13 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm= *svm) vmcb_mark_dirty(vmcb02, VMCB_CET); } =20 + if (l2_has_separate_pat(svm)) { + if (unlikely(new_vmcb12 || vmcb12_is_dirty(control, VMCB_NPT))) + vmcb_set_gpat(vmcb02, svm->nested.save.g_pat); + } else if (npt_enabled) { + vmcb_set_gpat(vmcb02, vcpu->arch.pat); + } + kvm_set_rflags(vcpu, save->rflags | X86_EFLAGS_FIXED); =20 svm_set_efer(vcpu, svm->nested.save.efer); --=20 2.53.0.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 B6FAB421EF7 for ; Thu, 26 Mar 2026 17:50:08 +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=1774547411; cv=none; b=o9AJ+iTI5RdsHiq9TRl8hkPRNdClGbsLRQW1VjZBV441a2iwH1MgXAgx13DnWZ9ZphfKmYrF9Y0J28pvyvi3Xmmg+60dYjei5wqwM3eHe6tJ25qebec06q4WmxJUtRgA1LOMPZo3DzZL1V13kf7gr+2KfXeOt+/HD4tPEARU1m0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547411; c=relaxed/simple; bh=X62HksLg050YL9v3riIZda6b41B7umKzI21DaTgbf/k=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Sqaq9kAY+tdvad2HI2aX9odUXPIeYcXMbHYD+ibANW6t8iH1ShKU5gQPLJh6k0j3HOkFQR9qzLvCon3DS0rJsH1bG5H7Kcet0hJ56ZNnZQwlNQlS8DUHMWVzFXkrEfSmjnhDzU2HafWy36KuEIDREwLdcI1ME+Sqp8JIHVz+Yc0= 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=JjWmzHeT; 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="JjWmzHeT" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-35c2dc274bdso72994a91.3 for ; Thu, 26 Mar 2026 10:50:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547408; x=1775152208; 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=A9S2mDvA0dSmiYZiR+DNxsk39toXNnVepGluK15UcSI=; b=JjWmzHeTVfG0PLNnrvcQFZ5T6HiSSZmY4UB434zas6nYQTepL5rtQ6PFNla9QyGs50 vffP5EbcM0loWJuT+w8/nINFkaZGiMz4FV2QPlVKL1sN5pIZbYT8t9z77mFUw0hnPpGw ECHUrHkDpHY67DtaZNn2e20XY8mohiQR6gDfoEBQkr9OAEmJXxypgD3hlM8kmjS9u3xD G1+7ARZH9medELUmDBSABgiAjaJGP7bb4drDnIn59XbTGTq7X97bczzindkjt6j+4/il U33i2uMvxKfkv89990FWJLm/RJ3sVEj30wz8AArNE8YW05qBED6N/MbutqbfrCk64G82 n6cw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547408; x=1775152208; 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=A9S2mDvA0dSmiYZiR+DNxsk39toXNnVepGluK15UcSI=; b=hszdkJJLBJTOoSgBOnR5Ajm2jegWfFYtpxwsHUGDpdZNeGLbGC/MzIeTfXSPyATwFc KVl1/yyr+2SCeqEhFX6FReB0W/6FjKgU62jpzMzu/+BtEtfGpiz6s2qnC+pOYpjsmVrQ WU2x+U/lnlu2SKqH+WtPlgodko+/CqpUWJScvCnDc0mchUX+sZYWwQ/NXK1veaS6JvC0 j1AnqAzraoANe96SHfiboG4EudBonPAnpb8DCxUsCJQGjTUWVtFlGvC7pRj8b6//ERyL wVq6p4aOpcOUuvB5/qTiC5YAt56/c984OQFmkrz8BZR0kXeB0ONfJSv1E3hjt1WFc8CH tSzA== X-Forwarded-Encrypted: i=1; AJvYcCVDUZbHaF76bS2osrNYrGOSPHD/HZMHCA0SLebqMTC0T0vyfEVTiksE+LKEe7NTQWUS/iDl1Dug7UrgPN0=@vger.kernel.org X-Gm-Message-State: AOJu0YxiZSTTt/tebdPO6bhK2+GUOn337qBeY9bZSJfLylLjbMFTv1JX 9eZ8hJYqCzGOfZoZII+SlKQ9zGeMrOx6vJ9ZSI2vTnkamDlWTiZC2FO8e8eMIezPEFFaOiYafhK XyuCJEpRpX7De2g== X-Received: from pgww20.prod.google.com ([2002:a05:6a02:2c94:b0:c76:681a:7042]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:748a:b0:398:a060:a97b with SMTP id adf61e73a8af0-39c4aa57082mr9347105637.1.1774547407685; Thu, 26 Mar 2026 10:50:07 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:23 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-6-jmattson@google.com> Subject: [PATCH v6 05/10] KVM: x86: nSVM: Redirect IA32_PAT accesses to either hPAT or gPAT From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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 KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT is disabled and 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's g_pat field. Non-guest accesses (e.g. from userspace) to IA32_PAT are always redirected to hPAT, which is stored in vcpu->arch.pat. Directing host-initiated accesses to hPAT ensures that KVM_GET/SET_MSRS and KVM_GET/SET_NESTED_STATE are independent of each other and can be ordered arbitrarily during save and restore. gPAT is saved and restored separately via KVM_GET/SET_NESTED_STATE. Add WARN_ON_ONCE to flag any host-initiated accesses originating from KVM itself rather than userspace. Fixes: 15038e147247 ("KVM: SVM: obey guest PAT") Signed-off-by: Jim Mattson Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/nested.c | 9 ------- arch/x86/kvm/svm/svm.c | 53 ++++++++++++++++++++++++++++++++++----- arch/x86/kvm/svm/svm.h | 1 - 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 405209f8c4cd..14063bef36f1 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -697,15 +697,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. */ - vmcb_set_gpat(svm->nested.vmcb02.ptr, svm->vmcb01.ptr->save.g_pat); -} - static bool nested_vmcb12_has_lbrv(struct kvm_vcpu *vcpu) { return guest_cpu_cap_has(vcpu, X86_FEATURE_LBRV) && diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index af808e83173e..6cf5fa87b4d4 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2776,6 +2776,47 @@ static bool sev_es_prevent_msr_access(struct kvm_vcp= u *vcpu, !msr_write_intercepted(vcpu, msr_info->index); } =20 +static bool svm_pat_accesses_gpat(struct kvm_vcpu *vcpu, bool from_host) +{ + struct vcpu_svm *svm =3D to_svm(vcpu); + + /* + * 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 so that + * KVM_GET/SET_MSRS and KVM_GET/SET_NESTED_STATE are independent of + * each other and can be ordered arbitrarily during save and restore. + */ + WARN_ON_ONCE(from_host && vcpu->wants_to_run); + return !from_host && is_guest_mode(vcpu) && l2_has_separate_pat(svm); +} + +static u64 svm_get_pat(struct kvm_vcpu *vcpu, bool from_host) +{ + if (svm_pat_accesses_gpat(vcpu, from_host)) + return to_svm(vcpu)->vmcb->save.g_pat; + else + return vcpu->arch.pat; +} + +static void svm_set_pat(struct kvm_vcpu *vcpu, bool from_host, u64 data) +{ + struct vcpu_svm *svm =3D to_svm(vcpu); + + if (svm_pat_accesses_gpat(vcpu, from_host)) { + vmcb_set_gpat(svm->vmcb, data); + return; + } + + svm->vcpu.arch.pat =3D data; + + if (npt_enabled) { + vmcb_set_gpat(svm->vmcb01.ptr, data); + if (is_guest_mode(&svm->vcpu) && !nested_npt_enabled(svm)) + vmcb_set_gpat(svm->vmcb, data); + } +} + static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct vcpu_svm *svm =3D to_svm(vcpu); @@ -2892,6 +2933,9 @@ 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: + msr_info->data =3D svm_get_pat(vcpu, msr_info->host_initiated); + break; default: return kvm_get_msr_common(vcpu, msr_info); } @@ -2975,13 +3019,10 @@ 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 - vmcb_set_gpat(svm->vmcb01.ptr, data); - if (is_guest_mode(vcpu)) - nested_vmcb02_compute_g_pat(svm); + svm_set_pat(vcpu, msr->host_initiated, 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 3588f6d3fb9b..220b8cb0c80f 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -864,7 +864,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.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 7D209410D38 for ; Thu, 26 Mar 2026 17:50:10 +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=1774547415; cv=none; b=fjbNb2MiwonnM/yv9i3QzBDvn7T3CL0vn+7m/VJvJCQYqipxGOIahf4LrH4BWNlU9XRiAM8N06+YTWMff9nRUV0b2hm/6UFBeX/ga6129UxnHxIBGk43/pcREulR6X4ZbIkCccKgC4Jd+i+Z7ZJUg5ZCIxvuw17TfJmjtFGx3Gk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547415; c=relaxed/simple; bh=BujWcctDq6eMuBK2P/8WUsaw3dQtOodTquIl5Xa9hFY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=plQfULjAEGx+PpdhkjDwCR8I8CGkemHhWeGNHT6iW9sLGfp5BL0tuBAVy1/B6Z/eugV21lqFBEYhwEoRvPEch0t4LsoJIXwNvRCtr9jCyi+219ns3ApaXcCQ2afr1LLYkFTuLoMTigXw+U6ps364KonOpYDm79AZKLiOQJ67MmI= 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=kenaLQ/U; 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="kenaLQ/U" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2adc527eaf5so10669635ad.0 for ; Thu, 26 Mar 2026 10:50:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547409; x=1775152209; 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=tLQEnswVcn2VF9Qdewg1FETHaeEFo8aaED/NYmj5Qz0=; b=kenaLQ/UIGY8iguqyNs5tNy+AcnSO/Cym/YJy2S//tVjmP7yPlOtfcmBmTm82Vq6pU GP5NHyVjB1W2KTzn+TBE/6a2wpHqlI4aCdaOh8WA01Ylnnjn/gQ27yKH9eo58aGzrSbM 48KRP44gjO16xdrFFhnrhv86/47cMynrlN3TtMQBEBWzDsdFN3UBpgdQTZD1miZiTeyT J+zNaum7by4FLaUcpjdzJWbA1yYx1cK4jGYnCMCorPvrw3Xs7Ru9IZs67qefiOiX7OXB AZXrtlw6Mm0110KQIwFlRVEno8bEeSzelo0v3bnyLl6ysEJiHCpPx9WFv0/4tOhWdOhA IvoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547409; x=1775152209; 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=tLQEnswVcn2VF9Qdewg1FETHaeEFo8aaED/NYmj5Qz0=; b=T9gKSdDuzlYWeNKvUZrObshLdP31lKHlTlkFuECtXApYkbGNa6oq3JYrh8aZ2wQZ/4 IYxqXwmkr7XmRcZIf11SmM0cjBb3b9HeahLtz40O+UV+fq4nEbGR2HStei03F4ACdDtP gkpxuBuS3TA+xQtCXeg7OTUng8ltM+8X3otZYD+MLc+xVm/2Te4CpEBQRunRQqj07wVY YIqSe7qbw9PUusIx0J+g+BNkDJE2RGmACy5OyaH/XN40dy/iXHH0NOa8xegti6rUNeXT vodNKU1Tq5fCLvxmbxO6pJWzYhpsS9fbmyXhobhct/i+n7dFToj3rqVNFrlsdJDuNDMn s6lQ== X-Forwarded-Encrypted: i=1; AJvYcCWvmVUldqWFAQMaggmbteDtVMV+925p/IrVXfJYEgU+h395hjcXfWBi9kpIKdVoTzWGj5EhGi9EX4LGltM=@vger.kernel.org X-Gm-Message-State: AOJu0Yzv32VSdlKTXxCxJqGkNW3fKz5KvI5l5nRgHJvQ0t8KR/RGybCl 4nAJGUOR6f5vsQdqo35O7iOWLP7cCE8Fr8da8FoUnB2BxbTT5x1QaevRaHKamk1wpPqz992tw1z prLDmG3u30daztA== X-Received: from pli5.prod.google.com ([2002:a17:902:c105:b0:2b0:495c:f3ec]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:d501:b0:2b0:b1e2:583 with SMTP id d9443c01a7336-2b0b1e22151mr92551175ad.2.1774547409214; Thu, 26 Mar 2026 10:50:09 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:24 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-7-jmattson@google.com> Subject: [PATCH v6 06/10] KVM: x86: Remove common handling of MSR_IA32_CR_PAT From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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" SVM now has completely independent handling of MSR_IA32_CR_PAT in svm_get_msr() and svm_set_msr(). To avoid any confusion, move the logic for MSR_IA32_CR_PAT from kvm_get_msr_common() and kvm_set_msr_common() into vmx_get_msr() and vmx_set_msr(). Signed-off-by: Jim Mattson --- arch/x86/kvm/vmx/vmx.c | 9 ++++++--- arch/x86/kvm/x86.c | 9 --------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index b15b4662b653..d87585a42736 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2110,6 +2110,9 @@ int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_dat= a *msr_info) !(vcpu->arch.arch_capabilities & ARCH_CAP_TSX_CTRL_MSR)) return 1; goto find_uret_msr; + case MSR_IA32_CR_PAT: + msr_info->data =3D vcpu->arch.pat; + break; case MSR_IA32_UMWAIT_CONTROL: if (!msr_info->host_initiated && !vmx_has_waitpkg(vmx)) return 1; @@ -2432,10 +2435,10 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_d= ata *msr_info) return 1; goto find_uret_msr; case MSR_IA32_CR_PAT: - ret =3D kvm_set_msr_common(vcpu, msr_info); - if (ret) - break; + if (!kvm_pat_valid(data)) + return 1; =20 + vcpu->arch.pat =3D data; if (is_guest_mode(vcpu) && get_vmcs12(vcpu)->vm_exit_controls & VM_EXIT_SAVE_IA32_PAT) get_vmcs12(vcpu)->guest_ia32_pat =3D data; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0b5d48e75b65..56857da9bda6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4024,12 +4024,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct= msr_data *msr_info) return 1; } break; - case MSR_IA32_CR_PAT: - if (!kvm_pat_valid(data)) - return 1; - - vcpu->arch.pat =3D data; - break; case MTRRphysBase_MSR(0) ... MSR_MTRRfix4K_F8000: case MSR_MTRRdefType: return kvm_mtrr_set_msr(vcpu, msr, data); @@ -4435,9 +4429,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct = msr_data *msr_info) msr_info->data =3D kvm_scale_tsc(rdtsc(), ratio) + offset; break; } - case MSR_IA32_CR_PAT: - msr_info->data =3D vcpu->arch.pat; - break; case MSR_MTRRcap: case MTRRphysBase_MSR(0) ... MSR_MTRRfix4K_F8000: case MSR_MTRRdefType: --=20 2.53.0.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 C8E0E423A7A for ; Thu, 26 Mar 2026 17:50:12 +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=1774547415; cv=none; b=T0qOP1s3ku+ugT1tfJSkdszCsSZdK+0QHlxswtVRclosMv9jxUFcAi1YGgJaIclir0r2MTc/8BnpUrkG54GZ0gxXetMaNAIOE46NlzXnk1LXROs9BigCTkEdYHhL5qk8Px9QqdIf6vffT9X9bjb0+DvQ23nHmW4xxMXc2DIUG9c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547415; c=relaxed/simple; bh=Y9rMXPhwhSPq2CcDwI9mgpPoQnii2Yurx3TfkOypRiU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=nrZF0fycrKT8Q6UtgDimcnpasctB9Wo9LcDMoBS4xtIn/skRJCtowkn5kkfU8CMLzZ5xUAhlOLlGAReJlA4KSU4V2HgF9KjsvGgmbB7shwl3hErEJRh17kCpTiM3gSdyJgpEUNnl6TvYH9iSR1yaIp7mhFVa1kmzfCWTc9J11cQ= 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=Pkwfwd50; 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="Pkwfwd50" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-35c12a3bbb9so1553010a91.3 for ; Thu, 26 Mar 2026 10:50:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547411; x=1775152211; 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=Jfn2M6k7bFpE7gypyjWrhFKs9Q/vfTaHTPk+frkTN9U=; b=Pkwfwd50S7d58+AQ4f3JKRAZCtl3E0VEqrqDH+eHc5x+6Av6VPxYRATHZ/gB7jNiUC SQpCPP7WernkPLo6fj4BSXJcpXhtKPrARPfX7/AJz4u8jR7C8NG31Lmolq+irL3aouBP Tx33Q+m0vnTSLocBonGLVBGRfiOe1H/2s4s8zxqtamw6zRd66M1sktLfowbXGnb6+K+y srn3w4DIdCdQpK9GhSXaC75IKXBGUuMCkcyHZ+Y09nWofZsAUfWeG1oWKUctMPH56cQL h/hvvLXEg+We3LLx1iEvSme7PIZrbtVsA7/L9HYO8PJH+OZBsMZzFhhtLe0BA5m02s9a VY/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547411; x=1775152211; 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=Jfn2M6k7bFpE7gypyjWrhFKs9Q/vfTaHTPk+frkTN9U=; b=c8Xg3v2WsXSg7IPh0CStF4h34iec3921O+xh0ES9P1vxg21nUD2wHo++Apr9okpTRR Bg5jbfm37tqvLq6pM6w5sfkWu3oftTCrXQJBEB2XEc2WRPNgBevFuhgr4pFauVl/bBZC /WJv3fdP512mHRg0BtYCeuzKjy70tJmZX4VZQS3ZEG6FaVH0A3fgXzFNw/dLKfoexdcd vo6e1ybVokk0jMnI7/crcckUzOjRjpIVbv71PDeyKyWBQQhDfCtlPmJCb6OCz3M+Ts1+ MMtNpzgKwzwLajT8+kRZWs8xEtxGU4wPG42mvBVCxlrmzWbOu19/3uxrfUk2u3ITCHl0 Tzmg== X-Forwarded-Encrypted: i=1; AJvYcCWilm+C5+rC+Al7RNmrzFBDUBDtTzaWbn3igqqoHQiP1TGHIudOdCUPbguqxZSnMXk8Sja1I/q+CyPXejQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwiwXa2hUOKTCLOFrB3i9SnBhg8j7CZ4XcXGKVWbGsGQUFVEM13 nOpErseYAAHcrsyInsQOml33DNnVOtjHDU0PKOPVNxJHvwEGw+n2F9lQ7K+IgEJkP+2JqUh6yKO MvIvyl3ZZ71W8lA== X-Received: from pjbco11.prod.google.com ([2002:a17:90a:fe8b:b0:35b:9314:520d]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2809:b0:356:22ef:57ba with SMTP id 98e67ed59e1d1-35c0dce8c1bmr8443122a91.7.1774547411019; Thu, 26 Mar 2026 10:50:11 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:25 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-8-jmattson@google.com> Subject: [PATCH v6 07/10] KVM: x86: nSVM: Save gPAT to vmcb12.g_pat on VMEXIT From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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. When KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT is disabled and the vCPU is in guest mode with nested NPT enabled, save the vmcb02 g_pat field 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 14063bef36f1..26bc33322a87 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1242,6 +1242,9 @@ static int nested_svm_vmexit_update_vmcb12(struct kvm= _vcpu *vcpu) vmcb12->save.dr6 =3D svm->vcpu.arch.dr6; vmcb12->save.cpl =3D vmcb02->save.cpl; =20 + if (l2_has_separate_pat(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.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 BF275423A75 for ; Thu, 26 Mar 2026 17:50:13 +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=1774547419; cv=none; b=hHs8pwR0dXhR//C22Lr0em7yxXJDOTw+YfVFLjJy/+dtZ/jSTZnEl4fNGDgTqE+ya0GvnBNxoiD4Sx76TpbLnuxi3Xc5zY21S8/ov84JUTRIvPXxuUVVFdxCFiB0w61aCLF8sR+B8hVGxITVb3qWDLisqszqGl8aq9G9/4IoDpE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547419; c=relaxed/simple; bh=XLgtzGzP42ljoyiyAMkJfrzmvotKaPs/WCkAxsvyobc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Gk7TaJ1pP605z81TL5ZB8SbE5q9VgrfWgYlEF3FE77iCo/Sp6qnHb8gXJU1q3vdXCEeDsXE8I3CWw69yuHw7T3y5N4xA1FlMj9+FEBKy+wdXJzBqsHsu2RbT8IX2U2xAzwEd9FbFPEolIreDu6FrUdouOClnXh+AC7Io3MALNWU= 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=JRkXjFX2; 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="JRkXjFX2" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-c7381a9a932so825740a12.3 for ; Thu, 26 Mar 2026 10:50:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547413; x=1775152213; 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=fcHCPa7TDJvI9dVBUyhh6A4BV1v5Np3TWFrOmkOsocE=; b=JRkXjFX2hoeTOEyJK5roSUd3wwK6/vRXt0JMEHr1VR4bkXglnc9pWPQqJlFkSQnJzF ZIdU0iywN0cA1uKaYKJXBlD2SvqSwD/5vYzkEZPegalisv3gwCzYMp2WRCoOrRNBLTxm hlKnDB8uf/QQQjVDzzmwnJ5qUQdUcONRoqa/bFBYrMlaF80f3s9gFyoQKfQ+htVlwD3I bqXRbdJTEymqtppI6uReQ4baWBEaFp9J7WWs0FTUJk2pFfJ8pEeNUEMpGoikQtVcIZAp 7ij41KJr67sOGLIYQXSa4MJPBPtSGSUqPQeMLAzwfM2LWEgl67W1ZegMGbK0xiSIJ2yC 4zsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547413; x=1775152213; 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=fcHCPa7TDJvI9dVBUyhh6A4BV1v5Np3TWFrOmkOsocE=; b=aMTXZuiJy9kjXVhpAOKBK4JGLY1TUaSrZlJnmpAMqq34F5UU45jQ2rvW14Om3E+JbW AQxRu+ati83S1An6EJarIYh43qSTroSUMV6HmppWjJ5CvSrNzspTyXoRvDDx3C0u78xp 0mgSJ+MNlViD2a560rIYn4oi//bQOCTGt//2GxphDJNp/BZhawqzMFw221uTWhfj05C7 K6YcEph6XWCyaCRcw3W2s0H4pxOeWfv4Fp7sjxjTfbmAwkFHttuZz3MYy8Q7syk/Osp8 8j6RYbNTFrVpg+fXjSvOGKSQWSCkJgwyPzeeyfGugiLhky+piKiN0VfcrrBELMscUurD +Dzg== X-Forwarded-Encrypted: i=1; AJvYcCW64Y7Ua0wjAk/22MGp5a3RsSERhe/t5U07bxUcOo4OhQ/ADPAeRRuR+jfdtwGZiy1l5sgHuKTvJBzNrBc=@vger.kernel.org X-Gm-Message-State: AOJu0YyGD44scIQWq3ps9RWQ3krBha1Co9AFzo0oyvD//s//TFF2o4Ah JdYDWxvXKZgEdlDY5A5YJXYGEAicINejd9Du4qohvxKtyfFx8VNV6CbWfh3PWBkM11bFHiCZa70 K/BcmPSKyEYMS7A== X-Received: from pghg20.prod.google.com ([2002:a63:e614:0:b0:c76:3f60:53ff]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:7f9a:b0:39c:235:c5d7 with SMTP id adf61e73a8af0-39c4ad57b34mr8886863637.39.1774547412536; Thu, 26 Mar 2026 10:50:12 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:26 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-9-jmattson@google.com> Subject: [PATCH v6 08/10] KVM: Documentation: document KVM_{GET,SET}_NESTED_STATE for SVM From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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" Document the nested state constants and structures for SVM that were added by commit cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE"). Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET= _NESTED_STATE") Signed-off-by: Jim Mattson --- Documentation/virt/kvm/api.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 2d56f17e3760..0a2d873ca5a3 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -4942,10 +4942,13 @@ Errors: #define KVM_STATE_NESTED_FORMAT_SVM 1 =20 #define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 + #define KVM_STATE_NESTED_SVM_VMCB_SIZE 0x1000 =20 #define KVM_STATE_NESTED_VMX_SMM_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_VMX_SMM_VMXON 0x00000002 =20 + #define KVM_STATE_NESTED_GIF_SET 0x00000100 + #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001 =20 struct kvm_vmx_nested_state_hdr { @@ -4960,11 +4963,19 @@ Errors: __u64 preemption_timer_deadline; }; =20 + struct kvm_svm_nested_state_hdr { + __u64 vmcb_pa; + }; + struct kvm_vmx_nested_state_data { __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; }; =20 + struct kvm_svm_nested_state_data { + __u8 vmcb12[KVM_STATE_NESTED_SVM_VMCB_SIZE]; + }; + This ioctl copies the vcpu's nested virtualization state from the kernel to userspace. =20 --=20 2.53.0.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 99A2330E85D for ; Thu, 26 Mar 2026 17:50:15 +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=1774547420; cv=none; b=MvevyeCYQnu99WWNeghuemPYkhZM1OUiB8fZzqAl4/YttO1KLQa98onagoqcUz+pGKf+SyT+aylWovUDOzoOT5TyffRI+ggrYN+0chZbYzTTYboJ4APTMXHn9dQY73Z77y9UR2SNZmXMEFFENnYu8ck4HUQ/Iv4Awhh95lXCVHo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547420; c=relaxed/simple; bh=Wul8FNwFXn6rmN8/WRF7/1kccFLl4cwAfy5g/Zw3EKk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EYGLOey/+kyVd6BbuISFqH5Hk6MCdCBwA2MtT2TcMiAMjRSKT7PBictX6FjlsmtOK6La23QvCjIzOQ++dW0svzTFD6CLkSQkXHz1m/hzhYFiHqjd3O44Uyy0hUKiCWNneb3egNLPdLw02t0K1rMTHehBDWfxxAXoR2AYIti6Z2Q= 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=VsrMugdM; 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="VsrMugdM" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-35c0cbe0f64so3176484a91.0 for ; Thu, 26 Mar 2026 10:50:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547415; x=1775152215; 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=CGeUy1ZbKHDK6Xn7+ThAu8RVGMbIzIVYHaJ8LNemyL4=; b=VsrMugdM4Rzxz7hd1u+zCMFl9FYAI3wAFLXV+XfovsD8skZ2L+tVdPUFCVRvSY8keE HJO1aNv+1CvPeNwWdF92cp1IoN+g+04j5IS8iIioiOiplk5nwWJ++GaY4UtXa0UNbwjp 9B91C+M2+1qA8duOa5nthMIrkSFSIb9iSyBJozN66hVPbuKUclp+R2Y2SSXKEfc7EKhZ kqZB4//YQs3B7I3PeukAa8EbXB5rikRNN9P7zhjZD8RRCy3TMy8xMAAurK0AGszMG2oV W9aQDbBpuabG2nz/9rYgVSNCdh2Zp9ewVSwAKRzFogLycDPkbjV+EObiPJ8wg761VhEk CTzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547415; x=1775152215; 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=CGeUy1ZbKHDK6Xn7+ThAu8RVGMbIzIVYHaJ8LNemyL4=; b=aHck3EWeecH7AY+ulBTtLg1E2j51mQR8rJns+6uets75DH8UXtr4K8QvVHZTc7C2qb 8y2v1dULMDFvKqJ3BhCwuUdoUMAEDn3lbaBG5m2Zy/pZFHB6puA/2iCxYrQHfXeYbEJm y2cIIGO2KeFJIKFfYaVI0z4ik18eLc2N4Nf6eTBwbG8S9k3X+UwSTCcHneWmJjf29EMA xezXXiXW5h/TueO6QG6mPRhC2Bz5iLnbY3ia0KFBU+MVl5mkb1KPXI1j9MrfiFkMXrOH LbceOkuong7F49hZk5xn296IVs/xtoEFKgOmO8GFna6OpavZS2k5ovftsELN6aeP3Ttc UySQ== X-Forwarded-Encrypted: i=1; AJvYcCWDA604oiwM6MCWKk39J6XvshX3IU2lbGnVJZn4MEaZN551VaK0UiY0VB5mThmEvG3oxPKChPeBMizB4/U=@vger.kernel.org X-Gm-Message-State: AOJu0Yx667OMV7okkoQpS2sN93PImyiUL2qlIRJ/aLVcOcVsqrXKayy6 geVpNeizmIX8qEOTD86fE+2Hm2/8MoaS+UJxTEPMR767pvnT1Qv8JZddBa/LpXYXW6iD7/8rQkT vDhXQrC7MWhaRgg== X-Received: from pjub5.prod.google.com ([2002:a17:90a:cc05:b0:359:f1f1:7bcb]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2249:b0:35b:a53a:7d0b with SMTP id 98e67ed59e1d1-35c0dd3ae00mr7357466a91.20.1774547414431; Thu, 26 Mar 2026 10:50:14 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:27 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-10-jmattson@google.com> Subject: [PATCH v6 09/10] KVM: x86: nSVM: Save/restore gPAT with KVM_{GET,SET}_NESTED_STATE From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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 'gpat' field to kvm_svm_nested_state_hdr to carry L2's guest PAT value across save and restore. When KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT is disabled and the vCPU is in guest mode with nested NPT enabled, save vmcb02's g_pat into the header on KVM_GET_NESTED_STATE, and restore it on KVM_SET_NESTED_STATE. Host-initiated accesses to IA32_PAT (via KVM_GET/SET_MSRS) always target L1's hPAT, so they cannot be used to save or restore gPAT. The separate header field ensures that KVM_GET/SET_MSRS and KVM_GET/SET_NESTED_STATE are independent and can be ordered arbitrarily during save and restore. Note that struct kvm_svm_nested_state_hdr is included in a union padded to 120 bytes, so there is room to add the gpat field without changing any offsets. Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET= _NESTED_STATE") Signed-off-by: Jim Mattson --- Documentation/virt/kvm/api.rst | 1 + arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/kvm/svm/nested.c | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 0a2d873ca5a3..d6bbb7bad173 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -4965,6 +4965,7 @@ Errors: =20 struct kvm_svm_nested_state_hdr { __u64 vmcb_pa; + __u64 gpat; }; =20 struct kvm_vmx_nested_state_data { diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kv= m.h index 3ada2fa9ca86..1585ec804066 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -533,6 +533,7 @@ struct kvm_svm_nested_state_data { =20 struct kvm_svm_nested_state_hdr { __u64 vmcb_pa; + __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 26bc33322a87..601ad3f34db1 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1859,6 +1859,9 @@ static int svm_get_nested_state(struct kvm_vcpu *vcpu, /* 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; + kvm_state.hdr.svm.gpat =3D 0; + if (l2_has_separate_pat(svm)) + kvm_state.hdr.svm.gpat =3D svm->vmcb->save.g_pat; kvm_state.size +=3D KVM_STATE_NESTED_SVM_VMCB_SIZE; kvm_state.flags |=3D KVM_STATE_NESTED_GUEST_MODE; =20 @@ -1987,6 +1990,15 @@ static int svm_set_nested_state(struct kvm_vcpu *vcp= u, !nested_vmcb_check_save(vcpu, &save_cached, false)) goto out_free; =20 + /* + * Validate gPAT when the shared PAT quirk is disabled (i.e. L2 + * has its own gPAT). This is done separately from the + * vmcb_save_area_cached validation above, because gPAT is L2 + * state, but the vmcb_save_area_cached is populated with L1 state. + */ + if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT) = && + !kvm_pat_valid(kvm_state->hdr.svm.gpat)) + goto out_free; =20 /* * All checks done, we can enter guest mode. Userspace provides @@ -2011,6 +2023,10 @@ static int svm_set_nested_state(struct kvm_vcpu *vcp= u, nested_copy_vmcb_control_to_cache(svm, ctl); =20 svm_switch_vmcb(svm, &svm->nested.vmcb02); + + if (l2_has_separate_pat(svm)) + vmcb_set_gpat(svm->vmcb, kvm_state->hdr.svm.gpat); + nested_vmcb02_prepare_control(svm); =20 /* --=20 2.53.0.1018.g2bb0e51243-goog From nobody Thu Apr 2 19:00:04 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 0B42D426692 for ; Thu, 26 Mar 2026 17:50:17 +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=1774547423; cv=none; b=qNLdu2Qey5yh/jhS7zoB/pIqmMC8M/gUN9oebMXrhQnr0uO7WcOETeyLrMnzfGRKRzh07kvQ9KVzQnLqBUKfdeil9vlH+BxMvtOfvaFoy85XurOi6QPFnTFMtpGHGWAJPzfXuf2vPReoAxlDotQiBFL8jpNYzuMC0tk7hXyZxu8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774547423; c=relaxed/simple; bh=J6e0QheWsV205OBFE1w2/3od2KuiGQ8chN9jIhmli0w=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=A7uqqXSluEB8ITHKX1AHQ5h+8gqaYpOsjEOg4JnK7cSiqNa+aD/FDTOmo6NkT38tgNO4+6bvgzwkzEMQ4UnPrmKFzo6oNoaHdEw+kLajStBWdOV+QZkL5s3ixuAlQOTccKOpejDaVyyzGTNDTc8Yk6Kn/NvPCgg7Iol1GeNR+js= 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=SNR9Rr9v; 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="SNR9Rr9v" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-35ba4bf54beso1172927a91.1 for ; Thu, 26 Mar 2026 10:50:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774547416; x=1775152216; 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=PZ/TyFghnFVNjOubdAxCNj3tm5pGnzmt2n9T/T2hdlg=; b=SNR9Rr9vscO78dkw+hcfv0NpOut1eBJbp6gA8SHWwanFStYxvln+ZRDDlILoUinPpq duaCHktttwdkriIWLSruxsq8p8d01wl942RBCEOqYNjv3EJpJlFuz2oX1p31WKU+o5wI 680hc15Zn3aR+ltEDKU7iT8gQnOkXNPnrgnaESaLGWZna7Oqk/HKDRFfg+dIc/8T2nLm yRpnvY0YQiSerrv2fVcufEKDcva8IY/HoSh9HJXDu2yrYWADEF4LZPqvLapRO5WgA37N 8+IjEKYMaEYvL/9EonLox6q4wNDcO8MQhjXJRSFrlGtsfbiMwrswQWRCuoVU906s0zeC 5/FA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774547416; x=1775152216; 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=PZ/TyFghnFVNjOubdAxCNj3tm5pGnzmt2n9T/T2hdlg=; b=iPhStFkI+qrhyXNiwxmGrySZig4sWJSTUTH8SwKdp5LfKaG9BqgNufJmJe+XgWZf+k farsMUqnx/YGn5ceIG9GRHpUHxvneh+YTVfTxcQCDAQR1EJfTEerkMkxNgUjCq8IiRTE +478wQu8HE6O9E2acV7k7sZUjm5hymuIPqOI1bfXwMhSYWK4MjLGYZIu6jjRg3FDrf/9 /mMYSBhkrsFLAA6ka4OwBzuEzOgvnRqNFjCdtVsBGjdnQ/Ln9XPy1JUlC6+choLUVtmQ /kRaDpzoJA3BfFEhdGG5bKmhzix59pSma4suegoby5V3vjnSL8rKAWaalvJTz+ff4w4j lzwQ== X-Forwarded-Encrypted: i=1; AJvYcCWxcCjyBzZuD6mi9D24wlZo+bl+1TCaLPhWqAXKDYzeKj1pd4Z4/OcBzEBoygZWPv6oTujbiL1VfvUv7Gw=@vger.kernel.org X-Gm-Message-State: AOJu0YyBZMVCeE1CBkwUwisfpKwwzNT93JQDw8twFZFs2D9HYpZhAG5r RbQ5PYW0wt02OVKp50D164B0e+LcbhycgW/rtj+Tyj9CXQ8DMlDsfnVs3sbxBp1lmx8JAUXYmSU moKirXLwIkQL/AQ== X-Received: from pjbsl12.prod.google.com ([2002:a17:90b:2e0c:b0:35c:e2c:6921]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3c0c:b0:354:a332:1a61 with SMTP id 98e67ed59e1d1-35c0dc8143emr8104477a91.5.1774547416255; Thu, 26 Mar 2026 10:50:16 -0700 (PDT) Date: Thu, 26 Mar 2026 10:49:28 -0700 In-Reply-To: <20260326174944.3820245-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: <20260326174944.3820245-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260326174944.3820245-11-jmattson@google.com> Subject: [PATCH v6 10/10] KVM: selftests: nSVM: Add svm_nested_pat test From: Jim Mattson To: Paolo Bonzini , Jonathan Corbet , Shuah Khan , Sean Christopherson , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-doc@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 KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT is disabled, verify that KVM correctly virtualizes the host PAT MSR and the guest PAT register for nested SVM guests. With nested NPT disabled: * L1 and L2 share the same PAT * The vmcb12.g_pat is ignored With nested NPT enabled: * An invalid g_pat in vmcb12 causes VMEXIT_INVALID * RDMSR(IA32_PAT) from L2 returns the value of the guest PAT register * WRMSR(IA32_PAT) from L2 is reflected in vmcb12's g_pat on VMEXIT * RDMSR(IA32_PAT) from L1 returns the value of the host PAT MSR * Save/restore with the vCPU in guest mode preserves both hPAT and gPAT Signed-off-by: Jim Mattson --- tools/arch/x86/include/uapi/asm/kvm.h | 2 + tools/testing/selftests/kvm/Makefile.kvm | 1 + .../selftests/kvm/x86/svm_nested_pat_test.c | 304 ++++++++++++++++++ 3 files changed, 307 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86/svm_nested_pat_test.c diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include= /uapi/asm/kvm.h index 7ceff6583652..be6f428a79aa 100644 --- a/tools/arch/x86/include/uapi/asm/kvm.h +++ b/tools/arch/x86/include/uapi/asm/kvm.h @@ -476,6 +476,7 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) #define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8) #define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9) +#define KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT (1 << 11) =20 #define KVM_STATE_NESTED_FORMAT_VMX 0 #define KVM_STATE_NESTED_FORMAT_SVM 1 @@ -530,6 +531,7 @@ struct kvm_svm_nested_state_data { =20 struct kvm_svm_nested_state_hdr { __u64 vmcb_pa; + __u64 gpat; }; =20 /* for KVM_CAP_NESTED_STATE */ diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 3d372d78a275..88871572ee9d 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -113,6 +113,7 @@ 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_clear_efer_svme TEST_GEN_PROGS_x86 +=3D x86/svm_nested_invalid_vmcb12_gpa +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/svm_lbr_nested_state 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..704f31a079a9 --- /dev/null +++ b/tools/testing/selftests/kvm/x86/svm_nested_pat_test.c @@ -0,0 +1,304 @@ +// 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); + vm_enable_cap(vm, KVM_CAP_DISABLE_QUIRKS2, + KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT); + 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); + vm_enable_cap(vm, KVM_CAP_DISABLE_QUIRKS2, + KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT); + 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)); + TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & + KVM_X86_QUIRK_NESTED_SVM_SHARED_PAT); + + 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.1018.g2bb0e51243-goog