lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri,  5 Feb 2021 18:03:10 +0800
From:   Zhimin Feng <fengzhimin@...edance.com>
To:     x86@...nel.org, kvm@...r.kernel.org, linux-kernel@...r.kernel.org
Cc:     pbonzini@...hat.com, seanjc@...gle.com, vkuznets@...hat.com,
        wanpengli@...cent.com, jmattson@...gle.com, joro@...tes.org,
        tglx@...utronix.de, mingo@...hat.com, bp@...en8.de, hpa@...or.com,
        fweisbec@...il.com, zhouyibo@...edance.com,
        zhanghaozhong@...edance.com, Zhimin Feng <fengzhimin@...edance.com>
Subject: [RFC: timer passthrough 2/9] KVM: vmx: enable host lapic timer offload preemtion timer

Use preemption timer to handle host timer

Signed-off-by: Zhimin Feng <fengzhimin@...edance.com>
---
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/vmx/vmx.c          | 54 +++++++++++++++++++++++++++++++++++++++++
 arch/x86/kvm/x86.c              |  1 +
 3 files changed, 56 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index eb6a611963b7..82a51f0d01a2 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -826,6 +826,7 @@ struct kvm_vcpu_arch {
 	} pv_cpuid;
 
 	bool timer_passth_enable;
+	u64 tscd;
 };
 
 struct kvm_lpage_info {
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 38b8d80fa157..0bf9941df842 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -5629,6 +5629,13 @@ static fastpath_t handle_fastpath_preemption_timer(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 
+	if (vcpu->arch.timer_passth_enable) {
+		local_irq_disable();
+		apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), LOCAL_TIMER_VECTOR);
+		local_irq_enable();
+
+		return EXIT_FASTPATH_NONE;
+	}
 	if (!vmx->req_immediate_exit &&
 	    !unlikely(vmx->loaded_vmcs->hv_timer_soft_disabled)) {
 		kvm_lapic_expired_hv_timer(vcpu);
@@ -6640,6 +6647,51 @@ static fastpath_t vmx_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
 
 bool __vmx_vcpu_run(struct vcpu_vmx *vmx, unsigned long *regs, bool launched);
 
+static void vmx_host_lapic_timer_offload(struct kvm_vcpu *vcpu)
+{
+	struct timer_passth_info *local_timer_info;
+	u64 tscl;
+	u64 guest_tscl;
+	u64 delta_tsc;
+	struct hrtimer *timer;
+
+	if (!vcpu->arch.timer_passth_enable)
+		return;
+
+	local_timer_info = &per_cpu(passth_info, smp_processor_id());
+
+	tscl = rdtsc();
+	guest_tscl = kvm_read_l1_tsc(vcpu, tscl);
+
+	timer = &vcpu->arch.apic->lapic_timer.timer;
+	if (hrtimer_active(timer))
+		hrtimer_cancel(timer);
+
+	if (local_timer_info->host_tscd > tscl) {
+		delta_tsc = (u32)((local_timer_info->host_tscd - tscl) >>
+				cpu_preemption_timer_multi);
+		vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, delta_tsc);
+		vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL,
+				PIN_BASED_VMX_PREEMPTION_TIMER);
+	} else {
+		vmcs_clear_bits(PIN_BASED_VM_EXEC_CONTROL,
+				PIN_BASED_VMX_PREEMPTION_TIMER);
+	}
+
+	wrmsrl(MSR_IA32_TSCDEADLINE, 0);
+	if (vcpu->arch.tscd > guest_tscl) {
+		wrmsrl(MSR_IA32_TSCDEADLINE, vcpu->arch.tscd);
+	} else {
+		if (vcpu->arch.tscd > 0) {
+			if (!atomic_read(&vcpu->arch.apic->lapic_timer.pending)) {
+				atomic_inc(&vcpu->arch.apic->lapic_timer.pending);
+				kvm_inject_pending_timer_irqs(vcpu);
+				kvm_x86_ops.sync_pir_to_irr(vcpu);
+			}
+		}
+	}
+}
+
 static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
 					struct vcpu_vmx *vmx)
 {
@@ -6761,6 +6813,8 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
 
 	kvm_wait_lapic_expire(vcpu);
 
+	vmx_host_lapic_timer_offload(vcpu);
+
 	/*
 	 * If this vCPU has touched SPEC_CTRL, restore the guest's value if
 	 * it's non-zero. Since vmentry is serialising on affected CPUs, there
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5d353a9c9881..e51fd52a4862 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9912,6 +9912,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 	vcpu->arch.pending_external_vector = -1;
 	vcpu->arch.preempted_in_kernel = false;
 	vcpu->arch.timer_passth_enable = false;
+	vcpu->arch.tscd = 0;
 
 	kvm_hv_vcpu_init(vcpu);
 
-- 
2.11.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ