From nobody Thu Apr 2 01:53:32 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 241F63A0B31 for ; Fri, 27 Mar 2026 23:40:37 +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=1774654841; cv=none; b=Na8vcwUTj+w3jc3sqRjdt5DDKcuaDpcBBW+XBW3Rhwpuo7Gwyh4KqLICIm+pD1PjxbLWufLiIWghhiwqH/4X2hL1DiqkDqcuWLEKmXUVXfwik3Cb5XXfsyI8T0wNxlxGzXyhVgQPj536jRcybO0axWtw9/Bb0UmwpDMvKMQoiTs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774654841; c=relaxed/simple; bh=OuR5MnB8UCFuMwjbw9rq52TUW4H3/Wius8t683uVsjc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ILJcfG2DUCT6AmCDN828PKo08mp4afAORAuopdoru11AD+JIUpS1mnnOMStfKrmgx9E3hdX0AnS7SLf2j1SD3Gxu5Qpy56kkllxuLrnl27w3uS9CwOkkVOYm2sN4mBtTA+naqXTn9I5Z/MXTtrX649PJXx8fcEyj9LzB3aOS38E= 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=GENvC0uo; 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="GENvC0uo" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-35d9010602bso530538a91.3 for ; Fri, 27 Mar 2026 16:40:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774654837; x=1775259637; 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=7y5HwBTSkwgoBBimZJGgWbMuctVLczxWfxP1tKWmKTY=; b=GENvC0uocV7kZaorplM7AuKAW/NO3vXV/4eXpLzfG6Lu4u5XBKAxWdnMe5Mi9RfOXc So3bQpiHlQSriHyws3SvFq3Ge1W1nAg8jAyZ83FFYqgo32sdlWm7KpAwweOm3Y7AwEUN DtVgfEJh9Zr9U0xWtKklZPHmOmQyMp/BacLrFCCFiMUCaWcawc5KshUsevYyi4yhBh07 cwLOK+LYlMGUer3pP80oEkE+bQlfNNpvDnoa60XAQYbXzM4wExs96X1Jk9yneWZqcGke SaVnX7FpADi6cbt88ubO88vy41HVBtwotJQGvqtXq1K9bKS21f/WUp/ODdo8NM7GjmKr +YNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774654837; x=1775259637; 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=7y5HwBTSkwgoBBimZJGgWbMuctVLczxWfxP1tKWmKTY=; b=eyGC2BKZ8OdJNxBntcVYvGbMmV4Pwt3oKVmMUhkqm0cQKfjYQbQFClasaDoQuSmHE4 Y+NyFqtCHeYqdXCSuyWcSTUocR9CWus0h3mXgjULl1gHc4OLq5ufof/8gRSZKR79VrLn z5hOIypI+8wet8XCyDeB29W2VlyvGlWr5DFj3jtdjLAY+bVF5Br/fHs/oJv9bIpn+KdT tahKW6tiPHUZ2gUY6k/QPysKiRF1DbW8PEfMjDl6ursgV3u4JhvNLz3auBkKmmPG2pvV 2opQ3z1j7b9tVhbHLzsgwp25IIdSfkmJ8aA6Ja4FsIFu7l0iha0TV1VckxNAL/py8+qs ivdA== X-Forwarded-Encrypted: i=1; AJvYcCXilRuBAVBuNXAaahXQ1/WoqnPxz7d4CQaBpee9CiBju6RovDKXCSM9YeN4cKmC/pnr9vdTKUaG0Kqu2a0=@vger.kernel.org X-Gm-Message-State: AOJu0YxiqBTximu0ykxJm7s8by7XZIQ8QKb7LnDGS8aWukkDvIewnmp9 br8n+WRn+rICrTmRzEU5hjPA9hJWF6i+KRjPN05zA60XMowZjX+lmADZG2pOe32AYpUOADA+M4L S2D3wuRG1SahPEA== X-Received: from pjbhv24.prod.google.com ([2002:a17:90a:e418:b0:35d:9373:e7d3]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3b4f:b0:35c:cba:3453 with SMTP id 98e67ed59e1d1-35c30076fe2mr4269476a91.22.1774654837106; Fri, 27 Mar 2026 16:40:37 -0700 (PDT) Date: Fri, 27 Mar 2026 16:40:12 -0700 In-Reply-To: <20260327234023.2659476-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: <20260327234023.2659476-1-jmattson@google.com> X-Mailer: git-send-email 2.53.0.1018.g2bb0e51243-goog Message-ID: <20260327234023.2659476-6-jmattson@google.com> Subject: [PATCH v7 5/9] 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. Use WARN_ON_ONCE to flag any host-initiated accesses originating from KVM itself rather than userspace. Use pr_warn_once to flag any use of the common MSR-handling code (now shared by VMX and TDX) for IA32_PAT by a vCPU that is SVM-capable. 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 - arch/x86/kvm/x86.c | 6 +++++ 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 8170042d5fb3..ccc556eb4d2f 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -703,15 +703,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..34fd07d6ad4d 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) && !l2_has_separate_pat(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 b43e37b0448c..0b0279734486 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -868,7 +868,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; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0b5d48e75b65..cfb2517f692a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4025,6 +4025,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct = msr_data *msr_info) } break; case MSR_IA32_CR_PAT: + if (!(efer_reserved_bits & EFER_SVME)) + pr_warn_once("%s: MSR_IA32_CR_PAT should be handled by AMD vendor-speci= fic code\n", __func__); + if (!kvm_pat_valid(data)) return 1; =20 @@ -4436,6 +4439,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct = msr_data *msr_info) break; } case MSR_IA32_CR_PAT: + if (!(efer_reserved_bits & EFER_SVME)) + pr_warn_once("%s: MSR_IA32_CR_PAT should be handled by AMD vendor-speci= fic code\n", __func__); + msr_info->data =3D vcpu->arch.pat; break; case MSR_MTRRcap: --=20 2.53.0.1018.g2bb0e51243-goog