Commit 6ca1a2ca authored by Bibo Mao's avatar Bibo Mao Committed by Xianglai Li
Browse files

LoongArch: KVM: Add PV steal time support in host side

mainline inclusion
from mainline-v6.11-rc1
commit b4ba157044ea433a66126603ad7140e12dbc794b
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IAZJDO


CVE: NA

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

Add ParaVirt steal time feature in host side, VM can search supported
features provided by KVM hypervisor, a feature KVM_FEATURE_STEAL_TIME
is added here. Like x86, steal time structure is saved in guest memory,
one hypercall function KVM_HCALL_FUNC_NOTIFY is added to notify KVM to
enable this feature.

One CPU attr ioctl command KVM_LOONGARCH_VCPU_PVTIME_CTRL is added to
save and restore the base address of steal time structure when a VM is
migrated.

Signed-off-by: default avatarBibo Mao <maobibo@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
Signed-off-by: default avatarXianglai Li <lixianglai@loongson.cn>
parent 0f720584
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@

#define KVM_HALT_POLL_NS_DEFAULT	500000
#define KVM_REQ_TLB_FLUSH_GPA		KVM_ARCH_REQ(0)
#define KVM_REQ_RECORD_STEAL		KVM_ARCH_REQ(1)
#define KVM_REQ_STEAL_UPDATE		KVM_ARCH_REQ(1)

#define KVM_GUESTDBG_SW_BP_MASK		\
	(KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ struct kvm_steal_time {
	__u32 pad[12];
};


/*
 * Hypercall interface for KVM hypervisor
 *
+5 −0
Original line number Diff line number Diff line
@@ -120,4 +120,9 @@ static inline void kvm_write_reg(struct kvm_vcpu *vcpu, int num, unsigned long v
	vcpu->arch.gprs[num] = val;
}

static inline bool kvm_pvtime_supported(void)
{
	return !!sched_info_on();
}

#endif /* __ASM_LOONGARCH_KVM_VCPU_H__ */
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ config KVM
	select KVM_GENERIC_HARDWARE_ENABLING
	select KVM_MMIO
	select KVM_XFER_TO_GUEST_WORK
	select SCHED_INFO
	select MMU_NOTIFIER
	select PREEMPT_NOTIFIERS
	help
+29 −26
Original line number Diff line number Diff line
@@ -259,12 +259,9 @@ static int kvm_emu_cpucfg(struct kvm_vcpu *vcpu, larch_inst inst)
			vcpu->arch.gprs[rd] = 0;
		break;
	case CPUCFG_KVM_FEATURE:
		ret = 0;
		if ((plv & CSR_CRMD_PLV) == PLV_KERN) {
			ret = KVM_FEATURE_PV_IPI;
			if (sched_info_on())
		ret = KVM_FEATURE_IPI;
		if (kvm_pvtime_supported())
			ret |= KVM_FEATURE_STEAL_TIME;
		}
		vcpu->arch.gprs[rd] = ret;
		break;
	default:
@@ -742,6 +739,31 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu)
	return RESUME_GUEST;
}

static long kvm_save_notify(struct kvm_vcpu *vcpu)
{
	unsigned long id, data;

	id   = kvm_read_reg(vcpu, LOONGARCH_GPR_A1);
	data = kvm_read_reg(vcpu, LOONGARCH_GPR_A2);
	switch (id) {
	case BIT(KVM_FEATURE_STEAL_TIME):
		if (data & ~(KVM_STEAL_PHYS_MASK | KVM_STEAL_PHYS_VALID))
			return KVM_HCALL_INVALID_PARAMETER;

		vcpu->arch.st.guest_addr = data;
		if (!(data & KVM_STEAL_PHYS_VALID))
			return 0;

		vcpu->arch.st.last_steal = current->sched_info.run_delay;
		kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
		return 0;
	default:
		return KVM_HCALL_INVALID_CODE;
	};

	return KVM_HCALL_INVALID_CODE;
};

/*
 * kvm_handle_lsx_disabled() - Guest used LSX while disabled in root.
 * @vcpu:      Virtual CPU context.
@@ -821,25 +843,6 @@ static void kvm_handle_service(struct kvm_vcpu *vcpu)
	kvm_write_reg(vcpu, LOONGARCH_GPR_A0, ret);
}

static int kvm_save_notify(struct kvm_vcpu *vcpu)
{
	unsigned long id, data;

	id = vcpu->arch.gprs[LOONGARCH_GPR_A1];
	data = vcpu->arch.gprs[LOONGARCH_GPR_A2];
	switch (id) {
	case KVM_FEATURE_STEAL_TIME:
		vcpu->arch.st.guest_addr = data;
		vcpu->arch.st.last_steal = current->sched_info.run_delay;
		kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
		break;
	default:
		break;
	};

	return 0;
};

static int kvm_handle_hypercall(struct kvm_vcpu *vcpu)
{
	int ret;
@@ -865,7 +868,7 @@ static int kvm_handle_hypercall(struct kvm_vcpu *vcpu)
		fallthrough;
	default:
		/* Treat it as noop intruction, only set return value */
		vcpu->arch.gprs[LOONGARCH_GPR_A0] = KVM_HCALL_INVALID_CODE;
		kvm_write_reg(vcpu, LOONGARCH_GPR_A0, KVM_HCALL_INVALID_CODE);
		break;
	}

Loading