Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: arm64: Implement PV_TIME_FEATURES call

This provides a mechanism for querying which paravirtualized time
features are available in this hypervisor.

Also add the header file which defines the ABI for the paravirtualized
time features we're about to add.

Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>

authored by

Steven Price and committed by
Marc Zyngier
b48c1a45 55009c6e

+67 -1
+6
arch/arm/include/asm/kvm_host.h
··· 7 7 #ifndef __ARM_KVM_HOST_H__ 8 8 #define __ARM_KVM_HOST_H__ 9 9 10 + #include <linux/arm-smccc.h> 10 11 #include <linux/errno.h> 11 12 #include <linux/types.h> 12 13 #include <linux/kvm_types.h> ··· 323 322 324 323 int kvm_perf_init(void); 325 324 int kvm_perf_teardown(void); 325 + 326 + static inline long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu) 327 + { 328 + return SMCCC_RET_NOT_SUPPORTED; 329 + } 326 330 327 331 void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot); 328 332
+2
arch/arm64/include/asm/kvm_host.h
··· 478 478 int kvm_perf_init(void); 479 479 int kvm_perf_teardown(void); 480 480 481 + long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu); 482 + 481 483 void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome); 482 484 483 485 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
+17
arch/arm64/include/asm/pvclock-abi.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (C) 2019 Arm Ltd. */ 3 + 4 + #ifndef __ASM_PVCLOCK_ABI_H 5 + #define __ASM_PVCLOCK_ABI_H 6 + 7 + /* The below structure is defined in ARM DEN0057A */ 8 + 9 + struct pvclock_vcpu_stolen_time { 10 + __le32 revision; 11 + __le32 attributes; 12 + __le64 stolen_time; 13 + /* Structure must be 64 byte aligned, pad to that size */ 14 + u8 padding[48]; 15 + } __packed; 16 + 17 + #endif
+1
arch/arm64/kvm/Makefile
··· 14 14 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arm.o $(KVM)/arm/mmu.o $(KVM)/arm/mmio.o 15 15 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/psci.o $(KVM)/arm/perf.o 16 16 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hypercalls.o 17 + kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/pvtime.o 17 18 18 19 kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o va_layout.o 19 20 kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
+14
include/linux/arm-smccc.h
··· 45 45 #define ARM_SMCCC_OWNER_SIP 2 46 46 #define ARM_SMCCC_OWNER_OEM 3 47 47 #define ARM_SMCCC_OWNER_STANDARD 4 48 + #define ARM_SMCCC_OWNER_STANDARD_HYP 5 48 49 #define ARM_SMCCC_OWNER_TRUSTED_APP 48 49 50 #define ARM_SMCCC_OWNER_TRUSTED_APP_END 49 50 51 #define ARM_SMCCC_OWNER_TRUSTED_OS 50 ··· 318 317 #define SMCCC_RET_SUCCESS 0 319 318 #define SMCCC_RET_NOT_SUPPORTED -1 320 319 #define SMCCC_RET_NOT_REQUIRED -2 320 + 321 + /* Paravirtualised time calls (defined by ARM DEN0057A) */ 322 + #define ARM_SMCCC_HV_PV_TIME_FEATURES \ 323 + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ 324 + ARM_SMCCC_SMC_64, \ 325 + ARM_SMCCC_OWNER_STANDARD_HYP, \ 326 + 0x20) 327 + 328 + #define ARM_SMCCC_HV_PV_TIME_ST \ 329 + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ 330 + ARM_SMCCC_SMC_64, \ 331 + ARM_SMCCC_OWNER_STANDARD_HYP, \ 332 + 0x21) 321 333 322 334 #endif /*__ASSEMBLY__*/ 323 335 #endif /*__LINUX_ARM_SMCCC_H*/
+7 -1
virt/kvm/arm/hypercalls.c
··· 12 12 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) 13 13 { 14 14 u32 func_id = smccc_get_function(vcpu); 15 - u32 val = SMCCC_RET_NOT_SUPPORTED; 15 + long val = SMCCC_RET_NOT_SUPPORTED; 16 16 u32 feature; 17 17 18 18 switch (func_id) { ··· 48 48 break; 49 49 } 50 50 break; 51 + case ARM_SMCCC_HV_PV_TIME_FEATURES: 52 + val = SMCCC_RET_SUCCESS; 53 + break; 51 54 } 55 + break; 56 + case ARM_SMCCC_HV_PV_TIME_FEATURES: 57 + val = kvm_hypercall_pv_features(vcpu); 52 58 break; 53 59 default: 54 60 return kvm_psci_call(vcpu);
+20
virt/kvm/arm/pvtime.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (C) 2019 Arm Ltd. 3 + 4 + #include <linux/arm-smccc.h> 5 + 6 + #include <kvm/arm_hypercalls.h> 7 + 8 + long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu) 9 + { 10 + u32 feature = smccc_get_arg1(vcpu); 11 + long val = SMCCC_RET_NOT_SUPPORTED; 12 + 13 + switch (feature) { 14 + case ARM_SMCCC_HV_PV_TIME_FEATURES: 15 + val = SMCCC_RET_SUCCESS; 16 + break; 17 + } 18 + 19 + return val; 20 + }