All of lore.kernel.org
 help / color / mirror / Atom feed
From: Raghavendra Rao Ananta <rananta@google.com>
To: Marc Zyngier <maz@kernel.org>, Andrew Jones <drjones@redhat.com>,
	 James Morse <james.morse@arm.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: kvm@vger.kernel.org, Catalin Marinas <catalin.marinas@arm.com>,
	Peter Shier <pshier@google.com>,
	linux-kernel@vger.kernel.org, Will Deacon <will@kernel.org>,
	kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 4/8] KVM: arm64: Add standard hypervisor service calls firmware register
Date: Tue,  2 Nov 2021 00:21:59 +0000	[thread overview]
Message-ID: <20211102002203.1046069-5-rananta@google.com> (raw)
In-Reply-To: <20211102002203.1046069-1-rananta@google.com>

Introduce the firmware register to hold the standard hypervisor
service calls (owner value 5) as a bitmap. The bitmap represents
the features that'll be enabled for the guest, as configured by
the user-space. Currently, this includes support only for
Paravirtualized time, represented by bit-0.

Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
---
 Documentation/virt/kvm/arm/hypercalls.rst | 23 ++++++++++++++++-------
 arch/arm64/include/asm/kvm_host.h         |  1 +
 arch/arm64/include/uapi/asm/kvm.h         |  6 ++++++
 arch/arm64/kvm/arm.c                      |  1 +
 arch/arm64/kvm/hypercalls.c               | 22 ++++++++++++++++++++++
 arch/arm64/kvm/pvtime.c                   |  3 +++
 include/kvm/arm_hypercalls.h              |  3 +++
 7 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index 1601919f256d..2cb82c694868 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -20,13 +20,13 @@ pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
 interface. These registers can be saved/restored by userspace, and set
 to a convenient value if required.
 
-The firmware register KVM_REG_ARM_STD exposes the hypercall services
-in the form of a feature bitmap. Upon VM creation, by default, KVM exposes
-all the features to the guest, which can be learnt using GET_ONE_REG
-interface. Conversely, the features can be enabled or disabled via the
-SET_ONE_REG interface. These registers allow the user-space modification
-only until the VM has started running, after which they turn to read-only
-registers. SET_ONE_REG in this scenario will return -EBUSY.
+The firmware registers, KVM_REG_ARM_STD and KVM_REG_ARM_STD_HYP exposes
+the hypercall services in the form of a feature bitmap. Upon VM creation,
+by default, KVM exposes all the features to the guest, which can be learnt
+using GET_ONE_REG interface. Conversely, the features can be enabled or
+disabled via the SET_ONE_REG interface. These registers allow the user-space
+modification only until the VM has started running, after which they turn to
+read-only registers. SET_ONE_REG in this scenario will return -EBUSY.
 
 The following register is defined:
 
@@ -91,4 +91,13 @@ The following register is defined:
         The bit represents the services offered under v1.0 of ARM True Random Number Generator
         (TRNG) specification (ARM DEN 0098).
 
+* KVM_REG_ARM_STD_HYP
+    Controls the bitmap of the ARM Standard Hypervisor Service Calls.
+
+    The following bits are accepted:
+
+      KVM_REG_ARM_STD_HYP_PV_TIME_ST:
+        The bit represents the Paravirtualized Time service (also known as stolen time) as
+        represented by ARM DEN0057A.
+
 .. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 176d6be7b4da..cee4f4b8a756 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -107,6 +107,7 @@ struct hvc_reg_desc {
 	bool write_attempted;
 
 	u64 kvm_std_bmap;
+	u64 kvm_std_hyp_bmap;
 };
 
 struct kvm_arch {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 6387dea5396d..46701da1a27d 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -287,6 +287,12 @@ enum kvm_reg_arm_std_bmap {
 	KVM_REG_ARM_STD_BMAP_MAX,
 };
 
+#define KVM_REG_ARM_STD_HYP		KVM_REG_ARM_FW_REG(4)
+enum kvm_reg_arm_std_hyp_bmap {
+	KVM_REG_ARM_STD_HYP_PV_TIME_ST,
+	KVM_REG_ARM_STD_HYP_BMAP_MAX,
+};
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 1cf58aa49222..1c69d2a71b86 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -135,6 +135,7 @@ static void set_default_hypercalls(struct kvm *kvm)
 	struct hvc_reg_desc *hvc_desc = &kvm->arch.hvc_desc;
 
 	hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES;
+	hvc_desc->kvm_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES;
 }
 
 /**
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 0b3006353bf6..46064c515058 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -65,6 +65,8 @@ static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg)
 	switch (fw_reg) {
 	case KVM_REG_ARM_STD:
 		return &hvc_desc->kvm_std_bmap;
+	case KVM_REG_ARM_STD_HYP:
+		return &hvc_desc->kvm_std_hyp_bmap;
 	default:
 		return NULL;
 	}
@@ -87,6 +89,10 @@ static const struct kvm_hvc_func_map hvc_std_map[] = {
 	HVC_FUNC_MAP_DESC(ARM_SMCCC_TRNG_RND64, KVM_REG_ARM_STD_TRNG_V1_0),
 };
 
+static const struct kvm_hvc_func_map hvc_std_hyp_map[] = {
+	HVC_FUNC_MAP_DESC(ARM_SMCCC_HV_PV_TIME_ST, KVM_REG_ARM_STD_HYP_PV_TIME_ST),
+};
+
 bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 {
 	struct kvm *kvm = vcpu->kvm;
@@ -102,6 +108,11 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 		hvc_func_map = hvc_std_map;
 		map_sz = ARRAY_SIZE(hvc_std_map);
 		break;
+	case ARM_SMCCC_OWNER_STANDARD_HYP:
+		fw_reg = KVM_REG_ARM_STD_HYP;
+		hvc_func_map = hvc_std_hyp_map;
+		map_sz = ARRAY_SIZE(hvc_std_hyp_map);
+		break;
 	default:
 		/* Allow all the owners that aren't mapped */
 		return true;
@@ -218,6 +229,7 @@ static const u64 fw_reg_ids[] = {
 	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1,
 	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
 	KVM_REG_ARM_STD,
+	KVM_REG_ARM_STD_HYP,
 };
 
 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
@@ -295,6 +307,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_STD:
 		val = hvc_desc->kvm_std_bmap;
 		break;
+	case KVM_REG_ARM_STD_HYP:
+		val = hvc_desc->kvm_std_hyp_bmap;
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -424,6 +439,13 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 
 		hvc_desc->kvm_std_bmap = val;
 		return 0;
+
+	case KVM_REG_ARM_STD_HYP:
+		if (val & ~ARM_SMCCC_STD_HYP_FEATURES)
+			return -EINVAL;
+
+		hvc_desc->kvm_std_hyp_bmap = val;
+		return 0;
 	default:
 		return -ENOENT;
 	}
diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c
index 78a09f7a6637..4fa436dbd0b7 100644
--- a/arch/arm64/kvm/pvtime.c
+++ b/arch/arm64/kvm/pvtime.c
@@ -37,6 +37,9 @@ long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
 	u32 feature = smccc_get_arg1(vcpu);
 	long val = SMCCC_RET_NOT_SUPPORTED;
 
+	if (!kvm_hvc_call_supported(vcpu, feature))
+		return val;
+
 	switch (feature) {
 	case ARM_SMCCC_HV_PV_TIME_FEATURES:
 	case ARM_SMCCC_HV_PV_TIME_ST:
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index 5f01bb139312..bbb3b12b10e3 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -9,6 +9,9 @@
 #define ARM_SMCCC_STD_FEATURES \
 	GENMASK_ULL(KVM_REG_ARM_STD_BMAP_MAX - 1, 0)
 
+#define ARM_SMCCC_STD_HYP_FEATURES \
+	GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_MAX - 1, 0)
+
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 
 static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
-- 
2.33.1.1089.g2158813163f-goog

_______________________________________________
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: Raghavendra Rao Ananta <rananta@google.com>
To: Marc Zyngier <maz@kernel.org>, Andrew Jones <drjones@redhat.com>,
	 James Morse <james.morse@arm.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,  Peter Shier <pshier@google.com>,
	Ricardo Koller <ricarkol@google.com>,
	 Oliver Upton <oupton@google.com>,
	Reiji Watanabe <reijiw@google.com>,
	 Jing Zhang <jingzhangos@google.com>,
	Raghavendra Rao Anata <rananta@google.com>,
	linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu,  linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org
Subject: [RFC PATCH 4/8] KVM: arm64: Add standard hypervisor service calls firmware register
Date: Tue,  2 Nov 2021 00:21:59 +0000	[thread overview]
Message-ID: <20211102002203.1046069-5-rananta@google.com> (raw)
In-Reply-To: <20211102002203.1046069-1-rananta@google.com>

Introduce the firmware register to hold the standard hypervisor
service calls (owner value 5) as a bitmap. The bitmap represents
the features that'll be enabled for the guest, as configured by
the user-space. Currently, this includes support only for
Paravirtualized time, represented by bit-0.

Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
---
 Documentation/virt/kvm/arm/hypercalls.rst | 23 ++++++++++++++++-------
 arch/arm64/include/asm/kvm_host.h         |  1 +
 arch/arm64/include/uapi/asm/kvm.h         |  6 ++++++
 arch/arm64/kvm/arm.c                      |  1 +
 arch/arm64/kvm/hypercalls.c               | 22 ++++++++++++++++++++++
 arch/arm64/kvm/pvtime.c                   |  3 +++
 include/kvm/arm_hypercalls.h              |  3 +++
 7 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index 1601919f256d..2cb82c694868 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -20,13 +20,13 @@ pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
 interface. These registers can be saved/restored by userspace, and set
 to a convenient value if required.
 
-The firmware register KVM_REG_ARM_STD exposes the hypercall services
-in the form of a feature bitmap. Upon VM creation, by default, KVM exposes
-all the features to the guest, which can be learnt using GET_ONE_REG
-interface. Conversely, the features can be enabled or disabled via the
-SET_ONE_REG interface. These registers allow the user-space modification
-only until the VM has started running, after which they turn to read-only
-registers. SET_ONE_REG in this scenario will return -EBUSY.
+The firmware registers, KVM_REG_ARM_STD and KVM_REG_ARM_STD_HYP exposes
+the hypercall services in the form of a feature bitmap. Upon VM creation,
+by default, KVM exposes all the features to the guest, which can be learnt
+using GET_ONE_REG interface. Conversely, the features can be enabled or
+disabled via the SET_ONE_REG interface. These registers allow the user-space
+modification only until the VM has started running, after which they turn to
+read-only registers. SET_ONE_REG in this scenario will return -EBUSY.
 
 The following register is defined:
 
@@ -91,4 +91,13 @@ The following register is defined:
         The bit represents the services offered under v1.0 of ARM True Random Number Generator
         (TRNG) specification (ARM DEN 0098).
 
+* KVM_REG_ARM_STD_HYP
+    Controls the bitmap of the ARM Standard Hypervisor Service Calls.
+
+    The following bits are accepted:
+
+      KVM_REG_ARM_STD_HYP_PV_TIME_ST:
+        The bit represents the Paravirtualized Time service (also known as stolen time) as
+        represented by ARM DEN0057A.
+
 .. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 176d6be7b4da..cee4f4b8a756 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -107,6 +107,7 @@ struct hvc_reg_desc {
 	bool write_attempted;
 
 	u64 kvm_std_bmap;
+	u64 kvm_std_hyp_bmap;
 };
 
 struct kvm_arch {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 6387dea5396d..46701da1a27d 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -287,6 +287,12 @@ enum kvm_reg_arm_std_bmap {
 	KVM_REG_ARM_STD_BMAP_MAX,
 };
 
+#define KVM_REG_ARM_STD_HYP		KVM_REG_ARM_FW_REG(4)
+enum kvm_reg_arm_std_hyp_bmap {
+	KVM_REG_ARM_STD_HYP_PV_TIME_ST,
+	KVM_REG_ARM_STD_HYP_BMAP_MAX,
+};
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 1cf58aa49222..1c69d2a71b86 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -135,6 +135,7 @@ static void set_default_hypercalls(struct kvm *kvm)
 	struct hvc_reg_desc *hvc_desc = &kvm->arch.hvc_desc;
 
 	hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES;
+	hvc_desc->kvm_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES;
 }
 
 /**
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 0b3006353bf6..46064c515058 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -65,6 +65,8 @@ static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg)
 	switch (fw_reg) {
 	case KVM_REG_ARM_STD:
 		return &hvc_desc->kvm_std_bmap;
+	case KVM_REG_ARM_STD_HYP:
+		return &hvc_desc->kvm_std_hyp_bmap;
 	default:
 		return NULL;
 	}
@@ -87,6 +89,10 @@ static const struct kvm_hvc_func_map hvc_std_map[] = {
 	HVC_FUNC_MAP_DESC(ARM_SMCCC_TRNG_RND64, KVM_REG_ARM_STD_TRNG_V1_0),
 };
 
+static const struct kvm_hvc_func_map hvc_std_hyp_map[] = {
+	HVC_FUNC_MAP_DESC(ARM_SMCCC_HV_PV_TIME_ST, KVM_REG_ARM_STD_HYP_PV_TIME_ST),
+};
+
 bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 {
 	struct kvm *kvm = vcpu->kvm;
@@ -102,6 +108,11 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 		hvc_func_map = hvc_std_map;
 		map_sz = ARRAY_SIZE(hvc_std_map);
 		break;
+	case ARM_SMCCC_OWNER_STANDARD_HYP:
+		fw_reg = KVM_REG_ARM_STD_HYP;
+		hvc_func_map = hvc_std_hyp_map;
+		map_sz = ARRAY_SIZE(hvc_std_hyp_map);
+		break;
 	default:
 		/* Allow all the owners that aren't mapped */
 		return true;
@@ -218,6 +229,7 @@ static const u64 fw_reg_ids[] = {
 	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1,
 	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
 	KVM_REG_ARM_STD,
+	KVM_REG_ARM_STD_HYP,
 };
 
 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
@@ -295,6 +307,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_STD:
 		val = hvc_desc->kvm_std_bmap;
 		break;
+	case KVM_REG_ARM_STD_HYP:
+		val = hvc_desc->kvm_std_hyp_bmap;
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -424,6 +439,13 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 
 		hvc_desc->kvm_std_bmap = val;
 		return 0;
+
+	case KVM_REG_ARM_STD_HYP:
+		if (val & ~ARM_SMCCC_STD_HYP_FEATURES)
+			return -EINVAL;
+
+		hvc_desc->kvm_std_hyp_bmap = val;
+		return 0;
 	default:
 		return -ENOENT;
 	}
diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c
index 78a09f7a6637..4fa436dbd0b7 100644
--- a/arch/arm64/kvm/pvtime.c
+++ b/arch/arm64/kvm/pvtime.c
@@ -37,6 +37,9 @@ long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
 	u32 feature = smccc_get_arg1(vcpu);
 	long val = SMCCC_RET_NOT_SUPPORTED;
 
+	if (!kvm_hvc_call_supported(vcpu, feature))
+		return val;
+
 	switch (feature) {
 	case ARM_SMCCC_HV_PV_TIME_FEATURES:
 	case ARM_SMCCC_HV_PV_TIME_ST:
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index 5f01bb139312..bbb3b12b10e3 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -9,6 +9,9 @@
 #define ARM_SMCCC_STD_FEATURES \
 	GENMASK_ULL(KVM_REG_ARM_STD_BMAP_MAX - 1, 0)
 
+#define ARM_SMCCC_STD_HYP_FEATURES \
+	GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_MAX - 1, 0)
+
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 
 static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
-- 
2.33.1.1089.g2158813163f-goog


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

WARNING: multiple messages have this Message-ID (diff)
From: Raghavendra Rao Ananta <rananta@google.com>
To: Marc Zyngier <maz@kernel.org>, Andrew Jones <drjones@redhat.com>,
	James Morse <james.morse@arm.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>, Peter Shier <pshier@google.com>,
	Ricardo Koller <ricarkol@google.com>,
	Oliver Upton <oupton@google.com>,
	Reiji Watanabe <reijiw@google.com>,
	Jing Zhang <jingzhangos@google.com>,
	Raghavendra Rao Anata <rananta@google.com>,
	linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org
Subject: [RFC PATCH 4/8] KVM: arm64: Add standard hypervisor service calls firmware register
Date: Tue,  2 Nov 2021 00:21:59 +0000	[thread overview]
Message-ID: <20211102002203.1046069-5-rananta@google.com> (raw)
In-Reply-To: <20211102002203.1046069-1-rananta@google.com>

Introduce the firmware register to hold the standard hypervisor
service calls (owner value 5) as a bitmap. The bitmap represents
the features that'll be enabled for the guest, as configured by
the user-space. Currently, this includes support only for
Paravirtualized time, represented by bit-0.

Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
---
 Documentation/virt/kvm/arm/hypercalls.rst | 23 ++++++++++++++++-------
 arch/arm64/include/asm/kvm_host.h         |  1 +
 arch/arm64/include/uapi/asm/kvm.h         |  6 ++++++
 arch/arm64/kvm/arm.c                      |  1 +
 arch/arm64/kvm/hypercalls.c               | 22 ++++++++++++++++++++++
 arch/arm64/kvm/pvtime.c                   |  3 +++
 include/kvm/arm_hypercalls.h              |  3 +++
 7 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index 1601919f256d..2cb82c694868 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -20,13 +20,13 @@ pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
 interface. These registers can be saved/restored by userspace, and set
 to a convenient value if required.
 
-The firmware register KVM_REG_ARM_STD exposes the hypercall services
-in the form of a feature bitmap. Upon VM creation, by default, KVM exposes
-all the features to the guest, which can be learnt using GET_ONE_REG
-interface. Conversely, the features can be enabled or disabled via the
-SET_ONE_REG interface. These registers allow the user-space modification
-only until the VM has started running, after which they turn to read-only
-registers. SET_ONE_REG in this scenario will return -EBUSY.
+The firmware registers, KVM_REG_ARM_STD and KVM_REG_ARM_STD_HYP exposes
+the hypercall services in the form of a feature bitmap. Upon VM creation,
+by default, KVM exposes all the features to the guest, which can be learnt
+using GET_ONE_REG interface. Conversely, the features can be enabled or
+disabled via the SET_ONE_REG interface. These registers allow the user-space
+modification only until the VM has started running, after which they turn to
+read-only registers. SET_ONE_REG in this scenario will return -EBUSY.
 
 The following register is defined:
 
@@ -91,4 +91,13 @@ The following register is defined:
         The bit represents the services offered under v1.0 of ARM True Random Number Generator
         (TRNG) specification (ARM DEN 0098).
 
+* KVM_REG_ARM_STD_HYP
+    Controls the bitmap of the ARM Standard Hypervisor Service Calls.
+
+    The following bits are accepted:
+
+      KVM_REG_ARM_STD_HYP_PV_TIME_ST:
+        The bit represents the Paravirtualized Time service (also known as stolen time) as
+        represented by ARM DEN0057A.
+
 .. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 176d6be7b4da..cee4f4b8a756 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -107,6 +107,7 @@ struct hvc_reg_desc {
 	bool write_attempted;
 
 	u64 kvm_std_bmap;
+	u64 kvm_std_hyp_bmap;
 };
 
 struct kvm_arch {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 6387dea5396d..46701da1a27d 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -287,6 +287,12 @@ enum kvm_reg_arm_std_bmap {
 	KVM_REG_ARM_STD_BMAP_MAX,
 };
 
+#define KVM_REG_ARM_STD_HYP		KVM_REG_ARM_FW_REG(4)
+enum kvm_reg_arm_std_hyp_bmap {
+	KVM_REG_ARM_STD_HYP_PV_TIME_ST,
+	KVM_REG_ARM_STD_HYP_BMAP_MAX,
+};
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 1cf58aa49222..1c69d2a71b86 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -135,6 +135,7 @@ static void set_default_hypercalls(struct kvm *kvm)
 	struct hvc_reg_desc *hvc_desc = &kvm->arch.hvc_desc;
 
 	hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES;
+	hvc_desc->kvm_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES;
 }
 
 /**
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 0b3006353bf6..46064c515058 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -65,6 +65,8 @@ static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg)
 	switch (fw_reg) {
 	case KVM_REG_ARM_STD:
 		return &hvc_desc->kvm_std_bmap;
+	case KVM_REG_ARM_STD_HYP:
+		return &hvc_desc->kvm_std_hyp_bmap;
 	default:
 		return NULL;
 	}
@@ -87,6 +89,10 @@ static const struct kvm_hvc_func_map hvc_std_map[] = {
 	HVC_FUNC_MAP_DESC(ARM_SMCCC_TRNG_RND64, KVM_REG_ARM_STD_TRNG_V1_0),
 };
 
+static const struct kvm_hvc_func_map hvc_std_hyp_map[] = {
+	HVC_FUNC_MAP_DESC(ARM_SMCCC_HV_PV_TIME_ST, KVM_REG_ARM_STD_HYP_PV_TIME_ST),
+};
+
 bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 {
 	struct kvm *kvm = vcpu->kvm;
@@ -102,6 +108,11 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 		hvc_func_map = hvc_std_map;
 		map_sz = ARRAY_SIZE(hvc_std_map);
 		break;
+	case ARM_SMCCC_OWNER_STANDARD_HYP:
+		fw_reg = KVM_REG_ARM_STD_HYP;
+		hvc_func_map = hvc_std_hyp_map;
+		map_sz = ARRAY_SIZE(hvc_std_hyp_map);
+		break;
 	default:
 		/* Allow all the owners that aren't mapped */
 		return true;
@@ -218,6 +229,7 @@ static const u64 fw_reg_ids[] = {
 	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1,
 	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
 	KVM_REG_ARM_STD,
+	KVM_REG_ARM_STD_HYP,
 };
 
 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
@@ -295,6 +307,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_STD:
 		val = hvc_desc->kvm_std_bmap;
 		break;
+	case KVM_REG_ARM_STD_HYP:
+		val = hvc_desc->kvm_std_hyp_bmap;
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -424,6 +439,13 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 
 		hvc_desc->kvm_std_bmap = val;
 		return 0;
+
+	case KVM_REG_ARM_STD_HYP:
+		if (val & ~ARM_SMCCC_STD_HYP_FEATURES)
+			return -EINVAL;
+
+		hvc_desc->kvm_std_hyp_bmap = val;
+		return 0;
 	default:
 		return -ENOENT;
 	}
diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c
index 78a09f7a6637..4fa436dbd0b7 100644
--- a/arch/arm64/kvm/pvtime.c
+++ b/arch/arm64/kvm/pvtime.c
@@ -37,6 +37,9 @@ long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
 	u32 feature = smccc_get_arg1(vcpu);
 	long val = SMCCC_RET_NOT_SUPPORTED;
 
+	if (!kvm_hvc_call_supported(vcpu, feature))
+		return val;
+
 	switch (feature) {
 	case ARM_SMCCC_HV_PV_TIME_FEATURES:
 	case ARM_SMCCC_HV_PV_TIME_ST:
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index 5f01bb139312..bbb3b12b10e3 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -9,6 +9,9 @@
 #define ARM_SMCCC_STD_FEATURES \
 	GENMASK_ULL(KVM_REG_ARM_STD_BMAP_MAX - 1, 0)
 
+#define ARM_SMCCC_STD_HYP_FEATURES \
+	GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_MAX - 1, 0)
+
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 
 static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
-- 
2.33.1.1089.g2158813163f-goog


  parent reply	other threads:[~2021-11-02  0:22 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-02  0:21 [RFC PATCH 0/8] KVM: arm64: Add support for hypercall services selection Raghavendra Rao Ananta
2021-11-02  0:21 ` Raghavendra Rao Ananta
2021-11-02  0:21 ` Raghavendra Rao Ananta
2021-11-02  0:21 ` [RFC PATCH 1/8] KVM: arm64: Factor out firmware register handling from psci.c Raghavendra Rao Ananta
2021-11-02  0:21   ` Raghavendra Rao Ananta
2021-11-02  0:21   ` Raghavendra Rao Ananta
2021-11-03 21:43   ` Oliver Upton
2021-11-03 21:43     ` Oliver Upton
2021-11-03 21:43     ` Oliver Upton
2021-11-04 17:16     ` Raghavendra Rao Ananta
2021-11-04 17:16       ` Raghavendra Rao Ananta
2021-11-04 17:16       ` Raghavendra Rao Ananta
2021-11-08 21:33       ` Oliver Upton
2021-11-08 21:33         ` Oliver Upton
2021-11-08 21:33         ` Oliver Upton
2021-11-02  0:21 ` [RFC PATCH 2/8] KVM: arm64: Setup base for hypercall firmware registers Raghavendra Rao Ananta
2021-11-02  0:21   ` Raghavendra Rao Ananta
2021-11-02  0:21   ` Raghavendra Rao Ananta
2021-11-03 22:18   ` Oliver Upton
2021-11-03 22:18     ` Oliver Upton
2021-11-03 22:18     ` Oliver Upton
2021-11-04 19:04     ` Raghavendra Rao Ananta
2021-11-04 19:04       ` Raghavendra Rao Ananta
2021-11-04 19:04       ` Raghavendra Rao Ananta
2021-11-02  0:21 ` [RFC PATCH 3/8] KVM: arm64: Add standard secure service calls firmware register Raghavendra Rao Ananta
2021-11-02  0:21   ` Raghavendra Rao Ananta
2021-11-02  0:21   ` Raghavendra Rao Ananta
2021-11-04  0:15   ` Oliver Upton
2021-11-04  0:15     ` Oliver Upton
2021-11-04  0:15     ` Oliver Upton
2021-11-04 18:00     ` Raghavendra Rao Ananta
2021-11-04 18:00       ` Raghavendra Rao Ananta
2021-11-04 18:00       ` Raghavendra Rao Ananta
2021-11-02  0:21 ` Raghavendra Rao Ananta [this message]
2021-11-02  0:21   ` [RFC PATCH 4/8] KVM: arm64: Add standard hypervisor " Raghavendra Rao Ananta
2021-11-02  0:21   ` Raghavendra Rao Ananta
2021-11-02  0:22 ` [RFC PATCH 5/8] KVM: arm64: Add vendor " Raghavendra Rao Ananta
2021-11-02  0:22   ` Raghavendra Rao Ananta
2021-11-02  0:22   ` Raghavendra Rao Ananta
2021-11-02  0:22 ` [RFC PATCH 6/8] tools: Import the firmware registers Raghavendra Rao Ananta
2021-11-02  0:22   ` Raghavendra Rao Ananta
2021-11-02  0:22   ` Raghavendra Rao Ananta
2021-11-04  0:23   ` Oliver Upton
2021-11-04  0:23     ` Oliver Upton
2021-11-04  0:23     ` Oliver Upton
2021-11-04 18:58     ` Raghavendra Rao Ananta
2021-11-04 18:58       ` Raghavendra Rao Ananta
2021-11-04 18:58       ` Raghavendra Rao Ananta
2021-11-02  0:22 ` [RFC PATCH 7/8] tools: Import ARM SMCCC definitions Raghavendra Rao Ananta
2021-11-02  0:22   ` Raghavendra Rao Ananta
2021-11-02  0:22   ` Raghavendra Rao Ananta
2021-11-02  0:22 ` [RFC PATCH 8/8] selftests: KVM: aarch64: Introduce hypercall ABI test Raghavendra Rao Ananta
2021-11-02  0:22   ` Raghavendra Rao Ananta
2021-11-02  0:22   ` Raghavendra Rao Ananta

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=20211102002203.1046069-5-rananta@google.com \
    --to=rananta@google.com \
    --cc=alexandru.elisei@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=drjones@redhat.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=pshier@google.com \
    --cc=suzuki.poulose@arm.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.