/* SPDX-License-Identifier: GPL-2.0-only *//* * Copyright (c) 2015, Linaro Limited */#ifndef __LINUX_ARM_SMCCC_H#define __LINUX_ARM_SMCCC_H #include <linux/args.h>#include <linux/init.h> #ifndef __ASSEMBLY__#include <linux/uuid.h>#endif #include <uapi/linux/const.h> /* * This file provides common defines for ARM SMC Calling Convention as * specified in * https://developer.arm.com/docs/den0028/latest * * This code is up-to-date with version DEN 0028 C */ #define ARM_SMCCC_STD_CALL _AC(0,U)#define ARM_SMCCC_FAST_CALL _AC(1,U)#define ARM_SMCCC_TYPE_SHIFT 31 #define ARM_SMCCC_SMC_32 0#define ARM_SMCCC_SMC_64 1#define ARM_SMCCC_CALL_CONV_SHIFT 30 #define ARM_SMCCC_OWNER_MASK 0x3F#define ARM_SMCCC_OWNER_SHIFT 24 #define ARM_SMCCC_FUNC_MASK 0xFFFF #define ARM_SMCCC_IS_FAST_CALL(smc_val) \ ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))#define ARM_SMCCC_IS_64(smc_val) \ ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)#define ARM_SMCCC_OWNER_NUM(smc_val) \ (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK) #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \ (((type) << ARM_SMCCC_TYPE_SHIFT) | \ ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \ (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \ ((func_num) & ARM_SMCCC_FUNC_MASK)) #define ARM_SMCCC_OWNER_ARCH 0#define ARM_SMCCC_OWNER_CPU 1#define ARM_SMCCC_OWNER_SIP 2#define ARM_SMCCC_OWNER_OEM 3#define ARM_SMCCC_OWNER_STANDARD 4#define ARM_SMCCC_OWNER_STANDARD_HYP 5#define ARM_SMCCC_OWNER_VENDOR_HYP 6#define ARM_SMCCC_OWNER_TRUSTED_APP 48#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49#define ARM_SMCCC_OWNER_TRUSTED_OS 50#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 #define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01 #define ARM_SMCCC_QUIRK_NONE 0#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ #define ARM_SMCCC_VERSION_1_0 0x10000#define ARM_SMCCC_VERSION_1_1 0x10001#define ARM_SMCCC_VERSION_1_2 0x10002#define ARM_SMCCC_VERSION_1_3 0x10003 #define ARM_SMCCC_1_3_SVE_HINT 0x10000#define ARM_SMCCC_CALL_HINTS ARM_SMCCC_1_3_SVE_HINT #define ARM_SMCCC_VERSION_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 0) #define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 1) #define ARM_SMCCC_ARCH_SOC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 2) #define ARM_SMCCC_ARCH_SOC_ID64 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ 0, 2) #define ARM_SMCCC_ARCH_WORKAROUND_1 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 0x8000) #define ARM_SMCCC_ARCH_WORKAROUND_2 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 0x7fff) #define ARM_SMCCC_ARCH_WORKAROUND_3 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 0x3fff) /* C1-Pro erratum 4193714: SME DVMSync early acknowledgement */#define ARM_SMCCC_CPU_WORKAROUND_4193714 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_CPU, 0x10) #define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_FUNC_QUERY_CALL_UID) /* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */#define ARM_SMCCC_VENDOR_HYP_UID_KVM UUID_INIT(\ 0x28b46fb6, 0x2ec5, 0x11e9, \ 0xa9, 0xca, 0x4b, 0x56, \ 0x4d, 0x00, 0x3a, 0x74) /* KVM "vendor specific" services */#define ARM_SMCCC_KVM_FUNC_FEATURES 0#define ARM_SMCCC_KVM_FUNC_PTP 1/* Start of pKVM hypercall range */#define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO 2#define ARM_SMCCC_KVM_FUNC_MEM_SHARE 3#define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE 4#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5 5#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6 6#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD 7#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_8 8#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_9 9#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_10 10#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_11 11#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_12 12#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_13 13#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_14 14#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_15 15#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_16 16#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_17 17#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_18 18#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_19 19#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_20 20#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_21 21#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_22 22#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_23 23#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_24 24#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_25 25#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_26 26#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_27 27#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_28 28#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_29 29#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_30 30#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_31 31#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_32 32#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_33 33#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_34 34#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_35 35#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_36 36#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_37 37#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_38 38#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_39 39#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_40 40#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_41 41#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_42 42#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_43 43#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_44 44#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_45 45#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_46 46#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_47 47#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_48 48#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_49 49#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_50 50#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_51 51#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_52 52#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_53 53#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_54 54#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_55 55#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_56 56#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_57 57#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_58 58#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59 59#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60 60#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61 61#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62 62#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63 63/* End of pKVM hypercall range */#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER 64#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS 65 #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127#define ARM_SMCCC_KVM_NUM_FUNCS 128 #define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_FEATURES) #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1 /* * ptp_kvm is a feature used for time sync between vm and host. * ptp_kvm module in guest kernel will get service from host using * this hypercall ID. */#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_PTP) #define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_HYP_MEMINFO) #define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_MEM_SHARE) #define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_MEM_UNSHARE) #define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_MMIO_GUARD) #define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER) #define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS) /* ptp_kvm counter type ID */#define KVM_PTP_VIRT_COUNTER 0#define KVM_PTP_PHYS_COUNTER 1 /* Paravirtualised time calls (defined by ARM DEN0057A) */#define ARM_SMCCC_HV_PV_TIME_FEATURES \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_STANDARD_HYP, \ 0x20) #define ARM_SMCCC_HV_PV_TIME_ST \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_STANDARD_HYP, \ 0x21) /* TRNG entropy source calls (defined by ARM DEN0098) */#define ARM_SMCCC_TRNG_VERSION \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_STANDARD, \ 0x50) #define ARM_SMCCC_TRNG_FEATURES \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_STANDARD, \ 0x51) #define ARM_SMCCC_TRNG_GET_UUID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_STANDARD, \ 0x52) #define ARM_SMCCC_TRNG_RND32 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_STANDARD, \ 0x53) #define ARM_SMCCC_TRNG_RND64 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_STANDARD, \ 0x53) /* * Return codes defined in ARM DEN 0070A * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C */#define SMCCC_RET_SUCCESS 0#define SMCCC_RET_NOT_SUPPORTED -1#define SMCCC_RET_NOT_REQUIRED -2#define SMCCC_RET_INVALID_PARAMETER -3 #ifndef __ASSEMBLY__ #include <linux/linkage.h>#include <linux/types.h> enum arm_smccc_conduit { SMCCC_CONDUIT_NONE, SMCCC_CONDUIT_SMC, SMCCC_CONDUIT_HVC,}; /** * arm_smccc_1_1_get_conduit() * * Returns the conduit to be used for SMCCCv1.1 or later. * * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE. */enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void); /** * arm_smccc_get_version() * * Returns the version to be used for SMCCCv1.1 or later. * * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this * does not imply the presence of firmware or a valid conduit. Caller * handling SMCCCv1.0 must determine the conduit by other means. */u32 arm_smccc_get_version(void); void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit); /** * arm_smccc_get_soc_id_version() * * Returns the SOC ID version. * * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED. */s32 arm_smccc_get_soc_id_version(void); /** * arm_smccc_get_soc_id_revision() * * Returns the SOC ID revision. * * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED. */s32 arm_smccc_get_soc_id_revision(void); #ifndef __ASSEMBLY__ /* * Returns whether a specific hypervisor UUID is advertised for the * Vendor Specific Hypervisor Service range. */bool arm_smccc_hypervisor_has_uuid(const uuid_t *uuid); static inline uuid_t smccc_res_to_uuid(u32 r0, u32 r1, u32 r2, u32 r3){ uuid_t uuid = { .b = { [0] = (r0 >> 0) & 0xff, [1] = (r0 >> 8) & 0xff, [2] = (r0 >> 16) & 0xff, [3] = (r0 >> 24) & 0xff, [4] = (r1 >> 0) & 0xff, [5] = (r1 >> 8) & 0xff, [6] = (r1 >> 16) & 0xff, [7] = (r1 >> 24) & 0xff, [8] = (r2 >> 0) & 0xff, [9] = (r2 >> 8) & 0xff, [10] = (r2 >> 16) & 0xff, [11] = (r2 >> 24) & 0xff, [12] = (r3 >> 0) & 0xff, [13] = (r3 >> 8) & 0xff, [14] = (r3 >> 16) & 0xff, [15] = (r3 >> 24) & 0xff, }, }; return uuid;} static inline u32 smccc_uuid_to_reg(const uuid_t *uuid, int reg){ u32 val = 0; val |= (u32)(uuid->b[4 * reg + 0] << 0); val |= (u32)(uuid->b[4 * reg + 1] << 8); val |= (u32)(uuid->b[4 * reg + 2] << 16); val |= (u32)(uuid->b[4 * reg + 3] << 24); return val;} #endif /* !__ASSEMBLY__ */ /** * struct arm_smccc_res - Result from SMC/HVC call * @a0-a3 result values from registers 0 to 3 */struct arm_smccc_res { unsigned long a0; unsigned long a1; unsigned long a2; unsigned long a3;}; #ifdef CONFIG_ARM64/** * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call * @a0-a17 argument values from registers 0 to 17 */struct arm_smccc_1_2_regs { unsigned long a0; unsigned long a1; unsigned long a2; unsigned long a3; unsigned long a4; unsigned long a5; unsigned long a6; unsigned long a7; unsigned long a8; unsigned long a9; unsigned long a10; unsigned long a11; unsigned long a12; unsigned long a13; unsigned long a14; unsigned long a15; unsigned long a16; unsigned long a17;}; /** * arm_smccc_1_2_hvc() - make HVC calls * @args: arguments passed via struct arm_smccc_1_2_regs * @res: result values via struct arm_smccc_1_2_regs * * This function is used to make HVC calls following SMC Calling Convention * v1.2 or above. The content of the supplied param are copied from the * structure to registers prior to the HVC instruction. The return values * are updated with the content from registers on return from the HVC * instruction. */asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args, struct arm_smccc_1_2_regs *res); /** * arm_smccc_1_2_smc() - make SMC calls * @args: arguments passed via struct arm_smccc_1_2_regs * @res: result values via struct arm_smccc_1_2_regs * * This function is used to make SMC calls following SMC Calling Convention * v1.2 or above. The content of the supplied param are copied from the * structure to registers prior to the SMC instruction. The return values * are updated with the content from registers on return from the SMC * instruction. */asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args, struct arm_smccc_1_2_regs *res);#endif /** * struct arm_smccc_quirk - Contains quirk information * @id: quirk identification * @state: quirk specific information * @a6: Qualcomm quirk entry for returning post-smc call contents of a6 */struct arm_smccc_quirk { int id; union { unsigned long a6; } state;}; /** * __arm_smccc_smc() - make SMC calls * @a0-a7: arguments passed in registers 0 to 7 * @res: result values from registers 0 to 3Lines 1–500 of 765. Load more
/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015, Linaro Limited */ #ifndef __LINUX_ARM_SMCCC_H #define __LINUX_ARM_SMCCC_H #include <linux/args.h> #include <linux/init.h> #ifndef __ASSEMBLY__ #include <linux/uuid.h> #endif #include <uapi/linux/const.h> /* * This file provides common defines for ARM SMC Calling Convention as * specified in * https://developer.arm.com/docs/den0028/latest * * This code is up-to-date with version DEN 0028 C */ #define ARM_SMCCC_STD_CALL _AC(0,U) #define ARM_SMCCC_FAST_CALL _AC(1,U) #define ARM_SMCCC_TYPE_SHIFT 31 #define ARM_SMCCC_SMC_32 0 #define ARM_SMCCC_SMC_64 1 #define ARM_SMCCC_CALL_CONV_SHIFT 30 #define ARM_SMCCC_OWNER_MASK 0x3F #define ARM_SMCCC_OWNER_SHIFT 24 #define ARM_SMCCC_FUNC_MASK 0xFFFF #define ARM_SMCCC_IS_FAST_CALL(smc_val) \ ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT)) #define ARM_SMCCC_IS_64(smc_val) \ ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT)) #define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK) #define ARM_SMCCC_OWNER_NUM(smc_val) \ (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK) #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \ (((type) << ARM_SMCCC_TYPE_SHIFT) | \ ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \ (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \ ((func_num) & ARM_SMCCC_FUNC_MASK)) #define ARM_SMCCC_OWNER_ARCH 0 #define ARM_SMCCC_OWNER_CPU 1 #define ARM_SMCCC_OWNER_SIP 2 #define ARM_SMCCC_OWNER_OEM 3 #define ARM_SMCCC_OWNER_STANDARD 4 #define ARM_SMCCC_OWNER_STANDARD_HYP 5 #define ARM_SMCCC_OWNER_VENDOR_HYP 6 #define ARM_SMCCC_OWNER_TRUSTED_APP 48 #define ARM_SMCCC_OWNER_TRUSTED_APP_END 49 #define ARM_SMCCC_OWNER_TRUSTED_OS 50 #define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 #define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01 #define ARM_SMCCC_QUIRK_NONE 0 #define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ #define ARM_SMCCC_VERSION_1_0 0x10000 #define ARM_SMCCC_VERSION_1_1 0x10001 #define ARM_SMCCC_VERSION_1_2 0x10002 #define ARM_SMCCC_VERSION_1_3 0x10003 #define ARM_SMCCC_1_3_SVE_HINT 0x10000 #define ARM_SMCCC_CALL_HINTS ARM_SMCCC_1_3_SVE_HINT #define ARM_SMCCC_VERSION_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 0) #define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 1) #define ARM_SMCCC_ARCH_SOC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 2) #define ARM_SMCCC_ARCH_SOC_ID64 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ 0, 2) #define ARM_SMCCC_ARCH_WORKAROUND_1 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 0x8000) #define ARM_SMCCC_ARCH_WORKAROUND_2 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 0x7fff) #define ARM_SMCCC_ARCH_WORKAROUND_3 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ 0, 0x3fff) /* C1-Pro erratum 4193714: SME DVMSync early acknowledgement */ #define ARM_SMCCC_CPU_WORKAROUND_4193714 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_CPU, 0x10) #define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_FUNC_QUERY_CALL_UID) /* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */ #define ARM_SMCCC_VENDOR_HYP_UID_KVM UUID_INIT(\ 0x28b46fb6, 0x2ec5, 0x11e9, \ 0xa9, 0xca, 0x4b, 0x56, \ 0x4d, 0x00, 0x3a, 0x74) /* KVM "vendor specific" services */ #define ARM_SMCCC_KVM_FUNC_FEATURES 0 #define ARM_SMCCC_KVM_FUNC_PTP 1 /* Start of pKVM hypercall range */ #define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO 2 #define ARM_SMCCC_KVM_FUNC_MEM_SHARE 3 #define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE 4 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5 5 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6 6 #define ARM_SMCCC_KVM_FUNC_MMIO_GUARD 7 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_8 8 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_9 9 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_10 10 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_11 11 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_12 12 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_13 13 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_14 14 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_15 15 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_16 16 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_17 17 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_18 18 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_19 19 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_20 20 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_21 21 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_22 22 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_23 23 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_24 24 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_25 25 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_26 26 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_27 27 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_28 28 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_29 29 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_30 30 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_31 31 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_32 32 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_33 33 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_34 34 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_35 35 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_36 36 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_37 37 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_38 38 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_39 39 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_40 40 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_41 41 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_42 42 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_43 43 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_44 44 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_45 45 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_46 46 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_47 47 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_48 48 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_49 49 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_50 50 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_51 51 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_52 52 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_53 53 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_54 54 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_55 55 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_56 56 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_57 57 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_58 58 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59 59 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60 60 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61 61 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62 62 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63 63 /* End of pKVM hypercall range */ #define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER 64 #define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS 65 #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 #define ARM_SMCCC_KVM_NUM_FUNCS 128 #define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_FEATURES) #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1 /* * ptp_kvm is a feature used for time sync between vm and host. * ptp_kvm module in guest kernel will get service from host using * this hypercall ID. */ #define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_PTP) #define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_HYP_MEMINFO) #define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_MEM_SHARE) #define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_MEM_UNSHARE) #define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_MMIO_GUARD) #define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER) #define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS) /* ptp_kvm counter type ID */ #define KVM_PTP_VIRT_COUNTER 0 #define KVM_PTP_PHYS_COUNTER 1 /* Paravirtualised time calls (defined by ARM DEN0057A) */ #define ARM_SMCCC_HV_PV_TIME_FEATURES \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_STANDARD_HYP, \ 0x20) #define ARM_SMCCC_HV_PV_TIME_ST \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_STANDARD_HYP, \ 0x21) /* TRNG entropy source calls (defined by ARM DEN0098) */ #define ARM_SMCCC_TRNG_VERSION \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_STANDARD, \ 0x50) #define ARM_SMCCC_TRNG_FEATURES \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_STANDARD, \ 0x51) #define ARM_SMCCC_TRNG_GET_UUID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_STANDARD, \ 0x52) #define ARM_SMCCC_TRNG_RND32 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ ARM_SMCCC_OWNER_STANDARD, \ 0x53) #define ARM_SMCCC_TRNG_RND64 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ ARM_SMCCC_OWNER_STANDARD, \ 0x53) /* * Return codes defined in ARM DEN 0070A * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C */ #define SMCCC_RET_SUCCESS 0 #define SMCCC_RET_NOT_SUPPORTED -1 #define SMCCC_RET_NOT_REQUIRED -2 #define SMCCC_RET_INVALID_PARAMETER -3 #ifndef __ASSEMBLY__ #include <linux/linkage.h> #include <linux/types.h> enum arm_smccc_conduit { SMCCC_CONDUIT_NONE, SMCCC_CONDUIT_SMC, SMCCC_CONDUIT_HVC, }; /** * arm_smccc_1_1_get_conduit() * * Returns the conduit to be used for SMCCCv1.1 or later. * * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE. */ enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void); /** * arm_smccc_get_version() * * Returns the version to be used for SMCCCv1.1 or later. * * When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this * does not imply the presence of firmware or a valid conduit. Caller * handling SMCCCv1.0 must determine the conduit by other means. */ u32 arm_smccc_get_version(void); void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit); /** * arm_smccc_get_soc_id_version() * * Returns the SOC ID version. * * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED. */ s32 arm_smccc_get_soc_id_version(void); /** * arm_smccc_get_soc_id_revision() * * Returns the SOC ID revision. * * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED. */ s32 arm_smccc_get_soc_id_revision(void); #ifndef __ASSEMBLY__ /* * Returns whether a specific hypervisor UUID is advertised for the * Vendor Specific Hypervisor Service range. */ bool arm_smccc_hypervisor_has_uuid(const uuid_t *uuid); static inline uuid_t smccc_res_to_uuid(u32 r0, u32 r1, u32 r2, u32 r3) { uuid_t uuid = { .b = { [0] = (r0 >> 0) & 0xff, [1] = (r0 >> 8) & 0xff, [2] = (r0 >> 16) & 0xff, [3] = (r0 >> 24) & 0xff, [4] = (r1 >> 0) & 0xff, [5] = (r1 >> 8) & 0xff, [6] = (r1 >> 16) & 0xff, [7] = (r1 >> 24) & 0xff, [8] = (r2 >> 0) & 0xff, [9] = (r2 >> 8) & 0xff, [10] = (r2 >> 16) & 0xff, [11] = (r2 >> 24) & 0xff, [12] = (r3 >> 0) & 0xff, [13] = (r3 >> 8) & 0xff, [14] = (r3 >> 16) & 0xff, [15] = (r3 >> 24) & 0xff, }, }; return uuid; } static inline u32 smccc_uuid_to_reg(const uuid_t *uuid, int reg) { u32 val = 0; val |= (u32)(uuid->b[4 * reg + 0] << 0); val |= (u32)(uuid->b[4 * reg + 1] << 8); val |= (u32)(uuid->b[4 * reg + 2] << 16); val |= (u32)(uuid->b[4 * reg + 3] << 24); return val; } #endif /* !__ASSEMBLY__ */ /** * struct arm_smccc_res - Result from SMC/HVC call * @a0-a3 result values from registers 0 to 3 */ struct arm_smccc_res { unsigned long a0; unsigned long a1; unsigned long a2; unsigned long a3; }; #ifdef CONFIG_ARM64 /** * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call * @a0-a17 argument values from registers 0 to 17 */ struct arm_smccc_1_2_regs { unsigned long a0; unsigned long a1; unsigned long a2; unsigned long a3; unsigned long a4; unsigned long a5; unsigned long a6; unsigned long a7; unsigned long a8; unsigned long a9; unsigned long a10; unsigned long a11; unsigned long a12; unsigned long a13; unsigned long a14; unsigned long a15; unsigned long a16; unsigned long a17; }; /** * arm_smccc_1_2_hvc() - make HVC calls * @args: arguments passed via struct arm_smccc_1_2_regs * @res: result values via struct arm_smccc_1_2_regs * * This function is used to make HVC calls following SMC Calling Convention * v1.2 or above. The content of the supplied param are copied from the * structure to registers prior to the HVC instruction. The return values * are updated with the content from registers on return from the HVC * instruction. */ asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args, struct arm_smccc_1_2_regs *res); /** * arm_smccc_1_2_smc() - make SMC calls * @args: arguments passed via struct arm_smccc_1_2_regs * @res: result values via struct arm_smccc_1_2_regs * * This function is used to make SMC calls following SMC Calling Convention * v1.2 or above. The content of the supplied param are copied from the * structure to registers prior to the SMC instruction. The return values * are updated with the content from registers on return from the SMC * instruction. */ asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args, struct arm_smccc_1_2_regs *res); #endif /** * struct arm_smccc_quirk - Contains quirk information * @id: quirk identification * @state: quirk specific information * @a6: Qualcomm quirk entry for returning post-smc call contents of a6 */ struct arm_smccc_quirk { int id; union { unsigned long a6; } state; }; /** * __arm_smccc_smc() - make SMC calls * @a0-a7: arguments passed in registers 0 to 7 * @res: result values from registers 0 to 3