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 5/8] KVM: arm64: Add vendor hypervisor service calls firmware register
Date: Tue, 2 Nov 2021 00:22:00 +0000 [thread overview]
Message-ID: <20211102002203.1046069-6-rananta@google.com> (raw)
In-Reply-To: <20211102002203.1046069-1-rananta@google.com>
Introduce the firmware register to hold the vendor specific
hypervisor service calls (owner value 6) 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 Precision Time Protocol (PTP),
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 | 33 ++++++++++++++++++++++-
include/kvm/arm_hypercalls.h | 3 +++
6 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index 2cb82c694868..61d95f4f1ddf 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -20,13 +20,14 @@ 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 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 firmware registers, KVM_REG_ARM_STD, KVM_REG_ARM_STD_HYP and
+KVM_REG_ARM_VENDOR_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:
@@ -100,4 +101,12 @@ The following register is defined:
The bit represents the Paravirtualized Time service (also known as stolen time) as
represented by ARM DEN0057A.
+* KVM_REG_ARM_VENDOR_HYP
+ Controls the bitmap of the Vendor specific Hypervisor Service Calls.
+
+ The following bits are accepted:
+
+ KVM_REG_ARM_STD_HYP_PTP:
+ The bit represents the Precision Time Protocol KVM service.
+
.. [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 cee4f4b8a756..27861b3bd25f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -108,6 +108,7 @@ struct hvc_reg_desc {
u64 kvm_std_bmap;
u64 kvm_std_hyp_bmap;
+ u64 kvm_vendor_hyp_bmap;
};
struct kvm_arch {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 46701da1a27d..a1d0e8e69eed 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -293,6 +293,12 @@ enum kvm_reg_arm_std_hyp_bmap {
KVM_REG_ARM_STD_HYP_BMAP_MAX,
};
+#define KVM_REG_ARM_VENDOR_HYP KVM_REG_ARM_FW_REG(5)
+enum kvm_reg_arm_vendor_hyp_bmap {
+ KVM_REG_ARM_VENDOR_HYP_PTP,
+ KVM_REG_ARM_VENDOR_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 1c69d2a71b86..5c89db8336eb 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -136,6 +136,7 @@ static void set_default_hypercalls(struct kvm *kvm)
hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES;
hvc_desc->kvm_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES;
+ hvc_desc->kvm_vendor_hyp_bmap = ARM_SMCCC_VENDOR_HYP_FEATURES;
}
/**
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 46064c515058..74ebe5355dc0 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -67,6 +67,8 @@ static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg)
return &hvc_desc->kvm_std_bmap;
case KVM_REG_ARM_STD_HYP:
return &hvc_desc->kvm_std_hyp_bmap;
+ case KVM_REG_ARM_VENDOR_HYP:
+ return &hvc_desc->kvm_vendor_hyp_bmap;
default:
return NULL;
}
@@ -93,6 +95,10 @@ 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),
};
+static const struct kvm_hvc_func_map hvc_vendor_hyp_map[] = {
+ HVC_FUNC_MAP_DESC(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, KVM_REG_ARM_VENDOR_HYP_PTP),
+};
+
bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
{
struct kvm *kvm = vcpu->kvm;
@@ -113,6 +119,11 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
hvc_func_map = hvc_std_hyp_map;
map_sz = ARRAY_SIZE(hvc_std_hyp_map);
break;
+ case ARM_SMCCC_OWNER_VENDOR_HYP:
+ fw_reg = KVM_REG_ARM_VENDOR_HYP;
+ hvc_func_map = hvc_vendor_hyp_map;
+ map_sz = ARRAY_SIZE(hvc_vendor_hyp_map);
+ break;
default:
/* Allow all the owners that aren't mapped */
return true;
@@ -133,6 +144,7 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
{
+ struct hvc_reg_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
u32 func_id = smccc_get_function(vcpu);
u64 val[4] = {SMCCC_RET_NOT_SUPPORTED};
u32 feature;
@@ -204,7 +216,14 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
break;
case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
- val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP);
+
+ /*
+ * The feature bits exposed to user-space doesn't include
+ * ARM_SMCCC_KVM_FUNC_FEATURES. However, we expose this to
+ * the guest as bit-0. Hence, left-shift the user-space
+ * exposed bitmap by 1 to accommodate this.
+ */
+ val[0] |= (hvc_desc->kvm_vendor_hyp_bmap << 1);
break;
case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
kvm_ptp_get_time(vcpu, val);
@@ -230,6 +249,7 @@ static const u64 fw_reg_ids[] = {
KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
KVM_REG_ARM_STD,
KVM_REG_ARM_STD_HYP,
+ KVM_REG_ARM_VENDOR_HYP,
};
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
@@ -310,6 +330,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
case KVM_REG_ARM_STD_HYP:
val = hvc_desc->kvm_std_hyp_bmap;
break;
+ case KVM_REG_ARM_VENDOR_HYP:
+ val = hvc_desc->kvm_vendor_hyp_bmap;
+ break;
default:
return -ENOENT;
}
@@ -446,6 +469,14 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
hvc_desc->kvm_std_hyp_bmap = val;
return 0;
+
+ case KVM_REG_ARM_VENDOR_HYP:
+ if (val & ~ARM_SMCCC_VENDOR_HYP_FEATURES)
+ return -EINVAL;
+
+ hvc_desc->kvm_vendor_hyp_bmap = val;
+ return 0;
+
default:
return -ENOENT;
}
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index bbb3b12b10e3..d8c17d161ee5 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -12,6 +12,9 @@
#define ARM_SMCCC_STD_HYP_FEATURES \
GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_MAX - 1, 0)
+#define ARM_SMCCC_VENDOR_HYP_FEATURES \
+ GENMASK_ULL(KVM_REG_ARM_VENDOR_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 5/8] KVM: arm64: Add vendor hypervisor service calls firmware register
Date: Tue, 2 Nov 2021 00:22:00 +0000 [thread overview]
Message-ID: <20211102002203.1046069-6-rananta@google.com> (raw)
In-Reply-To: <20211102002203.1046069-1-rananta@google.com>
Introduce the firmware register to hold the vendor specific
hypervisor service calls (owner value 6) 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 Precision Time Protocol (PTP),
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 | 33 ++++++++++++++++++++++-
include/kvm/arm_hypercalls.h | 3 +++
6 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index 2cb82c694868..61d95f4f1ddf 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -20,13 +20,14 @@ 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 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 firmware registers, KVM_REG_ARM_STD, KVM_REG_ARM_STD_HYP and
+KVM_REG_ARM_VENDOR_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:
@@ -100,4 +101,12 @@ The following register is defined:
The bit represents the Paravirtualized Time service (also known as stolen time) as
represented by ARM DEN0057A.
+* KVM_REG_ARM_VENDOR_HYP
+ Controls the bitmap of the Vendor specific Hypervisor Service Calls.
+
+ The following bits are accepted:
+
+ KVM_REG_ARM_STD_HYP_PTP:
+ The bit represents the Precision Time Protocol KVM service.
+
.. [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 cee4f4b8a756..27861b3bd25f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -108,6 +108,7 @@ struct hvc_reg_desc {
u64 kvm_std_bmap;
u64 kvm_std_hyp_bmap;
+ u64 kvm_vendor_hyp_bmap;
};
struct kvm_arch {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 46701da1a27d..a1d0e8e69eed 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -293,6 +293,12 @@ enum kvm_reg_arm_std_hyp_bmap {
KVM_REG_ARM_STD_HYP_BMAP_MAX,
};
+#define KVM_REG_ARM_VENDOR_HYP KVM_REG_ARM_FW_REG(5)
+enum kvm_reg_arm_vendor_hyp_bmap {
+ KVM_REG_ARM_VENDOR_HYP_PTP,
+ KVM_REG_ARM_VENDOR_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 1c69d2a71b86..5c89db8336eb 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -136,6 +136,7 @@ static void set_default_hypercalls(struct kvm *kvm)
hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES;
hvc_desc->kvm_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES;
+ hvc_desc->kvm_vendor_hyp_bmap = ARM_SMCCC_VENDOR_HYP_FEATURES;
}
/**
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 46064c515058..74ebe5355dc0 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -67,6 +67,8 @@ static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg)
return &hvc_desc->kvm_std_bmap;
case KVM_REG_ARM_STD_HYP:
return &hvc_desc->kvm_std_hyp_bmap;
+ case KVM_REG_ARM_VENDOR_HYP:
+ return &hvc_desc->kvm_vendor_hyp_bmap;
default:
return NULL;
}
@@ -93,6 +95,10 @@ 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),
};
+static const struct kvm_hvc_func_map hvc_vendor_hyp_map[] = {
+ HVC_FUNC_MAP_DESC(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, KVM_REG_ARM_VENDOR_HYP_PTP),
+};
+
bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
{
struct kvm *kvm = vcpu->kvm;
@@ -113,6 +119,11 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
hvc_func_map = hvc_std_hyp_map;
map_sz = ARRAY_SIZE(hvc_std_hyp_map);
break;
+ case ARM_SMCCC_OWNER_VENDOR_HYP:
+ fw_reg = KVM_REG_ARM_VENDOR_HYP;
+ hvc_func_map = hvc_vendor_hyp_map;
+ map_sz = ARRAY_SIZE(hvc_vendor_hyp_map);
+ break;
default:
/* Allow all the owners that aren't mapped */
return true;
@@ -133,6 +144,7 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
{
+ struct hvc_reg_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
u32 func_id = smccc_get_function(vcpu);
u64 val[4] = {SMCCC_RET_NOT_SUPPORTED};
u32 feature;
@@ -204,7 +216,14 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
break;
case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
- val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP);
+
+ /*
+ * The feature bits exposed to user-space doesn't include
+ * ARM_SMCCC_KVM_FUNC_FEATURES. However, we expose this to
+ * the guest as bit-0. Hence, left-shift the user-space
+ * exposed bitmap by 1 to accommodate this.
+ */
+ val[0] |= (hvc_desc->kvm_vendor_hyp_bmap << 1);
break;
case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
kvm_ptp_get_time(vcpu, val);
@@ -230,6 +249,7 @@ static const u64 fw_reg_ids[] = {
KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
KVM_REG_ARM_STD,
KVM_REG_ARM_STD_HYP,
+ KVM_REG_ARM_VENDOR_HYP,
};
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
@@ -310,6 +330,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
case KVM_REG_ARM_STD_HYP:
val = hvc_desc->kvm_std_hyp_bmap;
break;
+ case KVM_REG_ARM_VENDOR_HYP:
+ val = hvc_desc->kvm_vendor_hyp_bmap;
+ break;
default:
return -ENOENT;
}
@@ -446,6 +469,14 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
hvc_desc->kvm_std_hyp_bmap = val;
return 0;
+
+ case KVM_REG_ARM_VENDOR_HYP:
+ if (val & ~ARM_SMCCC_VENDOR_HYP_FEATURES)
+ return -EINVAL;
+
+ hvc_desc->kvm_vendor_hyp_bmap = val;
+ return 0;
+
default:
return -ENOENT;
}
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index bbb3b12b10e3..d8c17d161ee5 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -12,6 +12,9 @@
#define ARM_SMCCC_STD_HYP_FEATURES \
GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_MAX - 1, 0)
+#define ARM_SMCCC_VENDOR_HYP_FEATURES \
+ GENMASK_ULL(KVM_REG_ARM_VENDOR_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 5/8] KVM: arm64: Add vendor hypervisor service calls firmware register
Date: Tue, 2 Nov 2021 00:22:00 +0000 [thread overview]
Message-ID: <20211102002203.1046069-6-rananta@google.com> (raw)
In-Reply-To: <20211102002203.1046069-1-rananta@google.com>
Introduce the firmware register to hold the vendor specific
hypervisor service calls (owner value 6) 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 Precision Time Protocol (PTP),
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 | 33 ++++++++++++++++++++++-
include/kvm/arm_hypercalls.h | 3 +++
6 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index 2cb82c694868..61d95f4f1ddf 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -20,13 +20,14 @@ 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 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 firmware registers, KVM_REG_ARM_STD, KVM_REG_ARM_STD_HYP and
+KVM_REG_ARM_VENDOR_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:
@@ -100,4 +101,12 @@ The following register is defined:
The bit represents the Paravirtualized Time service (also known as stolen time) as
represented by ARM DEN0057A.
+* KVM_REG_ARM_VENDOR_HYP
+ Controls the bitmap of the Vendor specific Hypervisor Service Calls.
+
+ The following bits are accepted:
+
+ KVM_REG_ARM_STD_HYP_PTP:
+ The bit represents the Precision Time Protocol KVM service.
+
.. [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 cee4f4b8a756..27861b3bd25f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -108,6 +108,7 @@ struct hvc_reg_desc {
u64 kvm_std_bmap;
u64 kvm_std_hyp_bmap;
+ u64 kvm_vendor_hyp_bmap;
};
struct kvm_arch {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 46701da1a27d..a1d0e8e69eed 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -293,6 +293,12 @@ enum kvm_reg_arm_std_hyp_bmap {
KVM_REG_ARM_STD_HYP_BMAP_MAX,
};
+#define KVM_REG_ARM_VENDOR_HYP KVM_REG_ARM_FW_REG(5)
+enum kvm_reg_arm_vendor_hyp_bmap {
+ KVM_REG_ARM_VENDOR_HYP_PTP,
+ KVM_REG_ARM_VENDOR_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 1c69d2a71b86..5c89db8336eb 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -136,6 +136,7 @@ static void set_default_hypercalls(struct kvm *kvm)
hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES;
hvc_desc->kvm_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES;
+ hvc_desc->kvm_vendor_hyp_bmap = ARM_SMCCC_VENDOR_HYP_FEATURES;
}
/**
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 46064c515058..74ebe5355dc0 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -67,6 +67,8 @@ static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg)
return &hvc_desc->kvm_std_bmap;
case KVM_REG_ARM_STD_HYP:
return &hvc_desc->kvm_std_hyp_bmap;
+ case KVM_REG_ARM_VENDOR_HYP:
+ return &hvc_desc->kvm_vendor_hyp_bmap;
default:
return NULL;
}
@@ -93,6 +95,10 @@ 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),
};
+static const struct kvm_hvc_func_map hvc_vendor_hyp_map[] = {
+ HVC_FUNC_MAP_DESC(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, KVM_REG_ARM_VENDOR_HYP_PTP),
+};
+
bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
{
struct kvm *kvm = vcpu->kvm;
@@ -113,6 +119,11 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
hvc_func_map = hvc_std_hyp_map;
map_sz = ARRAY_SIZE(hvc_std_hyp_map);
break;
+ case ARM_SMCCC_OWNER_VENDOR_HYP:
+ fw_reg = KVM_REG_ARM_VENDOR_HYP;
+ hvc_func_map = hvc_vendor_hyp_map;
+ map_sz = ARRAY_SIZE(hvc_vendor_hyp_map);
+ break;
default:
/* Allow all the owners that aren't mapped */
return true;
@@ -133,6 +144,7 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
{
+ struct hvc_reg_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
u32 func_id = smccc_get_function(vcpu);
u64 val[4] = {SMCCC_RET_NOT_SUPPORTED};
u32 feature;
@@ -204,7 +216,14 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
break;
case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
- val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP);
+
+ /*
+ * The feature bits exposed to user-space doesn't include
+ * ARM_SMCCC_KVM_FUNC_FEATURES. However, we expose this to
+ * the guest as bit-0. Hence, left-shift the user-space
+ * exposed bitmap by 1 to accommodate this.
+ */
+ val[0] |= (hvc_desc->kvm_vendor_hyp_bmap << 1);
break;
case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
kvm_ptp_get_time(vcpu, val);
@@ -230,6 +249,7 @@ static const u64 fw_reg_ids[] = {
KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
KVM_REG_ARM_STD,
KVM_REG_ARM_STD_HYP,
+ KVM_REG_ARM_VENDOR_HYP,
};
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
@@ -310,6 +330,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
case KVM_REG_ARM_STD_HYP:
val = hvc_desc->kvm_std_hyp_bmap;
break;
+ case KVM_REG_ARM_VENDOR_HYP:
+ val = hvc_desc->kvm_vendor_hyp_bmap;
+ break;
default:
return -ENOENT;
}
@@ -446,6 +469,14 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
hvc_desc->kvm_std_hyp_bmap = val;
return 0;
+
+ case KVM_REG_ARM_VENDOR_HYP:
+ if (val & ~ARM_SMCCC_VENDOR_HYP_FEATURES)
+ return -EINVAL;
+
+ hvc_desc->kvm_vendor_hyp_bmap = val;
+ return 0;
+
default:
return -ENOENT;
}
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index bbb3b12b10e3..d8c17d161ee5 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -12,6 +12,9 @@
#define ARM_SMCCC_STD_HYP_FEATURES \
GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_MAX - 1, 0)
+#define ARM_SMCCC_VENDOR_HYP_FEATURES \
+ GENMASK_ULL(KVM_REG_ARM_VENDOR_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
next prev 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 ` [RFC PATCH 4/8] KVM: arm64: Add standard hypervisor " Raghavendra Rao Ananta
2021-11-02 0:21 ` Raghavendra Rao Ananta
2021-11-02 0:21 ` Raghavendra Rao Ananta
2021-11-02 0:22 ` Raghavendra Rao Ananta [this message]
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 ` [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-6-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.