All of lore.kernel.org
 help / color / mirror / Atom feed
From: Keqian Zhu <zhukeqian1@huawei.com>
To: <linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<kvmarm@lists.cs.columbia.edu>, <kvm@vger.kernel.org>
Cc: Marc Zyngier <maz@kernel.org>,
	Steven Price <steven.price@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>, James Morse <james.morse@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	<wanghaibin.wang@huawei.com>, Keqian Zhu <zhukeqian1@huawei.com>
Subject: [RFC PATCH 3/5] KVM: arm64: Provide VM device attributes for LPT time
Date: Mon, 17 Aug 2020 16:41:08 +0800	[thread overview]
Message-ID: <20200817084110.2672-4-zhukeqian1@huawei.com> (raw)
In-Reply-To: <20200817084110.2672-1-zhukeqian1@huawei.com>

Allow user space to inform the KVM host what the PV frequency is
and where in the physical memory map the paravirtualized LPT time
structures should be located. User space can set attributes on the
VM for that guest.

The address is given in terms of the physical address visible to
the guest and must be 64 byte aligned. The guest will discover the
address via a hypercall. PV frequency is 32 bits and must not be 0.

Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
 arch/arm64/include/asm/kvm_host.h |  4 ++
 arch/arm64/include/uapi/asm/kvm.h |  5 +++
 arch/arm64/kvm/arm.c              | 64 ++++++++++++++++++++++++++++
 arch/arm64/kvm/pvtime.c           | 87 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 160 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0c6a564..cbe330c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -523,6 +523,10 @@ int kvm_arm_pvtime_get_attr(struct kvm_vcpu *vcpu,
 int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu,
 			    struct kvm_device_attr *attr);
 
+int kvm_arm_pvtime_lpt_set_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+int kvm_arm_pvtime_lpt_get_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+int kvm_arm_pvtime_lpt_has_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+
 static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
 {
 	vcpu_arch->steal.base = GPA_INVALID;
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index ba85bb2..7b045c7 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -325,6 +325,11 @@ struct kvm_vcpu_events {
 #define   KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES	3
 #define   KVM_DEV_ARM_ITS_CTRL_RESET		4
 
+/* Device Control API on kvm fd */
+#define KVM_ARM_VM_PVTIME_LPT_CTRL	0
+#define   KVM_ARM_VM_PVTIME_LPT_IPA	0
+#define   KVM_ARM_VM_PVTIME_LPT_FREQ	1
+
 /* Device Control API on vcpu fd */
 #define KVM_ARM_VCPU_PMU_V3_CTRL	0
 #define   KVM_ARM_VCPU_PMU_V3_IRQ	0
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 671f1461..4a867e5 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1235,11 +1235,60 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
 	}
 }
 
+static int kvm_arm_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_set_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+static int kvm_arm_vm_get_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_get_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+static int kvm_arm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_has_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
 	struct kvm *kvm = filp->private_data;
 	void __user *argp = (void __user *)arg;
+	struct kvm_device_attr attr;
 
 	switch (ioctl) {
 	case KVM_CREATE_IRQCHIP: {
@@ -1271,6 +1320,21 @@ long kvm_arch_vm_ioctl(struct file *filp,
 
 		return 0;
 	}
+	case KVM_SET_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return -EFAULT;
+		return kvm_arm_vm_set_attr(kvm, &attr);
+	}
+	case KVM_GET_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return -EFAULT;
+		return kvm_arm_vm_get_attr(kvm, &attr);
+	}
+	case KVM_HAS_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return  -EFAULT;
+		return kvm_arm_vm_has_attr(kvm, &attr);
+	}
 	default:
 		return -EINVAL;
 	}
diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c
index 24131ca..3f93473 100644
--- a/arch/arm64/kvm/pvtime.c
+++ b/arch/arm64/kvm/pvtime.c
@@ -257,3 +257,90 @@ gpa_t kvm_init_lpt_time(struct kvm *kvm)
 {
 	return kvm->arch.lpt.base;
 }
+
+int kvm_arm_pvtime_lpt_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	u64 __user *user = (u64 __user *)attr->addr;
+	u64 ipa;
+	u32 freq;
+	int idx;
+	int ret = 0;
+
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+		if (get_user(ipa, user)) {
+			ret = -EFAULT;
+			break;
+		}
+		if (!IS_ALIGNED(ipa, 64)) {
+			ret = -EINVAL;
+			break;
+		}
+		if (kvm->arch.lpt.base != GPA_INVALID) {
+			ret = -EEXIST;
+			break;
+		}
+		/* Check the address is in a valid memslot */
+		idx = srcu_read_lock(&kvm->srcu);
+		if (kvm_is_error_hva(gfn_to_hva(kvm, ipa >> PAGE_SHIFT)))
+			ret = -EINVAL;
+		srcu_read_unlock(&kvm->srcu, idx);
+		if (ret)
+			break;
+
+		kvm->arch.lpt.base = ipa;
+		break;
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		if (get_user(freq, user)) {
+			ret = -EFAULT;
+			break;
+		}
+		if (freq == 0) {
+			ret = -EINVAL;
+			break;
+		}
+		if (kvm->arch.lpt.fpv != 0) {
+			ret = -EEXIST;
+			break;
+		}
+		kvm->arch.lpt.fpv = freq;
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+int kvm_arm_pvtime_lpt_get_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	u64 __user *user = (u64 __user *)attr->addr;
+	int ret = 0;
+
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+		if (put_user(kvm->arch.lpt.base, user))
+			ret = -EFAULT;
+		break;
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		if (put_user(kvm->arch.lpt.fpv, user))
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+int kvm_arm_pvtime_lpt_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		return 0;
+	}
+	return -ENXIO;
+}
-- 
1.8.3.1


WARNING: multiple messages have this Message-ID (diff)
From: Keqian Zhu <zhukeqian1@huawei.com>
To: <linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<kvmarm@lists.cs.columbia.edu>, <kvm@vger.kernel.org>
Cc: Marc Zyngier <maz@kernel.org>,
	Steven Price <steven.price@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>
Subject: [RFC PATCH 3/5] KVM: arm64: Provide VM device attributes for LPT time
Date: Mon, 17 Aug 2020 16:41:08 +0800	[thread overview]
Message-ID: <20200817084110.2672-4-zhukeqian1@huawei.com> (raw)
In-Reply-To: <20200817084110.2672-1-zhukeqian1@huawei.com>

Allow user space to inform the KVM host what the PV frequency is
and where in the physical memory map the paravirtualized LPT time
structures should be located. User space can set attributes on the
VM for that guest.

The address is given in terms of the physical address visible to
the guest and must be 64 byte aligned. The guest will discover the
address via a hypercall. PV frequency is 32 bits and must not be 0.

Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
 arch/arm64/include/asm/kvm_host.h |  4 ++
 arch/arm64/include/uapi/asm/kvm.h |  5 +++
 arch/arm64/kvm/arm.c              | 64 ++++++++++++++++++++++++++++
 arch/arm64/kvm/pvtime.c           | 87 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 160 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0c6a564..cbe330c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -523,6 +523,10 @@ int kvm_arm_pvtime_get_attr(struct kvm_vcpu *vcpu,
 int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu,
 			    struct kvm_device_attr *attr);
 
+int kvm_arm_pvtime_lpt_set_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+int kvm_arm_pvtime_lpt_get_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+int kvm_arm_pvtime_lpt_has_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+
 static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
 {
 	vcpu_arch->steal.base = GPA_INVALID;
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index ba85bb2..7b045c7 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -325,6 +325,11 @@ struct kvm_vcpu_events {
 #define   KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES	3
 #define   KVM_DEV_ARM_ITS_CTRL_RESET		4
 
+/* Device Control API on kvm fd */
+#define KVM_ARM_VM_PVTIME_LPT_CTRL	0
+#define   KVM_ARM_VM_PVTIME_LPT_IPA	0
+#define   KVM_ARM_VM_PVTIME_LPT_FREQ	1
+
 /* Device Control API on vcpu fd */
 #define KVM_ARM_VCPU_PMU_V3_CTRL	0
 #define   KVM_ARM_VCPU_PMU_V3_IRQ	0
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 671f1461..4a867e5 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1235,11 +1235,60 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
 	}
 }
 
+static int kvm_arm_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_set_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+static int kvm_arm_vm_get_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_get_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+static int kvm_arm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_has_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
 	struct kvm *kvm = filp->private_data;
 	void __user *argp = (void __user *)arg;
+	struct kvm_device_attr attr;
 
 	switch (ioctl) {
 	case KVM_CREATE_IRQCHIP: {
@@ -1271,6 +1320,21 @@ long kvm_arch_vm_ioctl(struct file *filp,
 
 		return 0;
 	}
+	case KVM_SET_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return -EFAULT;
+		return kvm_arm_vm_set_attr(kvm, &attr);
+	}
+	case KVM_GET_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return -EFAULT;
+		return kvm_arm_vm_get_attr(kvm, &attr);
+	}
+	case KVM_HAS_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return  -EFAULT;
+		return kvm_arm_vm_has_attr(kvm, &attr);
+	}
 	default:
 		return -EINVAL;
 	}
diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c
index 24131ca..3f93473 100644
--- a/arch/arm64/kvm/pvtime.c
+++ b/arch/arm64/kvm/pvtime.c
@@ -257,3 +257,90 @@ gpa_t kvm_init_lpt_time(struct kvm *kvm)
 {
 	return kvm->arch.lpt.base;
 }
+
+int kvm_arm_pvtime_lpt_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	u64 __user *user = (u64 __user *)attr->addr;
+	u64 ipa;
+	u32 freq;
+	int idx;
+	int ret = 0;
+
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+		if (get_user(ipa, user)) {
+			ret = -EFAULT;
+			break;
+		}
+		if (!IS_ALIGNED(ipa, 64)) {
+			ret = -EINVAL;
+			break;
+		}
+		if (kvm->arch.lpt.base != GPA_INVALID) {
+			ret = -EEXIST;
+			break;
+		}
+		/* Check the address is in a valid memslot */
+		idx = srcu_read_lock(&kvm->srcu);
+		if (kvm_is_error_hva(gfn_to_hva(kvm, ipa >> PAGE_SHIFT)))
+			ret = -EINVAL;
+		srcu_read_unlock(&kvm->srcu, idx);
+		if (ret)
+			break;
+
+		kvm->arch.lpt.base = ipa;
+		break;
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		if (get_user(freq, user)) {
+			ret = -EFAULT;
+			break;
+		}
+		if (freq == 0) {
+			ret = -EINVAL;
+			break;
+		}
+		if (kvm->arch.lpt.fpv != 0) {
+			ret = -EEXIST;
+			break;
+		}
+		kvm->arch.lpt.fpv = freq;
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+int kvm_arm_pvtime_lpt_get_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	u64 __user *user = (u64 __user *)attr->addr;
+	int ret = 0;
+
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+		if (put_user(kvm->arch.lpt.base, user))
+			ret = -EFAULT;
+		break;
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		if (put_user(kvm->arch.lpt.fpv, user))
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+int kvm_arm_pvtime_lpt_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		return 0;
+	}
+	return -ENXIO;
+}
-- 
1.8.3.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

WARNING: multiple messages have this Message-ID (diff)
From: Keqian Zhu <zhukeqian1@huawei.com>
To: <linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<kvmarm@lists.cs.columbia.edu>, <kvm@vger.kernel.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>,
	Marc Zyngier <maz@kernel.org>, Keqian Zhu <zhukeqian1@huawei.com>,
	Steven Price <steven.price@arm.com>,
	James Morse <james.morse@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	wanghaibin.wang@huawei.com, Will Deacon <will@kernel.org>
Subject: [RFC PATCH 3/5] KVM: arm64: Provide VM device attributes for LPT time
Date: Mon, 17 Aug 2020 16:41:08 +0800	[thread overview]
Message-ID: <20200817084110.2672-4-zhukeqian1@huawei.com> (raw)
In-Reply-To: <20200817084110.2672-1-zhukeqian1@huawei.com>

Allow user space to inform the KVM host what the PV frequency is
and where in the physical memory map the paravirtualized LPT time
structures should be located. User space can set attributes on the
VM for that guest.

The address is given in terms of the physical address visible to
the guest and must be 64 byte aligned. The guest will discover the
address via a hypercall. PV frequency is 32 bits and must not be 0.

Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
 arch/arm64/include/asm/kvm_host.h |  4 ++
 arch/arm64/include/uapi/asm/kvm.h |  5 +++
 arch/arm64/kvm/arm.c              | 64 ++++++++++++++++++++++++++++
 arch/arm64/kvm/pvtime.c           | 87 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 160 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0c6a564..cbe330c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -523,6 +523,10 @@ int kvm_arm_pvtime_get_attr(struct kvm_vcpu *vcpu,
 int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu,
 			    struct kvm_device_attr *attr);
 
+int kvm_arm_pvtime_lpt_set_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+int kvm_arm_pvtime_lpt_get_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+int kvm_arm_pvtime_lpt_has_attr(struct kvm *kvm, struct kvm_device_attr *attr);
+
 static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
 {
 	vcpu_arch->steal.base = GPA_INVALID;
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index ba85bb2..7b045c7 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -325,6 +325,11 @@ struct kvm_vcpu_events {
 #define   KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES	3
 #define   KVM_DEV_ARM_ITS_CTRL_RESET		4
 
+/* Device Control API on kvm fd */
+#define KVM_ARM_VM_PVTIME_LPT_CTRL	0
+#define   KVM_ARM_VM_PVTIME_LPT_IPA	0
+#define   KVM_ARM_VM_PVTIME_LPT_FREQ	1
+
 /* Device Control API on vcpu fd */
 #define KVM_ARM_VCPU_PMU_V3_CTRL	0
 #define   KVM_ARM_VCPU_PMU_V3_IRQ	0
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 671f1461..4a867e5 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1235,11 +1235,60 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
 	}
 }
 
+static int kvm_arm_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_set_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+static int kvm_arm_vm_get_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_get_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+static int kvm_arm_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	int ret;
+
+	switch (attr->group) {
+	case KVM_ARM_VM_PVTIME_LPT_CTRL:
+		ret = kvm_arm_pvtime_lpt_has_attr(kvm, attr);
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
 	struct kvm *kvm = filp->private_data;
 	void __user *argp = (void __user *)arg;
+	struct kvm_device_attr attr;
 
 	switch (ioctl) {
 	case KVM_CREATE_IRQCHIP: {
@@ -1271,6 +1320,21 @@ long kvm_arch_vm_ioctl(struct file *filp,
 
 		return 0;
 	}
+	case KVM_SET_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return -EFAULT;
+		return kvm_arm_vm_set_attr(kvm, &attr);
+	}
+	case KVM_GET_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return -EFAULT;
+		return kvm_arm_vm_get_attr(kvm, &attr);
+	}
+	case KVM_HAS_DEVICE_ATTR: {
+		if (copy_from_user(&attr, argp, sizeof(attr)))
+			return  -EFAULT;
+		return kvm_arm_vm_has_attr(kvm, &attr);
+	}
 	default:
 		return -EINVAL;
 	}
diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c
index 24131ca..3f93473 100644
--- a/arch/arm64/kvm/pvtime.c
+++ b/arch/arm64/kvm/pvtime.c
@@ -257,3 +257,90 @@ gpa_t kvm_init_lpt_time(struct kvm *kvm)
 {
 	return kvm->arch.lpt.base;
 }
+
+int kvm_arm_pvtime_lpt_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	u64 __user *user = (u64 __user *)attr->addr;
+	u64 ipa;
+	u32 freq;
+	int idx;
+	int ret = 0;
+
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+		if (get_user(ipa, user)) {
+			ret = -EFAULT;
+			break;
+		}
+		if (!IS_ALIGNED(ipa, 64)) {
+			ret = -EINVAL;
+			break;
+		}
+		if (kvm->arch.lpt.base != GPA_INVALID) {
+			ret = -EEXIST;
+			break;
+		}
+		/* Check the address is in a valid memslot */
+		idx = srcu_read_lock(&kvm->srcu);
+		if (kvm_is_error_hva(gfn_to_hva(kvm, ipa >> PAGE_SHIFT)))
+			ret = -EINVAL;
+		srcu_read_unlock(&kvm->srcu, idx);
+		if (ret)
+			break;
+
+		kvm->arch.lpt.base = ipa;
+		break;
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		if (get_user(freq, user)) {
+			ret = -EFAULT;
+			break;
+		}
+		if (freq == 0) {
+			ret = -EINVAL;
+			break;
+		}
+		if (kvm->arch.lpt.fpv != 0) {
+			ret = -EEXIST;
+			break;
+		}
+		kvm->arch.lpt.fpv = freq;
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+int kvm_arm_pvtime_lpt_get_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	u64 __user *user = (u64 __user *)attr->addr;
+	int ret = 0;
+
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+		if (put_user(kvm->arch.lpt.base, user))
+			ret = -EFAULT;
+		break;
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		if (put_user(kvm->arch.lpt.fpv, user))
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+int kvm_arm_pvtime_lpt_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
+{
+	switch (attr->attr) {
+	case KVM_ARM_VM_PVTIME_LPT_IPA:
+	case KVM_ARM_VM_PVTIME_LPT_FREQ:
+		return 0;
+	}
+	return -ENXIO;
+}
-- 
1.8.3.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2020-08-17  8:42 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-17  8:41 [RFC PATCH 0/5] KVM: arm64: Add pvtime LPT support Keqian Zhu
2020-08-17  8:41 ` Keqian Zhu
2020-08-17  8:41 ` Keqian Zhu
2020-08-17  8:41 ` [RFC PATCH 1/5] KVM: arm64: Document pvtime LPT interface Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17  8:41 ` [RFC PATCH 2/5] KVM: arm64: Support Live Physical Time reporting Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17  8:41 ` Keqian Zhu [this message]
2020-08-17  8:41   ` [RFC PATCH 3/5] KVM: arm64: Provide VM device attributes for LPT time Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17  8:41 ` [RFC PATCH 4/5] clocksource: arm_arch_timer: Add pvtime LPT initialization Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17  8:41 ` [RFC PATCH 5/5] clocksource: arm_arch_timer: Use pvtime LPT Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17  8:41   ` Keqian Zhu
2020-08-17 10:43   ` kernel test robot
2020-08-18 14:41 ` [RFC PATCH 0/5] KVM: arm64: Add pvtime LPT support Marc Zyngier
2020-08-18 14:41   ` Marc Zyngier
2020-08-18 14:41   ` Marc Zyngier
2020-08-19  8:54   ` Steven Price
2020-08-19  8:54     ` Steven Price
2020-08-19  8:54     ` Steven Price
2020-08-21  3:54     ` zhukeqian
2020-08-21  3:54       ` zhukeqian
2020-08-21  3:54       ` zhukeqian
2020-08-22 10:31     ` Marc Zyngier
2020-08-22 10:31       ` Marc Zyngier
2020-08-22 10:31       ` Marc Zyngier
2020-09-02 10:09       ` Steven Price
2020-09-02 10:09         ` Steven Price
2020-09-02 10:09         ` Steven Price
2020-09-07  2:48         ` zhukeqian
2020-09-07  2:48           ` zhukeqian
2020-09-07  2:48           ` zhukeqian
2020-08-25 12:52     ` Mark Rutland
2020-08-25 12:52       ` Mark Rutland
2020-08-25 12:52       ` Mark Rutland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200817084110.2672-4-zhukeqian1@huawei.com \
    --to=zhukeqian1@huawei.com \
    --cc=catalin.marinas@arm.com \
    --cc=james.morse@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=steven.price@arm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=wanghaibin.wang@huawei.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.