Commit d92912ef authored by Haibin Wang's avatar Haibin Wang Committed by Dongxu Sun
Browse files

KVM: arm64: arch_timer: Rework vcpu init/reset logic

virt inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8K89F


CVE: NA

------------------------------------------------------------------

Support vtimer irqbypass.

Signed-off-by: default avatarZenghui Yu <yuzenghui@huawei.com>
Signed-off-by: default avatarHaibin Wang <wanghaibin.wang@huawei.com>
Signed-off-by: default avatarKunkun Jiang <jiangkunkun@huawei.com>
Signed-off-by: default avatarDongxu Sun <sundongxu3@huawei.com>
parent a7d5bdc6
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -758,6 +758,15 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
	timer_set_ctl(vcpu_ptimer(vcpu), 0);

	if (timer->enabled) {
		if (vtimer_is_irqbypass()) {
			kvm_timer_update_irq(vcpu, false, vcpu_ptimer(vcpu));

			if (irqchip_in_kernel(vcpu->kvm) && map.direct_ptimer)
				kvm_vgic_reset_mapped_irq(vcpu, map.direct_ptimer->irq.irq);

			goto skip_reset_vtimer;
		}

		kvm_timer_update_irq(vcpu, false, vcpu_vtimer(vcpu));
		kvm_timer_update_irq(vcpu, false, vcpu_ptimer(vcpu));

@@ -768,6 +777,7 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
		}
	}

skip_reset_vtimer:
	if (map.emul_ptimer)
		soft_timer_cancel(&map.emul_ptimer->hrtimer);

@@ -1173,6 +1183,35 @@ bool kvm_arch_timer_get_input_level(int vintid)
	return kvm_timer_should_fire(timer);
}

static void vtimer_set_active_stat(struct kvm_vcpu *vcpu, int vintid, bool set)
{
}

static bool vtimer_get_active_stat(struct kvm_vcpu *vcpu, int vintid)
{
	return false;
}

int kvm_vtimer_config(struct kvm_vcpu *vcpu)
{
	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
	int intid;

	if (!vtimer_is_irqbypass())
		return 0;

	if (timer->enabled)
		return 0;

	if (!irqchip_in_kernel(vcpu->kvm))
		return -EINVAL;

	intid = vcpu_vtimer(vcpu)->irq.irq;
	return kvm_vgic_config_vtimer_irqbypass(vcpu, intid,
						vtimer_get_active_stat,
						vtimer_set_active_stat);
}

int kvm_timer_enable(struct kvm_vcpu *vcpu)
{
	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
@@ -1182,6 +1221,9 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
	if (timer->enabled)
		return 0;

	if (!irqchip_in_kernel(vcpu->kvm) && vtimer_is_irqbypass())
		return -EINVAL;

	/* Without a VGIC we do not map virtual IRQs to physical IRQs */
	if (!irqchip_in_kernel(vcpu->kvm))
		goto no_vgic;
@@ -1196,6 +1238,9 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)

	get_timer_map(vcpu, &map);

	if (vtimer_is_irqbypass())
		goto skip_map_vtimer;

	ret = kvm_vgic_map_phys_irq(vcpu,
				    map.direct_vtimer->host_timer_irq,
				    map.direct_vtimer->irq.irq,
@@ -1203,6 +1248,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
	if (ret)
		return ret;

skip_map_vtimer:
	if (map.direct_ptimer) {
		ret = kvm_vgic_map_phys_irq(vcpu,
					    map.direct_ptimer->host_timer_irq,
+4 −0
Original line number Diff line number Diff line
@@ -639,6 +639,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)

	kvm_arm_vcpu_init_debug(vcpu);

	ret = kvm_vtimer_config(vcpu);
	if (ret)
		return ret;

	if (likely(irqchip_in_kernel(kvm))) {
		/*
		 * Map the VGIC hardware resources before running a vcpu the
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ struct arch_timer_cpu {

int kvm_timer_hyp_init(bool);
int kvm_timer_enable(struct kvm_vcpu *vcpu);
int kvm_vtimer_config(struct kvm_vcpu *vcpu);
int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
void kvm_timer_sync_user(struct kvm_vcpu *vcpu);