* [PATCH kvmtool v3 01/17] Import arm-smccc.h from Linux 6.5-rc1
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 02/17] aarch64: Copy cputype.h " Oliver Upton
` (16 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Copy in the SMCCC definitions from the kernel, which will be used to
implement SMCCC handling in userspace.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
include/linux/arm-smccc.h | 240 ++++++++++++++++++++++++++++++++++++++
1 file changed, 240 insertions(+)
create mode 100644 include/linux/arm-smccc.h
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
new file mode 100644
index 000000000000..3663c31ba52c
--- /dev/null
+++ b/include/linux/arm-smccc.h
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015, Linaro Limited
+ */
+#ifndef __LINUX_ARM_SMCCC_H
+#define __LINUX_ARM_SMCCC_H
+
+#include <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_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_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)
+
+#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_REG_0 0xb66fb428U
+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU
+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U
+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU
+
+/* KVM "vendor specific" services */
+#define ARM_SMCCC_KVM_FUNC_FEATURES 0
+#define ARM_SMCCC_KVM_FUNC_PTP 1
+#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)
+
+/* 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/types.h>
+
+enum arm_smccc_conduit {
+ SMCCC_CONDUIT_NONE,
+ SMCCC_CONDUIT_SMC,
+ SMCCC_CONDUIT_HVC,
+};
+
+/**
+ * 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;
+};
+
+/**
+ * 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;
+};
+
+#endif /*__ASSEMBLY__*/
+#endif /*__LINUX_ARM_SMCCC_H*/
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 02/17] aarch64: Copy cputype.h from Linux 6.5-rc1
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 01/17] Import arm-smccc.h from Linux 6.5-rc1 Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 03/17] Update psci.h to " Oliver Upton
` (15 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
cputype.h has some helpful definitions for working with mpidrs and
affinity masks.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/include/asm/cputype.h | 186 ++++++++++++++++++++++++++++++
1 file changed, 186 insertions(+)
create mode 100644 arm/aarch64/include/asm/cputype.h
diff --git a/arm/aarch64/include/asm/cputype.h b/arm/aarch64/include/asm/cputype.h
new file mode 100644
index 000000000000..698665ab41ae
--- /dev/null
+++ b/arm/aarch64/include/asm/cputype.h
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ */
+#ifndef __ASM_CPUTYPE_H
+#define __ASM_CPUTYPE_H
+
+#define INVALID_HWID ULONG_MAX
+
+#define MPIDR_UP_BITMASK (0x1 << 30)
+#define MPIDR_MT_BITMASK (0x1 << 24)
+#define MPIDR_HWID_BITMASK UL(0xff00ffffff)
+
+#define MPIDR_LEVEL_BITS_SHIFT 3
+#define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT)
+#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
+
+#define MPIDR_LEVEL_SHIFT(level) \
+ (((1 << level) >> 1) << MPIDR_LEVEL_BITS_SHIFT)
+
+#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
+ ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK)
+
+#define MIDR_REVISION_MASK 0xf
+#define MIDR_REVISION(midr) ((midr) & MIDR_REVISION_MASK)
+#define MIDR_PARTNUM_SHIFT 4
+#define MIDR_PARTNUM_MASK (0xfff << MIDR_PARTNUM_SHIFT)
+#define MIDR_PARTNUM(midr) \
+ (((midr) & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT)
+#define MIDR_ARCHITECTURE_SHIFT 16
+#define MIDR_ARCHITECTURE_MASK (0xf << MIDR_ARCHITECTURE_SHIFT)
+#define MIDR_ARCHITECTURE(midr) \
+ (((midr) & MIDR_ARCHITECTURE_MASK) >> MIDR_ARCHITECTURE_SHIFT)
+#define MIDR_VARIANT_SHIFT 20
+#define MIDR_VARIANT_MASK (0xf << MIDR_VARIANT_SHIFT)
+#define MIDR_VARIANT(midr) \
+ (((midr) & MIDR_VARIANT_MASK) >> MIDR_VARIANT_SHIFT)
+#define MIDR_IMPLEMENTOR_SHIFT 24
+#define MIDR_IMPLEMENTOR_MASK (0xffU << MIDR_IMPLEMENTOR_SHIFT)
+#define MIDR_IMPLEMENTOR(midr) \
+ (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
+
+#define MIDR_CPU_MODEL(imp, partnum) \
+ ((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \
+ (0xf << MIDR_ARCHITECTURE_SHIFT) | \
+ ((partnum) << MIDR_PARTNUM_SHIFT))
+
+#define MIDR_CPU_VAR_REV(var, rev) \
+ (((var) << MIDR_VARIANT_SHIFT) | (rev))
+
+#define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
+ MIDR_ARCHITECTURE_MASK)
+
+#define ARM_CPU_IMP_ARM 0x41
+#define ARM_CPU_IMP_APM 0x50
+#define ARM_CPU_IMP_CAVIUM 0x43
+#define ARM_CPU_IMP_BRCM 0x42
+#define ARM_CPU_IMP_QCOM 0x51
+#define ARM_CPU_IMP_NVIDIA 0x4E
+#define ARM_CPU_IMP_FUJITSU 0x46
+#define ARM_CPU_IMP_HISI 0x48
+#define ARM_CPU_IMP_APPLE 0x61
+#define ARM_CPU_IMP_AMPERE 0xC0
+
+#define ARM_CPU_PART_AEM_V8 0xD0F
+#define ARM_CPU_PART_FOUNDATION 0xD00
+#define ARM_CPU_PART_CORTEX_A57 0xD07
+#define ARM_CPU_PART_CORTEX_A72 0xD08
+#define ARM_CPU_PART_CORTEX_A53 0xD03
+#define ARM_CPU_PART_CORTEX_A73 0xD09
+#define ARM_CPU_PART_CORTEX_A75 0xD0A
+#define ARM_CPU_PART_CORTEX_A35 0xD04
+#define ARM_CPU_PART_CORTEX_A55 0xD05
+#define ARM_CPU_PART_CORTEX_A76 0xD0B
+#define ARM_CPU_PART_NEOVERSE_N1 0xD0C
+#define ARM_CPU_PART_CORTEX_A77 0xD0D
+#define ARM_CPU_PART_NEOVERSE_V1 0xD40
+#define ARM_CPU_PART_CORTEX_A78 0xD41
+#define ARM_CPU_PART_CORTEX_A78AE 0xD42
+#define ARM_CPU_PART_CORTEX_X1 0xD44
+#define ARM_CPU_PART_CORTEX_A510 0xD46
+#define ARM_CPU_PART_CORTEX_A710 0xD47
+#define ARM_CPU_PART_CORTEX_A715 0xD4D
+#define ARM_CPU_PART_CORTEX_X2 0xD48
+#define ARM_CPU_PART_NEOVERSE_N2 0xD49
+#define ARM_CPU_PART_CORTEX_A78C 0xD4B
+
+#define APM_CPU_PART_POTENZA 0x000
+
+#define CAVIUM_CPU_PART_THUNDERX 0x0A1
+#define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2
+#define CAVIUM_CPU_PART_THUNDERX_83XX 0x0A3
+#define CAVIUM_CPU_PART_THUNDERX2 0x0AF
+/* OcteonTx2 series */
+#define CAVIUM_CPU_PART_OCTX2_98XX 0x0B1
+#define CAVIUM_CPU_PART_OCTX2_96XX 0x0B2
+#define CAVIUM_CPU_PART_OCTX2_95XX 0x0B3
+#define CAVIUM_CPU_PART_OCTX2_95XXN 0x0B4
+#define CAVIUM_CPU_PART_OCTX2_95XXMM 0x0B5
+#define CAVIUM_CPU_PART_OCTX2_95XXO 0x0B6
+
+#define BRCM_CPU_PART_BRAHMA_B53 0x100
+#define BRCM_CPU_PART_VULCAN 0x516
+
+#define QCOM_CPU_PART_FALKOR_V1 0x800
+#define QCOM_CPU_PART_FALKOR 0xC00
+#define QCOM_CPU_PART_KRYO 0x200
+#define QCOM_CPU_PART_KRYO_2XX_GOLD 0x800
+#define QCOM_CPU_PART_KRYO_2XX_SILVER 0x801
+#define QCOM_CPU_PART_KRYO_3XX_SILVER 0x803
+#define QCOM_CPU_PART_KRYO_4XX_GOLD 0x804
+#define QCOM_CPU_PART_KRYO_4XX_SILVER 0x805
+
+#define NVIDIA_CPU_PART_DENVER 0x003
+#define NVIDIA_CPU_PART_CARMEL 0x004
+
+#define FUJITSU_CPU_PART_A64FX 0x001
+
+#define HISI_CPU_PART_TSV110 0xD01
+
+#define APPLE_CPU_PART_M1_ICESTORM 0x022
+#define APPLE_CPU_PART_M1_FIRESTORM 0x023
+#define APPLE_CPU_PART_M1_ICESTORM_PRO 0x024
+#define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025
+#define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028
+#define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029
+#define APPLE_CPU_PART_M2_BLIZZARD 0x032
+#define APPLE_CPU_PART_M2_AVALANCHE 0x033
+
+#define AMPERE_CPU_PART_AMPERE1 0xAC3
+
+#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
+#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
+#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
+#define MIDR_CORTEX_A75 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A75)
+#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
+#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
+#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
+#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
+#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
+#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
+#define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE)
+#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
+#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
+#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
+#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
+#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
+#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
+#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
+#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
+#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
+#define MIDR_OCTX2_98XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_98XX)
+#define MIDR_OCTX2_96XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_96XX)
+#define MIDR_OCTX2_95XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XX)
+#define MIDR_OCTX2_95XXN MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXN)
+#define MIDR_OCTX2_95XXMM MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXMM)
+#define MIDR_OCTX2_95XXO MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_OCTX2_95XXO)
+#define MIDR_CAVIUM_THUNDERX2 MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX2)
+#define MIDR_BRAHMA_B53 MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_BRAHMA_B53)
+#define MIDR_BRCM_VULCAN MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN)
+#define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1)
+#define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR)
+#define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO)
+#define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_GOLD)
+#define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_SILVER)
+#define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER)
+#define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD)
+#define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
+#define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER)
+#define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
+#define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)
+#define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110)
+#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)
+#define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)
+#define MIDR_APPLE_M1_ICESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO)
+#define MIDR_APPLE_M1_FIRESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO)
+#define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX)
+#define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX)
+#define MIDR_APPLE_M2_BLIZZARD MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD)
+#define MIDR_APPLE_M2_AVALANCHE MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE)
+#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
+
+#endif
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 03/17] Update psci.h to Linux 6.5-rc1
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 01/17] Import arm-smccc.h from Linux 6.5-rc1 Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 02/17] aarch64: Copy cputype.h " Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 04/17] arm: Stash kvm_vcpu_init for later use Oliver Upton
` (14 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
In order to do PSCI emulation in kvmtool, we're going to need to pull in
a few more definitions.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
include/linux/psci.h | 47 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 310d83e0a91b..42a40ad3fb62 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* ARM Power State and Coordination Interface (PSCI) header
*
@@ -46,6 +47,28 @@
#define PSCI_0_2_FN64_MIGRATE PSCI_0_2_FN64(5)
#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7)
+#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10)
+#define PSCI_1_0_FN_CPU_FREEZE PSCI_0_2_FN(11)
+#define PSCI_1_0_FN_CPU_DEFAULT_SUSPEND PSCI_0_2_FN(12)
+#define PSCI_1_0_FN_NODE_HW_STATE PSCI_0_2_FN(13)
+#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14)
+#define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15)
+#define PSCI_1_0_FN_STAT_RESIDENCY PSCI_0_2_FN(16)
+#define PSCI_1_0_FN_STAT_COUNT PSCI_0_2_FN(17)
+
+#define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18)
+#define PSCI_1_1_FN_MEM_PROTECT PSCI_0_2_FN(19)
+#define PSCI_1_1_FN_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN(20)
+
+#define PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND PSCI_0_2_FN64(12)
+#define PSCI_1_0_FN64_NODE_HW_STATE PSCI_0_2_FN64(13)
+#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14)
+#define PSCI_1_0_FN64_STAT_RESIDENCY PSCI_0_2_FN64(16)
+#define PSCI_1_0_FN64_STAT_COUNT PSCI_0_2_FN64(17)
+
+#define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18)
+#define PSCI_1_1_FN64_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN64(20)
+
/* PSCI v0.2 power state encoding for CPU_SUSPEND function */
#define PSCI_0_2_POWER_STATE_ID_MASK 0xffff
#define PSCI_0_2_POWER_STATE_ID_SHIFT 0
@@ -56,6 +79,13 @@
#define PSCI_0_2_POWER_STATE_AFFL_MASK \
(0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
+/* PSCI extended power state encoding for CPU_SUSPEND function */
+#define PSCI_1_0_EXT_POWER_STATE_ID_MASK 0xfffffff
+#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT 0
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT 30
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK \
+ (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT)
+
/* PSCI v0.2 affinity level state returned by AFFINITY_INFO */
#define PSCI_0_2_AFFINITY_LEVEL_ON 0
#define PSCI_0_2_AFFINITY_LEVEL_OFF 1
@@ -66,6 +96,10 @@
#define PSCI_0_2_TOS_UP_NO_MIGRATE 1
#define PSCI_0_2_TOS_MP 2
+/* PSCI v1.1 reset type encoding for SYSTEM_RESET2 */
+#define PSCI_1_1_RESET_TYPE_SYSTEM_WARM_RESET 0
+#define PSCI_1_1_RESET_TYPE_VENDOR_START 0x80000000U
+
/* PSCI version decoding (independent of PSCI version) */
#define PSCI_VERSION_MAJOR_SHIFT 16
#define PSCI_VERSION_MINOR_MASK \
@@ -75,6 +109,18 @@
(((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT)
#define PSCI_VERSION_MINOR(ver) \
((ver) & PSCI_VERSION_MINOR_MASK)
+#define PSCI_VERSION(maj, min) \
+ ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \
+ ((min) & PSCI_VERSION_MINOR_MASK))
+
+/* PSCI features decoding (>=1.0) */
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK \
+ (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT)
+
+#define PSCI_1_0_OS_INITIATED BIT(0)
+#define PSCI_1_0_SUSPEND_MODE_PC 0
+#define PSCI_1_0_SUSPEND_MODE_OSI 1
/* PSCI return values (inclusive of all PSCI versions) */
#define PSCI_RET_SUCCESS 0
@@ -86,5 +132,6 @@
#define PSCI_RET_INTERNAL_FAILURE -6
#define PSCI_RET_NOT_PRESENT -7
#define PSCI_RET_DISABLED -8
+#define PSCI_RET_INVALID_ADDRESS -9
#endif /* _UAPI_LINUX_PSCI_H */
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 04/17] arm: Stash kvm_vcpu_init for later use
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (2 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 03/17] Update psci.h to " Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 05/17] arm: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs Oliver Upton
` (13 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
A subsequent change will add support for resetting a vCPU, which
requires reissuing the KVM_ARM_VCPU_INIT ioctl. Save the kvm_vcpu_init
worked out for later use.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/include/arm-common/kvm-cpu-arch.h | 2 +-
arm/kvm-cpu.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arm/include/arm-common/kvm-cpu-arch.h b/arm/include/arm-common/kvm-cpu-arch.h
index 923d2c4c7ad3..bf5223eaa851 100644
--- a/arm/include/arm-common/kvm-cpu-arch.h
+++ b/arm/include/arm-common/kvm-cpu-arch.h
@@ -11,7 +11,7 @@ struct kvm_cpu {
pthread_t thread;
unsigned long cpu_id;
- unsigned long cpu_type;
+ struct kvm_vcpu_init init;
const char *cpu_compatible;
struct kvm *kvm;
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index a43eb90a7642..0769eef198ac 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -114,7 +114,7 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
/* Populate the vcpu structure. */
vcpu->kvm = kvm;
vcpu->cpu_id = cpu_id;
- vcpu->cpu_type = vcpu_init.target;
+ vcpu->init = vcpu_init;
vcpu->cpu_compatible = target->compatible;
vcpu->is_running = true;
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 05/17] arm: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (3 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 04/17] arm: Stash kvm_vcpu_init for later use Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 06/17] aarch64: Expose ARM64_CORE_REG() for general use Oliver Upton
` (12 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Using the POWER_OFF flag in kvm_vcpu_init gets in the way of resetting a
vCPU in response to a PSCI CPU_ON call, for obvious reasons. Drop the
flag in favor of using the KVM_SET_MP_STATE call for non-boot vCPUs.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/kvm-cpu.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 0769eef198ac..7934d7994b52 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -63,10 +63,6 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
if (vcpu->kvm_run == MAP_FAILED)
die("unable to mmap vcpu fd");
- /* VCPU 0 is the boot CPU, the others start in a poweroff state. */
- if (cpu_id > 0)
- vcpu_init.features[0] |= (1UL << KVM_ARM_VCPU_POWER_OFF);
-
/* Set KVM_ARM_VCPU_PSCI_0_2 if available */
if (kvm__supports_extension(kvm, KVM_CAP_ARM_PSCI_0_2)) {
vcpu_init.features[0] |= (1UL << KVM_ARM_VCPU_PSCI_0_2);
@@ -121,6 +117,16 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
if (err || target->init(vcpu))
die("Unable to initialise vcpu");
+ /* VCPU 0 is the boot CPU, the others start in a poweroff state. */
+ if (cpu_id > 0) {
+ struct kvm_mp_state mp_state = {
+ .mp_state = KVM_MP_STATE_STOPPED,
+ };
+
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_MP_STATE, &mp_state))
+ die_perror("KVM_SET_MP_STATE failed");
+ }
+
coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION,
KVM_CAP_COALESCED_MMIO);
if (coalesced_offset)
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 06/17] aarch64: Expose ARM64_CORE_REG() for general use
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (4 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 05/17] arm: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 07/17] arm: Generalize execution state specific VM initialization Oliver Upton
` (11 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Expose the macro such that it may be used to get SMCCC arguments in a
future change.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/include/kvm/kvm-cpu-arch.h | 16 ++++++++++++++++
arm/aarch64/kvm-cpu.c | 16 ----------------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/arm/aarch64/include/kvm/kvm-cpu-arch.h b/arm/aarch64/include/kvm/kvm-cpu-arch.h
index aeae8c138bba..264d0016f7db 100644
--- a/arm/aarch64/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch64/include/kvm/kvm-cpu-arch.h
@@ -11,6 +11,22 @@
#define ARM_CPU_CTRL 3, 0, 1, 0
#define ARM_CPU_CTRL_SCTLR_EL1 0
+static inline __u64 __core_reg_id(__u64 offset)
+{
+ __u64 id = KVM_REG_ARM64 | KVM_REG_ARM_CORE | offset;
+
+ if (offset < KVM_REG_ARM_CORE_REG(fp_regs))
+ id |= KVM_REG_SIZE_U64;
+ else if (offset < KVM_REG_ARM_CORE_REG(fp_regs.fpsr))
+ id |= KVM_REG_SIZE_U128;
+ else
+ id |= KVM_REG_SIZE_U32;
+
+ return id;
+}
+
+#define ARM64_CORE_REG(x) __core_reg_id(KVM_REG_ARM_CORE_REG(x))
+
void kvm_cpu__select_features(struct kvm *kvm, struct kvm_vcpu_init *init);
int kvm_cpu__configure_features(struct kvm_cpu *vcpu);
int kvm_cpu__setup_pvtime(struct kvm_cpu *vcpu);
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index c8be10b3ca94..1e5a6cfdaf40 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -12,22 +12,6 @@
#define SCTLR_EL1_E0E_MASK (1 << 24)
#define SCTLR_EL1_EE_MASK (1 << 25)
-static __u64 __core_reg_id(__u64 offset)
-{
- __u64 id = KVM_REG_ARM64 | KVM_REG_ARM_CORE | offset;
-
- if (offset < KVM_REG_ARM_CORE_REG(fp_regs))
- id |= KVM_REG_SIZE_U64;
- else if (offset < KVM_REG_ARM_CORE_REG(fp_regs.fpsr))
- id |= KVM_REG_SIZE_U128;
- else
- id |= KVM_REG_SIZE_U32;
-
- return id;
-}
-
-#define ARM64_CORE_REG(x) __core_reg_id(KVM_REG_ARM_CORE_REG(x))
-
unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu)
{
struct kvm_one_reg reg;
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 07/17] arm: Generalize execution state specific VM initialization
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (5 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 06/17] aarch64: Expose ARM64_CORE_REG() for general use Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 08/17] Add helpers to pause the VM from vCPU thread Oliver Upton
` (10 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
The current state of MTE initialization sticks out a bit: an
MTE-specific init routine is implemented for both aarch32 and aarch64.
Generalize on the notion of execution state specific VM initialization
in preparation for SMCCC filter creation, as the feature is only present
on aarch64.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch32/include/kvm/kvm-arch.h | 2 +-
arm/aarch64/include/kvm/kvm-arch.h | 1 -
arm/aarch64/kvm.c | 7 ++++++-
arm/include/arm-common/kvm-arch.h | 2 ++
arm/kvm.c | 2 +-
5 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
index 467fb09175b8..c02fbea9f2fc 100644
--- a/arm/aarch32/include/kvm/kvm-arch.h
+++ b/arm/aarch32/include/kvm/kvm-arch.h
@@ -6,7 +6,7 @@
#define kvm__arch_get_kern_offset(...) 0x8000
struct kvm;
-static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
+static inline void __kvm__arm_init(struct kvm *kvm) {}
#define MAX_PAGE_SIZE SZ_4K
diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index 02d09a413831..0d3b169b3c93 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -6,7 +6,6 @@
struct kvm;
unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
int kvm__arch_get_ipa_limit(struct kvm *kvm);
-void kvm__arch_enable_mte(struct kvm *kvm);
#define MAX_PAGE_SIZE SZ_64K
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 54200c9eec9d..848e6909994a 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -134,7 +134,7 @@ int kvm__get_vm_type(struct kvm *kvm)
return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
}
-void kvm__arch_enable_mte(struct kvm *kvm)
+static void kvm__arch_enable_mte(struct kvm *kvm)
{
struct kvm_enable_cap cap = {
.cap = KVM_CAP_ARM_MTE,
@@ -160,3 +160,8 @@ void kvm__arch_enable_mte(struct kvm *kvm)
pr_debug("MTE capability enabled");
}
+
+void __kvm__arm_init(struct kvm *kvm)
+{
+ kvm__arch_enable_mte(kvm);
+}
diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h
index 60eec02c1d10..00c4b74c9d41 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -110,4 +110,6 @@ struct kvm_arch {
cpu_set_t *vcpu_affinity_cpuset;
};
+void __kvm__arm_init(struct kvm *kvm);
+
#endif /* ARM_COMMON__KVM_ARCH_H */
diff --git a/arm/kvm.c b/arm/kvm.c
index 9f9582326401..7042d0900664 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -93,7 +93,7 @@ void kvm__arch_init(struct kvm *kvm)
if (gic__create(kvm, kvm->cfg.arch.irqchip))
die("Failed to create virtual GIC");
- kvm__arch_enable_mte(kvm);
+ __kvm__arm_init(kvm);
}
#define FDT_ALIGN SZ_2M
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 08/17] Add helpers to pause the VM from vCPU thread
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (6 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 07/17] arm: Generalize execution state specific VM initialization Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-09-18 10:40 ` Will Deacon
2023-08-02 23:42 ` [PATCH kvmtool v3 09/17] aarch64: Add support for finding vCPU for given MPIDR Oliver Upton
` (9 subsequent siblings)
17 siblings, 1 reply; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Pausing the VM from a vCPU thread is perilous with the current helpers,
as it waits indefinitely for a signal that never comes when invoked from
a vCPU thread. Instead, add a helper for pausing the VM from a vCPU,
working around the issue by explicitly marking the caller as paused
before proceeding.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
include/kvm/kvm-cpu.h | 3 +++
kvm-cpu.c | 16 ++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/include/kvm/kvm-cpu.h b/include/kvm/kvm-cpu.h
index 0f16f8d6e872..9a4901bf94ca 100644
--- a/include/kvm/kvm-cpu.h
+++ b/include/kvm/kvm-cpu.h
@@ -29,4 +29,7 @@ void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu);
void kvm_cpu__arch_nmi(struct kvm_cpu *cpu);
void kvm_cpu__run_on_all_cpus(struct kvm *kvm, struct kvm_cpu_task *task);
+void kvm_cpu__pause_vm(struct kvm_cpu *vcpu);
+void kvm_cpu__continue_vm(struct kvm_cpu *vcpu);
+
#endif /* KVM__KVM_CPU_H */
diff --git a/kvm-cpu.c b/kvm-cpu.c
index 1c566b3f21d6..9adc9d4f7841 100644
--- a/kvm-cpu.c
+++ b/kvm-cpu.c
@@ -141,6 +141,22 @@ void kvm_cpu__run_on_all_cpus(struct kvm *kvm, struct kvm_cpu_task *task)
mutex_unlock(&task_lock);
}
+void kvm_cpu__pause_vm(struct kvm_cpu *vcpu)
+{
+ /*
+ * Mark the calling vCPU as paused to avoid waiting indefinitely for a
+ * signal exit.
+ */
+ vcpu->paused = true;
+ kvm__pause(vcpu->kvm);
+}
+
+void kvm_cpu__continue_vm(struct kvm_cpu *vcpu)
+{
+ vcpu->paused = false;
+ kvm__continue(vcpu->kvm);
+}
+
int kvm_cpu__start(struct kvm_cpu *cpu)
{
sigset_t sigset;
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH kvmtool v3 08/17] Add helpers to pause the VM from vCPU thread
2023-08-02 23:42 ` [PATCH kvmtool v3 08/17] Add helpers to pause the VM from vCPU thread Oliver Upton
@ 2023-09-18 10:40 ` Will Deacon
2023-09-18 17:05 ` Oliver Upton
0 siblings, 1 reply; 21+ messages in thread
From: Will Deacon @ 2023-09-18 10:40 UTC (permalink / raw)
To: Oliver Upton
Cc: kvmarm, kvm, Marc Zyngier, James Morse, Suzuki K Poulose,
Zenghui Yu, Julien Thierry, Salil Mehta
On Wed, Aug 02, 2023 at 11:42:46PM +0000, Oliver Upton wrote:
> Pausing the VM from a vCPU thread is perilous with the current helpers,
> as it waits indefinitely for a signal that never comes when invoked from
> a vCPU thread. Instead, add a helper for pausing the VM from a vCPU,
> working around the issue by explicitly marking the caller as paused
> before proceeding.
>
> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> ---
> include/kvm/kvm-cpu.h | 3 +++
> kvm-cpu.c | 16 ++++++++++++++++
> 2 files changed, 19 insertions(+)
>
> diff --git a/include/kvm/kvm-cpu.h b/include/kvm/kvm-cpu.h
> index 0f16f8d6e872..9a4901bf94ca 100644
> --- a/include/kvm/kvm-cpu.h
> +++ b/include/kvm/kvm-cpu.h
> @@ -29,4 +29,7 @@ void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu);
> void kvm_cpu__arch_nmi(struct kvm_cpu *cpu);
> void kvm_cpu__run_on_all_cpus(struct kvm *kvm, struct kvm_cpu_task *task);
>
> +void kvm_cpu__pause_vm(struct kvm_cpu *vcpu);
> +void kvm_cpu__continue_vm(struct kvm_cpu *vcpu);
> +
> #endif /* KVM__KVM_CPU_H */
> diff --git a/kvm-cpu.c b/kvm-cpu.c
> index 1c566b3f21d6..9adc9d4f7841 100644
> --- a/kvm-cpu.c
> +++ b/kvm-cpu.c
> @@ -141,6 +141,22 @@ void kvm_cpu__run_on_all_cpus(struct kvm *kvm, struct kvm_cpu_task *task)
> mutex_unlock(&task_lock);
> }
>
> +void kvm_cpu__pause_vm(struct kvm_cpu *vcpu)
> +{
> + /*
> + * Mark the calling vCPU as paused to avoid waiting indefinitely for a
> + * signal exit.
> + */
> + vcpu->paused = true;
> + kvm__pause(vcpu->kvm);
> +}
> +
> +void kvm_cpu__continue_vm(struct kvm_cpu *vcpu)
> +{
> + vcpu->paused = false;
> + kvm__continue(vcpu->kvm);
> +}
Why is it safe to manipulate 'vcpu->paused' here without the pause_lock
held? Relatedly, how does this interact with the 'pause' and 'resume'
lkvm commands?
Will
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH kvmtool v3 08/17] Add helpers to pause the VM from vCPU thread
2023-09-18 10:40 ` Will Deacon
@ 2023-09-18 17:05 ` Oliver Upton
0 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-09-18 17:05 UTC (permalink / raw)
To: Will Deacon
Cc: kvmarm, kvm, Marc Zyngier, James Morse, Suzuki K Poulose,
Zenghui Yu, Julien Thierry, Salil Mehta
Hey Will,
On Mon, Sep 18, 2023 at 11:40:28AM +0100, Will Deacon wrote:
> On Wed, Aug 02, 2023 at 11:42:46PM +0000, Oliver Upton wrote:
> > +void kvm_cpu__pause_vm(struct kvm_cpu *vcpu)
> > +{
> > + /*
> > + * Mark the calling vCPU as paused to avoid waiting indefinitely for a
> > + * signal exit.
> > + */
> > + vcpu->paused = true;
> > + kvm__pause(vcpu->kvm);
> > +}
> > +
> > +void kvm_cpu__continue_vm(struct kvm_cpu *vcpu)
> > +{
> > + vcpu->paused = false;
> > + kvm__continue(vcpu->kvm);
> > +}
>
> Why is it safe to manipulate 'vcpu->paused' here without the pause_lock
> held?
Heh, I hacked this up to get _something_ working and never re-evaluated
the locking that I completely sidestepped.
> Relatedly, how does this interact with the 'pause' and 'resume'
> lkvm commands?
Poorly, if I had to guess. I hadn't actually tested with them. I'll take
another crack at this to safely quiesce when handling calls.
Thanks for having a look.
--
Best,
Oliver
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH kvmtool v3 09/17] aarch64: Add support for finding vCPU for given MPIDR
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (7 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 08/17] Add helpers to pause the VM from vCPU thread Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 10/17] aarch64: Add skeleton implementation for PSCI Oliver Upton
` (8 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Some PSCI calls take an MPIDR affinity as an argument. Add a helper to
get the vCPU that matches an MPIDR so we can find the intended
recipient.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/include/kvm/kvm-arch.h | 1 +
arm/aarch64/kvm.c | 16 ++++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index 0d3b169b3c93..dacbc9286f50 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -6,6 +6,7 @@
struct kvm;
unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
int kvm__arch_get_ipa_limit(struct kvm *kvm);
+struct kvm_cpu *kvm__arch_mpidr_to_vcpu(struct kvm *kvm, u64 target_mpidr);
#define MAX_PAGE_SIZE SZ_64K
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 848e6909994a..4929ce48843b 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -1,4 +1,5 @@
#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
#include <asm/image.h>
@@ -165,3 +166,18 @@ void __kvm__arm_init(struct kvm *kvm)
{
kvm__arch_enable_mte(kvm);
}
+
+struct kvm_cpu *kvm__arch_mpidr_to_vcpu(struct kvm *kvm, u64 target_mpidr)
+{
+ int i;
+
+ for (i = 0; i < kvm->nrcpus; i++) {
+ struct kvm_cpu *tmp = kvm->cpus[i];
+ u64 mpidr = kvm_cpu__get_vcpu_mpidr(tmp) & ARM_MPIDR_HWID_BITMASK;
+
+ if (mpidr == target_mpidr)
+ return tmp;
+ }
+
+ return NULL;
+}
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 10/17] aarch64: Add skeleton implementation for PSCI
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (8 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 09/17] aarch64: Add support for finding vCPU for given MPIDR Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 11/17] aarch64: psci: Implement CPU_SUSPEND Oliver Upton
` (7 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Add an extremely barebones implementation for handling PSCI, where the
only supported call is PSCI_VERSION.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
Makefile | 4 +-
arm/aarch32/kvm-cpu.c | 5 +++
arm/aarch64/include/asm/smccc.h | 65 +++++++++++++++++++++++++++++++++
arm/aarch64/kvm-cpu.c | 14 +++++++
arm/aarch64/kvm.c | 2 +
arm/aarch64/psci.c | 36 ++++++++++++++++++
arm/aarch64/smccc.c | 44 ++++++++++++++++++++++
arm/kvm-cpu.c | 5 ---
8 files changed, 169 insertions(+), 6 deletions(-)
create mode 100644 arm/aarch64/include/asm/smccc.h
create mode 100644 arm/aarch64/psci.c
create mode 100644 arm/aarch64/smccc.c
diff --git a/Makefile b/Makefile
index e711670d081a..4b71fadd3928 100644
--- a/Makefile
+++ b/Makefile
@@ -192,8 +192,10 @@ ifeq ($(ARCH), arm64)
OBJS += arm/aarch64/arm-cpu.o
OBJS += arm/aarch64/kvm-cpu.o
OBJS += arm/aarch64/kvm.o
- OBJS += arm/aarch64/pvtime.o
OBJS += arm/aarch64/pmu.o
+ OBJS += arm/aarch64/psci.o
+ OBJS += arm/aarch64/pvtime.o
+ OBJS += arm/aarch64/smccc.o
ARCH_INCLUDE := $(HDRS_ARM_COMMON)
ARCH_INCLUDE += -Iarm/aarch64/include
diff --git a/arm/aarch32/kvm-cpu.c b/arm/aarch32/kvm-cpu.c
index 95fb1da5ba3d..1063b9e5b6a9 100644
--- a/arm/aarch32/kvm-cpu.c
+++ b/arm/aarch32/kvm-cpu.c
@@ -130,3 +130,8 @@ void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
die("KVM_GET_ONE_REG failed (LR_svc)");
dprintf(debug_fd, " LR_svc: 0x%x\n", data);
}
+
+bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
+{
+ return false;
+}
diff --git a/arm/aarch64/include/asm/smccc.h b/arm/aarch64/include/asm/smccc.h
new file mode 100644
index 000000000000..c1be21a7d6f6
--- /dev/null
+++ b/arm/aarch64/include/asm/smccc.h
@@ -0,0 +1,65 @@
+#ifndef __ARM_SMCCC_H__
+#define __ARM_SMCCC_H__
+
+#include "kvm/kvm-cpu.h"
+
+#include <linux/arm-smccc.h>
+#include <linux/types.h>
+
+static inline bool smccc_is_64bit(struct kvm_cpu *vcpu)
+{
+ return ARM_SMCCC_IS_64(vcpu->kvm_run->hypercall.nr);
+}
+
+static inline bool smccc_calling_conv_allowed(struct kvm_cpu *vcpu, u32 fn)
+{
+ return !(vcpu->kvm->cfg.arch.aarch32_guest && ARM_SMCCC_IS_64(fn));
+}
+
+static inline u64 smccc_get_arg(struct kvm_cpu *vcpu, u8 arg)
+{
+ u64 val;
+ struct kvm_one_reg reg = {
+ .id = ARM64_CORE_REG(regs.regs[arg]),
+ .addr = (u64)&val,
+ };
+
+ if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®))
+ die_perror("KVM_GET_ONE_REG failed");
+
+ if (!smccc_is_64bit(vcpu))
+ val = (u32)val;
+
+ return val;
+}
+
+static inline void smccc_return_result(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
+{
+ unsigned long *vals = (unsigned long *)res;
+ unsigned long i;
+
+ /*
+ * The author was lazy and chose to abuse the layout of struct
+ * arm_smccc_res to write a loop set the retvals.
+ */
+ for (i = 0; i < sizeof(*res) / sizeof(unsigned long); i++) {
+ u64 val = vals[i];
+ struct kvm_one_reg reg = {
+ .id = ARM64_CORE_REG(regs.regs[i]),
+ .addr = (u64)&val,
+ };
+
+ if (!smccc_is_64bit(vcpu))
+ val = (u32)val;
+
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®))
+ die_perror("KVM_SET_ONE_REG failed");
+ }
+}
+
+bool handle_hypercall(struct kvm_cpu *vcpu);
+void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res);
+
+void kvm__setup_smccc(struct kvm *kvm);
+
+#endif /* __ARM_SMCCC_H__ */
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 1e5a6cfdaf40..4feed9f41cb0 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -1,3 +1,4 @@
+#include "asm/smccc.h"
#include "kvm/kvm-cpu.h"
#include "kvm/kvm.h"
#include "kvm/virtio.h"
@@ -261,3 +262,16 @@ void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
die("KVM_GET_ONE_REG failed (lr)");
dprintf(debug_fd, " LR: 0x%lx\n", data);
}
+
+bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
+{
+ struct kvm_run *run = vcpu->kvm_run;
+
+ switch (run->exit_reason) {
+ case KVM_EXIT_HYPERCALL:
+ handle_hypercall(vcpu);
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 4929ce48843b..ce917ed01349 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -1,3 +1,4 @@
+#include "asm/smccc.h"
#include "kvm/kvm.h"
#include "kvm/kvm-cpu.h"
@@ -165,6 +166,7 @@ static void kvm__arch_enable_mte(struct kvm *kvm)
void __kvm__arm_init(struct kvm *kvm)
{
kvm__arch_enable_mte(kvm);
+ kvm__setup_smccc(kvm);
}
struct kvm_cpu *kvm__arch_mpidr_to_vcpu(struct kvm *kvm, u64 target_mpidr)
diff --git a/arm/aarch64/psci.c b/arm/aarch64/psci.c
new file mode 100644
index 000000000000..482b9a7442c6
--- /dev/null
+++ b/arm/aarch64/psci.c
@@ -0,0 +1,36 @@
+#include "asm/smccc.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+
+#include <linux/psci.h>
+#include <linux/types.h>
+
+static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
+{
+ u32 arg = smccc_get_arg(vcpu, 1);
+
+ res->a0 = PSCI_RET_NOT_SUPPORTED;
+ if (!smccc_calling_conv_allowed(vcpu, arg))
+ return;
+
+ switch (arg) {
+ case ARM_SMCCC_VERSION_FUNC_ID:
+ res->a0 = PSCI_RET_SUCCESS;
+ break;
+ }
+}
+
+void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
+{
+ switch (vcpu->kvm_run->hypercall.nr) {
+ case PSCI_0_2_FN_PSCI_VERSION:
+ res->a0 = PSCI_VERSION(1, 0);
+ break;
+ case PSCI_1_0_FN_PSCI_FEATURES:
+ psci_features(vcpu, res);
+ break;
+ default:
+ res->a0 = PSCI_RET_NOT_SUPPORTED;
+ }
+}
diff --git a/arm/aarch64/smccc.c b/arm/aarch64/smccc.c
new file mode 100644
index 000000000000..ef986d8c526f
--- /dev/null
+++ b/arm/aarch64/smccc.c
@@ -0,0 +1,44 @@
+#include "asm/smccc.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+
+#include <linux/types.h>
+
+static void handle_std_call(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
+{
+ u32 fn = vcpu->kvm_run->hypercall.nr;
+
+ switch (ARM_SMCCC_FUNC_NUM(fn)) {
+ /* PSCI */
+ case 0x00 ... 0x1F:
+ handle_psci(vcpu, res);
+ break;
+ }
+}
+
+bool handle_hypercall(struct kvm_cpu *vcpu)
+{
+ u32 fn = vcpu->kvm_run->hypercall.nr;
+ struct arm_smccc_res res = {
+ .a0 = SMCCC_RET_NOT_SUPPORTED,
+ };
+
+ if (!smccc_calling_conv_allowed(vcpu, fn))
+ goto out;
+
+ switch (ARM_SMCCC_OWNER_NUM(fn)) {
+ case ARM_SMCCC_OWNER_STANDARD:
+ handle_std_call(vcpu, &res);
+ break;
+ }
+
+out:
+ smccc_return_result(vcpu, &res);
+ return true;
+}
+
+void kvm__setup_smccc(struct kvm *kvm)
+{
+
+}
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 7934d7994b52..9eebfa6417e3 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -149,11 +149,6 @@ void kvm_cpu__delete(struct kvm_cpu *vcpu)
free(vcpu);
}
-bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
-{
- return false;
-}
-
void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
{
}
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 11/17] aarch64: psci: Implement CPU_SUSPEND
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (9 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 10/17] aarch64: Add skeleton implementation for PSCI Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 12/17] aarch64: psci: Implement CPU_OFF Oliver Upton
` (6 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Implement support for PSCI CPU_SUSPEND, leveraging in-kernel suspend
emulation (i.e. a WFI state). Eagerly resume the vCPU for any wakeup
event.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/kvm-cpu.c | 18 ++++++++++++++++++
arm/aarch64/psci.c | 19 +++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 4feed9f41cb0..316e20c7f157 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -263,6 +263,16 @@ void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
dprintf(debug_fd, " LR: 0x%lx\n", data);
}
+static void handle_wakeup(struct kvm_cpu *vcpu)
+{
+ struct kvm_mp_state mp_state = {
+ .mp_state = KVM_MP_STATE_RUNNABLE,
+ };
+
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_MP_STATE, &mp_state))
+ die_perror("KVM_SET_MP_STATE failed");
+}
+
bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
{
struct kvm_run *run = vcpu->kvm_run;
@@ -271,6 +281,14 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
case KVM_EXIT_HYPERCALL:
handle_hypercall(vcpu);
return true;
+ case KVM_EXIT_SYSTEM_EVENT:
+ switch (run->system_event.type) {
+ case KVM_SYSTEM_EVENT_WAKEUP:
+ handle_wakeup(vcpu);
+ return true;
+ default:
+ return false;
+ }
default:
return false;
}
diff --git a/arm/aarch64/psci.c b/arm/aarch64/psci.c
index 482b9a7442c6..abfdc764b7e0 100644
--- a/arm/aarch64/psci.c
+++ b/arm/aarch64/psci.c
@@ -15,12 +15,27 @@ static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
return;
switch (arg) {
+ case PSCI_0_2_FN_CPU_SUSPEND:
+ case PSCI_0_2_FN64_CPU_SUSPEND:
case ARM_SMCCC_VERSION_FUNC_ID:
res->a0 = PSCI_RET_SUCCESS;
break;
}
}
+static void cpu_suspend(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
+{
+ struct kvm_mp_state mp_state = {
+ .mp_state = KVM_MP_STATE_SUSPENDED,
+ };
+
+ /* Rely on in-kernel emulation of a 'suspended' (i.e. WFI) state. */
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_MP_STATE, &mp_state))
+ die_perror("KVM_SET_MP_STATE failed");
+
+ res->a0 = PSCI_RET_SUCCESS;
+}
+
void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
{
switch (vcpu->kvm_run->hypercall.nr) {
@@ -30,6 +45,10 @@ void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_1_0_FN_PSCI_FEATURES:
psci_features(vcpu, res);
break;
+ case PSCI_0_2_FN_CPU_SUSPEND:
+ case PSCI_0_2_FN64_CPU_SUSPEND:
+ cpu_suspend(vcpu, res);
+ break;
default:
res->a0 = PSCI_RET_NOT_SUPPORTED;
}
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 12/17] aarch64: psci: Implement CPU_OFF
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (10 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 11/17] aarch64: psci: Implement CPU_SUSPEND Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 13/17] aarch64: psci: Implement CPU_ON Oliver Upton
` (5 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Add support for PSCI CPU_OFF, relying on KVM emulation of a 'powered
off' vCPU by setting the MP state to KVM_MP_STATE_STOPPED.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/psci.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arm/aarch64/psci.c b/arm/aarch64/psci.c
index abfdc764b7e0..72429b36a835 100644
--- a/arm/aarch64/psci.c
+++ b/arm/aarch64/psci.c
@@ -17,6 +17,7 @@ static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
switch (arg) {
case PSCI_0_2_FN_CPU_SUSPEND:
case PSCI_0_2_FN64_CPU_SUSPEND:
+ case PSCI_0_2_FN_CPU_OFF:
case ARM_SMCCC_VERSION_FUNC_ID:
res->a0 = PSCI_RET_SUCCESS;
break;
@@ -36,6 +37,16 @@ static void cpu_suspend(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
res->a0 = PSCI_RET_SUCCESS;
}
+static void cpu_off(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
+{
+ struct kvm_mp_state mp_state = {
+ .mp_state = KVM_MP_STATE_STOPPED,
+ };
+
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_MP_STATE, &mp_state))
+ die_perror("KVM_SET_MP_STATE failed");
+}
+
void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
{
switch (vcpu->kvm_run->hypercall.nr) {
@@ -49,6 +60,9 @@ void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_0_2_FN64_CPU_SUSPEND:
cpu_suspend(vcpu, res);
break;
+ case PSCI_0_2_FN_CPU_OFF:
+ cpu_off(vcpu, res);
+ break;
default:
res->a0 = PSCI_RET_NOT_SUPPORTED;
}
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 13/17] aarch64: psci: Implement CPU_ON
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (11 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 12/17] aarch64: psci: Implement CPU_OFF Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 14/17] aarch64: psci: Implement AFFINITY_INFO Oliver Upton
` (4 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Add support for the PSCI CPU_ON call, wherein a caller can power on a
targeted CPU and reset it with the provided context (i.e. entrypoint and
context id). Rely on the KVM_ARM_VCPU_INIT ioctl, which has the effect
of an architectural warm reset, to do the heavy lifting.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/psci.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/arm/aarch64/psci.c b/arm/aarch64/psci.c
index 72429b36a835..254e16e7985d 100644
--- a/arm/aarch64/psci.c
+++ b/arm/aarch64/psci.c
@@ -18,6 +18,8 @@ static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_0_2_FN_CPU_SUSPEND:
case PSCI_0_2_FN64_CPU_SUSPEND:
case PSCI_0_2_FN_CPU_OFF:
+ case PSCI_0_2_FN_CPU_ON:
+ case PSCI_0_2_FN64_CPU_ON:
case ARM_SMCCC_VERSION_FUNC_ID:
res->a0 = PSCI_RET_SUCCESS;
break;
@@ -47,6 +49,68 @@ static void cpu_off(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
die_perror("KVM_SET_MP_STATE failed");
}
+static void reset_cpu_with_context(struct kvm_cpu *vcpu, u64 entry_addr, u64 ctx_id)
+{
+ struct kvm_one_reg reg;
+
+ if (ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_INIT, &vcpu->init))
+ die_perror("KVM_ARM_VCPU_INIT failed");
+
+ reg = (struct kvm_one_reg) {
+ .id = ARM64_CORE_REG(regs.pc),
+ .addr = (u64)&entry_addr,
+ };
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®))
+ die_perror("KVM_SET_ONE_REG failed");
+
+ reg = (struct kvm_one_reg) {
+ .id = ARM64_CORE_REG(regs.regs[0]),
+ .addr = (u64)&ctx_id,
+ };
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®))
+ die_perror("KVM_SET_ONE_REG failed");
+}
+
+static bool psci_valid_affinity(u64 affinity)
+{
+ return !(affinity & ~ARM_MPIDR_HWID_BITMASK);
+}
+
+static void cpu_on(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
+{
+ u64 target_mpidr = smccc_get_arg(vcpu, 1);
+ u64 entry_addr = smccc_get_arg(vcpu, 2);
+ u64 ctx_id = smccc_get_arg(vcpu, 3);
+ struct kvm_mp_state mp_state;
+ struct kvm_cpu *target;
+
+ if (!psci_valid_affinity(target_mpidr)) {
+ res->a0 = PSCI_RET_INVALID_PARAMS;
+ return;
+ }
+
+ kvm_cpu__pause_vm(vcpu);
+
+ target = kvm__arch_mpidr_to_vcpu(vcpu->kvm, target_mpidr);
+ if (!target) {
+ res->a0 = PSCI_RET_INVALID_PARAMS;
+ goto out_continue;
+ }
+
+ if (ioctl(target->vcpu_fd, KVM_GET_MP_STATE, &mp_state))
+ die_perror("KVM_GET_MP_STATE failed");
+
+ if (mp_state.mp_state != KVM_MP_STATE_STOPPED) {
+ res->a0 = PSCI_RET_ALREADY_ON;
+ goto out_continue;
+ }
+
+ reset_cpu_with_context(target, entry_addr, ctx_id);
+ res->a0 = PSCI_RET_SUCCESS;
+out_continue:
+ kvm_cpu__continue_vm(vcpu);
+}
+
void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
{
switch (vcpu->kvm_run->hypercall.nr) {
@@ -63,6 +127,10 @@ void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_0_2_FN_CPU_OFF:
cpu_off(vcpu, res);
break;
+ case PSCI_0_2_FN_CPU_ON:
+ case PSCI_0_2_FN64_CPU_ON:
+ cpu_on(vcpu, res);
+ break;
default:
res->a0 = PSCI_RET_NOT_SUPPORTED;
}
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 14/17] aarch64: psci: Implement AFFINITY_INFO
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (12 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 13/17] aarch64: psci: Implement CPU_ON Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 15/17] aarch64: psci: Implement MIGRATE_INFO_TYPE Oliver Upton
` (3 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Implement support for PSCI AFFINITY_INFO by iteratively searching all of
the vCPUs in a VM for those that match the specified affinity. Pause the
VM to avoid racing against other PSCI calls in the system that might
change the power state of the vCPUs.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/include/kvm/kvm-cpu-arch.h | 12 +++++-
arm/aarch64/psci.c | 59 ++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/arm/aarch64/include/kvm/kvm-cpu-arch.h b/arm/aarch64/include/kvm/kvm-cpu-arch.h
index 264d0016f7db..5dced04d4035 100644
--- a/arm/aarch64/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch64/include/kvm/kvm-cpu-arch.h
@@ -5,12 +5,22 @@
#include "arm-common/kvm-cpu-arch.h"
-#define ARM_MPIDR_HWID_BITMASK 0xFF00FFFFFFUL
#define ARM_CPU_ID 3, 0, 0, 0
#define ARM_CPU_ID_MPIDR 5
#define ARM_CPU_CTRL 3, 0, 1, 0
#define ARM_CPU_CTRL_SCTLR_EL1 0
+#define ARM_MPIDR_HWID_BITMASK 0xFF00FFFFFFUL
+#define ARM_MPIDR_LEVEL_BITS_SHIFT 3
+#define ARM_MPIDR_LEVEL_BITS (1 << ARM_MPIDR_LEVEL_BITS_SHIFT)
+#define ARM_MPIDR_LEVEL_MASK ((1 << ARM_MPIDR_LEVEL_BITS) - 1)
+
+#define ARM_MPIDR_LEVEL_SHIFT(level) \
+ (((1 << level) >> 1) << ARM_MPIDR_LEVEL_BITS_SHIFT)
+
+#define ARM_MPIDR_AFFINITY_LEVEL(mpidr, level) \
+ ((mpidr >> ARM_MPIDR_LEVEL_SHIFT(level)) & ARM_MPIDR_LEVEL_MASK)
+
static inline __u64 __core_reg_id(__u64 offset)
{
__u64 id = KVM_REG_ARM64 | KVM_REG_ARM_CORE | offset;
diff --git a/arm/aarch64/psci.c b/arm/aarch64/psci.c
index 254e16e7985d..ac49d7aa8f22 100644
--- a/arm/aarch64/psci.c
+++ b/arm/aarch64/psci.c
@@ -6,6 +6,16 @@
#include <linux/psci.h>
#include <linux/types.h>
+#define AFFINITY_MASK(level) ~((0x1UL << ((level) * ARM_MPIDR_LEVEL_BITS)) - 1)
+
+static unsigned long psci_affinity_mask(unsigned long affinity_level)
+{
+ if (affinity_level <= 3)
+ return ARM_MPIDR_HWID_BITMASK & AFFINITY_MASK(affinity_level);
+
+ return 0;
+}
+
static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
{
u32 arg = smccc_get_arg(vcpu, 1);
@@ -20,6 +30,8 @@ static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_0_2_FN_CPU_OFF:
case PSCI_0_2_FN_CPU_ON:
case PSCI_0_2_FN64_CPU_ON:
+ case PSCI_0_2_FN_AFFINITY_INFO:
+ case PSCI_0_2_FN64_AFFINITY_INFO:
case ARM_SMCCC_VERSION_FUNC_ID:
res->a0 = PSCI_RET_SUCCESS;
break;
@@ -111,6 +123,49 @@ out_continue:
kvm_cpu__continue_vm(vcpu);
}
+static void affinity_info(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
+{
+ u64 target_affinity = smccc_get_arg(vcpu, 1);
+ u64 lowest_level = smccc_get_arg(vcpu, 2);
+ u64 mpidr_mask = psci_affinity_mask(lowest_level);
+ struct kvm *kvm = vcpu->kvm;
+ bool matched = false;
+ int i;
+
+ if (!psci_valid_affinity(target_affinity) || lowest_level > 3) {
+ res->a0 = PSCI_RET_INVALID_PARAMS;
+ return;
+ }
+
+ kvm_cpu__pause_vm(vcpu);
+
+ for (i = 0; i < kvm->nrcpus; i++) {
+ struct kvm_cpu *tmp = kvm->cpus[i];
+ u64 mpidr = kvm_cpu__get_vcpu_mpidr(tmp);
+ struct kvm_mp_state mp_state;
+
+ if ((mpidr & mpidr_mask) != target_affinity)
+ continue;
+
+ if (ioctl(tmp->vcpu_fd, KVM_GET_MP_STATE, &mp_state))
+ die_perror("KVM_GET_MP_STATE failed");
+
+ if (mp_state.mp_state != KVM_MP_STATE_STOPPED) {
+ res->a0 = PSCI_0_2_AFFINITY_LEVEL_ON;
+ goto out_continue;
+ }
+
+ matched = true;
+ }
+
+ if (matched)
+ res->a0 = PSCI_0_2_AFFINITY_LEVEL_OFF;
+ else
+ res->a0 = PSCI_RET_INVALID_PARAMS;
+out_continue:
+ kvm_cpu__continue_vm(vcpu);
+}
+
void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
{
switch (vcpu->kvm_run->hypercall.nr) {
@@ -131,6 +186,10 @@ void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_0_2_FN64_CPU_ON:
cpu_on(vcpu, res);
break;
+ case PSCI_0_2_FN_AFFINITY_INFO:
+ case PSCI_0_2_FN64_AFFINITY_INFO:
+ affinity_info(vcpu, res);
+ break;
default:
res->a0 = PSCI_RET_NOT_SUPPORTED;
}
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 15/17] aarch64: psci: Implement MIGRATE_INFO_TYPE
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (13 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 14/17] aarch64: psci: Implement AFFINITY_INFO Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 16/17] aarch64: psci: Implement SYSTEM_{OFF,RESET} Oliver Upton
` (2 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Let the guest know that our PSCI implementation is entirely oblivious to
the existence of a Trusted OS, and thus shouldn't care about it.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/psci.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arm/aarch64/psci.c b/arm/aarch64/psci.c
index ac49d7aa8f22..bfd4756ea056 100644
--- a/arm/aarch64/psci.c
+++ b/arm/aarch64/psci.c
@@ -32,6 +32,7 @@ static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_0_2_FN64_CPU_ON:
case PSCI_0_2_FN_AFFINITY_INFO:
case PSCI_0_2_FN64_AFFINITY_INFO:
+ case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
case ARM_SMCCC_VERSION_FUNC_ID:
res->a0 = PSCI_RET_SUCCESS;
break;
@@ -190,6 +191,10 @@ void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_0_2_FN64_AFFINITY_INFO:
affinity_info(vcpu, res);
break;
+ case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
+ /* Trusted OS not present */
+ res->a0 = PSCI_0_2_TOS_MP;
+ break;
default:
res->a0 = PSCI_RET_NOT_SUPPORTED;
}
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 16/17] aarch64: psci: Implement SYSTEM_{OFF,RESET}
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (14 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 15/17] aarch64: psci: Implement MIGRATE_INFO_TYPE Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-08-02 23:42 ` [PATCH kvmtool v3 17/17] aarch64: smccc: Start sending PSCI to userspace Oliver Upton
2023-09-13 18:42 ` [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
Add support for the PSCI SYSTEM_{OFF,RESET} calls. Match the behavior of
the SYSTEM_EVENT based implementation and just terminate the VM.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/psci.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arm/aarch64/psci.c b/arm/aarch64/psci.c
index bfd4756ea056..b73c28729ddc 100644
--- a/arm/aarch64/psci.c
+++ b/arm/aarch64/psci.c
@@ -33,6 +33,8 @@ static void psci_features(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
case PSCI_0_2_FN_AFFINITY_INFO:
case PSCI_0_2_FN64_AFFINITY_INFO:
case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
+ case PSCI_0_2_FN_SYSTEM_OFF:
+ case PSCI_0_2_FN_SYSTEM_RESET:
case ARM_SMCCC_VERSION_FUNC_ID:
res->a0 = PSCI_RET_SUCCESS;
break;
@@ -195,6 +197,10 @@ void handle_psci(struct kvm_cpu *vcpu, struct arm_smccc_res *res)
/* Trusted OS not present */
res->a0 = PSCI_0_2_TOS_MP;
break;
+ case PSCI_0_2_FN_SYSTEM_OFF:
+ case PSCI_0_2_FN_SYSTEM_RESET:
+ kvm__reboot(vcpu->kvm);
+ break;
default:
res->a0 = PSCI_RET_NOT_SUPPORTED;
}
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH kvmtool v3 17/17] aarch64: smccc: Start sending PSCI to userspace
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (15 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 16/17] aarch64: psci: Implement SYSTEM_{OFF,RESET} Oliver Upton
@ 2023-08-02 23:42 ` Oliver Upton
2023-09-13 18:42 ` [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-08-02 23:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta, Oliver Upton
kvmtool now has a PSCI implementation that complies with v1.0 of the
specification. Use the SMCCC filter to start sending these calls out to
userspace for further handling. While at it, shut the door on the
legacy, KVM-specific v0.1 functions.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arm/aarch64/include/kvm/kvm-config-arch.h | 6 +++-
arm/aarch64/smccc.c | 37 +++++++++++++++++++++++
arm/include/arm-common/kvm-config-arch.h | 1 +
3 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index eae8080d3fd9..1c40bbac70f5 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -19,7 +19,11 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset);
"Specify random seed for Kernel Address Space " \
"Layout Randomization (KASLR)"), \
OPT_BOOLEAN('\0', "no-pvtime", &(cfg)->no_pvtime, "Disable" \
- " stolen time"),
+ " stolen time"), \
+ OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc, \
+ "Disable userspace handling of SMCCC, instead" \
+ " relying on the in-kernel implementation"),
+
#include "arm-common/kvm-config-arch.h"
#endif /* KVM__KVM_CONFIG_ARCH_H */
diff --git a/arm/aarch64/smccc.c b/arm/aarch64/smccc.c
index ef986d8c526f..62d826befa50 100644
--- a/arm/aarch64/smccc.c
+++ b/arm/aarch64/smccc.c
@@ -38,7 +38,44 @@ out:
return true;
}
+static struct kvm_smccc_filter filter_ranges[] = {
+ {
+ .base = KVM_PSCI_FN_BASE,
+ .nr_functions = 4,
+ .action = KVM_SMCCC_FILTER_DENY,
+ },
+ {
+ .base = PSCI_0_2_FN_BASE,
+ .nr_functions = 0x20,
+ .action = KVM_SMCCC_FILTER_FWD_TO_USER,
+ },
+ {
+ .base = PSCI_0_2_FN64_BASE,
+ .nr_functions = 0x20,
+ .action = KVM_SMCCC_FILTER_FWD_TO_USER,
+ },
+};
+
void kvm__setup_smccc(struct kvm *kvm)
{
+ struct kvm_device_attr attr = {
+ .group = KVM_ARM_VM_SMCCC_CTRL,
+ .attr = KVM_ARM_VM_SMCCC_FILTER,
+ };
+ unsigned int i;
+ if (kvm->cfg.arch.in_kernel_smccc)
+ return;
+
+ if (ioctl(kvm->vm_fd, KVM_HAS_DEVICE_ATTR, &attr)) {
+ pr_debug("KVM SMCCC filter not supported");
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(filter_ranges); i++) {
+ attr.addr = (u64)&filter_ranges[i];
+
+ if (ioctl(kvm->vm_fd, KVM_SET_DEVICE_ATTR, &attr))
+ die_perror("KVM_SET_DEVICE_ATTR failed");
+ }
}
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index 23a74867a474..223b5a933542 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -14,6 +14,7 @@ struct kvm_config_arch {
enum irqchip_type irqchip;
u64 fw_addr;
bool no_pvtime;
+ bool in_kernel_smccc;
};
int irqchip_parser(const struct option *opt, const char *arg, int unset);
--
2.41.0.585.gd2178a4bd4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace
2023-08-02 23:42 [PATCH kvmtool v3 00/17] aarch64: Handle PSCI calls in userspace Oliver Upton
` (16 preceding siblings ...)
2023-08-02 23:42 ` [PATCH kvmtool v3 17/17] aarch64: smccc: Start sending PSCI to userspace Oliver Upton
@ 2023-09-13 18:42 ` Oliver Upton
17 siblings, 0 replies; 21+ messages in thread
From: Oliver Upton @ 2023-09-13 18:42 UTC (permalink / raw)
To: kvmarm
Cc: kvm, Marc Zyngier, James Morse, Suzuki K Poulose, Zenghui Yu,
Will Deacon, Julien Thierry, Salil Mehta
Hey Will,
Haven't heard anything on v2 or v3 of this series and this has been on
the list for a while. Any thoughts?
I want to get a VMM using the SMCCC filtering UAPI ahead of CPU hotplug
on QEMU so we have some test coverage :) There's a knock-on benefit of
plugging some of the inherent races in system-scoped PSCI calls getting
out to userspace too.
--
Thanks,
Oliver
On Wed, Aug 02, 2023 at 11:42:38PM +0000, Oliver Upton wrote:
> v3 of the series to do PSCI calls in userspace, as an example for using
> the SMCCC filtering API added to KVM in 6.4.
>
> v2 -> v3:
> - Dropped some of the headers patches since they've already been
> updated
> - Redo header imports on top of 6.5-rc1
> - Actually use the right subject prefix...
>
> v2: https://lore.kernel.org/kvmarm/20230620163353.2688567-1-oliver.upton@linux.dev/
>
> Oliver Upton (17):
> Import arm-smccc.h from Linux 6.5-rc1
> aarch64: Copy cputype.h from Linux 6.5-rc1
> Update psci.h to Linux 6.5-rc1
> arm: Stash kvm_vcpu_init for later use
> arm: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs
> aarch64: Expose ARM64_CORE_REG() for general use
> arm: Generalize execution state specific VM initialization
> Add helpers to pause the VM from vCPU thread
> aarch64: Add support for finding vCPU for given MPIDR
> aarch64: Add skeleton implementation for PSCI
> aarch64: psci: Implement CPU_SUSPEND
> aarch64: psci: Implement CPU_OFF
> aarch64: psci: Implement CPU_ON
> aarch64: psci: Implement AFFINITY_INFO
> aarch64: psci: Implement MIGRATE_INFO_TYPE
> aarch64: psci: Implement SYSTEM_{OFF,RESET}
> aarch64: smccc: Start sending PSCI to userspace
>
> Makefile | 4 +-
> arm/aarch32/include/kvm/kvm-arch.h | 2 +-
> arm/aarch32/kvm-cpu.c | 5 +
> arm/aarch64/include/asm/cputype.h | 186 +++++++++++++++++
> arm/aarch64/include/asm/smccc.h | 65 ++++++
> arm/aarch64/include/kvm/kvm-arch.h | 2 +-
> arm/aarch64/include/kvm/kvm-config-arch.h | 6 +-
> arm/aarch64/include/kvm/kvm-cpu-arch.h | 28 ++-
> arm/aarch64/kvm-cpu.c | 48 +++--
> arm/aarch64/kvm.c | 25 ++-
> arm/aarch64/psci.c | 207 +++++++++++++++++++
> arm/aarch64/smccc.c | 81 ++++++++
> arm/include/arm-common/kvm-arch.h | 2 +
> arm/include/arm-common/kvm-config-arch.h | 1 +
> arm/include/arm-common/kvm-cpu-arch.h | 2 +-
> arm/kvm-cpu.c | 21 +-
> arm/kvm.c | 2 +-
> include/kvm/kvm-cpu.h | 3 +
> include/linux/arm-smccc.h | 240 ++++++++++++++++++++++
> include/linux/psci.h | 47 +++++
> kvm-cpu.c | 16 ++
> 21 files changed, 959 insertions(+), 34 deletions(-)
> create mode 100644 arm/aarch64/include/asm/cputype.h
> create mode 100644 arm/aarch64/include/asm/smccc.h
> create mode 100644 arm/aarch64/psci.c
> create mode 100644 arm/aarch64/smccc.c
> create mode 100644 include/linux/arm-smccc.h
>
>
> base-commit: 106e2ea7756d980454d68631b87d5e25ba4e4881
> --
> 2.41.0.585.gd2178a4bd4-goog
>
--
Thanks,
Oliver
^ permalink raw reply [flat|nested] 21+ messages in thread