From nobody Thu Apr 2 17:32:51 2026 Received: from out-174.mta0.migadu.com (out-174.mta0.migadu.com [91.218.175.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6AB3633F8B3; Wed, 11 Feb 2026 16:29:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827350; cv=none; b=NolVEZ9vxkuo/q25t95Z965W5ncFv6cu/wmdeesoiIrfw+WP+cmpQujiKuPQqznq868m2zhlRV12BsxJtAqDaNTcglPgLv/3wIJzMCwXmHi2JwuG4CVJEYmgArQiyIoqGfb5O/kcQ+OKeMk21ffuWSe1/YjzRpDdVL2qRZ1Alsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827350; c=relaxed/simple; bh=DwNMt9sTxMJvPffKqssdDnCVH7eazxC3nEWkZRv8nHs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nJuZgeuKiKRfltsuS/RW4NOgVcD84nllZFqieKy8b6SGzTlalFHlMCno6CgJ5VXhVYfNt5zAe5hf79BYBj0Gezx9tADaXMBQMchcmUFwnUvhpNJcuZ0/JbC/VAiEUf4nDw9gyVOI0YYeaf+en9EYUdm1uLVSenuVcT+L8w5/jkw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Vh9Zeag0; arc=none smtp.client-ip=91.218.175.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Vh9Zeag0" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770827347; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E0pfwtfuSAR+toNK8R5pgRmHFl05Ro/5VJ5HwjG4DKw=; b=Vh9Zeag0eUvYHlAg65EfEGWdcAaCR6oDF+VhAkKkBOyWWS60RRx8kH//EPOCMjbqJ6/9LR 9eSCnEThzVMUH5/WDZn6fXmCAaMvZO1KB+Ib55HVaiFHpmuH2lprjRLh/513lRyjhNULL9 P5tt5Q3DaZDtUr8c+qMyunltnDKvTo4= From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed , stable@vger.kernel.org Subject: [PATCH v2 1/5] KVM: nSVM: Sync NextRIP to cached vmcb12 after VMRUN of L2 Date: Wed, 11 Feb 2026 16:28:38 +0000 Message-ID: <20260211162842.454151-2-yosry.ahmed@linux.dev> In-Reply-To: <20260211162842.454151-1-yosry.ahmed@linux.dev> References: <20260211162842.454151-1-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" After VMRUN in guest mode, nested_sync_control_from_vmcb02() syncs fields written by the CPU from vmcb02 to the cached vmcb12. This is because the cached vmcb12 is used as the authoritative copy of some of the controls, and is the payload when saving/restoring nested state. NextRIP is also written by the CPU (in some cases) after VMRUN, but is not sync'd to the cached vmcb12. As a result, it is corrupted after save/restore (replaced by the original value written by L1 on nested VMRUN). This could cause problems for both KVM (e.g. when injecting a soft IRQ) or L1 (e.g. when using NextRIP to advance RIP after emulating an instruction). Fix this by sync'ing NextRIP to the cache after VMRUN of L2, but only after completing interrupts (not in nested_sync_control_from_vmcb02()), as KVM may update NextRIP (e.g. when re-injecting a soft IRQ). Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET= _NESTED_STATE") CC: stable@vger.kernel.org Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Signed-off-by: Yosry Ahmed --- arch/x86/kvm/svm/svm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 5f0136dbdde6..1073a32a96fa 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4435,6 +4435,16 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm= _vcpu *vcpu, u64 run_flags) =20 svm_complete_interrupts(vcpu); =20 + /* + * Update the cache after completing interrupts to get an accurate + * NextRIP, e.g. when re-injecting a soft interrupt. + * + * FIXME: Rework svm_get_nested_state() to not pull data from the + * cache (except for maybe int_ctl). + */ + if (is_guest_mode(vcpu)) + svm->nested.ctl.next_rip =3D svm->vmcb->control.next_rip; + return svm_exit_handlers_fastpath(vcpu); } =20 --=20 2.53.0.239.g8d8fc8a987-goog From nobody Thu Apr 2 17:32:51 2026 Received: from out-189.mta0.migadu.com (out-189.mta0.migadu.com [91.218.175.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 959F033FE08 for ; Wed, 11 Feb 2026 16:29:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827353; cv=none; b=A1MHn7RsArn0XymYwWofXFgtpoKbCRnJUujeHQO0pV+HGLCDwr1nai6VBJFKfnMflO5ND3lUaEtuFh3LBttBFo9TzuYfx3YQ3TtQ83zIYKpRnaVsh2VkXNKSo9SMRPU6H1xYLzxRl6RotlY62KkcDVCQ6Yb7RGcd3umVDyWv9V4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827353; c=relaxed/simple; bh=P+W34isyiDXmccZLS8OaycJD8Z07V6ZBtY4r8KCD8wI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=H+j6mtUr2G1ulyllBTWWSCBv2wjaV9KRaj1s4aCWQSbuqk4H9OJwd/mGMKRoLFiGU9bZANPC8OLhNsxS9oxF7+C0PO/VhGMUKQn8eWQMWhin1psKk93RfVp0HyuGEQax/sfUq7UDyaNWm1HPithSdGMAp08viAE2k6x8EMNqxuM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=HRXFzaqH; arc=none smtp.client-ip=91.218.175.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="HRXFzaqH" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770827348; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ybyst4NRcOI6MWu+lHAHowFuta/myHvvmn90Ih3KC60=; b=HRXFzaqHAmexWh1sonm7GjzFxnVCp3gWm1Z0NzhISuqoa6EizdcZ1aFBAkXfXYzwsZTFpP 9AOLIhOCpTBIm22DNUABa8cefLHXVYkrwMri3DHKcTTHqSJahyYZmyv1TkPmCiZO+Ic9x8 o9byBb28ecbPBDuGjqaEvhPZMitVfu8= From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed , stable@vger.kernel.org Subject: [PATCH v2 2/5] KVM: nSVM: Sync interrupt shadow to cached vmcb12 after VMRUN of L2 Date: Wed, 11 Feb 2026 16:28:39 +0000 Message-ID: <20260211162842.454151-3-yosry.ahmed@linux.dev> In-Reply-To: <20260211162842.454151-1-yosry.ahmed@linux.dev> References: <20260211162842.454151-1-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" After VMRUN in guest mode, nested_sync_control_from_vmcb02() syncs fields written by the CPU from vmcb02 to the cached vmcb12. This is because the cached vmcb12 is used as the authoritative copy of some of the controls, and is the payload when saving/restoring nested state. int_state is also written by the CPU, specifically bit 0 (i.e. SVM_INTERRUPT_SHADOW_MASK) for nested VMs, but it is not sync'd to cached vmcb12. This does not cause a problem if KVM_SET_NESTED_STATE preceeds KVM_SET_VCPU_EVENTS in the restore path, as an interrupt shadow would be correctly restored to vmcb02 (KVM_SET_VCPU_EVENTS overwrites what KVM_SET_NESTED_STATE restored in int_state). However, if KVM_SET_VCPU_EVENTS preceeds KVM_SET_NESTED_STATE, an interrupt shadow would be restored into vmcb01 instead of vmcb02. This would mostly be benign for L1 (delays an interrupt), but not for L2. For L2, the vCPU could hang (e.g. if a wakeup interrupt is delivered before a HLT that should have been in an interrupt shadow). Sync int_state to the cached vmcb12 in nested_sync_control_from_vmcb02() to avoid this problem. With that, KVM_SET_NESTED_STATE restores the correct interrupt shadow state, and if KVM_SET_VCPU_EVENTS follows it would overwrite it with the same value. Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET= _NESTED_STATE") CC: stable@vger.kernel.org Signed-off-by: Yosry Ahmed --- arch/x86/kvm/svm/nested.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index de90b104a0dd..9909ff237e5c 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -521,6 +521,7 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *s= vm) u32 mask; svm->nested.ctl.event_inj =3D svm->vmcb->control.event_inj; svm->nested.ctl.event_inj_err =3D svm->vmcb->control.event_inj_err; + svm->nested.ctl.int_state =3D svm->vmcb->control.int_state; =20 /* Only a few fields of int_ctl are written by the processor. */ mask =3D V_IRQ_MASK | V_TPR_MASK; --=20 2.53.0.239.g8d8fc8a987-goog From nobody Thu Apr 2 17:32:51 2026 Received: from out-179.mta0.migadu.com (out-179.mta0.migadu.com [91.218.175.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3543342C8C for ; Wed, 11 Feb 2026 16:29:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827353; cv=none; b=mpIrNG0h2fV2hlbvTXYkLujnfl4FOxwVjnFhoNcaxCxsEpp0YEPHCslpYIMacCk/GyiZroqwFiFiDB3GOTxB2/FpCdCIwD2eFASW8rN76Xx0v9i/kDaj5DZpy1whcwueaTPLnGMrzCRJ2vhpbq9l3HvoYWIxhAm/WFcVkojiojk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827353; c=relaxed/simple; bh=6YOnt69hh33xI0AM5ZsndXVvbB6SsOgg8IHG8x0zhkQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WQxi9D9kdqBg+VFlWVXMTB58Mtq8yCJzjSNfKPpnpT4agmqVa30fjLctc9Od0CZtCNX0XCvqFfJxhAlEgUqaffImouv6ljgonZH5Kz3QvsisZK9SYFIjPAUf7YrtsHOEGAy7/vP+yg7ef2hQNV5rCRcIgjXsLto/p9ubEpYh3CE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=VNqNxvUp; arc=none smtp.client-ip=91.218.175.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="VNqNxvUp" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770827350; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O2sl1XMMR/LmDqFSCtGv6iunZkhUJ85VwJIVaeYY+xw=; b=VNqNxvUpnNBdyNIcW0kZJjPrRRQDf8b0BA8D4qeT+vfpucdebZ3NoJinnWiQ6zZVxdNQcn 5VTi9uHzuN9eEYp8N0tq9qEZGCVITgCBQg/NBEedK251/cHCuDJ+k3NRnEdg3XuHLN4bvi 5BE1Pz6rROxQthyseiTVTeYxy4iLMEI= From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH v2 3/5] KVM: nSVM: Move sync'ing to vmcb12 cache after completing interrupts Date: Wed, 11 Feb 2026 16:28:40 +0000 Message-ID: <20260211162842.454151-4-yosry.ahmed@linux.dev> In-Reply-To: <20260211162842.454151-1-yosry.ahmed@linux.dev> References: <20260211162842.454151-1-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" nested_sync_control_from_vmcb02() sync's some fields from vmcb02 to the cached vmcb12 after a VMRUN of L2, mainly to keep the cache up-to-date for save/restore. However, NextRIP is sync'd separately after completing interrupts, as svm_complete_soft_interrupt() may update it (e.g. for soft IRQ re-injection). Move the call to nested_sync_control_from_vmcb02() after completing interrupts, moving the NextRIP sync (and the FIXME) inside it. This keeps the sync code together, and puts the FIXME in a more adequate location, as it applies to most/all fields sync'd by nested_sync_control_from_vmcb02(). Moving the call is safe, as nothing in-between accesses any of the VMCB fields sync'd by nested_sync_control_from_vmcb02(), except NextRIP. Opportunistically make some whitespace fixes. No functional change intended. Signed-off-by: Yosry Ahmed --- arch/x86/kvm/svm/nested.c | 10 ++++++++-- arch/x86/kvm/svm/svm.c | 26 ++++++++++---------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 9909ff237e5c..6a7c7c5b742a 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -519,9 +519,15 @@ void nested_copy_vmcb_save_to_cache(struct vcpu_svm *s= vm, void nested_sync_control_from_vmcb02(struct vcpu_svm *svm) { u32 mask; - svm->nested.ctl.event_inj =3D svm->vmcb->control.event_inj; - svm->nested.ctl.event_inj_err =3D svm->vmcb->control.event_inj_err; + + /* + * FIXME: Rework svm_get_nested_state() to not pull data from the + * cache (except for maybe int_ctl). + */ + svm->nested.ctl.event_inj =3D svm->vmcb->control.event_inj; + svm->nested.ctl.event_inj_err =3D svm->vmcb->control.event_inj_err; svm->nested.ctl.int_state =3D svm->vmcb->control.int_state; + svm->nested.ctl.next_rip =3D svm->vmcb->control.next_rip; =20 /* Only a few fields of int_ctl are written by the processor. */ mask =3D V_IRQ_MASK | V_TPR_MASK; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 1073a32a96fa..458abead9d5b 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4399,17 +4399,6 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm= _vcpu *vcpu, u64 run_flags) sync_cr8_to_lapic(vcpu); =20 svm->next_rip =3D 0; - if (is_guest_mode(vcpu)) { - nested_sync_control_from_vmcb02(svm); - - /* Track VMRUNs that have made past consistency checking */ - if (svm->nested.nested_run_pending && - !svm_is_vmrun_failure(svm->vmcb->control.exit_code)) - ++vcpu->stat.nested_run; - - svm->nested.nested_run_pending =3D 0; - } - svm->vmcb->control.tlb_ctl =3D TLB_CONTROL_DO_NOTHING; =20 /* @@ -4438,12 +4427,17 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kv= m_vcpu *vcpu, u64 run_flags) /* * Update the cache after completing interrupts to get an accurate * NextRIP, e.g. when re-injecting a soft interrupt. - * - * FIXME: Rework svm_get_nested_state() to not pull data from the - * cache (except for maybe int_ctl). */ - if (is_guest_mode(vcpu)) - svm->nested.ctl.next_rip =3D svm->vmcb->control.next_rip; + if (is_guest_mode(vcpu)) { + nested_sync_control_from_vmcb02(svm); + + /* Track VMRUNs that have made past consistency checking */ + if (svm->nested.nested_run_pending && + !svm_is_vmrun_failure(svm->vmcb->control.exit_code)) + ++vcpu->stat.nested_run; + + svm->nested.nested_run_pending =3D 0; + } =20 return svm_exit_handlers_fastpath(vcpu); } --=20 2.53.0.239.g8d8fc8a987-goog From nobody Thu Apr 2 17:32:51 2026 Received: from out-186.mta0.migadu.com (out-186.mta0.migadu.com [91.218.175.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B0F634404F for ; Wed, 11 Feb 2026 16:29:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827355; cv=none; b=FuYA9aV6JIMGl4xi+LB9LIicu4x9M0wjRwD2yiX7GcUpMfiPeOd5TamYLjJ2vV5uamgttfV6+T378jmFp/qVenQIrvkp3Rvtb1yToKuwSibuPaFJoTPQh+QCo9SskFoAfspoH4dmJDdYDaAc2wFt+VyHt5KzpQBqYkhkiHQ41AY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827355; c=relaxed/simple; bh=JQWwyvFcxCw9codsXvucZKYe/vNO0xvYDKNARMSJ61Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aFk7272PUScnoe+UtgKvFR9XGtu2mfnOompEiBgf1hrEl4sFC104ywyd+J7sIekjO9TLl18MzpRm0VllFLMO6VHUIRrsovNIP2Fa6qhGZ+RxbU7WuWRMhaWzSlBMfesYO5Qsn7BGVhs3XK6RT3yCA8q/iSQRGDQdgNoxGsEbVuo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Ge4nM4iq; arc=none smtp.client-ip=91.218.175.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Ge4nM4iq" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770827352; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IAHA1BoR9Ww40qGSdofKCW6ZALBTizq0Cah0BSADaW4=; b=Ge4nM4iqICA2l8ZV43Do6Ey+gRQjSyJutZYlR0G/WJHNwBDfkWMSvWiN+xZtMREl175h8H 0wTmZ2MLT0O2xXVKbGm24K53IgSptO8hWROXethlO6pgEJJAvojz86SYKFD3eWicvDIYFx GktqIAVQF5tIzM8NP0OpQiJYZILxUiM= From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH v2 4/5] KVM: selftests: Extend state_test to check vGIF Date: Wed, 11 Feb 2026 16:28:41 +0000 Message-ID: <20260211162842.454151-5-yosry.ahmed@linux.dev> In-Reply-To: <20260211162842.454151-1-yosry.ahmed@linux.dev> References: <20260211162842.454151-1-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" V_GIF_MASK is one of the fields written by the CPU after VMRUN, and sync'd by KVM from vmcb02 to cached vmcb12 after running L2. Part of the reason is to make sure V_GIF_MASK is saved/restored correctly, as the cached vmcb12 is the payload of nested state. Verify that V_GIF_MASK is saved/restored correctly in state_test by enabling vGIF in vmcb12, toggling GIF in L2 at different GUEST_SYNC() points, and verifying that V_GIF_MASK is correctly propagated to the nested state. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/x86/state_test.c | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/s= elftests/kvm/x86/state_test.c index f2c7a1c297e3..57c7546f3d7c 100644 --- a/tools/testing/selftests/kvm/x86/state_test.c +++ b/tools/testing/selftests/kvm/x86/state_test.c @@ -26,7 +26,9 @@ void svm_l2_guest_code(void) GUEST_SYNC(4); /* Exit to L1 */ vmcall(); + clgi(); GUEST_SYNC(6); + stgi(); /* Done, exit to L1 and never come back. */ vmcall(); } @@ -41,6 +43,8 @@ static void svm_l1_guest_code(struct svm_test_data *svm) generic_svm_setup(svm, svm_l2_guest_code, &l2_guest_stack[L2_GUEST_STACK_SIZE]); =20 + vmcb->control.int_ctl |=3D (V_GIF_ENABLE_MASK | V_GIF_MASK); + GUEST_SYNC(3); run_guest(vmcb, svm->vmcb_gpa); GUEST_ASSERT(vmcb->control.exit_code =3D=3D SVM_EXIT_VMMCALL); @@ -222,6 +226,24 @@ static void __attribute__((__flatten__)) guest_code(vo= id *arg) GUEST_DONE(); } =20 +void svm_check_nested_state(int stage, struct kvm_x86_state *state) +{ + struct vmcb *vmcb =3D (struct vmcb *)state->nested.data.svm; + + if (kvm_cpu_has(X86_FEATURE_VGIF)) { + if (stage =3D=3D 4) + TEST_ASSERT_EQ(!!(vmcb->control.int_ctl & V_GIF_MASK), 1); + if (stage =3D=3D 6) + TEST_ASSERT_EQ(!!(vmcb->control.int_ctl & V_GIF_MASK), 0); + } +} + +void check_nested_state(int stage, struct kvm_x86_state *state) +{ + if (kvm_has_cap(KVM_CAP_NESTED_STATE) && kvm_cpu_has(X86_FEATURE_SVM)) + svm_check_nested_state(stage, state); +} + int main(int argc, char *argv[]) { uint64_t *xstate_bv, saved_xstate_bv; @@ -278,6 +300,8 @@ int main(int argc, char *argv[]) =20 kvm_vm_release(vm); =20 + check_nested_state(stage, state); + /* Restore state in a new VM. */ vcpu =3D vm_recreate_with_one_vcpu(vm); vcpu_load_state(vcpu, state); --=20 2.53.0.239.g8d8fc8a987-goog From nobody Thu Apr 2 17:32:51 2026 Received: from out-180.mta0.migadu.com (out-180.mta0.migadu.com [91.218.175.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFE2633FE27 for ; Wed, 11 Feb 2026 16:29:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827357; cv=none; b=ajanjYaedYr+zx/oNCH6pThzQpEACi0M3N4GALqwdD3RdD9gP1AO216m6NEnaGvOT+To4QwNd4msRwBDXNtA++tsfr+cEqOFHLOG6cUbYHVUIF8py9DRB+MzFur6Zd3SGfqyPYx8lQbbgFjq6v/M3B2drRoElcVdFqe4wh6Jb48= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770827357; c=relaxed/simple; bh=/sgsLkfbqIClvvV8rFZNiXHMdUoW7U52VNMIRQlnhjw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VX3n70ecfRxy1Pe1eeQHLcbGMR3HsJv7fTafbnZ1y2a8vuV2R2DyIPQNO7MP+aSyn+zN3D+y+0nuTv7YdRC9iV8CcFgOEJu86ZiZWvux4q4zwi6AcaGpna111qJyVoNUuiiOkiVViPeLwCLRMe8ADQSeIyAKEpns8YM/J1SORYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=o+xoKSVX; arc=none smtp.client-ip=91.218.175.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="o+xoKSVX" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770827354; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1FICbsfpn2yI8rBPMCG8CPTHNhJDyAKHkEnxlfHtJ8g=; b=o+xoKSVXF6Qw/oWMzkhV5+/1XrWWKis6fBHmVQNLdugwO5JEny1kwirFzCFwzaf9x7mCFY ItVF6LAKi6lLZcrmQHToea1Wgo2ej9W8Gliy5JDI3rX6WNjxwmGoDiXsKDQFYBszyYma/X 4GAmm2JGhrmmGYxhC3uz9w4k7pUtLqM= From: Yosry Ahmed To: Sean Christopherson Cc: Paolo Bonzini , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed Subject: [PATCH v2 5/5] KVM: selftests: Extend state_test to check next_rip Date: Wed, 11 Feb 2026 16:28:42 +0000 Message-ID: <20260211162842.454151-6-yosry.ahmed@linux.dev> In-Reply-To: <20260211162842.454151-1-yosry.ahmed@linux.dev> References: <20260211162842.454151-1-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Similar to vGIF, extend state_test to make sure that next_rip is saved correctly in nested state. GUEST_SYNC() in L2 causes IO emulation by KVM, which advances the RIP to the value of next_rip. Hence, if next_rip is saved correctly, its value should match the saved RIP value. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/x86/state_test.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/testing/selftests/kvm/x86/state_test.c b/tools/testing/s= elftests/kvm/x86/state_test.c index 57c7546f3d7c..992a52504a4a 100644 --- a/tools/testing/selftests/kvm/x86/state_test.c +++ b/tools/testing/selftests/kvm/x86/state_test.c @@ -236,6 +236,17 @@ void svm_check_nested_state(int stage, struct kvm_x86_= state *state) if (stage =3D=3D 6) TEST_ASSERT_EQ(!!(vmcb->control.int_ctl & V_GIF_MASK), 0); } + + if (kvm_cpu_has(X86_FEATURE_NRIPS)) { + /* + * GUEST_SYNC() causes IO emulation in KVM, in which case the + * RIP is advanced before exiting to userspace. Hence, the RIP + * in the saved state should be the same as nRIP saved by the + * CPU in the VMCB. + */ + if (stage =3D=3D 6) + TEST_ASSERT_EQ(vmcb->control.next_rip, state->regs.rip); + } } =20 void check_nested_state(int stage, struct kvm_x86_state *state) --=20 2.53.0.239.g8d8fc8a987-goog