blob: b27f6afe47e4ad1b10600cdc96726bb3803ae878 [file] [log] [blame]
From 2b0b92a16c12c904e2e471d05b0bad85dc70a3e3 Mon Sep 17 00:00:00 2001
From: David Dai <davidai@google.com>
Date: Thu, 18 May 2023 16:02:14 +0900
Subject: [PATCH] BACKPORT: FROMLIST: kvm: arm64: Add support for util_hint
service
This service allows guests to send the utilization of workoads on its vCPUs
to the host. Utilization is represented as an arbitrary value of 0-1024
where 1024 represents the highest performance point normalized for
frequency and architecture across all CPUs. This hint is used by
the host for scheduling vCPU threads and deciding CPU frequency.
Co-developed-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: David Dai <davidai@google.com>
(am from https://patchwork.kernel.org/patch/13194984/)
(also found at https://lore.kernel.org/r/20230330224348.1006691-4-davidai@google.com)
Conflicts:
include/linux/arm-smccc.h
Changes:
Change the hypercall ID so that it doesn't share the possible new hypercall
IDs.
Remove KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT because it was assigned to
wrong number and the correct number is out of 64bit.
UTIL_HINT hypercall is hidden from UAPI and always available.
BUG=b:249685960
TEST=Build
UPSTREAM-TASK=b:256983979
Change-Id: I2072bf7b9b4053b469b0a1f3e71def4d70f30fc6
Signed-off-by: Masami Hiramatsu <mhiramat@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4546353
Reviewed-by: Suleiman Souhlal <suleiman@chromium.org>
Kcr-patch: 90c6e30bd939593dcaeac999b2bcbcc6c05188e509324e956efc9589.patch
---
Documentation/virt/kvm/api.rst | 12 ++++++++++++
Documentation/virt/kvm/arm/index.rst | 1 +
Documentation/virt/kvm/arm/util_hint.rst | 22 ++++++++++++++++++++++
arch/arm64/kvm/arm.c | 1 +
arch/arm64/kvm/hypercalls.c | 20 ++++++++++++++++++++
include/linux/arm-smccc.h | 7 +++++++
include/uapi/linux/kvm.h | 1 +
7 files changed, 64 insertions(+)
create mode 100644 Documentation/virt/kvm/arm/util_hint.rst
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 09c7e585ff5800da5a72a1f9dbd8b719f0b6d595..dc7a6779d9c141a810b6fb8207f1a56c8ec6e4d2 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -8796,6 +8796,18 @@ Do not use KVM_X86_SW_PROTECTED_VM for "real" VMs, and especially not in
production. The behavior and effective ABI for software-protected VMs is
unstable.
+8.42 KVM_CAP_UTIL_HINT
+----------------------
+
+:Architectures: arm64
+
+This capability indicates that the KVM supports taking utilization
+hints from the guest. Utilization is represented as a value from 0-1024
+where 1024 represents the highest performance point across all physical CPUs
+after normalizing for architecture. This is useful when guests are tracking
+workload on its vCPUs. Util hints allow the host to make more accurate
+frequency selections and task placement for vCPU threads.
+
9. Known KVM API problems
=========================
diff --git a/Documentation/virt/kvm/arm/index.rst b/Documentation/virt/kvm/arm/index.rst
index ae00dd14e740fdee47ce780a6bc04d085c0ec463..d23280f3ae500575039aaba672db8a0412927302 100644
--- a/Documentation/virt/kvm/arm/index.rst
+++ b/Documentation/virt/kvm/arm/index.rst
@@ -13,3 +13,4 @@ ARM
ptp_kvm
vcpu-features
get_cur_cpufreq
+ util_hint
diff --git a/Documentation/virt/kvm/arm/util_hint.rst b/Documentation/virt/kvm/arm/util_hint.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6704cf43cf4898952964b6574a9e8f5b74b15359
--- /dev/null
+++ b/Documentation/virt/kvm/arm/util_hint.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Util_hint support for arm64
+============================
+
+Util_hint is used for sharing the utilization value from the guest
+to the host.
+
+* ARM_SMCCC_HYP_KVM_UTIL_HINT_FUNC_ID: 0x86000042
+
+This hypercall using the SMC32/HVC32 calling convention:
+
+ARM_SMCCC_HYP_KVM_UTIL_HINT_FUNC_ID
+ ============== ========= ============================
+ Function ID: (uint32) 0x86000042
+ Arguments: (uint32) util value(0-1024) where 1024 represents
+ the highest performance point normalized
+ across all CPUs
+ Return values: (int32) NOT_SUPPORTED(-1) on error.
+ Endianness: Must be the same endianness
+ as the host.
+ ============== ======== ============================
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index f2404be63b16e4220ecbe228e3c13c2b4c77a5cc..d12f21bf63516f2b2267d75460589430b12fc776 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -242,6 +242,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_GET_CUR_CPUFREQ:
case KVM_CAP_IRQFD_RESAMPLE:
case KVM_CAP_COUNTER_OFFSET:
+ case KVM_CAP_UTIL_HINT:
r = 1;
break;
case KVM_CAP_SET_GUEST_DEBUG2:
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 419f3d8a98e8704bb9b3c5ace5d3b5e8dbd59d80..bfd63805aa79e65a96554a600186834e852b06ff 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -28,6 +28,20 @@ static void kvm_sched_get_cur_cpufreq(struct kvm_vcpu *vcpu, u64 *val)
val[0] = ret_freq;
}
+static void kvm_sched_set_util(struct kvm_vcpu *vcpu, u64 *val)
+{
+ struct sched_attr attr = {
+ .sched_flags = SCHED_FLAG_UTIL_GUEST,
+ };
+ int ret;
+
+ attr.sched_util_min = smccc_get_arg1(vcpu);
+
+ ret = sched_setattr_nocheck(current, &attr);
+
+ val[0] = (u64)ret;
+}
+
static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
{
struct system_time_snapshot systime_snapshot;
@@ -129,6 +143,7 @@ static bool kvm_smccc_test_fw_bmap(struct kvm_vcpu *vcpu, u32 func_id)
return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_PTP,
&smccc_feat->vendor_hyp_bmap);
case ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID:
+ case ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID:
return true;
default:
return false;
@@ -376,6 +391,8 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
val[0] = smccc_feat->vendor_hyp_bmap;
val[ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ / 32] |=
BIT(ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ % 32);
+ val[ARM_SMCCC_KVM_FUNC_UTIL_HINT / 32] |=
+ BIT(ARM_SMCCC_KVM_FUNC_UTIL_HINT % 32);
break;
case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
kvm_ptp_get_time(vcpu, val);
@@ -383,6 +400,9 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
case ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID:
kvm_sched_get_cur_cpufreq(vcpu, val);
break;
+ case ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID:
+ kvm_sched_set_util(vcpu, val);
+ break;
case ARM_SMCCC_TRNG_VERSION:
case ARM_SMCCC_TRNG_FEATURES:
case ARM_SMCCC_TRNG_GET_UUID:
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 22d47cb9e62d683f54b5d4b5471a8a67b93903e9..1f4865dd95b037bdb4991c6b2ad26998faded507 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -116,6 +116,7 @@
#define ARM_SMCCC_KVM_FUNC_FEATURES 0
#define ARM_SMCCC_KVM_FUNC_PTP 1
#define ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ 65
+#define ARM_SMCCC_KVM_FUNC_UTIL_HINT 66
#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
#define ARM_SMCCC_KVM_NUM_FUNCS 128
@@ -148,6 +149,12 @@
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ)
+#define ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_32, \
+ ARM_SMCCC_OWNER_VENDOR_HYP, \
+ ARM_SMCCC_KVM_FUNC_UTIL_HINT)
+
/* Paravirtualised time calls (defined by ARM DEN0057A) */
#define ARM_SMCCC_HV_PV_TIME_FEATURES \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index aa9a3530bd3492b95074578deaed7b0bf7b12bbe..ff602b11af810d62f35288e49d0ac8aefd6207e5 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1156,6 +1156,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_GUEST_MEMFD 234
#define KVM_CAP_VM_TYPES 235
#define KVM_CAP_GET_CUR_CPUFREQ 512
+#define KVM_CAP_UTIL_HINT 513
#ifdef KVM_CAP_IRQ_ROUTING
--
2.44.0.278.ge034bb2e1d-goog