| From 12bca95b2b15abdbed95b0b19452a2122dfb2d93 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 |
| get_cur_cpufreq service |
| |
| This service allows guests to query the host for frequency of the CPU |
| that the vCPU is currently running on. |
| |
| 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/13194986/) |
| (also found at https://lore.kernel.org/r/20230330224348.1006691-3-davidai@google.com) |
| |
| Conflicts: |
| include/uapi/linux/kvm.h |
| |
| Changes: |
| Change the hypercall ID so that it doesn't share the possible new hypercall |
| IDs. |
| Remove KVM_REG_ARM_VENDOR_HYP_BIT_GET_CUR_CPUFREQ because it was assigned |
| to wrong number and the correct number is out of 64bit. |
| GET_CUR_CPUFREQ hypercall is hidden from UAPI and always available. |
| |
| BUG=b:249685960 |
| TEST=Build |
| UPSTREAM-TASK=b:256983979 |
| |
| Change-Id: I12e23cbc8578176992a2847062b6547570fba197 |
| Signed-off-by: Masami Hiramatsu <mhiramat@google.com> |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4546352 |
| Reviewed-by: Suleiman Souhlal <suleiman@chromium.org> |
| --- |
| Documentation/virt/kvm/api.rst | 9 ++++++++ |
| .../virt/kvm/arm/get_cur_cpufreq.rst | 21 +++++++++++++++++++ |
| Documentation/virt/kvm/arm/index.rst | 1 + |
| arch/arm64/kvm/arm.c | 1 + |
| arch/arm64/kvm/hypercalls.c | 19 +++++++++++++++++ |
| include/linux/arm-smccc.h | 7 +++++++ |
| include/uapi/linux/kvm.h | 1 + |
| 7 files changed, 59 insertions(+) |
| create mode 100644 Documentation/virt/kvm/arm/get_cur_cpufreq.rst |
| |
| diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst |
| index 7025b37510279530058dc68f66a1140fd72458a5..96627673539d481137c9662037bbdfdc63ba9a00 100644 |
| --- a/Documentation/virt/kvm/api.rst |
| +++ b/Documentation/virt/kvm/api.rst |
| @@ -8596,6 +8596,15 @@ block sizes is exposed in KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES as a |
| 64-bit bitmap (each bit describing a block size). The default value is |
| 0, to disable the eager page splitting. |
| |
| +8.41 KVM_CAP_GET_CUR_CPUFREQ |
| +------------------------ |
| + |
| +:Architectures: arm64 |
| + |
| +This capability indicates that KVM supports getting the |
| +frequency of the current CPU that the vCPU thread is running on. |
| + |
| + |
| 9. Known KVM API problems |
| ========================= |
| |
| diff --git a/Documentation/virt/kvm/arm/get_cur_cpufreq.rst b/Documentation/virt/kvm/arm/get_cur_cpufreq.rst |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e100826d5e0973dda8c654ae5af4593abd3fc72d |
| --- /dev/null |
| +++ b/Documentation/virt/kvm/arm/get_cur_cpufreq.rst |
| @@ -0,0 +1,21 @@ |
| +.. SPDX-License-Identifier: GPL-2.0 |
| + |
| +get_cur_cpufreq support for arm/arm64 |
| +============================= |
| + |
| +Get_cur_cpufreq support is used to get current frequency(in KHz) of the |
| +current CPU that the vCPU thread is running on. |
| + |
| +* ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID: 0x86000041 |
| + |
| +This hypercall uses the SMC32/HVC32 calling convention: |
| + |
| +ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID |
| + ============== ======== ===================================== |
| + Function ID: (uint32) 0x86000041 |
| + Return Values: (int32) NOT_SUPPORTED(-1) on error, or |
| + (uint32) Frequency in KHz of current CPU that the |
| + vCPU thread is running on. |
| + Endianness: Must be the same endianness |
| + as the host. |
| + ============== ======== ===================================== |
| diff --git a/Documentation/virt/kvm/arm/index.rst b/Documentation/virt/kvm/arm/index.rst |
| index 7f231c724e16756f63b2a38e9e2df6a60727d2ee..ae00dd14e740fdee47ce780a6bc04d085c0ec463 100644 |
| --- a/Documentation/virt/kvm/arm/index.rst |
| +++ b/Documentation/virt/kvm/arm/index.rst |
| @@ -12,3 +12,4 @@ ARM |
| pvtime |
| ptp_kvm |
| vcpu-features |
| + get_cur_cpufreq |
| diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c |
| index a64cd69e174ecabf119004391eefe8b87cf9918b..4e0b91fe5cffc98befdd97c7ff3cdbc6054e628d 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_ARM_SYSTEM_SUSPEND: |
| case KVM_CAP_IRQFD_RESAMPLE: |
| case KVM_CAP_COUNTER_OFFSET: |
| + case KVM_CAP_GET_CUR_CPUFREQ: |
| r = 1; |
| break; |
| case KVM_CAP_SET_GUEST_DEBUG2: |
| diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c |
| index 5763d979d8cae00ac206a6f80f10c2d36f86bdac..419f3d8a98e8704bb9b3c5ace5d3b5e8dbd59d80 100644 |
| --- a/arch/arm64/kvm/hypercalls.c |
| +++ b/arch/arm64/kvm/hypercalls.c |
| @@ -3,6 +3,9 @@ |
| |
| #include <linux/arm-smccc.h> |
| #include <linux/kvm_host.h> |
| +#include <linux/cpufreq.h> |
| +#include <linux/sched.h> |
| +#include <uapi/linux/sched/types.h> |
| |
| #include <asm/kvm_emulate.h> |
| |
| @@ -16,6 +19,15 @@ |
| #define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES \ |
| GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT - 1, 0) |
| |
| +static void kvm_sched_get_cur_cpufreq(struct kvm_vcpu *vcpu, u64 *val) |
| +{ |
| + unsigned long ret_freq; |
| + |
| + ret_freq = cpufreq_get(task_cpu(current)); |
| + |
| + val[0] = ret_freq; |
| +} |
| + |
| static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) |
| { |
| struct system_time_snapshot systime_snapshot; |
| @@ -116,6 +128,8 @@ static bool kvm_smccc_test_fw_bmap(struct kvm_vcpu *vcpu, u32 func_id) |
| case ARM_SMCCC_VENDOR_HYP_KVM_PTP_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: |
| + return true; |
| default: |
| return false; |
| } |
| @@ -360,10 +374,15 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu) |
| break; |
| case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: |
| 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); |
| break; |
| case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: |
| kvm_ptp_get_time(vcpu, val); |
| break; |
| + case ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID: |
| + kvm_sched_get_cur_cpufreq(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 083f8565371616269fa0050036ec8a3631c44357..22d47cb9e62d683f54b5d4b5471a8a67b93903e9 100644 |
| --- a/include/linux/arm-smccc.h |
| +++ b/include/linux/arm-smccc.h |
| @@ -115,6 +115,7 @@ |
| /* KVM "vendor specific" services */ |
| #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_FEATURES_2 127 |
| #define ARM_SMCCC_KVM_NUM_FUNCS 128 |
| |
| @@ -141,6 +142,12 @@ |
| #define KVM_PTP_VIRT_COUNTER 0 |
| #define KVM_PTP_PHYS_COUNTER 1 |
| |
| +#define ARM_SMCCC_VENDOR_HYP_KVM_GET_CUR_CPUFREQ_FUNC_ID \ |
| + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ |
| + ARM_SMCCC_SMC_32, \ |
| + ARM_SMCCC_OWNER_VENDOR_HYP, \ |
| + ARM_SMCCC_KVM_FUNC_GET_CUR_CPUFREQ) |
| + |
| /* 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 211b86de35ac53f6457bbd2fae8c973ce6b3a968..4c0280ed164e4e1c164741f33e57f0b2a2d9a7b8 100644 |
| --- a/include/uapi/linux/kvm.h |
| +++ b/include/uapi/linux/kvm.h |
| @@ -1201,6 +1201,7 @@ struct kvm_ppc_resize_hpt { |
| #define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228 |
| #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 |
| #define KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES 230 |
| +#define KVM_CAP_GET_CUR_CPUFREQ 512 |
| |
| #ifdef KVM_CAP_IRQ_ROUTING |
| |
| -- |
| 2.43.0.rc2.451.g8631bc7472-goog |
| |