From nobody Thu Apr 2 06:28:47 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 8F5B23EFD1B; Thu, 5 Mar 2026 17:44:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772732683; cv=none; b=mek5L0wQeif8mr0CE5i4uYC4+RVaOdle901Xe6wy/YLtLgVgvX3cR3JXRYGhQb/Trpkwi3NAtsQX9g+PSmCdoLX2kK8tXPsA/62d9HJePBGRBgbioFrNjg52mHIuqqljBHtysFBWKQC29Q16jnotbAGduJTGD5qB8aQFfH3Wl4c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772732683; c=relaxed/simple; bh=huoyecPz/KqXQIsJELqEpkmIqLLtCWXKLwItJRSV4Ww=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fYmNJMQiZgQtx0szYmPCRcgV2EfS54sEf+Kq62tRK0noVjMZN4BzJgCcFoD+Gp2y+NELsmTK3qnBDEGeBOTsZFlgmptCl04KDT/JMKytvzoSsC1pf8Rj4AdhMlTZTy+ti+TzGI+iPje042j6l/NFw9SUTtLQlAkld0vmqHaqFR0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=T3p9JFcF; arc=none smtp.client-ip=198.175.65.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="T3p9JFcF" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1772732682; x=1804268682; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=huoyecPz/KqXQIsJELqEpkmIqLLtCWXKLwItJRSV4Ww=; b=T3p9JFcFdpfuF135KJKs3N72BCQWlj7TXfgZ8cpI/+7+j/+nBBx6n4z8 S8u1I5MC6JQV7PRzrVRwsPo2GZe4bq3yPzbWV/CKMiFTOcELrLyc3aj5l TlHgocjN0lTgORseVkdeuou0Ew26lwyi08tbSqm0qmFNhNM8nrAFBh3rb DHGCCZiL3fB04DjJMOugcmUssk2PX4R7Z09E+g/4UC5e94u1e/hsnpgno wXOsEf7QZ8R5Z01hs2eytM+WlPO/4NG55ChfSlBgH5LuCZ1x02YxAExDy lAu4EaDIHndWiYlmuRiA5MHnhNgm+PHrDCEl3JjqWLBeTXrWHIKz1vlAl Q==; X-CSE-ConnectionGUID: GznQX1t/RSWziGaHCbeHcg== X-CSE-MsgGUID: mGNGYQneTsq2Kp6gwthNjQ== X-IronPort-AV: E=McAfee;i="6800,10657,11720"; a="77431583" X-IronPort-AV: E=Sophos;i="6.23,103,1770624000"; d="scan'208";a="77431583" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Mar 2026 09:44:39 -0800 X-CSE-ConnectionGUID: 43bUw0QRTcyiNNbpraHERg== X-CSE-MsgGUID: 74Vlv3WxSmGfw9VvEzNlsw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,103,1770624000"; d="scan'208";a="223447891" Received: from mdroper-mobl2.amr.corp.intel.com (HELO localhost) ([10.124.220.244]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Mar 2026 09:44:38 -0800 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , Sean Christopherson , linux-kernel@vger.kernel.org Subject: [PATCH v2 16/36] KVM: nVMX: Enable guest deadline and its shadow VMCS field Date: Thu, 5 Mar 2026 09:43:56 -0800 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" From: Isaku Yamahata Support the guest deadline and the guest deadline shadow VMCS field. Signed-off-by: Isaku Yamahata --- Changes: v1 -> v2: - the offsets of vmcs fields changed due to rebase. --- arch/x86/kvm/vmx/nested.c | 48 +++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/vmx/vmcs12.c | 2 ++ arch/x86/kvm/vmx/vmcs12.h | 5 ++++ arch/x86/kvm/vmx/vmx.h | 2 ++ 4 files changed, 57 insertions(+) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index b7561f8f4565..3f1318736205 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2768,6 +2768,22 @@ static void prepare_vmcs02_rare(struct vcpu_vmx *vmx= , struct vmcs12 *vmcs12) set_cr4_guest_host_mask(vmx); } =20 +static void nested_guest_apic_timer(struct kvm_vcpu *vcpu, struct vmcs12 *= vmcs12) +{ + u64 guest_deadline_shadow =3D vmcs12->guest_deadline_shadow; + u64 guest_deadline =3D vmcs12->guest_deadline; + struct vcpu_vmx *vmx =3D to_vmx(vcpu); + + if (!vmx->nested.guest_deadline_dirty) + return; + + guest_deadline =3D vmx_calc_deadline_l1_to_host(vcpu, guest_deadline); + + vmcs_write64(GUEST_DEADLINE_PHY, guest_deadline); + vmcs_write64(GUEST_DEADLINE_VIR, guest_deadline_shadow); + vmx->nested.guest_deadline_dirty =3D false; +} + /* * prepare_vmcs02 is called when the L1 guest hypervisor runs its nested * L2 guest. L1 has a vmcs for L2 (vmcs12), and this function "merges" it @@ -2845,6 +2861,9 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, stru= ct vmcs12 *vmcs12, if (kvm_caps.has_tsc_control) vmcs_write64(TSC_MULTIPLIER, vcpu->arch.tsc_scaling_ratio); =20 + if (nested_cpu_has_guest_apic_timer(vmcs12)) + nested_guest_apic_timer(vcpu, vmcs12); + nested_vmx_transition_tlb_flush(vcpu, vmcs12, true); =20 if (nested_cpu_has_ept(vmcs12)) @@ -4635,6 +4654,8 @@ static bool is_vmcs12_ext_field(unsigned long field) case GUEST_IDTR_BASE: case GUEST_PENDING_DBG_EXCEPTIONS: case GUEST_BNDCFGS: + case GUEST_DEADLINE_PHY: + case GUEST_DEADLINE_VIR: return true; default: break; @@ -4685,6 +4706,24 @@ static void sync_vmcs02_to_vmcs12_rare(struct kvm_vc= pu *vcpu, vmcs12->guest_pending_dbg_exceptions =3D vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS); =20 + if (nested_cpu_has_guest_apic_timer(vmcs12)) { + u64 guest_deadline_shadow =3D vmcs_read64(GUEST_DEADLINE_VIR); + u64 guest_deadline =3D vmcs_read64(GUEST_DEADLINE_PHY); + + if (guest_deadline) { + guest_deadline =3D kvm_read_l1_tsc(vcpu, guest_deadline); + if (!guest_deadline) + guest_deadline =3D 1; + } + + vmcs12->guest_deadline =3D guest_deadline; + vmcs12->guest_deadline_shadow =3D guest_deadline_shadow; + } else if (vmx->nested.msrs.tertiary_ctls & TERTIARY_EXEC_GUEST_APIC_TIME= R) { + vmcs12->guest_deadline =3D 0; + vmcs12->guest_deadline_shadow =3D 0; + } + vmx->nested.guest_deadline_dirty =3D false; + vmx->nested.need_sync_vmcs02_to_vmcs12_rare =3D false; } =20 @@ -5933,6 +5972,13 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) vmx->nested.dirty_vmcs12 =3D true; } =20 + if (!is_guest_mode(vcpu) && + (field =3D=3D GUEST_DEADLINE_PHY || + field =3D=3D GUEST_DEADLINE_PHY_HIGH || + field =3D=3D GUEST_DEADLINE_VIR || + field =3D=3D GUEST_DEADLINE_VIR_HIGH)) + vmx->nested.guest_deadline_dirty =3D true; + return nested_vmx_succeed(vcpu); } =20 @@ -5947,6 +5993,7 @@ static void set_current_vmptr(struct vcpu_vmx *vmx, g= pa_t vmptr) } vmx->nested.dirty_vmcs12 =3D true; vmx->nested.force_msr_bitmap_recalc =3D true; + vmx->nested.guest_deadline_dirty =3D true; } =20 /* Emulate the VMPTRLD instruction */ @@ -7124,6 +7171,7 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, =20 vmx->nested.dirty_vmcs12 =3D true; vmx->nested.force_msr_bitmap_recalc =3D true; + vmx->nested.guest_deadline_dirty =3D true; ret =3D nested_vmx_enter_non_root_mode(vcpu, false); if (ret) goto error_guest_mode; diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c index dac796fc20f2..d2098767dd7a 100644 --- a/arch/x86/kvm/vmx/vmcs12.c +++ b/arch/x86/kvm/vmx/vmcs12.c @@ -70,6 +70,8 @@ static const u16 kvm_supported_vmcs12_field_offsets[] __i= nitconst =3D { FIELD64(HOST_IA32_PAT, host_ia32_pat), FIELD64(HOST_IA32_EFER, host_ia32_efer), FIELD64(HOST_IA32_PERF_GLOBAL_CTRL, host_ia32_perf_global_ctrl), + FIELD64(GUEST_DEADLINE_PHY, guest_deadline), + FIELD64(GUEST_DEADLINE_VIR, guest_deadline_shadow), FIELD(PIN_BASED_VM_EXEC_CONTROL, pin_based_vm_exec_control), FIELD(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control), FIELD(EXCEPTION_BITMAP, exception_bitmap), diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 7a20d6661da0..0846033b6759 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h @@ -192,6 +192,9 @@ struct __packed vmcs12 { u16 host_tr_selector; u16 guest_pml_index; u16 virtual_timer_vector; + + u64 guest_deadline; + u64 guest_deadline_shadow; }; =20 /* @@ -376,6 +379,8 @@ static inline void vmx_check_vmcs12_offsets(void) CHECK_OFFSET(host_tr_selector, 994); CHECK_OFFSET(guest_pml_index, 996); CHECK_OFFSET(virtual_timer_vector, 998); + CHECK_OFFSET(guest_deadline, 1000); + CHECK_OFFSET(guest_deadline_shadow, 1008); } =20 extern u16 vmcs12_field_offsets[] __ro_after_init; diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 6f1caf3ef5b7..fbbbae46e0b2 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -163,6 +163,8 @@ struct nested_vmx { bool has_preemption_timer_deadline; bool preemption_timer_expired; =20 + bool guest_deadline_dirty; + /* * Used to snapshot MSRs that are conditionally loaded on VM-Enter in * order to propagate the guest's pre-VM-Enter value into vmcs02. For --=20 2.45.2