From nobody Sun Feb 8 02:21:26 2026 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.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 55779328B52 for ; Thu, 15 Jan 2026 23:22:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519335; cv=none; b=ZsF5UxAFL25DvRG5ZUxR55S+fqDplCpepXSXTSHkovnx8TiaZcWkA38z9kATTFOuANIYaWO18LBR/4B5g13B76/uCnIuhWdc/4+tl1TRIU5+biLgbwvVGUiiWHikGiajT0FgDxnZhf/e07ykVVbpsgzaKLRV3IH2bJbzemwj3MI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519335; c=relaxed/simple; bh=O8JPsEukT2yzt7zvNXp8mKQmoxRMvqrQ7tGet8dBl4A=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Pv1EPUifWeiOg1Y866Uhapc5a2KFv8Riv7zhN7/w4U/8RB7lGcZwZNEbnQVaRJCQH/MinA00LMwxonHlXE9dErQa2nBpP5wJdL+jiZQBe8ycJrldPgjMsWIThkeETEEXCJfRjCt3hsNMXAykTWI75ix53nrF9iyC6x3bmOsMvlI= 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=ehqXKrw5; arc=none smtp.client-ip=209.85.210.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="ehqXKrw5" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-81ed3e6b917so1470197b3a.1 for ; Thu, 15 Jan 2026 15:22:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768519333; x=1769124133; 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=htGq+Uz9N574rHPXi8Cv7teGXNue+pPUNMmd++slxUM=; b=ehqXKrw5QjjssZ765G5dOIKdZ0BDNRZ5nvEREHLfkCHs9YY+FrxSq5pbAZtfuJJgch k8MCl+4dTb+X0h7CcKdxdyqM01irhlVJ7UC2jiRwo1EXaMzsQ99s1dsfWUi0/hdTJI/f ekUd34S6NFmJJuftxQPabLV+DLCw8EUVtWcKCM0l3dueOgmbF0nNbF0jsy4qGJaPKoXq /m/4WR19SP+6QdpsdFWfQt5wqJXbRjW8I4zeRt9w1/eFug4x017lvurPS45HsaO9Lcq0 gpSaG1wuD9hQV0TjcVc6dcnhWgEtHQgR40tRXOVn8DF/1g0pkULshEO3/nfmflt/vfoa pONQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768519333; x=1769124133; 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=htGq+Uz9N574rHPXi8Cv7teGXNue+pPUNMmd++slxUM=; b=rEFgS5tvjP9t4PDx5Cw7IISqEfgKBenfzN8KnBulcIsuExWulRzDYmQ9z90Hwm2C2k fmL7oU0A5AXJyOTGnb/fPLj1RG7tCkB5GqbMUP+czCgI7EVLRB8SorYU0Az7m3sJfof8 iQbTzKuPpKZRG3EFNWlBOuYHDDioHuy/tCMd6qeSO1wW1h6ABj50cuCpqHN8jf/1ikR9 8C439SqexzEacAy5K5sHsGxoxbSIBss33xLPKHuJoTVKTNtVpVrxNnb9GTEL+268jDQO 5XTC5JVHcBJ89Q+w2ZVqHAZc+9k8NSNSmlVYHQze5jl5uXZ2frjF24427zcn5FWaugI3 vsxw== X-Forwarded-Encrypted: i=1; AJvYcCXmIKKbD561GJjQqJ+vSZEUveD/uCaa26OAV9e7i1lvf1biZgcxabAzHTvIhPODUEOau7xuX7U3tKIIKl0=@vger.kernel.org X-Gm-Message-State: AOJu0YwNXpF9xTnuhApKV7F/r6M4s41mUL4wX+xLg9dwI+tnB+wSV92p QXCFj/sedST7yfA2yzV3IdFTwBT8XpTTlj+EPbHdK2L6WPKqAS4hgQsXVJ42ZJtovf4r5RQRQ8g /xUNXe71nm8z1wQ== X-Received: from pfbk10.prod.google.com ([2002:a05:6a00:b00a:b0:7dd:8bba:63ab]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:4c9b:b0:81f:50ea:5d97 with SMTP id d2e1a72fcca58-81fa0355280mr985031b3a.44.1768519333438; Thu, 15 Jan 2026 15:22:13 -0800 (PST) Date: Thu, 15 Jan 2026 15:21:40 -0800 In-Reply-To: <20260115232154.3021475-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: <20260115232154.3021475-1-jmattson@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260115232154.3021475-2-jmattson@google.com> Subject: [PATCH v2 1/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 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. Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/svm.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 7041498a8091..3f8581adf0c1 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2846,6 +2846,13 @@ 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: + if (!msr_info->host_initiated && is_guest_mode(vcpu) && + nested_npt_enabled(svm)) + msr_info->data =3D svm->vmcb->save.g_pat; /* gPAT */ + else + msr_info->data =3D vcpu->arch.pat; /* hPAT */ + break; default: return kvm_get_msr_common(vcpu, msr_info); } @@ -2929,14 +2936,24 @@ 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->vmcb01.ptr->save.g_pat =3D data; - if (is_guest_mode(vcpu)) - nested_vmcb02_compute_g_pat(svm); - vmcb_mark_dirty(svm->vmcb, VMCB_NPT); + if (!msr->host_initiated && is_guest_mode(vcpu) && + nested_npt_enabled(svm)) { + svm->vmcb->save.g_pat =3D data; /* gPAT */ + vmcb_mark_dirty(svm->vmcb, VMCB_NPT); + } else { + vcpu->arch.pat =3D data; /* hPAT */ + if (npt_enabled) { + svm->vmcb01.ptr->save.g_pat =3D data; + vmcb_mark_dirty(svm->vmcb01.ptr, VMCB_NPT); + if (is_guest_mode(vcpu)) { + svm->vmcb->save.g_pat =3D data; + vmcb_mark_dirty(svm->vmcb, VMCB_NPT); + } + } + } break; case MSR_IA32_SPEC_CTRL: if (!msr->host_initiated && --=20 2.52.0.457.g6b5491de43-goog From nobody Sun Feb 8 02:21:26 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 7A34B3101B4 for ; Thu, 15 Jan 2026 23:22:15 +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=1768519338; cv=none; b=H+LoryrHtOD53FI4MlVLidgmUggvzYqXLBBFrf+kgYojnX10GlbRzVjqvcb0v7D688m4950bfoiSXlzoOtxsjm9CQx16W4bNAkQ+oZsPrP2Ol1+QaNLEs/iUktvFNK30IxOuWdeyNompHRhIR/aybuoJMZ9HTHkt76TQzQbQly4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519338; c=relaxed/simple; bh=RW48TPdvb5xAKUsQXmeyEK97Shn/whfhWqOquQdudkY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=WDMh86hgawbGSgO4Vg3X9l7vr7GeSKCstD8DPN1nfUkBoJXza7EnV+gwqfD9cgyHGhDZzTK6Emt6sWm7LyjOp1fZBQDCZBs8+UCH0XEINjL17art+qN3BxGWI7+X8I0K11Kvme8E+XG3uwBtfZbHK0/prONjQAXsRWBWI5SXMo8= 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=Ar9iMgRm; 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="Ar9iMgRm" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2a089575ab3so12338905ad.0 for ; Thu, 15 Jan 2026 15:22:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768519335; x=1769124135; 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=hfgEug5UPVe3ZZ5958Qf800gsqyZ1Jrc8uLtmlr2csE=; b=Ar9iMgRmnrh1Wc8H6dATOsRGGYYYd4CVfdMM+XOTV5Pj+epYwDPzORfcL7rrW2bxdI rNKd8qq2ga+qFKLeGEe+Tp4RC7YZlyVly6sgw4jlHh44cCHpf3EcPvnpipIzqSlHFtba OnQ2DjogB9TmJo0w/zBxqE3cWU/QE/jOUqAnYEmEx8t/Jvpu1Io2TYAfLSdeLl0uDEYl asVxCSh5lE9eNw/C8EyX0T0HqRf+H6a9JXHdE6m5qEvTMmKaJVKT1k9W2wsdb61YdChU wbfUjZH1CtTznDkqi0ktroCQYi2eYfUDpGMipfGgwktIvOTFZiao7gjx1SVEAoz5xZcS skOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768519335; x=1769124135; 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=hfgEug5UPVe3ZZ5958Qf800gsqyZ1Jrc8uLtmlr2csE=; b=koiUZgBOLwHEks7aGMExVtigt/K6kW5RjJuvg5WbqaCuhiEnoWsGrjf7hFK+OcH2rt XG1+phblKv1NAYiPnDrnli0OUwIN43c2EKoBHEiIc3rdGci9n0uN7C5yALH3Ay4OVQDr KR27PK9R3Q9vei3QSNew8AqyBNTF3LE5c+8H1RAds+mw78rCFMGOrd9nhZbvkbYNciqP U0BtasmmgDt/WA8hfoP0fONAZka+QZtr7bqsBBy5n2pJR3xLnve/qfDI6EIZPJcJe2iD rWdjyCrmd6N9EmO6Y1b4ay9+TWz6v0DriRbYayBW/pqz++QlEcm+e5I1GrrPv5ytBH3W ZGDw== X-Forwarded-Encrypted: i=1; AJvYcCXtlYWlkIX53JtIC48WKGzCzwnnVGmzlEB88tEzjCO6Fun3Gw8+d9sWcB9TpH6oB1f8I06kIFPHI0fPzGo=@vger.kernel.org X-Gm-Message-State: AOJu0Yz9LyW2jrblADCmr5TUbhkafwHFJLyM6FW+b5iHV7R1vZYjrDcQ p0VXUGhMBdufz4GCPHuNCf0m94LJsMfOhHi+4pPmiyCUu3vVM0gg22nw2XKZrKabWy+Df/dMBLh sBxlUbcROr8H6lQ== X-Received: from pleo7.prod.google.com ([2002:a17:903:2107:b0:29f:1738:99f3]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:22cb:b0:295:5da6:6011 with SMTP id d9443c01a7336-2a7174fa899mr10665615ad.11.1768519334810; Thu, 15 Jan 2026 15:22:14 -0800 (PST) Date: Thu, 15 Jan 2026 15:21:41 -0800 In-Reply-To: <20260115232154.3021475-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: <20260115232154.3021475-1-jmattson@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260115232154.3021475-3-jmattson@google.com> Subject: [PATCH v2 2/8] KVM: x86: nSVM: Cache g_pat in vmcb_save_area_cached 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 Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To avoid TOCTTOU issues, all fields in the vmcb12 save area that are subject to validation must be copied to svm->nested.save prior to validation, since vmcb12 is writable by the guest. Add g_pat to this set in preparation for validting it. Fixes: 3d6368ef580a ("KVM: SVM: Add VMRUN handler") Signed-off-by: Jim Mattson Reviewed-by: Yosry Ahmed --- arch/x86/kvm/svm/nested.c | 2 ++ arch/x86/kvm/svm/svm.h | 1 + 2 files changed, 3 insertions(+) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index f295a41ec659..07a57a43fc3b 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -506,6 +506,8 @@ static void __nested_copy_vmcb_save_to_cache(struct vmc= b_save_area_cached *to, =20 to->dr6 =3D from->dr6; to->dr7 =3D from->dr7; + + to->g_pat =3D from->g_pat; } =20 void nested_copy_vmcb_save_to_cache(struct vcpu_svm *svm, diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 7d28a739865f..39138378531e 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -145,6 +145,7 @@ struct vmcb_save_area_cached { u64 cr0; u64 dr7; u64 dr6; + u64 g_pat; }; =20 struct vmcb_ctrl_area_cached { --=20 2.52.0.457.g6b5491de43-goog From nobody Sun Feb 8 02:21:26 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 05C50330332 for ; Thu, 15 Jan 2026 23:22:16 +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=1768519339; cv=none; b=ujj2vmrSvMOUQ04hwKACHTTQap/HuOoQIbGDPvd55TreDwWJJGIvEJgbMZzGmlu+zr8LvoejgUMH3tNWHS7s0k3PK5LK0CEOmwE55LbvLwtHZvHGdYRE2uF6eCHcNmDLgemNp6jxtav4kVCJCD+JKqsSEoA9XpKS49BQ30POQr8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519339; c=relaxed/simple; bh=uwL+q/W1CxUvgMFsliajMlQsLTrx9NGxQZcgHZ24XHE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=q2LaNRL24RvKmomVM5az0vcIKX42F1FGk5wrnyosCgzGaTcTIiwESFELj3VJrhg/TG0dspuDD7MyyI7s4bEMw/kwn3ottI5SLefhAe+wxydw6q2/hdO4ZD5LYCidwy30JkAp16EKzcOCxDhWaXXefsc0DmVPVswqCIXvXN/s1xY= 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=tWSzmM15; 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="tWSzmM15" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2a0dabc192eso14095615ad.0 for ; Thu, 15 Jan 2026 15:22:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768519336; x=1769124136; 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=j2a2OqxtfCuKT3wr2Ja9hUv7m6j011UQrkURc2LP8Lw=; b=tWSzmM15nVpgOav07acxwYd9ASDYHeLi6Z1oStsJmDbSzzBlqpOQkXTvrGKvROJCTG Icj2S2RVZew2E7g0pNmT+2hTrZuad95zmS0N/+Ml+cwejaBq8iZBrU/LUDo0fqjac62s ZuUjETsuGnHtppJ0DfCV16GigSteeQUmdzIcP3zq7LdYDBb3MF9bK+YLIdQ5V5s64lj5 7wZnWBJ4saJeNwhDlqDtPAHucsWliTXcJtnqAU0guC2HdLwDDeCe2yCyTrB1NyC2+vqK THkRfud+h/aDvvhjpEFruiWX+RRawRoWrnSV5xWVjhhV8dIQJeBvt1cQkEq71JRwe6l9 gyYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768519336; x=1769124136; 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=j2a2OqxtfCuKT3wr2Ja9hUv7m6j011UQrkURc2LP8Lw=; b=Ud4VjZIFfEgVcqfHRYd0Tkp23YYd1pAM23csuVeKggvbreeo93YVhRY1jnbQgFIl6v 7K0qMf9MXCPQYcZuWA1aSycIJ7piFTLJZB+hfqCr7j0gmNR3Po+0jN7+FqSNmUpEzQ6n vmnf413VZ0v4Xd8PvRelMwk+uvOdT0JOPIHs3OY6aUDZaQe5JqfHg1L7PufQ6IL1YZLq HR+Tng4foS8h5FbpZUFVcrxVIyeW81MP1zH2lbZo0ogv9YTx/X34SQF5UcBmLkjWNYS9 tOoZP7pbd8/jdeXFTTCiTsiM26Fgm+UhjqhvmYjrgMRFwVZLyN0B2RvQhc//ElZ1PmZX R7ag== X-Forwarded-Encrypted: i=1; AJvYcCV9NDV0SRu57Xbj94eT3YWgmvcmXA6zjaCz6aoqbW4LsWMM0rviPioHB85YPEnglKMYJR86ZwLOoHMcUyc=@vger.kernel.org X-Gm-Message-State: AOJu0YydKWeadwhNEkQaP1cOCDUTStTDJdPPPEQW/XbUb4o8f5C6u9cs YzRiA75JpNg2M/Ntru1Vwec6ojVzzBks4GeBbkvpXHgIA1TpPA1UrbLFECu/3gbD+MoENceyp6d luCpKIpXvLTFaeA== X-Received: from plbmp7.prod.google.com ([2002:a17:902:fd07:b0:29f:2ec2:58b]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1a2e:b0:2a1:1f28:d7ee with SMTP id d9443c01a7336-2a7189737e7mr6780315ad.57.1768519336400; Thu, 15 Jan 2026 15:22:16 -0800 (PST) Date: Thu, 15 Jan 2026 15:21:42 -0800 In-Reply-To: <20260115232154.3021475-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: <20260115232154.3021475-1-jmattson@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260115232154.3021475-4-jmattson@google.com> Subject: [PATCH v2 3/8] KVM: x86: nSVM: Add validity check for 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 Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a validity check for g_pat, 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." Update the signature of __nested_vmcb_check_save() to include a pointer to a struct vmcb_ctrl_area_cached, since the g_pat validity check depend on the nested paging control bit. Fixes: 3d6368ef580a ("KVM: SVM: Add VMRUN handler") Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/nested.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 07a57a43fc3b..e65291434be9 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -369,7 +369,8 @@ static bool __nested_vmcb_check_controls(struct kvm_vcp= u *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, + struct vmcb_ctrl_area_cached *control) { if (CC(!(save->efer & EFER_SVME))) return false; @@ -400,6 +401,10 @@ static bool __nested_vmcb_check_save(struct kvm_vcpu *= vcpu, if (CC(!kvm_valid_efer(vcpu, save->efer))) return false; =20 + if (CC((control->nested_ctl & SVM_NESTED_CTL_NP_ENABLE) && + npt_enabled && !kvm_pat_valid(save->g_pat))) + return false; + return true; } =20 @@ -407,8 +412,9 @@ static bool nested_vmcb_check_save(struct kvm_vcpu *vcp= u) { struct vcpu_svm *svm =3D to_svm(vcpu); struct vmcb_save_area_cached *save =3D &svm->nested.save; + struct vmcb_ctrl_area_cached *ctl =3D &svm->nested.ctl; =20 - return __nested_vmcb_check_save(vcpu, save); + return __nested_vmcb_check_save(vcpu, save, ctl); } =20 static bool nested_vmcb_check_controls(struct kvm_vcpu *vcpu) @@ -1892,7 +1898,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, 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, &ctl_cached)) goto out_free; =20 =20 --=20 2.52.0.457.g6b5491de43-goog From nobody Sun Feb 8 02:21:26 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 B962032C333 for ; Thu, 15 Jan 2026 23:22:18 +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=1768519340; cv=none; b=d/r0JCHf96s8anIvC12XVjMI50FWCrjfH/hodpZvvdfKF5ffetyR0UHRCir36LwQeNyYiTzxbkfjd5/x7/lnRZEbu4OChlNZgPSkC07YBsFJRDUk8n/o9vW9rl5raHnVTAnjBcBK24Tm//5TBm6kVnzQFKto+/0hog2ksAqzxVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519340; c=relaxed/simple; bh=pQGqZHvp21TJMQpJakX2U4AKh8qO1CopjjvFOdIp6ko=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PLPjbhkLKT9gPGxqf4mvuqwQbzd2RNJKKvi78ZmuNIG039cNVMTfwhYKEWF99eEWY6Lw1QmHe+RPq7R5GZUqG6p7OzojzXhcY9wWawUZ4b9kjABjXqgmr6vZilhgZ7XOICag4xnYNeoIOdbVnQhRIDS/HLTDWw/ldwNZ3z0D70c= 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=NpW59nio; 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="NpW59nio" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-c52d37d346dso770185a12.3 for ; Thu, 15 Jan 2026 15:22:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768519338; x=1769124138; 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=M/rH7YdPCxq3Y37lIh13jkzHenRj4dLCp8dTpSUr3u0=; b=NpW59niolhJW9LTEvEBhLa2YE6rELXZZ0J3OmLd+CsODYS9fVLAzXI1U7x5YSlBOZ2 N7fvIYwYbWQwpFuUMD/rHd+4rDl4oazUHzJ2tT2fksIONqT0UktLi8d0WpXD/Btg03Vb 75snIUS5c6yZKCsBYHwr3PIqJtA5xDHwxz/qCoM3Fd9odc4C867JlGTP56MTvrbYrcRm Jsdhr/Px5Z9ChuOfkclknmlm7qQPYunxQz15KUCRqEkaR8nG/kevGeY7KwEYVZxVJrN2 x4F5EuEucQ8UracKlSQ2NBP2WyICbiLNcBNwufHpBR86hNWn8FsYoMh7l3QMm8hTsqqQ FcZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768519338; x=1769124138; 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=M/rH7YdPCxq3Y37lIh13jkzHenRj4dLCp8dTpSUr3u0=; b=L/tLtZOOHJ/D+DIgZZXsrMxKmw1cCN80nWLiJXTRgKs5CJwxXf2xHrYKefyu8VPV+n StVeqrAVDUcLsdLknhJTMxoP12N1+QBQMrSh+2PNrE7C0PLhHGp3ZGoooU79s7gPl/A1 Q+9jcwk16gZUoaEH6JbpqrYulxhMAN+Tgrizje/EcaXSoK9kjFaLdM2TNmWsOBkuVJZH ZngrZ6a6uPDclZ0kn4EvMYY4WqnVqnOasftz6CpCX+MZklB0HZcJiPZubYFWxdQLXyfo l3d4F6Zt3W94qkVItWYB6HG4nyrvcY0sZGBOBsMDIJsAoPOxUXV54ybdpcEtF6OHCSMw VA+w== X-Forwarded-Encrypted: i=1; AJvYcCV/b+913Clxkcw1AJgxOc0QGgwVn+2msH9Vgo9u83cfP17LC7lDYX9QRnplwr0QRIJEX9DSIIHf1MxeJK4=@vger.kernel.org X-Gm-Message-State: AOJu0YzuUEbo3GImdlOLd6gkDak63dxkLfcb38lsPYWhQhmouSSaKgOG kCxzY6zr+HhLuMjf5Ux468vwSNEywr7aZZ8qGowbl2hWLg6niuJqizLmxqgb8ke0EEjyUT1GVkB bRdrF1u25cu7WFA== X-Received: from pghi22.prod.google.com ([2002:a63:e916:0:b0:c52:7760:c1bb]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:428b:b0:334:8a8e:6576 with SMTP id adf61e73a8af0-38dfe5e7ae7mr1184649637.29.1768519337975; Thu, 15 Jan 2026 15:22:17 -0800 (PST) Date: Thu, 15 Jan 2026 15:21:43 -0800 In-Reply-To: <20260115232154.3021475-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: <20260115232154.3021475-1-jmattson@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260115232154.3021475-5-jmattson@google.com> Subject: [PATCH v2 4/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 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 e65291434be9..b0c0184e6e24 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -656,9 +656,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; @@ -666,6 +663,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.save.g_pat; + 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.52.0.457.g6b5491de43-goog From nobody Sun Feb 8 02:21:26 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 65CC032694D for ; Thu, 15 Jan 2026 23:22:20 +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=1768519344; cv=none; b=LdlfIg42I1q7REqEDIZ4FMidndwC6ftzdK1v1KWronKoLgY5oo22ltjJ8uimA34Mb+wzRC68494UtkQgYz8QfTlQphoxNtnNULhIycKtBNvlgXbZaNKT+ET21Z/zO1srkf3QIw+lXsdHfEf819Juve4okI1fFcgR2GzM6YKZ6xQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519344; c=relaxed/simple; bh=n9VuXnyas8RzAVq5FNPFG4pbXM3KIqWWE1kNwMcTCbA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=B/YCR/HGjtNrkP7UQVdXU3BzN8b8/aE/iGH2bMLOnXaiG0hEgGbGc4E4kuVp/WCWBG+9lJT9PInqree9TiR9H1yauS//ysR87zxB2iMRnug6TYhAmGfNJGKzqX+9bA8hGI11FZd3CHrL11Ber4kSrGJP8TKeriLEh6dkZxN8T4s= 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=TmIyEX/D; 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="TmIyEX/D" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2a351686c17so13662265ad.0 for ; Thu, 15 Jan 2026 15:22:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768519340; x=1769124140; 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=c/zBrN190qohWKUBRuSYnE9mFnTLenfIQq4Uzz5XlzA=; b=TmIyEX/DYynmIOIJ4etW66jP19V46ZK2mcXN1ZcRtJ+ganeVyCMBbNdWn0USfMTJB/ VMGEx/rFp5LAWZxOdZvq4u3KJ79sGTJqrXhSAVTdlV4rxZY+ekd7izHDUkulnv3PD/g3 /z2owod91ZUuwcOIAPVyopqmyz/zsPD/6ERIaaWaCNldtR3PhxrHguxN6S5evrumJ3rc SRcykru2Sc4waO82Nf64Gw3sOOuGw08aLjB1btnk3wPpuuMXmvJymDZLvLWJlvQ900sU Z7Lpq/eICv6YwaydWOBVjn2/v1HEGkKqn0W4K3gkYBWzCjdXeCojvynoK00ee4uSUneu SVSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768519340; x=1769124140; 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=c/zBrN190qohWKUBRuSYnE9mFnTLenfIQq4Uzz5XlzA=; b=IeegdLuMVhiyM6FiqykhPi1oc9X5YLPO7jlUIou0KRQzqYNnCXstp+bVOY9sw8Vhi+ lLdjv3XZZtcTw2XsDxAxsHelzDznQPdMqjcva0FPFJAYcJFF03azGJwsB1MJmA+EGrZM UYFH8eUe7ZY97c9A+qNV/oGdZHei5mNzvZ6MyvUU3VeNu6a0+A/z1GDzRsuXVsVWxBjx qPecdqstdG+QcegLPNN5KyjeRYCtPkY6pFxsc9xqCvnVRgeKXUGIpF8TMG1pf5uYI/HP N0LUezVGo0ZTvAbLUfiy9hicxI50YmmmhPh9ZHN4OPQ1iBg95mYXby1IJc83WQemKUaZ FP4Q== X-Forwarded-Encrypted: i=1; AJvYcCUHENFuxaYgYaFG3MEN2urFFkh73uwLmla0bwePZS1aVx1NrzlnfKAl+OByF8d2RGc4WstEhX9nf9p06c0=@vger.kernel.org X-Gm-Message-State: AOJu0Ywk+zNqn1AxHTObJfmz5lANxoxDyEz+bd4Y7EENFqUddBU94MxI JwZ/2sce4U7PtovaORMOHRPrfw45jf2kaBHJsVkG7jnRjwBjSNyfhK7zjfxDLTAPP2sVuDIGCpU AHoSMMv90stzOAw== X-Received: from plcl20.prod.google.com ([2002:a17:902:e2d4:b0:2a0:9fe7:eaa6]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:f685:b0:2a1:3ee7:cc75 with SMTP id d9443c01a7336-2a717539460mr9150535ad.19.1768519339675; Thu, 15 Jan 2026 15:22:19 -0800 (PST) Date: Thu, 15 Jan 2026 15:21:44 -0800 In-Reply-To: <20260115232154.3021475-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: <20260115232154.3021475-1-jmattson@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260115232154.3021475-6-jmattson@google.com> Subject: [PATCH v2 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 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 b0c0184e6e24..5fb31faf2b46 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1189,6 +1189,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 svm->vmcb->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.52.0.457.g6b5491de43-goog From nobody Sun Feb 8 02:21:26 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 C1CD2331230 for ; Thu, 15 Jan 2026 23:22:21 +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=1768519346; cv=none; b=iRjWu9GFYNOJMk456p2Lqc90oxks9KU4LkbGSqRKVNpLSXjFf7xEfF0rx9ablokwQmzE+62h6aYRMTpvml6UrVJ5yDpw3cFoWWLHcNNqVbNrPr59zAfm6Zxv+ZwxZwRQQxsvUHSOiR41puCWU4R9n49BVXZw6OGMSfLJvjW1nnI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519346; c=relaxed/simple; bh=2NzeuSJSVheMxnsV7mxVLQattsOjStF0SiM4zA2NR6I=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Z6c5Atps5+6Bj2Q299duiie4LsWwKgEigzdXZv/cTj+xew/oAh4t9JCgSgJdvtQ9rasG/Ed7Y+Xze61SdilTKVROyIkyESa7p0wF0y2jX/CSZGObL1wPJtaB/VBiD+lTLM/khMJeNooWKPK6BQdTIAg3RIXVO0WrcxoYNMOgIGI= 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=sQoV1DHQ; 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="sQoV1DHQ" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-34c43f8ef9bso2391549a91.1 for ; Thu, 15 Jan 2026 15:22:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768519341; x=1769124141; 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=V4Qn/qvBRqPl8GPJICacl87zhupPz7yPwc1Yli3IWWE=; b=sQoV1DHQm7uYCzYzRazQfEVB98VoG9z4OofGW32r4mRv0yZy2vYvBljkzKd6VaVzya u3KNcfgh+BVtRZhVldmXXZa6eMQEGFNQN0OjTJoVxwVUxYOaZxOnul7i7mIO4QSghIpc Mdp//pDfvs2+JNiZ5egcPuq0b1y6hY4CHXi8Q7X3NwCFBqFAnIbLxQvaSAGVa2JZfBUt +9n7w2eH0/IxfB7j0cnNGOLgTTrLps3OHzb3HlB5f+Qx0oV8qgxfqIG0IRKE4Y6Yn5iE WlI00rEexmHHZoox8RJsbou9RTbG3An1QBfv1ANnZXtEzhxjJWHpNkEvELkNxpcZBe9+ RBKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768519341; x=1769124141; 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=V4Qn/qvBRqPl8GPJICacl87zhupPz7yPwc1Yli3IWWE=; b=bX/TOzHApVDqJ1dN0Rm1LoWPrS+2q4Rqb5sbrrtba4oeM9AsY2pIaFL0fjpESeK0AX pPf49lJ39J92FQUpiUTot6LHamyEjYf86fNjalo9u+aQlNnRzKR9usL2BK8ngEH6iYaY s4G3BCFWERkKT5+bqpFpyhHIJ7pCfhd1vbgYfrtrsomAnwRFRZW6gGkEOAqQjbLza5xT qE4ZFhgDV+/tdxa32ze6PfVBKSX09PCxXffqFSyCUlOCKKN4uhQEyiSsXOWul2j3cB77 H6JkuDi12W3Z0Tlx6YGmLUNpAg0mjm6RQl6sjceZzSFPBw6kGMx5pZdtFJGTe5TDiVJv pjkQ== X-Forwarded-Encrypted: i=1; AJvYcCVGVd5JY0moNtKl470qKxJY2gCgEEi1XgtLG/WLLQYioWDO2FYW+w/xYr6W3kuyHWzzQESXhP95TuTk1es=@vger.kernel.org X-Gm-Message-State: AOJu0YyWq4PGjqadl2cX1lsJrt0qD/BNq4/JwwDdeCW9Um6O5AJ1Ki11 LrgmwnkVzDcpG3sLd19K6qeeEMNgCB7mchgNXE6O87Wr5XrREsj3Q/2gk/1fzg9dN3Y8ZqAZb44 fX7AyfdkBDtd4fQ== X-Received: from pjy23.prod.google.com ([2002:a17:90a:f17:b0:34c:e971:cfb1]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2b86:b0:34c:9cec:3898 with SMTP id 98e67ed59e1d1-352678d9b78mr4080056a91.13.1768519341059; Thu, 15 Jan 2026 15:22:21 -0800 (PST) Date: Thu, 15 Jan 2026 15:21:45 -0800 In-Reply-To: <20260115232154.3021475-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: <20260115232154.3021475-1-jmattson@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260115232154.3021475-7-jmattson@google.com> Subject: [PATCH v2 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 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 vmcb save area of the nested state, and set the flag. Note that most of the vmcb save area in the nested state is populated with dead (and potentially already clobbered) vmcb01 state. A few fields hold L1 state to be restored at VMEXIT. Previously, the g_pat field was in the former category. Also 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 without changing any offsets. Signed-off-by: Jim Mattson --- arch/x86/include/uapi/asm/kvm.h | 3 +++ arch/x86/kvm/svm/nested.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kv= m.h index 7ceff6583652..80157b9597db 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 BIT(0) + /* vendor-independent attributes for system fd (group 0) */ #define KVM_X86_GRP_SYSTEM 0 # define KVM_X86_XCOMP_GUEST_SUPP 0 @@ -530,6 +532,7 @@ struct kvm_svm_nested_state_data { =20 struct kvm_svm_nested_state_hdr { __u64 vmcb_pa; + __u32 flags; }; =20 /* for KVM_CAP_NESTED_STATE */ diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 5fb31faf2b46..c50fb7172672 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1789,6 +1789,8 @@ 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; + if (nested_npt_enabled(svm)) + kvm_state.hdr.svm.flags |=3D KVM_STATE_SVM_VALID_GPAT; kvm_state.size +=3D KVM_STATE_NESTED_SVM_VMCB_SIZE; kvm_state.flags |=3D KVM_STATE_NESTED_GUEST_MODE; =20 @@ -1823,6 +1825,11 @@ static int svm_get_nested_state(struct kvm_vcpu *vcp= u, if (r) return -EFAULT; =20 + /* + * vmcb01->save.g_pat is dead now, so it is safe to overwrite it with + * vmcb02->save.g_pat, whether or not nested NPT is enabled. + */ + svm->vmcb01.ptr->save.g_pat =3D svm->vmcb->save.g_pat; if (copy_to_user(&user_vmcb->save, &svm->vmcb01.ptr->save, sizeof(user_vmcb->save))) return -EFAULT; @@ -1904,7 +1911,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, goto out_free; =20 /* - * Validate host state saved from before VMRUN (see + * Validate host state saved from before VMRUN and gPAT (see * nested_svm_check_permissions). */ __nested_copy_vmcb_save_to_cache(&save_cached, save); @@ -1951,6 +1958,10 @@ static int svm_set_nested_state(struct kvm_vcpu *vcp= u, if (ret) goto out_free; =20 + if (is_guest_mode(vcpu) && nested_npt_enabled(svm) && + (kvm_state.hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT)) + svm->vmcb->save.g_pat =3D save_cached.g_pat; + svm->nested.force_msr_bitmap_recalc =3D true; =20 kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); --=20 2.52.0.457.g6b5491de43-goog From nobody Sun Feb 8 02:21:26 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 C1D56331238 for ; Thu, 15 Jan 2026 23:22:23 +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=1768519346; cv=none; b=DBOQh1Q6bCFS3JRyRxd2QXCPZJRJdn1gVUDGJOtuABIc7DJvZyLEqSQC1tq/LjyUx/HT+26bJBwgEStSSz1IFDpBsUUnwoGXgbxFvlyS11LSkSdkN7QXvMEeQm1ygtivMk/2Mktl8arz9y74fzCVyudZIlRUZZ1GlvMrnBiGFA0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519346; c=relaxed/simple; bh=QGaBI2jmMXiz5Zzh8UzMEfKuZBd6orN3mlkFUEX03hI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=E89FbT+yqDphqPQxspxlx8OzOIA7nmr942uujG3ifF+ZrzoYyjRR+Hr7zzuUKhbfSlfly8wm++Ct8W25BguoEGbXOu/aR6D1AEgSYqX2XEUgdP2Fl3coFTaTQ00bpItqmSZWFckz0jxTQPz6JXaK7K3UCMagRrq6TnZjeX2LdPA= 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=cxPsHpYF; 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="cxPsHpYF" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-34ab459c051so2814251a91.0 for ; Thu, 15 Jan 2026 15:22:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768519343; x=1769124143; 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=X41FAJWB3N1JsaEn1Z67wfrNr3PEAApqVjSGPombTu8=; b=cxPsHpYFdUSeHGJ9xX3z+/Yt6qKvljuGIAInnN2I65i78DPIUmHJV6UmYqeMdVtKkd zr9ylpi1hpiZJURV6smmbLB7kbHcIX0sQnzLXcsVEEEUkSjo2ehvXtjIIB8TmLdB3XPC hzNtEoD8mEU/XyuVQm6QbOyFHbp3YCrjD7T3NX9fu6nfYDKowuaAYpjtQtD0TO3zMdpB jir6ay6CnKDpvSzGOEHdpupD+EKaSGeGyXctWEdQ47bcmILjWFiq32uEzUb/y/51eHNZ /SHXLXH+D2WYy5i1SqJJMgmobI4LqcJ3v1BVYqVmc4oq7cLwZaRdZJgmVlRWMlwgfcyw aGmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768519343; x=1769124143; 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=X41FAJWB3N1JsaEn1Z67wfrNr3PEAApqVjSGPombTu8=; b=b4x4m34c/SMrWxULC8jiY9xN6QtYum7F9fr0CNpcmEJYqWCU8iYL8ZzUg+90V81b2E /rItq/QzcDeBREhJlPmGXTBLMcXINN/NisJXAS5AWO19/CeI5oI//PdoO14fHHk34uiK ppC39o3OHaQMRHY4cIp8/0tb7yhauigMPWXaBLXXXTNxQqvvWMiHNeD+eyGz8fqlNmO8 CVdGrKwXAEchwxZ5Lf44pGKhULOmznJg0LXqZ/Q204YYsx6psyl1qFAQF947reZoDJkJ UNqY29OtKf200jjzNCr978kfW4QCCZO/9Guli4DDH/p/66cYFK/Yl9NNPwE77ToQCUPp JE/g== X-Forwarded-Encrypted: i=1; AJvYcCXoj9yrhgy8l1r3QaDNCogGlrXUH6FT1KKmAHVNThsQrzRPpvv4MSRHxtrAAYSXSnv0qPs/9B8XNxrWAjY=@vger.kernel.org X-Gm-Message-State: AOJu0Yzrj9aH3T4+bF/HXMhlq7FW2fjAaEEqQ3xZm9JOaJLVxJbBdA2E XXu7QTlavlTuYP+5/o12qw2CxZKSUyNRefUHP/A9fcjnujJWS54q5eAfheqnilmlYX/Mv7w5HFz 2hPRWVTlE3DBKqQ== X-Received: from pgct22.prod.google.com ([2002:a05:6a02:5296:b0:c1d:b0b3:5e63]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:7116:b0:38b:e9eb:b12c with SMTP id adf61e73a8af0-38dfe67bddemr1490481637.31.1768519342651; Thu, 15 Jan 2026 15:22:22 -0800 (PST) Date: Thu, 15 Jan 2026 15:21:46 -0800 In-Reply-To: <20260115232154.3021475-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: <20260115232154.3021475-1-jmattson@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260115232154.3021475-8-jmattson@google.com> Subject: [PATCH v2 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 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 copied to vmcb02->save.g_pat. Unfortunately, the current IA32_PAT value may be restored by KVM_SET_MSRS after KVM_SET_NESTED_STATE. Introduce a new boolean, svm->nested.restore_gpat_from_pat. If set, svm_vcpu_pre_run() will copy vcpu->arch.pat to vmcb02->save.g_pat and clear the boolean. Signed-off-by: Jim Mattson --- arch/x86/kvm/svm/nested.c | 9 ++++++--- arch/x86/kvm/svm/svm.c | 8 ++++++++ arch/x86/kvm/svm/svm.h | 6 ++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index c50fb7172672..61a3e7226cde 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1958,9 +1958,12 @@ static int svm_set_nested_state(struct kvm_vcpu *vcp= u, if (ret) goto out_free; =20 - if (is_guest_mode(vcpu) && nested_npt_enabled(svm) && - (kvm_state.hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT)) - svm->vmcb->save.g_pat =3D save_cached.g_pat; + if (is_guest_mode(vcpu) && nested_npt_enabled(svm)) { + svm->nested.restore_gpat_from_pat =3D + !(kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT); + if (kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT) + svm->vmcb->save.g_pat =3D save_cached.g_pat; + } =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 3f8581adf0c1..5dceab9f4c3f 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4217,9 +4217,17 @@ static void svm_cancel_injection(struct kvm_vcpu *vc= pu) =20 static int svm_vcpu_pre_run(struct kvm_vcpu *vcpu) { + struct vcpu_svm *svm =3D to_svm(vcpu); + if (to_kvm_sev_info(vcpu->kvm)->need_init) return -EINVAL; =20 + if (svm->nested.restore_gpat_from_pat) { + svm->vmcb->save.g_pat =3D vcpu->arch.pat; + vmcb_mark_dirty(svm->vmcb, VMCB_NPT); + svm->nested.restore_gpat_from_pat =3D false; + } + return 1; } =20 diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 39138378531e..1964ab6e45f4 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -219,6 +219,12 @@ struct svm_nested_state { * on its side. */ bool force_msr_bitmap_recalc; + + /* + * Indicates that vcpu->arch.pat should be copied to + * vmcb02->save.g_pat at the next vcpu_run. + */ + bool restore_gpat_from_pat; }; =20 struct vcpu_sev_es_state { --=20 2.52.0.457.g6b5491de43-goog From nobody Sun Feb 8 02:21:26 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 CE1DA3314A9 for ; Thu, 15 Jan 2026 23:22:24 +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=1768519349; cv=none; b=YHB31HsvuQjweVQdQ2FqduRRRDtMvHT0u2mfKIdT8K2SpKS8UEYDYMYG/7NPp4LbkEKW33OFDjd6li1BkbYx7veEuDULa2X8gJpZuZmh4AJWsUNiMMIFQavhQFnEOdb8IwsxXHiIEze1gh5gBNj2uRwcKD3NfZ76yybv3B332+0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768519349; c=relaxed/simple; bh=5DdPKhUC3tqjAJhoNjUWwOywZ3/REq9WTqJCgMSs0Hc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qQlflQ7oNCoAZ3w7bSQnYQmyzM1/5DIpiiTvSn/vLtNognkeuBZj5OQLkvPVQVmtQQ4bxAqoxmCgqOd5YpEp5UB2fCCmm49K9xRJdd2emwNzDVijv9UO5JXYrIHnKI9DBb9AdzmZQWCSnxFDOjLyUM9sr0F+jrUI30vqB1EqA34= 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=y5k8CK5b; 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="y5k8CK5b" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-34e5a9de94bso2552701a91.0 for ; Thu, 15 Jan 2026 15:22:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768519344; x=1769124144; 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=ap0zEkswS31SalcAiSeHGwE2Ya7ICFH0PawOpIHfqNA=; b=y5k8CK5bPpKu673LvXunu+KXBZi6DsugsM/ikcxXVXPo6u3vWmfE5Q35+Y372VJQLi eYXF/V/K/zbH3yLOSAISdknQXpEAZSIgTeHdXQOWrEh7Ufqbc5f0lnyZ0U7UXEsiPYro HIvU+XLGnAvMgTRKSInrGxs8Sm++QaVMv9LSlx6iLtOgiKJ/wicz3ObW4tF4ZQFs4yOO Oy/jqIxNqvNaVUpGwT9TQrFipKNbUc05yNd0+iT7/3SHQfazNrxmX/D4E2MhI3v6TsgQ U3x67wHWcMRcAFfBO12G6xcrRjUlTilhK1czgw66x8N5/s+Q2lGjunsM6Cru5RZS5wRK LQyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768519344; x=1769124144; 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=ap0zEkswS31SalcAiSeHGwE2Ya7ICFH0PawOpIHfqNA=; b=BcU9Z3UalKXmi4Afu61Xi0UBJtBWj/DxuXDOOrsrvhNJ+tGHzW/LRsbutIZvl7all8 l9t+W143nTywLmnVCHTDl4A4HAcuysDwCo+BcQ/Rx3majcx4AQLsmg6erX9CkqNdYE7l Kitf5Vra95hXAp4cUN0IasuVY9JNbWgqemH3kOWBZN/blHIO5ayF1dqZjCKfiEM+lcG6 PHWc+25p2X1SKCPJkLis3Vk1gr0DnvUldff2vq0wgLJk8jAJ4nYdno8rdo4p5wyWCTBr Oa9CCtxZEwBZ1rjgQ0tlqRgp2i2uKZVsIMTkyLzooy1Nu+oFI4lI+OjZ/pJHMEXqc0R4 UPwg== X-Forwarded-Encrypted: i=1; AJvYcCXDDgWNqvxCc1AdxbVqZxe4SrJ9MGaCxKg4/BY3EzZ2v8p4J8H6oifSK/l4AZ702mB3lYjVH7/UxKQi6J4=@vger.kernel.org X-Gm-Message-State: AOJu0YxPMt0TW5PjcU4ZbjBnHbYTCsEUmt4g1HTDEwDu8gaCDnGWK1Ca 3WTrWUNsMEQPWyyzoxUEZxQMAoYJkFafybnF94MhPhBuur4TsANkNb0STZ6kpnTc5ouGLoiaFEc R3OGjKHH0iMXoaw== X-Received: from pjyu16.prod.google.com ([2002:a17:90a:e010:b0:340:6b70:821e]) (user=jmattson job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3dcc:b0:340:c4dc:4b70 with SMTP id 98e67ed59e1d1-3527315e60dmr859728a91.6.1768519344201; Thu, 15 Jan 2026 15:22:24 -0800 (PST) Date: Thu, 15 Jan 2026 15:21:47 -0800 In-Reply-To: <20260115232154.3021475-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: <20260115232154.3021475-1-jmattson@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260115232154.3021475-9-jmattson@google.com> Subject: [PATCH v2 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 Cc: Jim Mattson Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Verify KVM's virtualization of the PAT MSR and--when nested NPT is enabled--the vmcb12 g_pat field and the guest PAT register (gPAT). Signed-off-by: Jim Mattson --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../selftests/kvm/x86/svm_nested_pat_test.c | 357 ++++++++++++++++++ 2 files changed, 358 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 33ff81606638..27f8087eafec 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -109,6 +109,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..fa016e65dbf6 --- /dev/null +++ b/tools/testing/selftests/kvm/x86/svm_nested_pat_test.c @@ -0,0 +1,357 @@ +// 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_npt_disabled(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_npt_enabled(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 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 =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_npt_disabled, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + vmcb->save.g_pat =3D L2_VMCB12_PAT; + + vmcb->control.intercept &=3D ~(1ULL << INTERCEPT_MSR_PROT); + + 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, L1_PAT_VALUE); + + GUEST_ASSERT_EQ(data->l2_pat_after_write, L2_PAT_MODIFIED); + + 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 =3D svm->vmcb; + + pat_data =3D data; + + generic_svm_setup(svm, l2_guest_code_npt_enabled, + &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 =3D svm->vmcb; + uint64_t l1_pat_before; + + pat_data =3D data; + + wrmsr(MSR_IA32_CR_PAT, L1_PAT_VALUE); + l1_pat_before =3D rdmsr(MSR_IA32_CR_PAT); + GUEST_ASSERT_EQ(l1_pat_before, L1_PAT_VALUE); + + generic_svm_setup(svm, l2_guest_code_npt_enabled, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + vmcb->save.g_pat =3D L2_VMCB12_PAT; + + vmcb->control.intercept &=3D ~(1ULL << INTERCEPT_MSR_PROT); + + 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_VMCB12_PAT); + + GUEST_ASSERT_EQ(data->l2_pat_after_write, L2_PAT_MODIFIED); + + 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 =3D svm->vmcb; + + pat_data =3D data; + + wrmsr(MSR_IA32_CR_PAT, L1_PAT_VALUE); + + generic_svm_setup(svm, l2_guest_code_saverestoretest, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + vmcb->save.g_pat =3D L2_VMCB12_PAT; + vmcb->control.intercept &=3D ~(1ULL << INTERCEPT_MSR_PROT); + + 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(); +} + +/* + * L2 guest code for multiple VM-entry test. + * On first VM-entry, read and modify PAT, then VM-exit. + * On second VM-entry, verify we see our modified PAT from first VM-entry. + */ +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 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 =3D svm->vmcb; + + pat_data =3D data; + + wrmsr(MSR_IA32_CR_PAT, L1_PAT_VALUE); + + generic_svm_setup(svm, l2_guest_code_multi_vmentry, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + vmcb->save.g_pat =3D L2_VMCB12_PAT; + vmcb->control.intercept &=3D ~(1ULL << INTERCEPT_MSR_PROT); + + 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 l1_guest_code(struct svm_test_data *svm, struct pat_test_data = *data, + int test_num) +{ + switch (test_num) { + case 0: + l1_svm_code_npt_disabled(svm, data); + break; + case 1: + l1_svm_code_invalid_gpat(svm, data); + break; + case 2: + l1_svm_code_npt_enabled(svm, data); + break; + case 3: + l1_svm_code_saverestore(svm, data); + break; + case 4: + l1_svm_code_multi_vmentry(svm, data); + break; + } +} + +static void run_test(int test_number, const char *test_name, bool npt_enab= led, + 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: %d: %s\n", test_number, test_name); + + vm =3D vm_create_with_one_vcpu(&vcpu, l1_guest_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, 3, svm_gva, data_gva, test_number); + + 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(0, "nested NPT disabled", false, false); + + run_test(1, "invalid g_pat", true, false); + + run_test(2, "nested NPT enabled", true, false); + + run_test(3, "save/restore", true, true); + + run_test(4, "multiple entries", true, false); + + return 0; +} --=20 2.52.0.457.g6b5491de43-goog