@@ -8388,6 +8388,18 @@ must point to a byte where the value will be stored or retrieved from.
This capability indicates that KVM supports getting the
frequency of the current CPU that the vCPU thread is running on.
+8.41 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
=========================
@@ -12,3 +12,4 @@ ARM
pvtime
ptp_kvm
get_cur_cpufreq
+ util_hint
new file mode 100644
@@ -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: 0x86000041
+
+This hypercall using the SMC32/HVC32 calling convention:
+
+ARM_SMCCC_HYP_KVM_UTIL_HINT_FUNC_ID
+ ============== ========= ============================
+ Function ID: (uint32) 0x86000041
+ 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.
+ ============== ======== ============================
@@ -368,6 +368,7 @@ enum {
KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0,
KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1,
KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ = 2,
+ KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT = 3,
#ifdef __KERNEL__
KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT,
#endif
@@ -221,6 +221,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_PTP_KVM:
case KVM_CAP_ARM_SYSTEM_SUSPEND:
case KVM_CAP_GET_CUR_CPUFREQ:
+ case KVM_CAP_UTIL_HINT:
r = 1;
break;
case KVM_CAP_SET_GUEST_DEBUG2:
@@ -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;
@@ -131,6 +145,9 @@ static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, u32 func_id)
case ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID:
return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ,
&smccc_feat->vendor_hyp_bmap);
+ case ARM_SMCCC_VENDOR_HYP_KVM_UTIL_HINT_FUNC_ID:
+ return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT,
+ &smccc_feat->vendor_hyp_bmap);
default:
return kvm_hvc_call_default_allowed(func_id);
}
@@ -231,6 +248,9 @@ int kvm_hvc_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:
@@ -113,6 +113,7 @@
#define ARM_SMCCC_KVM_FUNC_FEATURES 0
#define ARM_SMCCC_KVM_FUNC_PTP 1
#define ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ 64
+#define ARM_SMCCC_KVM_FUNC_UTIL_HINT 65
#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
#define ARM_SMCCC_KVM_NUM_FUNCS 128
@@ -145,6 +146,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, \
@@ -1185,6 +1185,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225
#define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226
#define KVM_CAP_GET_CUR_CPUFREQ 512
+#define KVM_CAP_UTIL_HINT 513
#ifdef KVM_CAP_IRQ_ROUTING
@@ -368,6 +368,7 @@ enum {
KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0,
KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1,
KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ = 2,
+ KVM_REG_ARM_VENDOR_HYP_BIT_UTIL_HINT = 3,
#ifdef __KERNEL__
KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT,
#endif