public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace
@ 2025-09-30 10:31 Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 01/15] Allow pausing the VM from vcpu thread Suzuki K Poulose
                   ` (16 more replies)
  0 siblings, 17 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

This is version 4 of the patch series, originally posted by Oliver [0]. Mostly
remains the same as v3, except for

 - Address Will's comment on the race between pause/resume - Patch 1
 - Rebase on to v6.17-rc7
 - Drop importing cputype.h, which was not used by the series

[0] https://lore.kernel.org/all/20230802234255.466782-1-oliver.upton@linux.dev/


Oliver Upton (12):
  Import arm-smccc.h from Linux 6.17-rc7
  arm64: Stash kvm_vcpu_init for later use
  arm64: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs
  arm64: Expose ARM64_CORE_REG() for general use
  arm64: Add support for finding vCPU for given MPIDR
  arm64: Add skeleton implementation for PSCI
  arm64: psci: Implement CPU_SUSPEND
  arm64: psci: Implement CPU_ON
  arm64: psci: Implement AFFINITY_INFO
  arm64: psci: Implement MIGRATE_INFO_TYPE
  arm64: psci: Implement SYSTEM_{OFF,RESET}
  arm64: smccc: Start sending PSCI to userspace

Suzuki K Poulose (3):
  Allow pausing the VM from vcpu thread
  update_headers: arm64: Track psci.h for PSCI definitions
  update headers: Linux v6.17-rc7

 Makefile                            |   2 +
 arm64/include/asm/kvm.h             |  23 ++-
 arm64/include/asm/smccc.h           |  65 ++++++
 arm64/include/kvm/kvm-arch.h        |   2 +
 arm64/include/kvm/kvm-config-arch.h |   8 +-
 arm64/include/kvm/kvm-cpu-arch.h    |  30 ++-
 arm64/kvm-cpu.c                     |  51 +++--
 arm64/kvm.c                         |  20 ++
 arm64/psci.c                        | 207 +++++++++++++++++++
 arm64/smccc.c                       |  81 ++++++++
 include/linux/arm-smccc.h           | 305 ++++++++++++++++++++++++++++
 include/linux/kvm.h                 |  33 +++
 include/linux/psci.h                |  52 +++++
 include/linux/virtio_net.h          |  46 +++++
 include/linux/virtio_pci.h          |   1 +
 kvm-cpu.c                           |  13 ++
 kvm.c                               |  35 +++-
 powerpc/include/asm/kvm.h           |  13 --
 riscv/include/asm/kvm.h             |   3 +
 util/update_headers.sh              |  17 +-
 x86/include/asm/kvm.h               |  81 ++++++++
 21 files changed, 1030 insertions(+), 58 deletions(-)
 create mode 100644 arm64/include/asm/smccc.h
 create mode 100644 arm64/psci.c
 create mode 100644 arm64/smccc.c
 create mode 100644 include/linux/arm-smccc.h

-- 
2.43.0


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 01/15] Allow pausing the VM from vcpu thread
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2026-01-08 14:19   ` Marc Zyngier
  2025-09-30 10:31 ` [PATCH kvmtool v4 02/15] update_headers: arm64: Track psci.h for PSCI definitions Suzuki K Poulose
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

Pausing the VM from a vCPU thread doesn't work today, as it waits indefinitely
for a signal that never comes. By using the "current_kvm_cpu", enlighten the
kvm__pause() to skip the current CPU and do it inline. This also brings in a
restriction that a following kvm__continue() must be called from the same vCPU
thread.

Cc: Will Deacon <will@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/all/20230918104028.GA17744@willie-the-truck/
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 kvm.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/kvm.c b/kvm.c
index 07089cf1..cc25ecdb 100644
--- a/kvm.c
+++ b/kvm.c
@@ -59,6 +59,8 @@ const char *kvm_exit_reasons[] = {
 
 static int pause_event;
 static DEFINE_MUTEX(pause_lock);
+static struct kvm_cpu *pause_req_cpu;
+
 extern struct kvm_ext kvm_req_ext[];
 
 static char kvm_dir[PATH_MAX];
@@ -573,9 +575,25 @@ void kvm__reboot(struct kvm *kvm)
 
 void kvm__continue(struct kvm *kvm)
 {
+	/*
+	 * We must ensure that the resume request comes from the same context
+	 * as the one requested the pause, especially if it was issued from a
+	 * vCPU thread.
+	 */
+	if (current_kvm_cpu) {
+		if (pause_req_cpu != current_kvm_cpu ||
+		    !current_kvm_cpu->paused)
+			die("Trying to resume VM from invalid context");
+		current_kvm_cpu->paused = 0;
+	}
 	mutex_unlock(&pause_lock);
 }
 
+/*
+ * Mark all active CPUs as paused, until kvm__continue() is issued.
+ * NOTE: If this is called from a cpu thread, kvm__continue() must
+ * be called from the same thread.
+ */
 void kvm__pause(struct kvm *kvm)
 {
 	int i, paused_vcpus = 0;
@@ -590,10 +608,17 @@ void kvm__pause(struct kvm *kvm)
 	if (pause_event < 0)
 		die("Failed creating pause notification event");
 	for (i = 0; i < kvm->nrcpus; i++) {
-		if (kvm->cpus[i]->is_running && kvm->cpus[i]->paused == 0)
-			pthread_kill(kvm->cpus[i]->thread, SIGKVMPAUSE);
-		else
-			paused_vcpus++;
+		if (kvm->cpus[i]->is_running && kvm->cpus[i]->paused == 0) {
+			if (current_kvm_cpu != kvm->cpus[i]) {
+				pthread_kill(kvm->cpus[i]->thread, SIGKVMPAUSE);
+				continue;
+			} else if (current_kvm_cpu) {
+				current_kvm_cpu->paused = 1;
+				pause_req_cpu = current_kvm_cpu;
+				/* fall through to update our count */
+			}
+		}
+		paused_vcpus++;
 	}
 
 	while (paused_vcpus < kvm->nrcpus) {
@@ -604,6 +629,8 @@ void kvm__pause(struct kvm *kvm)
 		paused_vcpus += cur_read;
 	}
 	close(pause_event);
+	/* Remember the context requesting pause */
+	pause_req_cpu = current_kvm_cpu;
 }
 
 void kvm__notify_paused(void)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 02/15] update_headers: arm64: Track psci.h for PSCI definitions
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 01/15] Allow pausing the VM from vcpu thread Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 03/15] update headers: Linux v6.17-rc7 Suzuki K Poulose
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

Track UAPI psci.h for PSCI definitions

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 util/update_headers.sh | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/util/update_headers.sh b/util/update_headers.sh
index af75ca36..9fe782a2 100755
--- a/util/update_headers.sh
+++ b/util/update_headers.sh
@@ -37,13 +37,16 @@ done
 
 unset KVMTOOL_PATH
 
-copy_optional_arch () {
-	local src="$LINUX_ROOT/arch/$arch/include/uapi/$1"
+copy_arm64_headers () {
+	local uapi_asm_hdr="$LINUX_ROOT/arch/$arch/include/uapi/asm"
 
-	if [ -r "$src" ]
-	then
-		cp -- "$src" "$KVMTOOL_PATH/include/asm/"
-	fi
+	for f in sve_context.h psci.h
+	do
+		if [ -r "$uapi_asm_hdr/$f" ]
+		then
+			cp -- "$uapi_asm_hdr/$f" "$KVMTOOL_PATH/include/asm/"
+		fi
+	done
 }
 
 for arch in arm64 mips powerpc riscv x86
@@ -51,7 +54,7 @@ do
 	KVMTOOL_PATH=$arch
 
 	case $arch in
-		arm64) copy_optional_arch asm/sve_context.h ;;
+		arm64) copy_arm64_headers;;
 	esac
 	cp -- "$LINUX_ROOT/arch/$arch/include/uapi/asm/kvm.h" \
 		"$KVMTOOL_PATH/include/asm"
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 03/15] update headers: Linux v6.17-rc7
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 01/15] Allow pausing the VM from vcpu thread Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 02/15] update_headers: arm64: Track psci.h for PSCI definitions Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.16-rc1 Suzuki K Poulose
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

Update our headers fron linux-v6.17-rc7

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/include/asm/kvm.h    | 23 +++++++++--
 include/linux/kvm.h        | 33 ++++++++++++++++
 include/linux/psci.h       | 52 ++++++++++++++++++++++++
 include/linux/virtio_net.h | 46 ++++++++++++++++++++++
 include/linux/virtio_pci.h |  1 +
 powerpc/include/asm/kvm.h  | 13 ------
 riscv/include/asm/kvm.h    |  3 ++
 x86/include/asm/kvm.h      | 81 ++++++++++++++++++++++++++++++++++++++
 8 files changed, 235 insertions(+), 17 deletions(-)

diff --git a/arm64/include/asm/kvm.h b/arm64/include/asm/kvm.h
index 568bf858..ed5f3892 100644
--- a/arm64/include/asm/kvm.h
+++ b/arm64/include/asm/kvm.h
@@ -105,6 +105,7 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_PTRAUTH_ADDRESS	5 /* VCPU uses address authentication */
 #define KVM_ARM_VCPU_PTRAUTH_GENERIC	6 /* VCPU uses generic authentication */
 #define KVM_ARM_VCPU_HAS_EL2		7 /* Support nested virtualization */
+#define KVM_ARM_VCPU_HAS_EL2_E2H0	8 /* Limit NV support to E2H RES0 */
 
 struct kvm_vcpu_init {
 	__u32 target;
@@ -371,6 +372,7 @@ enum {
 #endif
 };
 
+/* Vendor hyper call function numbers 0-63 */
 #define KVM_REG_ARM_VENDOR_HYP_BMAP		KVM_REG_ARM_FW_FEAT_BMAP_REG(2)
 
 enum {
@@ -381,6 +383,17 @@ enum {
 #endif
 };
 
+/* Vendor hyper call function numbers 64-127 */
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_2		KVM_REG_ARM_FW_FEAT_BMAP_REG(3)
+
+enum {
+	KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER	= 0,
+	KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS	= 1,
+#ifdef __KERNEL__
+	KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_COUNT,
+#endif
+};
+
 /* Device Control API on vm fd */
 #define KVM_ARM_VM_SMCCC_CTRL		0
 #define   KVM_ARM_VM_SMCCC_FILTER	0
@@ -403,6 +416,7 @@ enum {
 #define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
 #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO  7
 #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8
+#define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ  9
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT	10
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
 			(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
@@ -417,10 +431,11 @@ enum {
 
 /* Device Control API on vcpu fd */
 #define KVM_ARM_VCPU_PMU_V3_CTRL	0
-#define   KVM_ARM_VCPU_PMU_V3_IRQ	0
-#define   KVM_ARM_VCPU_PMU_V3_INIT	1
-#define   KVM_ARM_VCPU_PMU_V3_FILTER	2
-#define   KVM_ARM_VCPU_PMU_V3_SET_PMU	3
+#define   KVM_ARM_VCPU_PMU_V3_IRQ		0
+#define   KVM_ARM_VCPU_PMU_V3_INIT		1
+#define   KVM_ARM_VCPU_PMU_V3_FILTER		2
+#define   KVM_ARM_VCPU_PMU_V3_SET_PMU		3
+#define   KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS	4
 #define KVM_ARM_VCPU_TIMER_CTRL		1
 #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 45e6d8fc..f0f0d49d 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -178,6 +178,7 @@ struct kvm_xen_exit {
 #define KVM_EXIT_NOTIFY           37
 #define KVM_EXIT_LOONGARCH_IOCSR  38
 #define KVM_EXIT_MEMORY_FAULT     39
+#define KVM_EXIT_TDX              40
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -375,6 +376,7 @@ struct kvm_run {
 #define KVM_SYSTEM_EVENT_WAKEUP         4
 #define KVM_SYSTEM_EVENT_SUSPEND        5
 #define KVM_SYSTEM_EVENT_SEV_TERM       6
+#define KVM_SYSTEM_EVENT_TDX_FATAL      7
 			__u32 type;
 			__u32 ndata;
 			union {
@@ -446,6 +448,31 @@ struct kvm_run {
 			__u64 gpa;
 			__u64 size;
 		} memory_fault;
+		/* KVM_EXIT_TDX */
+		struct {
+			__u64 flags;
+			__u64 nr;
+			union {
+				struct {
+					__u64 ret;
+					__u64 data[5];
+				} unknown;
+				struct {
+					__u64 ret;
+					__u64 gpa;
+					__u64 size;
+				} get_quote;
+				struct {
+					__u64 ret;
+					__u64 leaf;
+					__u64 r11, r12, r13, r14;
+				} get_tdvmcall_info;
+				struct {
+					__u64 ret;
+					__u64 vector;
+				} setup_event_notify;
+			};
+		} tdx;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -617,6 +644,7 @@ struct kvm_ioeventfd {
 #define KVM_X86_DISABLE_EXITS_HLT            (1 << 1)
 #define KVM_X86_DISABLE_EXITS_PAUSE          (1 << 2)
 #define KVM_X86_DISABLE_EXITS_CSTATE         (1 << 3)
+#define KVM_X86_DISABLE_EXITS_APERFMPERF     (1 << 4)
 
 /* for KVM_ENABLE_CAP */
 struct kvm_enable_cap {
@@ -929,6 +957,11 @@ struct kvm_enable_cap {
 #define KVM_CAP_PRE_FAULT_MEMORY 236
 #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237
 #define KVM_CAP_X86_GUEST_MODE 238
+#define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239
+#define KVM_CAP_ARM_EL2 240
+#define KVM_CAP_ARM_EL2_E2H0 241
+#define KVM_CAP_RISCV_MP_STATE_RESET 242
+#define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243
 
 struct kvm_irq_routing_irqchip {
 	__u32 irqchip;
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 310d83e0..81759ff3 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,30 @@
 #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_3_FN_SYSTEM_OFF2			PSCI_0_2_FN(21)
+
+#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)
+#define PSCI_1_3_FN64_SYSTEM_OFF2		PSCI_0_2_FN64(21)
+
 /* 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 +81,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 +98,13 @@
 #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 v1.3 hibernate type for SYSTEM_OFF2 */
+#define PSCI_1_3_OFF_TYPE_HIBERNATE_OFF		BIT(0)
+
 /* PSCI version decoding (independent of PSCI version) */
 #define PSCI_VERSION_MAJOR_SHIFT		16
 #define PSCI_VERSION_MINOR_MASK			\
@@ -75,6 +114,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 +137,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 */
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index ac917471..8bf27ab8 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -70,6 +70,28 @@
 					 * with the same MAC.
 					 */
 #define VIRTIO_NET_F_SPEED_DUPLEX 63	/* Device set linkspeed and duplex */
+#define VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO 65 /* Driver can receive
+					      * GSO-over-UDP-tunnel packets
+					      */
+#define VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_CSUM 66 /* Driver handles
+						   * GSO-over-UDP-tunnel
+						   * packets with partial csum
+						   * for the outer header
+						   */
+#define VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO 67 /* Device can receive
+					     * GSO-over-UDP-tunnel packets
+					     */
+#define VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO_CSUM 68 /* Device handles
+						  * GSO-over-UDP-tunnel
+						  * packets with partial csum
+						  * for the outer header
+						  */
+
+/* Offloads bits corresponding to VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO{,_CSUM}
+ * features
+ */
+#define VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_MAPPED	46
+#define VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO_CSUM_MAPPED	47
 
 #ifndef VIRTIO_NET_NO_LEGACY
 #define VIRTIO_NET_F_GSO	6	/* Host handles pkts w/ any GSO type */
@@ -131,12 +153,17 @@ struct virtio_net_hdr_v1 {
 #define VIRTIO_NET_HDR_F_NEEDS_CSUM	1	/* Use csum_start, csum_offset */
 #define VIRTIO_NET_HDR_F_DATA_VALID	2	/* Csum is valid */
 #define VIRTIO_NET_HDR_F_RSC_INFO	4	/* rsc info in csum_ fields */
+#define VIRTIO_NET_HDR_F_UDP_TUNNEL_CSUM 8	/* UDP tunnel csum offload */
 	__u8 flags;
 #define VIRTIO_NET_HDR_GSO_NONE		0	/* Not a GSO frame */
 #define VIRTIO_NET_HDR_GSO_TCPV4	1	/* GSO frame, IPv4 TCP (TSO) */
 #define VIRTIO_NET_HDR_GSO_UDP		3	/* GSO frame, IPv4 UDP (UFO) */
 #define VIRTIO_NET_HDR_GSO_TCPV6	4	/* GSO frame, IPv6 TCP */
 #define VIRTIO_NET_HDR_GSO_UDP_L4	5	/* GSO frame, IPv4& IPv6 UDP (USO) */
+#define VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV4 0x20 /* UDPv4 tunnel present */
+#define VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6 0x40 /* UDPv6 tunnel present */
+#define VIRTIO_NET_HDR_GSO_UDP_TUNNEL (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV4 | \
+				       VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6)
 #define VIRTIO_NET_HDR_GSO_ECN		0x80	/* TCP has ECN set */
 	__u8 gso_type;
 	__virtio16 hdr_len;	/* Ethernet + IP + tcp/udp hdrs */
@@ -181,6 +208,12 @@ struct virtio_net_hdr_v1_hash {
 	__le16 padding;
 };
 
+struct virtio_net_hdr_v1_hash_tunnel {
+	struct virtio_net_hdr_v1_hash hash_hdr;
+	__le16 outer_th_offset;
+	__le16 inner_nh_offset;
+};
+
 #ifndef VIRTIO_NET_NO_LEGACY
 /* This header comes first in the scatter-gather list.
  * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, it must
@@ -327,6 +360,19 @@ struct virtio_net_rss_config {
 	__u8 hash_key_data[/* hash_key_length */];
 };
 
+struct virtio_net_rss_config_hdr {
+	__le32 hash_types;
+	__le16 indirection_table_mask;
+	__le16 unclassified_queue;
+	__le16 indirection_table[/* 1 + indirection_table_mask */];
+};
+
+struct virtio_net_rss_config_trailer {
+	__le16 max_tx_vq;
+	__u8 hash_key_length;
+	__u8 hash_key_data[/* hash_key_length */];
+};
+
  #define VIRTIO_NET_CTRL_MQ_RSS_CONFIG          1
 
 /*
diff --git a/include/linux/virtio_pci.h b/include/linux/virtio_pci.h
index 8549d457..c691ac21 100644
--- a/include/linux/virtio_pci.h
+++ b/include/linux/virtio_pci.h
@@ -246,6 +246,7 @@ struct virtio_pci_cfg_cap {
 #define VIRTIO_ADMIN_CMD_LIST_USE	0x1
 
 /* Admin command group type. */
+#define VIRTIO_ADMIN_GROUP_TYPE_SELF	0x0
 #define VIRTIO_ADMIN_GROUP_TYPE_SRIOV	0x1
 
 /* Transitional device admin command. */
diff --git a/powerpc/include/asm/kvm.h b/powerpc/include/asm/kvm.h
index eaeda001..077c5437 100644
--- a/powerpc/include/asm/kvm.h
+++ b/powerpc/include/asm/kvm.h
@@ -1,18 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
  * Copyright IBM Corp. 2007
  *
  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
diff --git a/riscv/include/asm/kvm.h b/riscv/include/asm/kvm.h
index f06bc5ef..ef27d428 100644
--- a/riscv/include/asm/kvm.h
+++ b/riscv/include/asm/kvm.h
@@ -18,6 +18,7 @@
 #define __KVM_HAVE_IRQ_LINE
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
+#define KVM_DIRTY_LOG_PAGE_OFFSET 64
 
 #define KVM_INTERRUPT_SET	-1U
 #define KVM_INTERRUPT_UNSET	-2U
@@ -182,6 +183,8 @@ enum KVM_RISCV_ISA_EXT_ID {
 	KVM_RISCV_ISA_EXT_SVVPTC,
 	KVM_RISCV_ISA_EXT_ZABHA,
 	KVM_RISCV_ISA_EXT_ZICCRSE,
+	KVM_RISCV_ISA_EXT_ZAAMO,
+	KVM_RISCV_ISA_EXT_ZALRSC,
 	KVM_RISCV_ISA_EXT_MAX,
 };
 
diff --git a/x86/include/asm/kvm.h b/x86/include/asm/kvm.h
index 9e75da97..0f15d683 100644
--- a/x86/include/asm/kvm.h
+++ b/x86/include/asm/kvm.h
@@ -441,6 +441,7 @@ struct kvm_sync_regs {
 #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS	(1 << 6)
 #define KVM_X86_QUIRK_SLOT_ZAP_ALL		(1 << 7)
 #define KVM_X86_QUIRK_STUFF_FEATURE_MSRS	(1 << 8)
+#define KVM_X86_QUIRK_IGNORE_GUEST_PAT		(1 << 9)
 
 #define KVM_STATE_NESTED_FORMAT_VMX	0
 #define KVM_STATE_NESTED_FORMAT_SVM	1
@@ -559,6 +560,9 @@ struct kvm_x86_mce {
 #define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE	(1 << 7)
 #define KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA	(1 << 8)
 
+#define KVM_XEN_MSR_MIN_INDEX			0x40000000u
+#define KVM_XEN_MSR_MAX_INDEX			0x4fffffffu
+
 struct kvm_xen_hvm_config {
 	__u32 flags;
 	__u32 msr;
@@ -841,6 +845,7 @@ struct kvm_sev_snp_launch_start {
 };
 
 /* Kept in sync with firmware values for simplicity. */
+#define KVM_SEV_PAGE_TYPE_INVALID		0x0
 #define KVM_SEV_SNP_PAGE_TYPE_NORMAL		0x1
 #define KVM_SEV_SNP_PAGE_TYPE_ZERO		0x3
 #define KVM_SEV_SNP_PAGE_TYPE_UNMEASURED	0x4
@@ -927,4 +932,80 @@ struct kvm_hyperv_eventfd {
 #define KVM_X86_SNP_VM		4
 #define KVM_X86_TDX_VM		5
 
+/* Trust Domain eXtension sub-ioctl() commands. */
+enum kvm_tdx_cmd_id {
+	KVM_TDX_CAPABILITIES = 0,
+	KVM_TDX_INIT_VM,
+	KVM_TDX_INIT_VCPU,
+	KVM_TDX_INIT_MEM_REGION,
+	KVM_TDX_FINALIZE_VM,
+	KVM_TDX_GET_CPUID,
+
+	KVM_TDX_CMD_NR_MAX,
+};
+
+struct kvm_tdx_cmd {
+	/* enum kvm_tdx_cmd_id */
+	__u32 id;
+	/* flags for sub-commend. If sub-command doesn't use this, set zero. */
+	__u32 flags;
+	/*
+	 * data for each sub-command. An immediate or a pointer to the actual
+	 * data in process virtual address.  If sub-command doesn't use it,
+	 * set zero.
+	 */
+	__u64 data;
+	/*
+	 * Auxiliary error code.  The sub-command may return TDX SEAMCALL
+	 * status code in addition to -Exxx.
+	 */
+	__u64 hw_error;
+};
+
+struct kvm_tdx_capabilities {
+	__u64 supported_attrs;
+	__u64 supported_xfam;
+
+	__u64 kernel_tdvmcallinfo_1_r11;
+	__u64 user_tdvmcallinfo_1_r11;
+	__u64 kernel_tdvmcallinfo_1_r12;
+	__u64 user_tdvmcallinfo_1_r12;
+
+	__u64 reserved[250];
+
+	/* Configurable CPUID bits for userspace */
+	struct kvm_cpuid2 cpuid;
+};
+
+struct kvm_tdx_init_vm {
+	__u64 attributes;
+	__u64 xfam;
+	__u64 mrconfigid[6];	/* sha384 digest */
+	__u64 mrowner[6];	/* sha384 digest */
+	__u64 mrownerconfig[6];	/* sha384 digest */
+
+	/* The total space for TD_PARAMS before the CPUIDs is 256 bytes */
+	__u64 reserved[12];
+
+	/*
+	 * Call KVM_TDX_INIT_VM before vcpu creation, thus before
+	 * KVM_SET_CPUID2.
+	 * This configuration supersedes KVM_SET_CPUID2s for VCPUs because the
+	 * TDX module directly virtualizes those CPUIDs without VMM.  The user
+	 * space VMM, e.g. qemu, should make KVM_SET_CPUID2 consistent with
+	 * those values.  If it doesn't, KVM may have wrong idea of vCPUIDs of
+	 * the guest, and KVM may wrongly emulate CPUIDs or MSRs that the TDX
+	 * module doesn't virtualize.
+	 */
+	struct kvm_cpuid2 cpuid;
+};
+
+#define KVM_TDX_MEASURE_MEMORY_REGION   _BITULL(0)
+
+struct kvm_tdx_init_mem_region {
+	__u64 source_addr;
+	__u64 gpa;
+	__u64 nr_pages;
+};
+
 #endif /* _ASM_X86_KVM_H */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.16-rc1
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (2 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 03/15] update headers: Linux v6.17-rc7 Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:37   ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.17-rc7 Suzuki K Poulose
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

Copy in the SMCCC definitions from the kernel, which will be used to
implement SMCCC handling in userspace. Strip off unnecessary kernel specific
bits.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 include/linux/arm-smccc.h | 305 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 305 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 00000000..121a9608
--- /dev/null
+++ b/include/linux/arm-smccc.h
@@ -0,0 +1,305 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015, Linaro Limited
+ * Copied from $linux/include/linux/arm-smccc.h
+ */
+#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_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_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 "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
+
+/**
+ * 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;
+};
+
+#endif /*__LINUX_ARM_SMCCC_H*/
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.17-rc7
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (3 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.16-rc1 Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 05/15] arm64: Stash kvm_vcpu_init for later use Suzuki K Poulose
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

Copy in the SMCCC definitions from the kernel, which will be used to
implement SMCCC handling in userspace. Strip off unnecessary kernel specific
bits.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 include/linux/arm-smccc.h | 305 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 305 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 00000000..121a9608
--- /dev/null
+++ b/include/linux/arm-smccc.h
@@ -0,0 +1,305 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015, Linaro Limited
+ * Copied from $linux/include/linux/arm-smccc.h
+ */
+#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_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_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 "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
+
+/**
+ * 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;
+};
+
+#endif /*__LINUX_ARM_SMCCC_H*/
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 05/15] arm64: Stash kvm_vcpu_init for later use
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (4 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.17-rc7 Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 06/15] arm64: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs Suzuki K Poulose
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/include/kvm/kvm-cpu-arch.h | 2 +-
 arm64/kvm-cpu.c                  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arm64/include/kvm/kvm-cpu-arch.h b/arm64/include/kvm/kvm-cpu-arch.h
index 1af394aa..2f189abc 100644
--- a/arm64/include/kvm/kvm-cpu-arch.h
+++ b/arm64/include/kvm/kvm-cpu-arch.h
@@ -17,7 +17,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/arm64/kvm-cpu.c b/arm64/kvm-cpu.c
index 94c08a4d..3d914112 100644
--- a/arm64/kvm-cpu.c
+++ b/arm64/kvm-cpu.c
@@ -194,7 +194,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.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 06/15] arm64: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (5 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 05/15] arm64: Stash kvm_vcpu_init for later use Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 07/15] arm64: Expose ARM64_CORE_REG() for general use Suzuki K Poulose
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/kvm-cpu.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arm64/kvm-cpu.c b/arm64/kvm-cpu.c
index 3d914112..c7286484 100644
--- a/arm64/kvm-cpu.c
+++ b/arm64/kvm-cpu.c
@@ -143,10 +143,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);
@@ -201,6 +197,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.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 07/15] arm64: Expose ARM64_CORE_REG() for general use
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (6 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 06/15] arm64: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 08/15] arm64: Add support for finding vCPU for given MPIDR Suzuki K Poulose
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/include/kvm/kvm-cpu-arch.h | 16 ++++++++++++++++
 arm64/kvm-cpu.c                  | 16 ----------------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arm64/include/kvm/kvm-cpu-arch.h b/arm64/include/kvm/kvm-cpu-arch.h
index 2f189abc..dbd90647 100644
--- a/arm64/include/kvm/kvm-cpu-arch.h
+++ b/arm64/include/kvm/kvm-cpu-arch.h
@@ -67,4 +67,20 @@ unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu);
 int kvm_cpu__setup_pvtime(struct kvm_cpu *vcpu);
 int kvm_cpu__teardown_pvtime(struct kvm *kvm);
 
+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))
+
 #endif /* ARM_COMMON__KVM_CPU_ARCH_H */
diff --git a/arm64/kvm-cpu.c b/arm64/kvm-cpu.c
index c7286484..f8e08b5d 100644
--- a/arm64/kvm-cpu.c
+++ b/arm64/kvm-cpu.c
@@ -238,22 +238,6 @@ void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
 {
 }
 
-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.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 08/15] arm64: Add support for finding vCPU for given MPIDR
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (7 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 07/15] arm64: Expose ARM64_CORE_REG() for general use Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 09/15] arm64: Add skeleton implementation for PSCI Suzuki K Poulose
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/include/kvm/kvm-arch.h |  2 ++
 arm64/kvm.c                  | 17 +++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/arm64/include/kvm/kvm-arch.h b/arm64/include/kvm/kvm-arch.h
index 8f508ef8..a50e6a4f 100644
--- a/arm64/include/kvm/kvm-arch.h
+++ b/arm64/include/kvm/kvm-arch.h
@@ -114,4 +114,6 @@ struct kvm_arch {
 	cpu_set_t *vcpu_affinity_cpuset;
 };
 
+struct kvm_cpu *kvm__arch_mpidr_to_vcpu(struct kvm *kvm, u64 target_mpidr);
+
 #endif /* ARM_COMMON__KVM_ARCH_H */
diff --git a/arm64/kvm.c b/arm64/kvm.c
index 23b4dab1..41c47b13 100644
--- a/arm64/kvm.c
+++ b/arm64/kvm.c
@@ -5,6 +5,7 @@
 #include "kvm/virtio-console.h"
 #include "kvm/fdt.h"
 #include "kvm/gic.h"
+#include "kvm/kvm-cpu.h"
 
 #include <linux/byteorder.h>
 #include <linux/cpumask.h>
@@ -128,6 +129,22 @@ void kvm__arch_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;
+}
+
 static u64 kvm__arch_get_payload_region_size(struct kvm *kvm)
 {
 	if (kvm->cfg.arch.aarch32_guest)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 09/15] arm64: Add skeleton implementation for PSCI
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (8 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 08/15] arm64: Add support for finding vCPU for given MPIDR Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 10/15] arm64: psci: Implement CPU_SUSPEND Suzuki K Poulose
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 Makefile                  |  2 ++
 arm64/include/asm/smccc.h | 65 ++++++++++++++++++++++++++++++++++++
 arm64/kvm-cpu.c           | 19 ++++++++---
 arm64/kvm.c               |  3 ++
 arm64/psci.c              | 69 +++++++++++++++++++++++++++++++++++++++
 arm64/smccc.c             | 44 +++++++++++++++++++++++++
 6 files changed, 197 insertions(+), 5 deletions(-)
 create mode 100644 arm64/include/asm/smccc.h
 create mode 100644 arm64/psci.c
 create mode 100644 arm64/smccc.c

diff --git a/Makefile b/Makefile
index 60e551fd..1c0e7f55 100644
--- a/Makefile
+++ b/Makefile
@@ -181,6 +181,8 @@ ifeq ($(ARCH), arm64)
 	OBJS		+= arm64/arm-cpu.o
 	OBJS		+= arm64/pvtime.o
 	OBJS		+= arm64/pmu.o
+	OBJS		+= arm64/psci.o
+	OBJS		+= arm64/smccc.o
 	ARCH_INCLUDE	:= arm64/include
 
 	ARCH_WANT_LIBFDT := y
diff --git a/arm64/include/asm/smccc.h b/arm64/include/asm/smccc.h
new file mode 100644
index 00000000..c1be21a7
--- /dev/null
+++ b/arm64/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, &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, &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/arm64/kvm-cpu.c b/arm64/kvm-cpu.c
index f8e08b5d..6cd058fa 100644
--- a/arm64/kvm-cpu.c
+++ b/arm64/kvm-cpu.c
@@ -1,6 +1,7 @@
 #include "kvm/kvm.h"
 #include "kvm/kvm-cpu.h"
 #include "kvm/virtio.h"
+#include "asm/smccc.h"
 
 #include <asm/ptrace.h>
 #include <linux/bitops.h>
@@ -229,11 +230,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)
 {
 }
@@ -469,3 +465,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/arm64/kvm.c b/arm64/kvm.c
index 41c47b13..56e4f149 100644
--- a/arm64/kvm.c
+++ b/arm64/kvm.c
@@ -7,6 +7,8 @@
 #include "kvm/gic.h"
 #include "kvm/kvm-cpu.h"
 
+#include "asm/smccc.h"
+
 #include <linux/byteorder.h>
 #include <linux/cpumask.h>
 #include <linux/kernel.h>
@@ -127,6 +129,7 @@ void kvm__arch_init(struct kvm *kvm)
 		die("Failed to create virtual GIC");
 
 	kvm__arch_enable_mte(kvm);
+	kvm__setup_smccc(kvm);
 }
 
 
diff --git a/arm64/psci.c b/arm64/psci.c
new file mode 100644
index 00000000..72429b36
--- /dev/null
+++ b/arm64/psci.c
@@ -0,0 +1,69 @@
+#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 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;
+	}
+}
+
+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;
+}
+
+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) {
+	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;
+	case PSCI_0_2_FN_CPU_SUSPEND:
+	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;
+	}
+}
diff --git a/arm64/smccc.c b/arm64/smccc.c
new file mode 100644
index 00000000..ef986d8c
--- /dev/null
+++ b/arm64/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)
+{
+
+}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 10/15] arm64: psci: Implement CPU_SUSPEND
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (9 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 09/15] arm64: Add skeleton implementation for PSCI Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 11/15] arm64: psci: Implement CPU_ON Suzuki K Poulose
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 kvm-cpu.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/kvm-cpu.c b/kvm-cpu.c
index 7362f2e9..d718ef60 100644
--- a/kvm-cpu.c
+++ b/kvm-cpu.c
@@ -143,6 +143,16 @@ void kvm_cpu__run_on_all_cpus(struct kvm *kvm, struct kvm_cpu_task *task)
 	mutex_unlock(&task_lock);
 }
 
+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");
+}
+
 int kvm_cpu__start(struct kvm_cpu *cpu)
 {
 	sigset_t sigset;
@@ -236,6 +246,9 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
 				 */
 				kvm__reboot(cpu->kvm);
 				goto exit_kvm;
+			case KVM_SYSTEM_EVENT_WAKEUP:
+				handle_wakeup(cpu);
+				break;
 			};
 			break;
 		default: {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 11/15] arm64: psci: Implement CPU_ON
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (10 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 10/15] arm64: psci: Implement CPU_SUSPEND Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 12/15] arm64: psci: Implement AFFINITY_INFO Suzuki K Poulose
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/psci.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/arm64/psci.c b/arm64/psci.c
index 72429b36..14c98639 100644
--- a/arm64/psci.c
+++ b/arm64/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, &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, &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__pause(vcpu->kvm);
+
+	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__continue(vcpu->kvm);
+}
+
 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.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 12/15] arm64: psci: Implement AFFINITY_INFO
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (11 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 11/15] arm64: psci: Implement CPU_ON Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 13/15] arm64: psci: Implement MIGRATE_INFO_TYPE Suzuki K Poulose
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/include/kvm/kvm-cpu-arch.h | 12 ++++++-
 arm64/psci.c                     | 59 ++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/arm64/include/kvm/kvm-cpu-arch.h b/arm64/include/kvm/kvm-cpu-arch.h
index dbd90647..d9eb5f0e 100644
--- a/arm64/include/kvm/kvm-cpu-arch.h
+++ b/arm64/include/kvm/kvm-cpu-arch.h
@@ -7,7 +7,6 @@
 #include <pthread.h>
 #include <stdbool.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
@@ -67,6 +66,17 @@ unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu);
 int kvm_cpu__setup_pvtime(struct kvm_cpu *vcpu);
 int kvm_cpu__teardown_pvtime(struct kvm *kvm);
 
+#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/arm64/psci.c b/arm64/psci.c
index 14c98639..94e39d40 100644
--- a/arm64/psci.c
+++ b/arm64/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__continue(vcpu->kvm);
 }
 
+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__pause(vcpu->kvm);
+
+	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__continue(vcpu->kvm);
+}
+
 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.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 13/15] arm64: psci: Implement MIGRATE_INFO_TYPE
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (12 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 12/15] arm64: psci: Implement AFFINITY_INFO Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 14/15] arm64: psci: Implement SYSTEM_{OFF,RESET} Suzuki K Poulose
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/psci.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arm64/psci.c b/arm64/psci.c
index 94e39d40..3deb672e 100644
--- a/arm64/psci.c
+++ b/arm64/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.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 14/15] arm64: psci: Implement SYSTEM_{OFF,RESET}
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (13 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 13/15] arm64: psci: Implement MIGRATE_INFO_TYPE Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2025-09-30 10:31 ` [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace Suzuki K Poulose
  2026-01-08 14:19 ` [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Marc Zyngier
  16 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/psci.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arm64/psci.c b/arm64/psci.c
index 3deb672e..874ad141 100644
--- a/arm64/psci.c
+++ b/arm64/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.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (14 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 14/15] arm64: psci: Implement SYSTEM_{OFF,RESET} Suzuki K Poulose
@ 2025-09-30 10:31 ` Suzuki K Poulose
  2026-01-08 14:14   ` Marc Zyngier
  2026-01-08 14:19 ` [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Marc Zyngier
  16 siblings, 1 reply; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:31 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba, Suzuki K Poulose

From: Oliver Upton <oliver.upton@linux.dev>

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>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arm64/include/kvm/kvm-config-arch.h |  8 +++++--
 arm64/smccc.c                       | 37 +++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/arm64/include/kvm/kvm-config-arch.h b/arm64/include/kvm/kvm-config-arch.h
index ee031f01..3158fadf 100644
--- a/arm64/include/kvm/kvm-config-arch.h
+++ b/arm64/include/kvm/kvm-config-arch.h
@@ -15,6 +15,7 @@ struct kvm_config_arch {
 	u64		fw_addr;
 	unsigned int	sve_max_vq;
 	bool		no_pvtime;
+	bool		in_kernel_smccc;
 };
 
 int irqchip_parser(const struct option *opt, const char *arg, int unset);
@@ -52,11 +53,14 @@ int sve_vl_parser(const struct option *opt, const char *arg, int unset);
 			   "Force virtio devices to use PCI as their default "	\
 			   "transport (Deprecated: Use --virtio-transport "	\
 			   "option instead)", virtio_transport_parser, kvm),	\
-        OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
+	OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
 		     "[gicv2|gicv2m|gicv3|gicv3-its]",				\
 		     "Type of interrupt controller to emulate in the guest",	\
 		     irqchip_parser, NULL),					\
 	OPT_U64('\0', "firmware-address", &(cfg)->fw_addr,			\
-		"Address where firmware should be loaded"),
+		"Address where firmware should be loaded"),			\
+	OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc,		\
+			"Disable userspace handling of SMCCC, instead"		\
+			" relying on the in-kernel implementation"),
 
 #endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
diff --git a/arm64/smccc.c b/arm64/smccc.c
index ef986d8c..62d826be 100644
--- a/arm64/smccc.c
+++ b/arm64/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");
+	}
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.16-rc1
  2025-09-30 10:31 ` [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.16-rc1 Suzuki K Poulose
@ 2025-09-30 10:37   ` Suzuki K Poulose
  0 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2025-09-30 10:37 UTC (permalink / raw)
  To: kvmarm
  Cc: kvm, linux-kernel, will, oliver.upton, maz, alexandru.elisei,
	aneesh.kumar, steven.price, tabba

On 30/09/2025 11:31, Suzuki K Poulose wrote:
> From: Oliver Upton <oliver.upton@linux.dev>
> 
> Copy in the SMCCC definitions from the kernel, which will be used to
> implement SMCCC handling in userspace. Strip off unnecessary kernel specific
> bits.
> 
> Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

Please ignore this patch, I fixed the subject to reflect the rebase to 
v6.17 and sent this in duplicate.

Suzuki


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace
  2025-09-30 10:31 ` [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace Suzuki K Poulose
@ 2026-01-08 14:14   ` Marc Zyngier
  2026-01-08 14:23     ` Suzuki K Poulose
  2026-01-09  2:36     ` Aneesh Kumar K.V
  0 siblings, 2 replies; 26+ messages in thread
From: Marc Zyngier @ 2026-01-08 14:14 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: kvmarm, kvm, linux-kernel, will, oliver.upton, alexandru.elisei,
	aneesh.kumar, steven.price, tabba

On Tue, 30 Sep 2025 11:31:30 +0100,
Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
> 
> From: Oliver Upton <oliver.upton@linux.dev>
> 
> 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>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
>  arm64/include/kvm/kvm-config-arch.h |  8 +++++--
>  arm64/smccc.c                       | 37 +++++++++++++++++++++++++++++
>  2 files changed, 43 insertions(+), 2 deletions(-)
> 
> diff --git a/arm64/include/kvm/kvm-config-arch.h b/arm64/include/kvm/kvm-config-arch.h
> index ee031f01..3158fadf 100644
> --- a/arm64/include/kvm/kvm-config-arch.h
> +++ b/arm64/include/kvm/kvm-config-arch.h
> @@ -15,6 +15,7 @@ struct kvm_config_arch {
>  	u64		fw_addr;
>  	unsigned int	sve_max_vq;
>  	bool		no_pvtime;
> +	bool		in_kernel_smccc;
>  };
>  
>  int irqchip_parser(const struct option *opt, const char *arg, int unset);
> @@ -52,11 +53,14 @@ int sve_vl_parser(const struct option *opt, const char *arg, int unset);
>  			   "Force virtio devices to use PCI as their default "	\
>  			   "transport (Deprecated: Use --virtio-transport "	\
>  			   "option instead)", virtio_transport_parser, kvm),	\
> -        OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
> +	OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>  		     "[gicv2|gicv2m|gicv3|gicv3-its]",				\
>  		     "Type of interrupt controller to emulate in the guest",	\
>  		     irqchip_parser, NULL),					\
>  	OPT_U64('\0', "firmware-address", &(cfg)->fw_addr,			\
> -		"Address where firmware should be loaded"),
> +		"Address where firmware should be loaded"),			\
> +	OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc,		\
> +			"Disable userspace handling of SMCCC, instead"		\
> +			" relying on the in-kernel implementation"),
>

nit: this really is about PSCI, not SMCCC. The fact that we use the
SMCCC interface to route PSCI calls is an implementation detail,
really. The other thing is that this is a change in default behaviour,
and I'd rather keep in-kernel PSCI to be the default, specially given
that this otherwise silently fails on old kernels.

To that effect, I'd suggest the following instead:

+	OPT_BOOLEAN('\0', "psci", &(cfg)->userspace_psci,		\
+			"Request userspace handling of PSCI, instead"		\
+			" relying on the in-kernel implementation"),

and the code modified accordingly.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool v4 01/15] Allow pausing the VM from vcpu thread
  2025-09-30 10:31 ` [PATCH kvmtool v4 01/15] Allow pausing the VM from vcpu thread Suzuki K Poulose
@ 2026-01-08 14:19   ` Marc Zyngier
  0 siblings, 0 replies; 26+ messages in thread
From: Marc Zyngier @ 2026-01-08 14:19 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: kvmarm, kvm, linux-kernel, will, oliver.upton, alexandru.elisei,
	aneesh.kumar, steven.price, tabba

On Tue, 30 Sep 2025 11:31:15 +0100,
Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
> 
> Pausing the VM from a vCPU thread doesn't work today, as it waits indefinitely
> for a signal that never comes. By using the "current_kvm_cpu", enlighten the
> kvm__pause() to skip the current CPU and do it inline. This also brings in a
> restriction that a following kvm__continue() must be called from the same vCPU
> thread.
> 
> Cc: Will Deacon <will@kernel.org>
> Cc: Oliver Upton <oliver.upton@linux.dev>
> Link: https://lore.kernel.org/all/20230918104028.GA17744@willie-the-truck/
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
>  kvm.c | 35 +++++++++++++++++++++++++++++++----
>  1 file changed, 31 insertions(+), 4 deletions(-)
> 
> diff --git a/kvm.c b/kvm.c
> index 07089cf1..cc25ecdb 100644
> --- a/kvm.c
> +++ b/kvm.c
> @@ -59,6 +59,8 @@ const char *kvm_exit_reasons[] = {
>  
>  static int pause_event;
>  static DEFINE_MUTEX(pause_lock);
> +static struct kvm_cpu *pause_req_cpu;
> +
>  extern struct kvm_ext kvm_req_ext[];
>  
>  static char kvm_dir[PATH_MAX];
> @@ -573,9 +575,25 @@ void kvm__reboot(struct kvm *kvm)
>  
>  void kvm__continue(struct kvm *kvm)
>  {
> +	/*
> +	 * We must ensure that the resume request comes from the same context
> +	 * as the one requested the pause, especially if it was issued from a
> +	 * vCPU thread.
> +	 */
> +	if (current_kvm_cpu) {
> +		if (pause_req_cpu != current_kvm_cpu ||
> +		    !current_kvm_cpu->paused)
> +			die("Trying to resume VM from invalid context");
> +		current_kvm_cpu->paused = 0;
> +	}
>  	mutex_unlock(&pause_lock);
>  }
>  
> +/*
> + * Mark all active CPUs as paused, until kvm__continue() is issued.
> + * NOTE: If this is called from a cpu thread, kvm__continue() must
> + * be called from the same thread.
> + */
>  void kvm__pause(struct kvm *kvm)
>  {
>  	int i, paused_vcpus = 0;
> @@ -590,10 +608,17 @@ void kvm__pause(struct kvm *kvm)
>  	if (pause_event < 0)
>  		die("Failed creating pause notification event");
>  	for (i = 0; i < kvm->nrcpus; i++) {
> -		if (kvm->cpus[i]->is_running && kvm->cpus[i]->paused == 0)
> -			pthread_kill(kvm->cpus[i]->thread, SIGKVMPAUSE);
> -		else
> -			paused_vcpus++;
> +		if (kvm->cpus[i]->is_running && kvm->cpus[i]->paused == 0) {
> +			if (current_kvm_cpu != kvm->cpus[i]) {
> +				pthread_kill(kvm->cpus[i]->thread, SIGKVMPAUSE);
> +				continue;
> +			} else if (current_kvm_cpu) {
> +				current_kvm_cpu->paused = 1;
> +				pause_req_cpu = current_kvm_cpu;

This is also set as we leave the function. Why do we need to set it
twice?

> +				/* fall through to update our count */
> +			}
> +		}
> +		paused_vcpus++;
>  	}
>  
>  	while (paused_vcpus < kvm->nrcpus) {
> @@ -604,6 +629,8 @@ void kvm__pause(struct kvm *kvm)
>  		paused_vcpus += cur_read;
>  	}
>  	close(pause_event);
> +	/* Remember the context requesting pause */
> +	pause_req_cpu = current_kvm_cpu;
>  }
>  
>  void kvm__notify_paused(void)

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace
  2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
                   ` (15 preceding siblings ...)
  2025-09-30 10:31 ` [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace Suzuki K Poulose
@ 2026-01-08 14:19 ` Marc Zyngier
  16 siblings, 0 replies; 26+ messages in thread
From: Marc Zyngier @ 2026-01-08 14:19 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: kvmarm, kvm, linux-kernel, will, oliver.upton, alexandru.elisei,
	aneesh.kumar, steven.price, tabba

On Tue, 30 Sep 2025 11:31:14 +0100,
Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
> 
> This is version 4 of the patch series, originally posted by Oliver [0]. Mostly
> remains the same as v3, except for
> 
>  - Address Will's comment on the race between pause/resume - Patch 1
>  - Rebase on to v6.17-rc7
>  - Drop importing cputype.h, which was not used by the series
> 
> [0] https://lore.kernel.org/all/20230802234255.466782-1-oliver.upton@linux.dev/

The remark on the first and last patches aside, this looks rather good
to me. With that addressed:

Reviewed-by: Marc Zyngier <maz@kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace
  2026-01-08 14:14   ` Marc Zyngier
@ 2026-01-08 14:23     ` Suzuki K Poulose
  2026-01-09  2:36     ` Aneesh Kumar K.V
  1 sibling, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2026-01-08 14:23 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm, kvm, linux-kernel, will, oliver.upton, alexandru.elisei,
	aneesh.kumar, steven.price, tabba

On 08/01/2026 14:14, Marc Zyngier wrote:
> On Tue, 30 Sep 2025 11:31:30 +0100,
> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>
>> From: Oliver Upton <oliver.upton@linux.dev>
>>
>> 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>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> ---
>>   arm64/include/kvm/kvm-config-arch.h |  8 +++++--
>>   arm64/smccc.c                       | 37 +++++++++++++++++++++++++++++
>>   2 files changed, 43 insertions(+), 2 deletions(-)
>>
>> diff --git a/arm64/include/kvm/kvm-config-arch.h b/arm64/include/kvm/kvm-config-arch.h
>> index ee031f01..3158fadf 100644
>> --- a/arm64/include/kvm/kvm-config-arch.h
>> +++ b/arm64/include/kvm/kvm-config-arch.h
>> @@ -15,6 +15,7 @@ struct kvm_config_arch {
>>   	u64		fw_addr;
>>   	unsigned int	sve_max_vq;
>>   	bool		no_pvtime;
>> +	bool		in_kernel_smccc;
>>   };
>>   
>>   int irqchip_parser(const struct option *opt, const char *arg, int unset);
>> @@ -52,11 +53,14 @@ int sve_vl_parser(const struct option *opt, const char *arg, int unset);
>>   			   "Force virtio devices to use PCI as their default "	\
>>   			   "transport (Deprecated: Use --virtio-transport "	\
>>   			   "option instead)", virtio_transport_parser, kvm),	\
>> -        OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>> +	OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>>   		     "[gicv2|gicv2m|gicv3|gicv3-its]",				\
>>   		     "Type of interrupt controller to emulate in the guest",	\
>>   		     irqchip_parser, NULL),					\
>>   	OPT_U64('\0', "firmware-address", &(cfg)->fw_addr,			\
>> -		"Address where firmware should be loaded"),
>> +		"Address where firmware should be loaded"),			\
>> +	OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc,		\
>> +			"Disable userspace handling of SMCCC, instead"		\
>> +			" relying on the in-kernel implementation"),
>>
> 
> nit: this really is about PSCI, not SMCCC. The fact that we use the
> SMCCC interface to route PSCI calls is an implementation detail,
> really. The other thing is that this is a change in default behaviour,
> and I'd rather keep in-kernel PSCI to be the default, specially given
> that this otherwise silently fails on old kernels.
> 

Agreed, I will address this.

> To that effect, I'd suggest the following instead:
> 
> +	OPT_BOOLEAN('\0', "psci", &(cfg)->userspace_psci,		\
> +			"Request userspace handling of PSCI, instead"		\
> +			" relying on the in-kernel implementation"),
> 
> and the code modified accordingly.
> 

Cheers
Suzuki


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace
  2026-01-08 14:14   ` Marc Zyngier
  2026-01-08 14:23     ` Suzuki K Poulose
@ 2026-01-09  2:36     ` Aneesh Kumar K.V
  2026-01-09 10:21       ` Suzuki K Poulose
  1 sibling, 1 reply; 26+ messages in thread
From: Aneesh Kumar K.V @ 2026-01-09  2:36 UTC (permalink / raw)
  To: Marc Zyngier, Suzuki K Poulose
  Cc: kvmarm, kvm, linux-kernel, will, oliver.upton, alexandru.elisei,
	steven.price, tabba

Marc Zyngier <maz@kernel.org> writes:

> On Tue, 30 Sep 2025 11:31:30 +0100,
> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>> 
>> From: Oliver Upton <oliver.upton@linux.dev>
>> 
>> 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>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> ---
>>  arm64/include/kvm/kvm-config-arch.h |  8 +++++--
>>  arm64/smccc.c                       | 37 +++++++++++++++++++++++++++++
>>  2 files changed, 43 insertions(+), 2 deletions(-)
>> 
>> diff --git a/arm64/include/kvm/kvm-config-arch.h b/arm64/include/kvm/kvm-config-arch.h
>> index ee031f01..3158fadf 100644
>> --- a/arm64/include/kvm/kvm-config-arch.h
>> +++ b/arm64/include/kvm/kvm-config-arch.h
>> @@ -15,6 +15,7 @@ struct kvm_config_arch {
>>  	u64		fw_addr;
>>  	unsigned int	sve_max_vq;
>>  	bool		no_pvtime;
>> +	bool		in_kernel_smccc;
>>  };
>>  
>>  int irqchip_parser(const struct option *opt, const char *arg, int unset);
>> @@ -52,11 +53,14 @@ int sve_vl_parser(const struct option *opt, const char *arg, int unset);
>>  			   "Force virtio devices to use PCI as their default "	\
>>  			   "transport (Deprecated: Use --virtio-transport "	\
>>  			   "option instead)", virtio_transport_parser, kvm),	\
>> -        OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>> +	OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>>  		     "[gicv2|gicv2m|gicv3|gicv3-its]",				\
>>  		     "Type of interrupt controller to emulate in the guest",	\
>>  		     irqchip_parser, NULL),					\
>>  	OPT_U64('\0', "firmware-address", &(cfg)->fw_addr,			\
>> -		"Address where firmware should be loaded"),
>> +		"Address where firmware should be loaded"),			\
>> +	OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc,		\
>> +			"Disable userspace handling of SMCCC, instead"		\
>> +			" relying on the in-kernel implementation"),
>>
>
> nit: this really is about PSCI, not SMCCC. The fact that we use the
> SMCCC interface to route PSCI calls is an implementation detail,
> really. The other thing is that this is a change in default behaviour,
> and I'd rather keep in-kernel PSCI to be the default, specially given
> that this otherwise silently fails on old kernels.
>
> To that effect, I'd suggest the following instead:
>
> +	OPT_BOOLEAN('\0', "psci", &(cfg)->userspace_psci,		\
> +			"Request userspace handling of PSCI, instead"		\
> +			" relying on the in-kernel implementation"),
>
> and the code modified accordingly.
>

The same option will also be used to handle RHI or may be we could say
--realm implies userspace_psci = true?

-aneesh

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace
  2026-01-09  2:36     ` Aneesh Kumar K.V
@ 2026-01-09 10:21       ` Suzuki K Poulose
  2026-01-09 10:43         ` Aneesh Kumar K.V
  0 siblings, 1 reply; 26+ messages in thread
From: Suzuki K Poulose @ 2026-01-09 10:21 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Marc Zyngier
  Cc: kvmarm, kvm, linux-kernel, will, oliver.upton, alexandru.elisei,
	steven.price, tabba

On 09/01/2026 02:36, Aneesh Kumar K.V wrote:
> Marc Zyngier <maz@kernel.org> writes:
> 
>> On Tue, 30 Sep 2025 11:31:30 +0100,
>> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>>
>>> From: Oliver Upton <oliver.upton@linux.dev>
>>>
>>> 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>
>>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>> ---
>>>   arm64/include/kvm/kvm-config-arch.h |  8 +++++--
>>>   arm64/smccc.c                       | 37 +++++++++++++++++++++++++++++
>>>   2 files changed, 43 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arm64/include/kvm/kvm-config-arch.h b/arm64/include/kvm/kvm-config-arch.h
>>> index ee031f01..3158fadf 100644
>>> --- a/arm64/include/kvm/kvm-config-arch.h
>>> +++ b/arm64/include/kvm/kvm-config-arch.h
>>> @@ -15,6 +15,7 @@ struct kvm_config_arch {
>>>   	u64		fw_addr;
>>>   	unsigned int	sve_max_vq;
>>>   	bool		no_pvtime;
>>> +	bool		in_kernel_smccc;
>>>   };
>>>   
>>>   int irqchip_parser(const struct option *opt, const char *arg, int unset);
>>> @@ -52,11 +53,14 @@ int sve_vl_parser(const struct option *opt, const char *arg, int unset);
>>>   			   "Force virtio devices to use PCI as their default "	\
>>>   			   "transport (Deprecated: Use --virtio-transport "	\
>>>   			   "option instead)", virtio_transport_parser, kvm),	\
>>> -        OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>>> +	OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>>>   		     "[gicv2|gicv2m|gicv3|gicv3-its]",				\
>>>   		     "Type of interrupt controller to emulate in the guest",	\
>>>   		     irqchip_parser, NULL),					\
>>>   	OPT_U64('\0', "firmware-address", &(cfg)->fw_addr,			\
>>> -		"Address where firmware should be loaded"),
>>> +		"Address where firmware should be loaded"),			\
>>> +	OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc,		\
>>> +			"Disable userspace handling of SMCCC, instead"		\
>>> +			" relying on the in-kernel implementation"),
>>>
>>
>> nit: this really is about PSCI, not SMCCC. The fact that we use the
>> SMCCC interface to route PSCI calls is an implementation detail,
>> really. The other thing is that this is a change in default behaviour,
>> and I'd rather keep in-kernel PSCI to be the default, specially given
>> that this otherwise silently fails on old kernels.
>>
>> To that effect, I'd suggest the following instead:
>>
>> +	OPT_BOOLEAN('\0', "psci", &(cfg)->userspace_psci,		\
>> +			"Request userspace handling of PSCI, instead"		\
>> +			" relying on the in-kernel implementation"),
>>
>> and the code modified accordingly.
>>
> 
> The same option will also be used to handle RHI or may be we could say
> --realm implies userspace_psci = true?

Not necessarily. For a Realm, we should always handle the RHI calls in
VMM and VMM must do this irrespective of where the PSCI is emulated.
i.e., they both are different things. KVM allows controlling the SMCCC
for FID ranges. For Realm, RHI range can be requested by the VMM.
Depending on the --psci option, PSCI range can also be requested.

Suzuki


> 
> -aneesh


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace
  2026-01-09 10:21       ` Suzuki K Poulose
@ 2026-01-09 10:43         ` Aneesh Kumar K.V
  2026-01-09 17:14           ` Suzuki K Poulose
  0 siblings, 1 reply; 26+ messages in thread
From: Aneesh Kumar K.V @ 2026-01-09 10:43 UTC (permalink / raw)
  To: Suzuki K Poulose, Marc Zyngier
  Cc: kvmarm, kvm, linux-kernel, will, oliver.upton, alexandru.elisei,
	steven.price, tabba

Suzuki K Poulose <suzuki.poulose@arm.com> writes:

> On 09/01/2026 02:36, Aneesh Kumar K.V wrote:
>> Marc Zyngier <maz@kernel.org> writes:
>> 
>>> On Tue, 30 Sep 2025 11:31:30 +0100,
>>> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>>>
>>>> From: Oliver Upton <oliver.upton@linux.dev>
>>>>
>>>> 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>
>>>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>>> ---
>>>>   arm64/include/kvm/kvm-config-arch.h |  8 +++++--
>>>>   arm64/smccc.c                       | 37 +++++++++++++++++++++++++++++
>>>>   2 files changed, 43 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/arm64/include/kvm/kvm-config-arch.h b/arm64/include/kvm/kvm-config-arch.h
>>>> index ee031f01..3158fadf 100644
>>>> --- a/arm64/include/kvm/kvm-config-arch.h
>>>> +++ b/arm64/include/kvm/kvm-config-arch.h
>>>> @@ -15,6 +15,7 @@ struct kvm_config_arch {
>>>>   	u64		fw_addr;
>>>>   	unsigned int	sve_max_vq;
>>>>   	bool		no_pvtime;
>>>> +	bool		in_kernel_smccc;
>>>>   };
>>>>   
>>>>   int irqchip_parser(const struct option *opt, const char *arg, int unset);
>>>> @@ -52,11 +53,14 @@ int sve_vl_parser(const struct option *opt, const char *arg, int unset);
>>>>   			   "Force virtio devices to use PCI as their default "	\
>>>>   			   "transport (Deprecated: Use --virtio-transport "	\
>>>>   			   "option instead)", virtio_transport_parser, kvm),	\
>>>> -        OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>>>> +	OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>>>>   		     "[gicv2|gicv2m|gicv3|gicv3-its]",				\
>>>>   		     "Type of interrupt controller to emulate in the guest",	\
>>>>   		     irqchip_parser, NULL),					\
>>>>   	OPT_U64('\0', "firmware-address", &(cfg)->fw_addr,			\
>>>> -		"Address where firmware should be loaded"),
>>>> +		"Address where firmware should be loaded"),			\
>>>> +	OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc,		\
>>>> +			"Disable userspace handling of SMCCC, instead"		\
>>>> +			" relying on the in-kernel implementation"),
>>>>
>>>
>>> nit: this really is about PSCI, not SMCCC. The fact that we use the
>>> SMCCC interface to route PSCI calls is an implementation detail,
>>> really. The other thing is that this is a change in default behaviour,
>>> and I'd rather keep in-kernel PSCI to be the default, specially given
>>> that this otherwise silently fails on old kernels.
>>>
>>> To that effect, I'd suggest the following instead:
>>>
>>> +	OPT_BOOLEAN('\0', "psci", &(cfg)->userspace_psci,		\
>>> +			"Request userspace handling of PSCI, instead"		\
>>> +			" relying on the in-kernel implementation"),
>>>
>>> and the code modified accordingly.
>>>
>> 
>> The same option will also be used to handle RHI or may be we could say
>> --realm implies userspace_psci = true?
>
> Not necessarily. For a Realm, we should always handle the RHI calls in
> VMM and VMM must do this irrespective of where the PSCI is emulated.
> i.e., they both are different things. KVM allows controlling the SMCCC
> for FID ranges. For Realm, RHI range can be requested by the VMM.
> Depending on the --psci option, PSCI range can also be requested.
>

We can rename static struct kvm_smccc_filter filter_ranges[] to
psci_filter_ranges[] and for RHI we can have another
rhi_smccc_fid_ranges[]?.

-aneesh

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace
  2026-01-09 10:43         ` Aneesh Kumar K.V
@ 2026-01-09 17:14           ` Suzuki K Poulose
  0 siblings, 0 replies; 26+ messages in thread
From: Suzuki K Poulose @ 2026-01-09 17:14 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Marc Zyngier
  Cc: kvmarm, kvm, linux-kernel, will, oliver.upton, alexandru.elisei,
	steven.price, tabba

On 09/01/2026 10:43, Aneesh Kumar K.V wrote:
> Suzuki K Poulose <suzuki.poulose@arm.com> writes:
> 
>> On 09/01/2026 02:36, Aneesh Kumar K.V wrote:
>>> Marc Zyngier <maz@kernel.org> writes:
>>>
>>>> On Tue, 30 Sep 2025 11:31:30 +0100,
>>>> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>>>>
>>>>> From: Oliver Upton <oliver.upton@linux.dev>
>>>>>
>>>>> 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>
>>>>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>>>> ---
>>>>>    arm64/include/kvm/kvm-config-arch.h |  8 +++++--
>>>>>    arm64/smccc.c                       | 37 +++++++++++++++++++++++++++++
>>>>>    2 files changed, 43 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/arm64/include/kvm/kvm-config-arch.h b/arm64/include/kvm/kvm-config-arch.h
>>>>> index ee031f01..3158fadf 100644
>>>>> --- a/arm64/include/kvm/kvm-config-arch.h
>>>>> +++ b/arm64/include/kvm/kvm-config-arch.h
>>>>> @@ -15,6 +15,7 @@ struct kvm_config_arch {
>>>>>    	u64		fw_addr;
>>>>>    	unsigned int	sve_max_vq;
>>>>>    	bool		no_pvtime;
>>>>> +	bool		in_kernel_smccc;
>>>>>    };
>>>>>    
>>>>>    int irqchip_parser(const struct option *opt, const char *arg, int unset);
>>>>> @@ -52,11 +53,14 @@ int sve_vl_parser(const struct option *opt, const char *arg, int unset);
>>>>>    			   "Force virtio devices to use PCI as their default "	\
>>>>>    			   "transport (Deprecated: Use --virtio-transport "	\
>>>>>    			   "option instead)", virtio_transport_parser, kvm),	\
>>>>> -        OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>>>>> +	OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip,				\
>>>>>    		     "[gicv2|gicv2m|gicv3|gicv3-its]",				\
>>>>>    		     "Type of interrupt controller to emulate in the guest",	\
>>>>>    		     irqchip_parser, NULL),					\
>>>>>    	OPT_U64('\0', "firmware-address", &(cfg)->fw_addr,			\
>>>>> -		"Address where firmware should be loaded"),
>>>>> +		"Address where firmware should be loaded"),			\
>>>>> +	OPT_BOOLEAN('\0', "in-kernel-smccc", &(cfg)->in_kernel_smccc,		\
>>>>> +			"Disable userspace handling of SMCCC, instead"		\
>>>>> +			" relying on the in-kernel implementation"),
>>>>>
>>>>
>>>> nit: this really is about PSCI, not SMCCC. The fact that we use the
>>>> SMCCC interface to route PSCI calls is an implementation detail,
>>>> really. The other thing is that this is a change in default behaviour,
>>>> and I'd rather keep in-kernel PSCI to be the default, specially given
>>>> that this otherwise silently fails on old kernels.
>>>>
>>>> To that effect, I'd suggest the following instead:
>>>>
>>>> +	OPT_BOOLEAN('\0', "psci", &(cfg)->userspace_psci,		\
>>>> +			"Request userspace handling of PSCI, instead"		\
>>>> +			" relying on the in-kernel implementation"),
>>>>
>>>> and the code modified accordingly.
>>>>
>>>
>>> The same option will also be used to handle RHI or may be we could say
>>> --realm implies userspace_psci = true?
>>
>> Not necessarily. For a Realm, we should always handle the RHI calls in
>> VMM and VMM must do this irrespective of where the PSCI is emulated.
>> i.e., they both are different things. KVM allows controlling the SMCCC
>> for FID ranges. For Realm, RHI range can be requested by the VMM.
>> Depending on the --psci option, PSCI range can also be requested.
>>
> 
> We can rename static struct kvm_smccc_filter filter_ranges[] to
> psci_filter_ranges[] and for RHI we can have another
> rhi_smccc_fid_ranges[]?.

Yep, that can done in respective patches, where we add RHI. Since we
only have psci in the ranges, I am a bit lazy/reluctant to rename it.

Cheers
Suzuki

> 
> -aneesh


^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2026-01-09 17:14 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-30 10:31 [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 01/15] Allow pausing the VM from vcpu thread Suzuki K Poulose
2026-01-08 14:19   ` Marc Zyngier
2025-09-30 10:31 ` [PATCH kvmtool v4 02/15] update_headers: arm64: Track psci.h for PSCI definitions Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 03/15] update headers: Linux v6.17-rc7 Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.16-rc1 Suzuki K Poulose
2025-09-30 10:37   ` Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 04/15] Import arm-smccc.h from Linux 6.17-rc7 Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 05/15] arm64: Stash kvm_vcpu_init for later use Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 06/15] arm64: Use KVM_SET_MP_STATE ioctl to power off non-boot vCPUs Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 07/15] arm64: Expose ARM64_CORE_REG() for general use Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 08/15] arm64: Add support for finding vCPU for given MPIDR Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 09/15] arm64: Add skeleton implementation for PSCI Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 10/15] arm64: psci: Implement CPU_SUSPEND Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 11/15] arm64: psci: Implement CPU_ON Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 12/15] arm64: psci: Implement AFFINITY_INFO Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 13/15] arm64: psci: Implement MIGRATE_INFO_TYPE Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 14/15] arm64: psci: Implement SYSTEM_{OFF,RESET} Suzuki K Poulose
2025-09-30 10:31 ` [PATCH kvmtool v4 15/15] arm64: smccc: Start sending PSCI to userspace Suzuki K Poulose
2026-01-08 14:14   ` Marc Zyngier
2026-01-08 14:23     ` Suzuki K Poulose
2026-01-09  2:36     ` Aneesh Kumar K.V
2026-01-09 10:21       ` Suzuki K Poulose
2026-01-09 10:43         ` Aneesh Kumar K.V
2026-01-09 17:14           ` Suzuki K Poulose
2026-01-08 14:19 ` [PATCH kvmtool 00/15] arm64: Handle PSCI calls in userspace Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox