Unverified Commit a3cf1794 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!5547 Synchronizing upstream patch

Merge Pull Request from: @lixianglai 
 
This PR will synchronize the optimization patch of loongarch, and the optimization involves loongson-exiointc timer simulation and cpucfg simulation.

https://gitee.com/openeuler/kernel/issues/I9BTOX
 
 
Link:https://gitee.com/openeuler/kernel/pulls/5547

 

Reviewed-by: default avatarMao Bibo <maobibo@loongson.cn>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents e2b058b2 9becbc2e
Loading
Loading
Loading
Loading
+10 −33
Original line number Diff line number Diff line
@@ -23,24 +23,6 @@ static inline u64 tick_to_ns(struct kvm_vcpu *vcpu, u64 tick)
	return div_u64(tick * MNSEC_PER_SEC, vcpu->arch.timer_mhz);
}

/*
 * Push timer forward on timeout.
 * Handle an hrtimer event by push the hrtimer forward a period.
 */
static enum hrtimer_restart kvm_count_timeout(struct kvm_vcpu *vcpu)
{
	unsigned long cfg, period;

	/* Add periodic tick to current expire time */
	cfg = kvm_read_sw_gcsr(vcpu->arch.csr, LOONGARCH_CSR_TCFG);
	if (cfg & CSR_TCFG_PERIOD) {
		period = tick_to_ns(vcpu, cfg & CSR_TCFG_VAL);
		hrtimer_add_expires_ns(&vcpu->arch.swtimer, period);
		return HRTIMER_RESTART;
	} else
		return HRTIMER_NORESTART;
}

/* Low level hrtimer wake routine */
enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer)
{
@@ -50,7 +32,7 @@ enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer)
	kvm_queue_irq(vcpu, INT_TI);
	rcuwait_wake_up(&vcpu->wait);

	return kvm_count_timeout(vcpu);
	return HRTIMER_NORESTART;
}

/*
@@ -93,6 +75,7 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu)
	/*
	 * Freeze the soft-timer and sync the guest stable timer with it.
	 */
	if (kvm_vcpu_is_blocking(vcpu))
		hrtimer_cancel(&vcpu->arch.swtimer);

	/*
@@ -168,26 +151,20 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu)
	 * Here judge one-shot timer fired by checking whether TVAL is larger
	 * than TCFG
	 */
	if (ticks < cfg) {
	if (ticks < cfg)
		delta = tick_to_ns(vcpu, ticks);
	else
		delta = 0;

	expire = ktime_add_ns(ktime_get(), delta);
	vcpu->arch.expire = expire;
	if (kvm_vcpu_is_blocking(vcpu)) {

		/*
		 * HRTIMER_MODE_PINNED is suggested since vcpu may run in
		 * the same physical cpu in next time
		 */
		hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
	} else if (vcpu->stat.generic.blocking) {
		/*
		 * Inject timer interrupt so that halt polling can dectect and exit.
		 * VCPU is scheduled out already and sleeps in rcuwait queue and
		 * will not poll pending events again. kvm_queue_irq() is not enough,
		 * hrtimer swtimer should be used here.
		 */
		expire = ktime_add_ns(ktime_get(), 10);
		vcpu->arch.expire = expire;
		hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
	}
}

+26 −7
Original line number Diff line number Diff line
@@ -304,11 +304,18 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
		return -EINVAL;

	switch (id) {
	case 2:
	case LOONGARCH_CPUCFG0:
		*v = GENMASK(31, 0);
		return 0;
	case LOONGARCH_CPUCFG1:
		/* CPUCFG1_MSGINT is not supported by KVM */
		*v = GENMASK(25, 0);
		return 0;
	case LOONGARCH_CPUCFG2:
		/* CPUCFG2 features unconditionally supported by KVM */
		*v = CPUCFG2_FP     | CPUCFG2_FPSP  | CPUCFG2_FPDP     |
		     CPUCFG2_FPVERS | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV |
		     CPUCFG2_LAM;
		     CPUCFG2_LSPW | CPUCFG2_LAM;
		/*
		 * For the ISA extensions listed below, if one is supported
		 * by the host, then it is also supported by KVM.
@@ -318,14 +325,26 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
		if (cpu_has_lasx)
			*v |= CPUCFG2_LASX;

		return 0;
	case LOONGARCH_CPUCFG3:
		*v = GENMASK(16, 0);
		return 0;
	case LOONGARCH_CPUCFG4:
	case LOONGARCH_CPUCFG5:
		*v = GENMASK(31, 0);
		return 0;
	case LOONGARCH_CPUCFG16:
		*v = GENMASK(16, 0);
		return 0;
	case LOONGARCH_CPUCFG17 ... LOONGARCH_CPUCFG20:
		*v = GENMASK(30, 0);
		return 0;
	default:
		/*
		 * No restrictions on other valid CPUCFG IDs' values, but
		 * CPUCFG data is limited to 32 bits as the LoongArch ISA
		 * manual says (Volume 1, Section 2.2.10.5 "CPUCFG").
		 * CPUCFG bits should be zero if reserved by HW or not
		 * supported by KVM.
		 */
		*v = U32_MAX;
		*v = 0;
		return 0;
	}
}
@@ -344,7 +363,7 @@ static int kvm_check_cpucfg(int id, u64 val)
		return -EINVAL;

	switch (id) {
	case 2:
	case LOONGARCH_CPUCFG2:
		if (!(val & CPUCFG2_LLFTP))
			/* Guests must have a constant timer */
			return -EINVAL;
+6 −16
Original line number Diff line number Diff line
@@ -212,6 +212,12 @@ static void eiointc_irq_dispatch(struct irq_desc *desc)

	for (i = 0; i < eiointc_priv[0]->vec_count / VEC_COUNT_PER_REG; i++) {
		pending = iocsr_read64(EIOINTC_REG_ISR + (i << 3));

		/* Skip handling if pending bitmap is zero */
		if (!pending)
			continue;

		/* Clear the IRQs */
		iocsr_write64(pending, EIOINTC_REG_ISR + (i << 3));
		while (pending) {
			int bit = __ffs(pending);
@@ -318,23 +324,7 @@ static int eiointc_suspend(void)

static void eiointc_resume(void)
{
	int i, j;
	struct irq_desc *desc;
	struct irq_data *irq_data;

	eiointc_router_init(0);

	for (i = 0; i < nr_pics; i++) {
		for (j = 0; j < eiointc_priv[0]->vec_count; j++) {
			desc = irq_resolve_mapping(eiointc_priv[i]->eiointc_domain, j);
			if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) {
				raw_spin_lock(&desc->lock);
				irq_data = irq_domain_get_irq_data(eiointc_priv[i]->eiointc_domain, irq_desc_get_irq(desc));
				eiointc_set_irq_affinity(irq_data, irq_data->common->affinity, 0);
				raw_spin_unlock(&desc->lock);
			}
		}
	}
}

static struct syscore_ops eiointc_syscore_ops = {