| 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 |
| |