Commit 3d731fef authored by Bibo Mao's avatar Bibo Mao Committed by Xianglai Li
Browse files

LoongArch: KVM: Add VM feature detection function

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


CVE: NA

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

Loongson SIMD Extension (LSX), Loongson Advanced SIMD Extension (LASX)
and Loongson Binary Translation (LBT) features are defined in register
CPUCFG2. Two kinds of LSX/LASX/LBT feature detection are added here, one
is VCPU feature, and the other is VM feature. VCPU feature dection can
only work with VCPU thread itself, and requires VCPU thread is created
already. So LSX/LASX/LBT feature detection for VM is added also, it can
be done even if VM is not created, and also can be done by any threads
besides VCPU threads.

Here ioctl command KVM_HAS_DEVICE_ATTR is added for VM, and macro
KVM_LOONGARCH_VM_FEAT_CTRL is added to check supported feature. And
five sub-features relative with LSX/LASX/LBT are added as following:
 KVM_LOONGARCH_VM_FEAT_LSX
 KVM_LOONGARCH_VM_FEAT_LASX
 KVM_LOONGARCH_VM_FEAT_X86BT
 KVM_LOONGARCH_VM_FEAT_ARMBT
 KVM_LOONGARCH_VM_FEAT_MIPSBT

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 a237ea36
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -85,6 +85,14 @@ struct kvm_fpu {
#define KVM_IOC_CSRID(REG)		LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG)
#define KVM_IOC_CPUCFG(REG)		LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)

/* Device Control API on vm fd */
#define KVM_LOONGARCH_VM_FEAT_CTRL	0
#define  KVM_LOONGARCH_VM_FEAT_LSX	0
#define  KVM_LOONGARCH_VM_FEAT_LASX	1
#define  KVM_LOONGARCH_VM_FEAT_X86BT	2
#define  KVM_LOONGARCH_VM_FEAT_ARMBT	3
#define  KVM_LOONGARCH_VM_FEAT_MIPSBT	4

/* Device Control API on vcpu fd */
#define KVM_LOONGARCH_VCPU_CPUCFG	0
#define KVM_LOONGARCH_VCPU_PVTIME_CTRL	1
+6 −0
Original line number Diff line number Diff line
@@ -698,6 +698,12 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
			*v |= CPUCFG2_LSX;
		if (cpu_has_lasx)
			*v |= CPUCFG2_LASX;
		if (cpu_has_lbt_x86)
			*v |= CPUCFG2_X86BT;
		if (cpu_has_lbt_arm)
			*v |= CPUCFG2_ARMBT;
		if (cpu_has_lbt_mips)
			*v |= CPUCFG2_MIPSBT;

		return 0;
	case LOONGARCH_CPUCFG3:
+49 −0
Original line number Diff line number Diff line
@@ -104,15 +104,64 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
	return r;
}

static int kvm_vm_feature_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
{
	switch (attr->attr) {
	case KVM_LOONGARCH_VM_FEAT_LSX:
		if (cpu_has_lsx)
			return 0;
		return -ENXIO;
	case KVM_LOONGARCH_VM_FEAT_LASX:
		if (cpu_has_lasx)
			return 0;
		return -ENXIO;
	case KVM_LOONGARCH_VM_FEAT_X86BT:
		if (cpu_has_lbt_x86)
			return 0;
		return -ENXIO;
	case KVM_LOONGARCH_VM_FEAT_ARMBT:
		if (cpu_has_lbt_arm)
			return 0;
		return -ENXIO;
	case KVM_LOONGARCH_VM_FEAT_MIPSBT:
		if (cpu_has_lbt_mips)
			return 0;
		return -ENXIO;
	default:
		return -ENXIO;
	}
}

static int kvm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
{
	switch (attr->group) {
	case KVM_LOONGARCH_VM_FEAT_CTRL:
		return kvm_vm_feature_has_attr(kvm, attr);
	case KVM_LOONGARCH_VM_HAVE_IRQCHIP:
		return 0;
	default:
		return -ENXIO;
	}
}

int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
{
	int r;
	void __user *argp = (void __user *)arg;
	struct kvm *kvm = filp->private_data;
	struct kvm_device_attr attr;

	switch (ioctl) {
	case KVM_CREATE_IRQCHIP: {
		r = 1;
		break;
	}
	case KVM_HAS_DEVICE_ATTR: {
		if (copy_from_user(&attr, argp, sizeof(attr)))
			return -EFAULT;

		return kvm_vm_has_attr(kvm, &attr);
	}
	default:
		return -EINVAL;
	}