* [PATCH 01/16] KVM: Add capability to advertise PSCI v0.2 support
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 02/16] ARM/ARM64: KVM: Add common header for PSCI related defines Christoffer Dall
` (14 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
User space (i.e. QEMU or KVMTOOL) should be able to check whether KVM
ARM/ARM64 supports in-kernel PSCI v0.2 emulation. For this purpose, we
define KVM_CAP_ARM_PSCI_0_2 in KVM user space interface header.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
include/uapi/linux/kvm.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 836e15b..f3252b1 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -746,6 +746,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_S390_IRQCHIP 99
#define KVM_CAP_IOEVENTFD_NO_LENGTH 100
#define KVM_CAP_VM_ATTRIBUTES 101
+#define KVM_CAP_ARM_PSCI_0_2 102
#ifdef KVM_CAP_IRQ_ROUTING
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 02/16] ARM/ARM64: KVM: Add common header for PSCI related defines
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
2014-05-25 18:18 ` [PATCH 01/16] KVM: Add capability to advertise PSCI v0.2 support Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 03/16] ARM/ARM64: KVM: Add base for PSCI v0.2 emulation Christoffer Dall
` (13 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
We need a common place to share PSCI related defines among ARM kernel,
ARM64 kernel, KVM ARM/ARM64 PSCI emulation, and user space.
We introduce uapi/linux/psci.h for this purpose. This newly added
header will be first used by KVM ARM/ARM64 in-kernel PSCI emulation
and user space (i.e. QEMU or KVMTOOL).
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/psci.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 91 insertions(+)
create mode 100644 include/uapi/linux/psci.h
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 6929571..24e9033 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -317,6 +317,7 @@ header-y += ppp-ioctl.h
header-y += ppp_defs.h
header-y += pps.h
header-y += prctl.h
+header-y += psci.h
header-y += ptp_clock.h
header-y += ptrace.h
header-y += qnx4_fs.h
diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
new file mode 100644
index 0000000..310d83e
--- /dev/null
+++ b/include/uapi/linux/psci.h
@@ -0,0 +1,90 @@
+/*
+ * ARM Power State and Coordination Interface (PSCI) header
+ *
+ * This header holds common PSCI defines and macros shared
+ * by: ARM kernel, ARM64 kernel, KVM ARM/ARM64 and user space.
+ *
+ * Copyright (C) 2014 Linaro Ltd.
+ * Author: Anup Patel <anup.patel@linaro.org>
+ */
+
+#ifndef _UAPI_LINUX_PSCI_H
+#define _UAPI_LINUX_PSCI_H
+
+/*
+ * PSCI v0.1 interface
+ *
+ * The PSCI v0.1 function numbers are implementation defined.
+ *
+ * Only PSCI return values such as: SUCCESS, NOT_SUPPORTED,
+ * INVALID_PARAMS, and DENIED defined below are applicable
+ * to PSCI v0.1.
+ */
+
+/* PSCI v0.2 interface */
+#define PSCI_0_2_FN_BASE 0x84000000
+#define PSCI_0_2_FN(n) (PSCI_0_2_FN_BASE + (n))
+#define PSCI_0_2_64BIT 0x40000000
+#define PSCI_0_2_FN64_BASE \
+ (PSCI_0_2_FN_BASE + PSCI_0_2_64BIT)
+#define PSCI_0_2_FN64(n) (PSCI_0_2_FN64_BASE + (n))
+
+#define PSCI_0_2_FN_PSCI_VERSION PSCI_0_2_FN(0)
+#define PSCI_0_2_FN_CPU_SUSPEND PSCI_0_2_FN(1)
+#define PSCI_0_2_FN_CPU_OFF PSCI_0_2_FN(2)
+#define PSCI_0_2_FN_CPU_ON PSCI_0_2_FN(3)
+#define PSCI_0_2_FN_AFFINITY_INFO PSCI_0_2_FN(4)
+#define PSCI_0_2_FN_MIGRATE PSCI_0_2_FN(5)
+#define PSCI_0_2_FN_MIGRATE_INFO_TYPE PSCI_0_2_FN(6)
+#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU PSCI_0_2_FN(7)
+#define PSCI_0_2_FN_SYSTEM_OFF PSCI_0_2_FN(8)
+#define PSCI_0_2_FN_SYSTEM_RESET PSCI_0_2_FN(9)
+
+#define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1)
+#define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3)
+#define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4)
+#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)
+
+/* 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
+#define PSCI_0_2_POWER_STATE_TYPE_SHIFT 16
+#define PSCI_0_2_POWER_STATE_TYPE_MASK \
+ (0x1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT)
+#define PSCI_0_2_POWER_STATE_AFFL_SHIFT 24
+#define PSCI_0_2_POWER_STATE_AFFL_MASK \
+ (0x3 << PSCI_0_2_POWER_STATE_AFFL_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
+#define PSCI_0_2_AFFINITY_LEVEL_ON_PENDING 2
+
+/* PSCI v0.2 multicore support in Trusted OS returned by MIGRATE_INFO_TYPE */
+#define PSCI_0_2_TOS_UP_MIGRATE 0
+#define PSCI_0_2_TOS_UP_NO_MIGRATE 1
+#define PSCI_0_2_TOS_MP 2
+
+/* PSCI version decoding (independent of PSCI version) */
+#define PSCI_VERSION_MAJOR_SHIFT 16
+#define PSCI_VERSION_MINOR_MASK \
+ ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1)
+#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK
+#define PSCI_VERSION_MAJOR(ver) \
+ (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT)
+#define PSCI_VERSION_MINOR(ver) \
+ ((ver) & PSCI_VERSION_MINOR_MASK)
+
+/* PSCI return values (inclusive of all PSCI versions) */
+#define PSCI_RET_SUCCESS 0
+#define PSCI_RET_NOT_SUPPORTED -1
+#define PSCI_RET_INVALID_PARAMS -2
+#define PSCI_RET_DENIED -3
+#define PSCI_RET_ALREADY_ON -4
+#define PSCI_RET_ON_PENDING -5
+#define PSCI_RET_INTERNAL_FAILURE -6
+#define PSCI_RET_NOT_PRESENT -7
+#define PSCI_RET_DISABLED -8
+
+#endif /* _UAPI_LINUX_PSCI_H */
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 03/16] ARM/ARM64: KVM: Add base for PSCI v0.2 emulation
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
2014-05-25 18:18 ` [PATCH 01/16] KVM: Add capability to advertise PSCI v0.2 support Christoffer Dall
2014-05-25 18:18 ` [PATCH 02/16] ARM/ARM64: KVM: Add common header for PSCI related defines Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 04/16] KVM: Documentation: Add info regarding KVM_ARM_VCPU_PSCI_0_2 feature Christoffer Dall
` (12 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
Currently, the in-kernel PSCI emulation provides PSCI v0.1 interface to
VCPUs. This patch extends current in-kernel PSCI emulation to provide
PSCI v0.2 interface to VCPUs.
By default, ARM/ARM64 KVM will always provide PSCI v0.1 interface for
keeping the ABI backward-compatible.
To select PSCI v0.2 interface for VCPUs, the user space (i.e. QEMU or
KVMTOOL) will have to set KVM_ARM_VCPU_PSCI_0_2 feature when doing VCPU
init using KVM_ARM_VCPU_INIT ioctl.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/include/asm/kvm_host.h | 2 +-
arch/arm/include/asm/kvm_psci.h | 4 ++
arch/arm/include/uapi/asm/kvm.h | 10 +++--
arch/arm/kvm/psci.c | 93 ++++++++++++++++++++++++++++++++-------
arch/arm64/include/asm/kvm_host.h | 2 +-
arch/arm64/include/asm/kvm_psci.h | 4 ++
arch/arm64/include/uapi/asm/kvm.h | 10 +++--
7 files changed, 99 insertions(+), 26 deletions(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 09af149..193ceaf 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -36,7 +36,7 @@
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_HAVE_ONE_REG
-#define KVM_VCPU_MAX_FEATURES 1
+#define KVM_VCPU_MAX_FEATURES 2
#include <kvm/arm_vgic.h>
diff --git a/arch/arm/include/asm/kvm_psci.h b/arch/arm/include/asm/kvm_psci.h
index 9a83d98..4c0e3e1 100644
--- a/arch/arm/include/asm/kvm_psci.h
+++ b/arch/arm/include/asm/kvm_psci.h
@@ -18,6 +18,10 @@
#ifndef __ARM_KVM_PSCI_H__
#define __ARM_KVM_PSCI_H__
+#define KVM_ARM_PSCI_0_1 1
+#define KVM_ARM_PSCI_0_2 2
+
+int kvm_psci_version(struct kvm_vcpu *vcpu);
bool kvm_psci_call(struct kvm_vcpu *vcpu);
#endif /* __ARM_KVM_PSCI_H__ */
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index ef0c878..e6ebdd3 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -20,6 +20,7 @@
#define __ARM_KVM_H__
#include <linux/types.h>
+#include <linux/psci.h>
#include <asm/ptrace.h>
#define __KVM_HAVE_GUEST_DEBUG
@@ -83,6 +84,7 @@ struct kvm_regs {
#define KVM_VGIC_V2_CPU_SIZE 0x2000
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
+#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
struct kvm_vcpu_init {
__u32 target;
@@ -201,9 +203,9 @@ struct kvm_arch_memory_slot {
#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
-#define KVM_PSCI_RET_SUCCESS 0
-#define KVM_PSCI_RET_NI ((unsigned long)-1)
-#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
-#define KVM_PSCI_RET_DENIED ((unsigned long)-3)
+#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
+#define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
+#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
+#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
#endif /* __ARM_KVM_H__ */
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 448f60e..8c42596c 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -59,7 +59,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
* turned off.
*/
if (!vcpu || !vcpu->arch.pause)
- return KVM_PSCI_RET_INVAL;
+ return PSCI_RET_INVALID_PARAMS;
target_pc = *vcpu_reg(source_vcpu, 2);
@@ -82,20 +82,60 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
wq = kvm_arch_vcpu_wq(vcpu);
wake_up_interruptible(wq);
- return KVM_PSCI_RET_SUCCESS;
+ return PSCI_RET_SUCCESS;
}
-/**
- * kvm_psci_call - handle PSCI call if r0 value is in range
- * @vcpu: Pointer to the VCPU struct
- *
- * Handle PSCI calls from guests through traps from HVC instructions.
- * The calling convention is similar to SMC calls to the secure world where
- * the function number is placed in r0 and this function returns true if the
- * function number specified in r0 is withing the PSCI range, and false
- * otherwise.
- */
-bool kvm_psci_call(struct kvm_vcpu *vcpu)
+int kvm_psci_version(struct kvm_vcpu *vcpu)
+{
+ if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
+ return KVM_ARM_PSCI_0_2;
+
+ return KVM_ARM_PSCI_0_1;
+}
+
+static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
+{
+ unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
+ unsigned long val;
+
+ switch (psci_fn) {
+ case PSCI_0_2_FN_PSCI_VERSION:
+ /*
+ * Bits[31:16] = Major Version = 0
+ * Bits[15:0] = Minor Version = 2
+ */
+ val = 2;
+ break;
+ case PSCI_0_2_FN_CPU_OFF:
+ kvm_psci_vcpu_off(vcpu);
+ val = PSCI_RET_SUCCESS;
+ break;
+ case PSCI_0_2_FN_CPU_ON:
+ case PSCI_0_2_FN64_CPU_ON:
+ val = kvm_psci_vcpu_on(vcpu);
+ break;
+ case PSCI_0_2_FN_CPU_SUSPEND:
+ case PSCI_0_2_FN_AFFINITY_INFO:
+ case PSCI_0_2_FN_MIGRATE:
+ case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
+ case PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
+ case PSCI_0_2_FN_SYSTEM_OFF:
+ case PSCI_0_2_FN_SYSTEM_RESET:
+ case PSCI_0_2_FN64_CPU_SUSPEND:
+ case PSCI_0_2_FN64_AFFINITY_INFO:
+ case PSCI_0_2_FN64_MIGRATE:
+ case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
+ val = PSCI_RET_NOT_SUPPORTED;
+ break;
+ default:
+ return false;
+ }
+
+ *vcpu_reg(vcpu, 0) = val;
+ return true;
+}
+
+static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
{
unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
unsigned long val;
@@ -103,16 +143,15 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
switch (psci_fn) {
case KVM_PSCI_FN_CPU_OFF:
kvm_psci_vcpu_off(vcpu);
- val = KVM_PSCI_RET_SUCCESS;
+ val = PSCI_RET_SUCCESS;
break;
case KVM_PSCI_FN_CPU_ON:
val = kvm_psci_vcpu_on(vcpu);
break;
case KVM_PSCI_FN_CPU_SUSPEND:
case KVM_PSCI_FN_MIGRATE:
- val = KVM_PSCI_RET_NI;
+ val = PSCI_RET_NOT_SUPPORTED;
break;
-
default:
return false;
}
@@ -120,3 +159,25 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
*vcpu_reg(vcpu, 0) = val;
return true;
}
+
+/**
+ * kvm_psci_call - handle PSCI call if r0 value is in range
+ * @vcpu: Pointer to the VCPU struct
+ *
+ * Handle PSCI calls from guests through traps from HVC instructions.
+ * The calling convention is similar to SMC calls to the secure world where
+ * the function number is placed in r0 and this function returns true if the
+ * function number specified in r0 is withing the PSCI range, and false
+ * otherwise.
+ */
+bool kvm_psci_call(struct kvm_vcpu *vcpu)
+{
+ switch (kvm_psci_version(vcpu)) {
+ case KVM_ARM_PSCI_0_2:
+ return kvm_psci_0_2_call(vcpu);
+ case KVM_ARM_PSCI_0_1:
+ return kvm_psci_0_1_call(vcpu);
+ default:
+ return false;
+ };
+}
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0a1d697..92242ce 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -39,7 +39,7 @@
#include <kvm/arm_vgic.h>
#include <kvm/arm_arch_timer.h>
-#define KVM_VCPU_MAX_FEATURES 2
+#define KVM_VCPU_MAX_FEATURES 3
struct kvm_vcpu;
int kvm_target_cpu(void);
diff --git a/arch/arm64/include/asm/kvm_psci.h b/arch/arm64/include/asm/kvm_psci.h
index e301a48..e25c658 100644
--- a/arch/arm64/include/asm/kvm_psci.h
+++ b/arch/arm64/include/asm/kvm_psci.h
@@ -18,6 +18,10 @@
#ifndef __ARM64_KVM_PSCI_H__
#define __ARM64_KVM_PSCI_H__
+#define KVM_ARM_PSCI_0_1 1
+#define KVM_ARM_PSCI_0_2 2
+
+int kvm_psci_version(struct kvm_vcpu *vcpu);
bool kvm_psci_call(struct kvm_vcpu *vcpu);
#endif /* __ARM64_KVM_PSCI_H__ */
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index eaf54a3..e6471da 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -31,6 +31,7 @@
#define KVM_NR_SPSR 5
#ifndef __ASSEMBLY__
+#include <linux/psci.h>
#include <asm/types.h>
#include <asm/ptrace.h>
@@ -77,6 +78,7 @@ struct kvm_regs {
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
+#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
struct kvm_vcpu_init {
__u32 target;
@@ -186,10 +188,10 @@ struct kvm_arch_memory_slot {
#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
-#define KVM_PSCI_RET_SUCCESS 0
-#define KVM_PSCI_RET_NI ((unsigned long)-1)
-#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
-#define KVM_PSCI_RET_DENIED ((unsigned long)-3)
+#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
+#define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
+#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
+#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
#endif
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 04/16] KVM: Documentation: Add info regarding KVM_ARM_VCPU_PSCI_0_2 feature
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (2 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 03/16] ARM/ARM64: KVM: Add base for PSCI v0.2 emulation Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 05/16] ARM/ARM64: KVM: Make kvm_psci_call() return convention more flexible Christoffer Dall
` (11 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
We have in-kernel emulation of PSCI v0.2 in KVM ARM/ARM64. To provide
PSCI v0.2 interface to VCPUs, we have to enable KVM_ARM_VCPU_PSCI_0_2
feature when doing KVM_ARM_VCPU_INIT ioctl.
The patch updates documentation of KVM_ARM_VCPU_INIT ioctl to provide
info regarding KVM_ARM_VCPU_PSCI_0_2 feature.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
Documentation/virtual/kvm/api.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 2014ff1..556d056 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2376,6 +2376,8 @@ Possible features:
Depends on KVM_CAP_ARM_PSCI.
- KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode.
Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only).
+ - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU.
+ Depends on KVM_CAP_ARM_PSCI_0_2.
4.83 KVM_ARM_PREFERRED_TARGET
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 05/16] ARM/ARM64: KVM: Make kvm_psci_call() return convention more flexible
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (3 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 04/16] KVM: Documentation: Add info regarding KVM_ARM_VCPU_PSCI_0_2 feature Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header Christoffer Dall
` (10 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
Currently, the kvm_psci_call() returns 'true' or 'false' based on whether
the PSCI function call was handled successfully or not. This does not help
us emulate system-level PSCI functions where the actual emulation work will
be done by user space (QEMU or KVMTOOL). Examples of such system-level PSCI
functions are: PSCI v0.2 SYSTEM_OFF and SYSTEM_RESET.
This patch updates kvm_psci_call() to return three types of values:
1) > 0 (success)
2) = 0 (success but exit to user space)
3) < 0 (errors)
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/include/asm/kvm_psci.h | 2 +-
arch/arm/kvm/handle_exit.c | 10 +++++++---
arch/arm/kvm/psci.c | 28 ++++++++++++++++------------
arch/arm64/include/asm/kvm_psci.h | 2 +-
arch/arm64/kvm/handle_exit.c | 10 +++++++---
5 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/arch/arm/include/asm/kvm_psci.h b/arch/arm/include/asm/kvm_psci.h
index 4c0e3e1..6bda945 100644
--- a/arch/arm/include/asm/kvm_psci.h
+++ b/arch/arm/include/asm/kvm_psci.h
@@ -22,6 +22,6 @@
#define KVM_ARM_PSCI_0_2 2
int kvm_psci_version(struct kvm_vcpu *vcpu);
-bool kvm_psci_call(struct kvm_vcpu *vcpu);
+int kvm_psci_call(struct kvm_vcpu *vcpu);
#endif /* __ARM_KVM_PSCI_H__ */
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
index 0de91fc..4c979d4 100644
--- a/arch/arm/kvm/handle_exit.c
+++ b/arch/arm/kvm/handle_exit.c
@@ -38,14 +38,18 @@ static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
+ int ret;
+
trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
kvm_vcpu_hvc_get_imm(vcpu));
- if (kvm_psci_call(vcpu))
+ ret = kvm_psci_call(vcpu);
+ if (ret < 0) {
+ kvm_inject_undefined(vcpu);
return 1;
+ }
- kvm_inject_undefined(vcpu);
- return 1;
+ return ret;
}
static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 8c42596c..14e6fa6 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -93,7 +93,7 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
return KVM_ARM_PSCI_0_1;
}
-static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
+static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
{
unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
unsigned long val;
@@ -128,14 +128,14 @@ static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
val = PSCI_RET_NOT_SUPPORTED;
break;
default:
- return false;
+ return -EINVAL;
}
*vcpu_reg(vcpu, 0) = val;
- return true;
+ return 1;
}
-static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
+static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
{
unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
unsigned long val;
@@ -153,11 +153,11 @@ static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
val = PSCI_RET_NOT_SUPPORTED;
break;
default:
- return false;
+ return -EINVAL;
}
*vcpu_reg(vcpu, 0) = val;
- return true;
+ return 1;
}
/**
@@ -165,12 +165,16 @@ static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
* @vcpu: Pointer to the VCPU struct
*
* Handle PSCI calls from guests through traps from HVC instructions.
- * The calling convention is similar to SMC calls to the secure world where
- * the function number is placed in r0 and this function returns true if the
- * function number specified in r0 is withing the PSCI range, and false
- * otherwise.
+ * The calling convention is similar to SMC calls to the secure world
+ * where the function number is placed in r0.
+ *
+ * This function returns: > 0 (success), 0 (success but exit to user
+ * space), and < 0 (errors)
+ *
+ * Errors:
+ * -EINVAL: Unrecognized PSCI function
*/
-bool kvm_psci_call(struct kvm_vcpu *vcpu)
+int kvm_psci_call(struct kvm_vcpu *vcpu)
{
switch (kvm_psci_version(vcpu)) {
case KVM_ARM_PSCI_0_2:
@@ -178,6 +182,6 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
case KVM_ARM_PSCI_0_1:
return kvm_psci_0_1_call(vcpu);
default:
- return false;
+ return -EINVAL;
};
}
diff --git a/arch/arm64/include/asm/kvm_psci.h b/arch/arm64/include/asm/kvm_psci.h
index e25c658..bc39e55 100644
--- a/arch/arm64/include/asm/kvm_psci.h
+++ b/arch/arm64/include/asm/kvm_psci.h
@@ -22,6 +22,6 @@
#define KVM_ARM_PSCI_0_2 2
int kvm_psci_version(struct kvm_vcpu *vcpu);
-bool kvm_psci_call(struct kvm_vcpu *vcpu);
+int kvm_psci_call(struct kvm_vcpu *vcpu);
#endif /* __ARM64_KVM_PSCI_H__ */
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 7bc41ea..182415e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -30,11 +30,15 @@ typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
- if (kvm_psci_call(vcpu))
+ int ret;
+
+ ret = kvm_psci_call(vcpu);
+ if (ret < 0) {
+ kvm_inject_undefined(vcpu);
return 1;
+ }
- kvm_inject_undefined(vcpu);
- return 1;
+ return ret;
}
static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (4 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 05/16] ARM/ARM64: KVM: Make kvm_psci_call() return convention more flexible Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-08-29 17:39 ` Peter Maydell
2014-05-25 18:18 ` [PATCH 07/16] ARM/ARM64: KVM: Emulate PSCI v0.2 SYSTEM_OFF and SYSTEM_RESET Christoffer Dall
` (9 subsequent siblings)
15 siblings, 1 reply; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
Currently, we don't have an exit reason to notify user space about
a system-level event (for e.g. system reset or shutdown) triggered
by the VCPU. This patch adds exit reason KVM_EXIT_SYSTEM_EVENT for
this purpose. We can also inform user space about the 'type' and
architecture specific 'flags' of a system-level event using the
kvm_run structure.
This newly added KVM_EXIT_SYSTEM_EVENT will be used by KVM ARM/ARM64
in-kernel PSCI v0.2 support to reset/shutdown VMs.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
Documentation/virtual/kvm/api.txt | 15 +++++++++++++++
include/uapi/linux/kvm.h | 8 ++++++++
2 files changed, 23 insertions(+)
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 556d056..6a5de56 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2740,6 +2740,21 @@ It gets triggered whenever both KVM_CAP_PPC_EPR are enabled and an
external interrupt has just been delivered into the guest. User space
should put the acknowledged interrupt vector into the 'epr' field.
+ /* KVM_EXIT_SYSTEM_EVENT */
+ struct {
+#define KVM_SYSTEM_EVENT_SHUTDOWN 1
+#define KVM_SYSTEM_EVENT_RESET 2
+ __u32 type;
+ __u64 flags;
+ } system_event;
+
+If exit_reason is KVM_EXIT_SYSTEM_EVENT then the vcpu has triggered
+a system-level event using some architecture specific mechanism (hypercall
+or some special instruction). In case of ARM/ARM64, this is triggered using
+HVC instruction based PSCI call from the vcpu. The 'type' field describes
+the system-level event type. The 'flags' field describes architecture
+specific flags for the system-level event.
+
/* Fix the size of the union. */
char padding[256];
};
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index f3252b1..16cb1a1 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -171,6 +171,7 @@ struct kvm_pit_config {
#define KVM_EXIT_WATCHDOG 21
#define KVM_EXIT_S390_TSCH 22
#define KVM_EXIT_EPR 23
+#define KVM_EXIT_SYSTEM_EVENT 24
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -301,6 +302,13 @@ struct kvm_run {
struct {
__u32 epr;
} epr;
+ /* KVM_EXIT_SYSTEM_EVENT */
+ struct {
+#define KVM_SYSTEM_EVENT_SHUTDOWN 1
+#define KVM_SYSTEM_EVENT_RESET 2
+ __u32 type;
+ __u64 flags;
+ } system_event;
/* Fix the size of the union. */
char padding[256];
};
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header
2014-05-25 18:18 ` [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header Christoffer Dall
@ 2014-08-29 17:39 ` Peter Maydell
2014-09-01 9:20 ` Christoffer Dall
0 siblings, 1 reply; 27+ messages in thread
From: Peter Maydell @ 2014-08-29 17:39 UTC (permalink / raw)
To: linux-arm-kernel
On 25 May 2014 19:18, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> From: Anup Patel <anup.patel@linaro.org>
>
> Currently, we don't have an exit reason to notify user space about
> a system-level event (for e.g. system reset or shutdown) triggered
> by the VCPU. This patch adds exit reason KVM_EXIT_SYSTEM_EVENT for
> this purpose. We can also inform user space about the 'type' and
> architecture specific 'flags' of a system-level event using the
> kvm_run structure.
>
> This newly added KVM_EXIT_SYSTEM_EVENT will be used by KVM ARM/ARM64
> in-kernel PSCI v0.2 support to reset/shutdown VMs.
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -2740,6 +2740,21 @@ It gets triggered whenever both KVM_CAP_PPC_EPR are enabled and an
> external interrupt has just been delivered into the guest. User space
> should put the acknowledged interrupt vector into the 'epr' field.
>
> + /* KVM_EXIT_SYSTEM_EVENT */
> + struct {
> +#define KVM_SYSTEM_EVENT_SHUTDOWN 1
> +#define KVM_SYSTEM_EVENT_RESET 2
> + __u32 type;
> + __u64 flags;
> + } system_event;
> +
> +If exit_reason is KVM_EXIT_SYSTEM_EVENT then the vcpu has triggered
> +a system-level event using some architecture specific mechanism (hypercall
> +or some special instruction). In case of ARM/ARM64, this is triggered using
> +HVC instruction based PSCI call from the vcpu. The 'type' field describes
> +the system-level event type. The 'flags' field describes architecture
> +specific flags for the system-level event.
Talking with Ard I realised that there's actually a hole in the
specification of this new ABI. Did we intend these shutdown
and reset exits to be:
(1) requests from the guest for the shutdown/reset to be
scheduled in the near future (and we'll continue to execute
the guest until the shutdown actually happens)
(2) requests for shutdown/reset right now, with no further
guest instructions to be executed
?
As currently implemented in QEMU we get behaviour (1),
but I think the kernel PSCI implementation assumes
behaviour (2). Who's right?
thanks
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header
2014-08-29 17:39 ` Peter Maydell
@ 2014-09-01 9:20 ` Christoffer Dall
2014-09-01 9:30 ` Peter Maydell
0 siblings, 1 reply; 27+ messages in thread
From: Christoffer Dall @ 2014-09-01 9:20 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Aug 29, 2014 at 06:39:09PM +0100, Peter Maydell wrote:
> On 25 May 2014 19:18, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> > From: Anup Patel <anup.patel@linaro.org>
> >
> > Currently, we don't have an exit reason to notify user space about
> > a system-level event (for e.g. system reset or shutdown) triggered
> > by the VCPU. This patch adds exit reason KVM_EXIT_SYSTEM_EVENT for
> > this purpose. We can also inform user space about the 'type' and
> > architecture specific 'flags' of a system-level event using the
> > kvm_run structure.
> >
> > This newly added KVM_EXIT_SYSTEM_EVENT will be used by KVM ARM/ARM64
> > in-kernel PSCI v0.2 support to reset/shutdown VMs.
>
> > --- a/Documentation/virtual/kvm/api.txt
> > +++ b/Documentation/virtual/kvm/api.txt
> > @@ -2740,6 +2740,21 @@ It gets triggered whenever both KVM_CAP_PPC_EPR are enabled and an
> > external interrupt has just been delivered into the guest. User space
> > should put the acknowledged interrupt vector into the 'epr' field.
> >
> > + /* KVM_EXIT_SYSTEM_EVENT */
> > + struct {
> > +#define KVM_SYSTEM_EVENT_SHUTDOWN 1
> > +#define KVM_SYSTEM_EVENT_RESET 2
> > + __u32 type;
> > + __u64 flags;
> > + } system_event;
> > +
> > +If exit_reason is KVM_EXIT_SYSTEM_EVENT then the vcpu has triggered
> > +a system-level event using some architecture specific mechanism (hypercall
> > +or some special instruction). In case of ARM/ARM64, this is triggered using
> > +HVC instruction based PSCI call from the vcpu. The 'type' field describes
> > +the system-level event type. The 'flags' field describes architecture
> > +specific flags for the system-level event.
>
> Talking with Ard I realised that there's actually a hole in the
> specification of this new ABI. Did we intend these shutdown
> and reset exits to be:
> (1) requests from the guest for the shutdown/reset to be
> scheduled in the near future (and we'll continue to execute
> the guest until the shutdown actually happens)
> (2) requests for shutdown/reset right now, with no further
> guest instructions to be executed
>
> ?
>
> As currently implemented in QEMU we get behaviour (1),
> but I think the kernel PSCI implementation assumes
> behaviour (2). Who's right?
>
For the arm/arm64 use of this API (currently the only one?) the host
would not break or anything like that if you keep executing the VM, but
the guest will expect that no other instructions are executed after this
call.
The PSCI spec states that it's the responsibility of the PSCI
implementation (here KVM), that "Implementation must ensure that all
cores are in a known state with caches cleaned". I guess we don't need
to worry about the latter, but we could handle the former by pausing all
VCPUs prior to exiting with the SHUTDOWN system event. In that
scenario, user space could choose to do either (1) or (2), but it gets a
little fishy with a reset if we set the pause flag, because we would
then at least need to specify in this ABI that this happens for
ARM/ARM64 on reset.
We could clarify this ABI to the fact that user space should not run any
VCPUs after receiving this event, but the above change should probably
be made anyhow, to make sure KVM implements PSCI as much as it can in
the kernel?
-Christoffer
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header
2014-09-01 9:20 ` Christoffer Dall
@ 2014-09-01 9:30 ` Peter Maydell
2014-09-01 9:56 ` Christoffer Dall
0 siblings, 1 reply; 27+ messages in thread
From: Peter Maydell @ 2014-09-01 9:30 UTC (permalink / raw)
To: linux-arm-kernel
On 1 September 2014 10:20, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> On Fri, Aug 29, 2014 at 06:39:09PM +0100, Peter Maydell wrote:
>> Talking with Ard I realised that there's actually a hole in the
>> specification of this new ABI. Did we intend these shutdown
>> and reset exits to be:
>> (1) requests from the guest for the shutdown/reset to be
>> scheduled in the near future (and we'll continue to execute
>> the guest until the shutdown actually happens)
>> (2) requests for shutdown/reset right now, with no further
>> guest instructions to be executed
>>
>> ?
>>
>> As currently implemented in QEMU we get behaviour (1),
>> but I think the kernel PSCI implementation assumes
>> behaviour (2). Who's right?
>>
> For the arm/arm64 use of this API (currently the only one?) the host
> would not break or anything like that if you keep executing the VM, but
> the guest will expect that no other instructions are executed after this
> call.
Well, if we do that then between QEMU and KVM we've
violated the PSCI ABI we're supposed to provide, so somebody
is wrong :-)
I guess that since the kernel already implements "assume
userspace won't resume the guest vcpu" the path of least
resistance is to make userspace follow that.
What does kvmtool do here (if it implements PSCI shutdown
and reset at all)?
thanks
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header
2014-09-01 9:30 ` Peter Maydell
@ 2014-09-01 9:56 ` Christoffer Dall
2014-09-01 10:11 ` Peter Maydell
0 siblings, 1 reply; 27+ messages in thread
From: Christoffer Dall @ 2014-09-01 9:56 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Sep 01, 2014 at 10:30:17AM +0100, Peter Maydell wrote:
> On 1 September 2014 10:20, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> > On Fri, Aug 29, 2014 at 06:39:09PM +0100, Peter Maydell wrote:
> >> Talking with Ard I realised that there's actually a hole in the
> >> specification of this new ABI. Did we intend these shutdown
> >> and reset exits to be:
> >> (1) requests from the guest for the shutdown/reset to be
> >> scheduled in the near future (and we'll continue to execute
> >> the guest until the shutdown actually happens)
> >> (2) requests for shutdown/reset right now, with no further
> >> guest instructions to be executed
> >>
> >> ?
> >>
> >> As currently implemented in QEMU we get behaviour (1),
> >> but I think the kernel PSCI implementation assumes
> >> behaviour (2). Who's right?
> >>
> > For the arm/arm64 use of this API (currently the only one?) the host
> > would not break or anything like that if you keep executing the VM, but
> > the guest will expect that no other instructions are executed after this
> > call.
>
> Well, if we do that then between QEMU and KVM we've
> violated the PSCI ABI we're supposed to provide, so somebody
> is wrong :-)
>
> I guess that since the kernel already implements "assume
> userspace won't resume the guest vcpu" the path of least
> resistance is to make userspace follow that.
The thing is that we're not exposing PSCI to user space, we're just
exposing a system event, so it feels a bit weird to rely on user space's
correct interpretation of a more generic API, to correctly implement
PSCI in the kernel. On the other hand, user space can always break the
guest as it sees fit...
-Christoffer
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header
2014-09-01 9:56 ` Christoffer Dall
@ 2014-09-01 10:11 ` Peter Maydell
0 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2014-09-01 10:11 UTC (permalink / raw)
To: linux-arm-kernel
On 1 September 2014 10:56, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> The thing is that we're not exposing PSCI to user space, we're just
> exposing a system event, so it feels a bit weird to rely on user space's
> correct interpretation of a more generic API, to correctly implement
> PSCI in the kernel.
Yeah; if somebody wants to argue that the other set of semantics
make more sense considered purely as a KVM kernel-to-user
API I have no objection. (QEMU's current "we'll do that at some
point in the future" implementation follows the typical semantics
for reset/shutdown triggered by a device register write I think:
the write-to-device-register instruction will generally complete
and CPU execution continue before the prodded device can
get the system reset process done. But we don't necessarily
need to be bound by that idea.)
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 07/16] ARM/ARM64: KVM: Emulate PSCI v0.2 SYSTEM_OFF and SYSTEM_RESET
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (5 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 06/16] KVM: Add KVM_EXIT_SYSTEM_EVENT to user space API header Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 08/16] ARM/ARM64: KVM: Emulate PSCI v0.2 AFFINITY_INFO Christoffer Dall
` (8 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
The PSCI v0.2 SYSTEM_OFF and SYSTEM_RESET functions are system-level
functions hence cannot be fully emulated by in-kernel PSCI emulation code.
To tackle this, we forward PSCI v0.2 SYSTEM_OFF and SYSTEM_RESET function
calls from vcpu to user space (i.e. QEMU or KVMTOOL) via kvm_run structure
using KVM_EXIT_SYSTEM_EVENT exit reasons.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/kvm/psci.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 14e6fa6..5936213 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -85,6 +85,23 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
return PSCI_RET_SUCCESS;
}
+static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
+{
+ memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event));
+ vcpu->run->system_event.type = type;
+ vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+}
+
+static void kvm_psci_system_off(struct kvm_vcpu *vcpu)
+{
+ kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_SHUTDOWN);
+}
+
+static void kvm_psci_system_reset(struct kvm_vcpu *vcpu)
+{
+ kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET);
+}
+
int kvm_psci_version(struct kvm_vcpu *vcpu)
{
if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
@@ -95,6 +112,7 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
{
+ int ret = 1;
unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
unsigned long val;
@@ -114,13 +132,35 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
case PSCI_0_2_FN64_CPU_ON:
val = kvm_psci_vcpu_on(vcpu);
break;
+ case PSCI_0_2_FN_SYSTEM_OFF:
+ kvm_psci_system_off(vcpu);
+ /*
+ * We should'nt be going back to guest VCPU after
+ * receiving SYSTEM_OFF request.
+ *
+ * If user space accidently/deliberately resumes
+ * guest VCPU after SYSTEM_OFF request then guest
+ * VCPU should see internal failure from PSCI return
+ * value. To achieve this, we preload r0 (or x0) with
+ * PSCI return value INTERNAL_FAILURE.
+ */
+ val = PSCI_RET_INTERNAL_FAILURE;
+ ret = 0;
+ break;
+ case PSCI_0_2_FN_SYSTEM_RESET:
+ kvm_psci_system_reset(vcpu);
+ /*
+ * Same reason as SYSTEM_OFF for preloading r0 (or x0)
+ * with PSCI return value INTERNAL_FAILURE.
+ */
+ val = PSCI_RET_INTERNAL_FAILURE;
+ ret = 0;
+ break;
case PSCI_0_2_FN_CPU_SUSPEND:
case PSCI_0_2_FN_AFFINITY_INFO:
case PSCI_0_2_FN_MIGRATE:
case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
case PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
- case PSCI_0_2_FN_SYSTEM_OFF:
- case PSCI_0_2_FN_SYSTEM_RESET:
case PSCI_0_2_FN64_CPU_SUSPEND:
case PSCI_0_2_FN64_AFFINITY_INFO:
case PSCI_0_2_FN64_MIGRATE:
@@ -132,7 +172,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
}
*vcpu_reg(vcpu, 0) = val;
- return 1;
+ return ret;
}
static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 08/16] ARM/ARM64: KVM: Emulate PSCI v0.2 AFFINITY_INFO
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (6 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 07/16] ARM/ARM64: KVM: Emulate PSCI v0.2 SYSTEM_OFF and SYSTEM_RESET Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 09/16] ARM/ARM64: KVM: Emulate PSCI v0.2 MIGRATE_INFO_TYPE and related functions Christoffer Dall
` (7 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
This patch adds emulation of PSCI v0.2 AFFINITY_INFO function call
for KVM ARM/ARM64. This is a VCPU-level function call which will be
used to determine current state of given affinity level.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/kvm/psci.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 5936213..3b6a0cf 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -27,6 +27,16 @@
* as described in ARM document number ARM DEN 0022A.
*/
+#define AFFINITY_MASK(level) ~((0x1UL << ((level) * MPIDR_LEVEL_BITS)) - 1)
+
+static unsigned long psci_affinity_mask(unsigned long affinity_level)
+{
+ if (affinity_level <= 3)
+ return MPIDR_HWID_BITMASK & AFFINITY_MASK(affinity_level);
+
+ return 0;
+}
+
static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
{
vcpu->arch.pause = true;
@@ -85,6 +95,42 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
return PSCI_RET_SUCCESS;
}
+static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
+{
+ int i;
+ unsigned long mpidr;
+ unsigned long target_affinity;
+ unsigned long target_affinity_mask;
+ unsigned long lowest_affinity_level;
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_vcpu *tmp;
+
+ target_affinity = *vcpu_reg(vcpu, 1);
+ lowest_affinity_level = *vcpu_reg(vcpu, 2);
+
+ /* Determine target affinity mask */
+ target_affinity_mask = psci_affinity_mask(lowest_affinity_level);
+ if (!target_affinity_mask)
+ return PSCI_RET_INVALID_PARAMS;
+
+ /* Ignore other bits of target affinity */
+ target_affinity &= target_affinity_mask;
+
+ /*
+ * If one or more VCPU matching target affinity are running
+ * then ON else OFF
+ */
+ kvm_for_each_vcpu(i, tmp, kvm) {
+ mpidr = kvm_vcpu_get_mpidr(tmp);
+ if (((mpidr & target_affinity_mask) == target_affinity) &&
+ !tmp->arch.pause) {
+ return PSCI_0_2_AFFINITY_LEVEL_ON;
+ }
+ }
+
+ return PSCI_0_2_AFFINITY_LEVEL_OFF;
+}
+
static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
{
memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event));
@@ -132,6 +178,10 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
case PSCI_0_2_FN64_CPU_ON:
val = kvm_psci_vcpu_on(vcpu);
break;
+ case PSCI_0_2_FN_AFFINITY_INFO:
+ case PSCI_0_2_FN64_AFFINITY_INFO:
+ val = kvm_psci_vcpu_affinity_info(vcpu);
+ break;
case PSCI_0_2_FN_SYSTEM_OFF:
kvm_psci_system_off(vcpu);
/*
@@ -157,12 +207,10 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
ret = 0;
break;
case PSCI_0_2_FN_CPU_SUSPEND:
- case PSCI_0_2_FN_AFFINITY_INFO:
case PSCI_0_2_FN_MIGRATE:
case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
case PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
case PSCI_0_2_FN64_CPU_SUSPEND:
- case PSCI_0_2_FN64_AFFINITY_INFO:
case PSCI_0_2_FN64_MIGRATE:
case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
val = PSCI_RET_NOT_SUPPORTED;
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 09/16] ARM/ARM64: KVM: Emulate PSCI v0.2 MIGRATE_INFO_TYPE and related functions
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (7 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 08/16] ARM/ARM64: KVM: Emulate PSCI v0.2 AFFINITY_INFO Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 10/16] ARM/ARM64: KVM: Fix CPU_ON emulation for PSCI v0.2 Christoffer Dall
` (6 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
This patch adds emulation of PSCI v0.2 MIGRATE, MIGRATE_INFO_TYPE, and
MIGRATE_INFO_UP_CPU function calls for KVM ARM/ARM64.
KVM ARM/ARM64 being a hypervisor (and not a Trusted OS), we cannot provide
this functions hence we emulate these functions in following way:
1. MIGRATE - Returns "Not Supported"
2. MIGRATE_INFO_TYPE - Return 2 i.e. Trusted OS is not present
3. MIGRATE_INFO_UP_CPU - Returns "Not Supported"
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/kvm/psci.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 3b6a0cf..cce901a 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -182,6 +182,22 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
case PSCI_0_2_FN64_AFFINITY_INFO:
val = kvm_psci_vcpu_affinity_info(vcpu);
break;
+ case PSCI_0_2_FN_MIGRATE:
+ case PSCI_0_2_FN64_MIGRATE:
+ val = PSCI_RET_NOT_SUPPORTED;
+ break;
+ case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
+ /*
+ * Trusted OS is MP hence does not require migration
+ * or
+ * Trusted OS is not present
+ */
+ val = PSCI_0_2_TOS_MP;
+ break;
+ case PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
+ case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
+ val = PSCI_RET_NOT_SUPPORTED;
+ break;
case PSCI_0_2_FN_SYSTEM_OFF:
kvm_psci_system_off(vcpu);
/*
@@ -207,12 +223,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
ret = 0;
break;
case PSCI_0_2_FN_CPU_SUSPEND:
- case PSCI_0_2_FN_MIGRATE:
- case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
- case PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
case PSCI_0_2_FN64_CPU_SUSPEND:
- case PSCI_0_2_FN64_MIGRATE:
- case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
val = PSCI_RET_NOT_SUPPORTED;
break;
default:
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 10/16] ARM/ARM64: KVM: Fix CPU_ON emulation for PSCI v0.2
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (8 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 09/16] ARM/ARM64: KVM: Emulate PSCI v0.2 MIGRATE_INFO_TYPE and related functions Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 11/16] ARM/ARM64: KVM: Emulate PSCI v0.2 CPU_SUSPEND Christoffer Dall
` (5 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
As-per PSCI v0.2, the source CPU provides physical address of
"entry point" and "context id" for starting a target CPU. Also,
if target CPU is already running then we should return ALREADY_ON.
Current emulation of CPU_ON function does not consider physical
address of "context id" and returns INVALID_PARAMETERS if target
CPU is already running.
This patch updates kvm_psci_vcpu_on() such that it works for both
PSCI v0.1 and PSCI v0.2.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/kvm/psci.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index cce901a..1067579 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -48,6 +48,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
struct kvm_vcpu *vcpu = NULL, *tmp;
wait_queue_head_t *wq;
unsigned long cpu_id;
+ unsigned long context_id;
unsigned long mpidr;
phys_addr_t target_pc;
int i;
@@ -68,10 +69,17 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
* Make sure the caller requested a valid CPU and that the CPU is
* turned off.
*/
- if (!vcpu || !vcpu->arch.pause)
+ if (!vcpu)
return PSCI_RET_INVALID_PARAMS;
+ if (!vcpu->arch.pause) {
+ if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1)
+ return PSCI_RET_ALREADY_ON;
+ else
+ return PSCI_RET_INVALID_PARAMS;
+ }
target_pc = *vcpu_reg(source_vcpu, 2);
+ context_id = *vcpu_reg(source_vcpu, 3);
kvm_reset_vcpu(vcpu);
@@ -86,6 +94,11 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
kvm_vcpu_set_be(vcpu);
*vcpu_pc(vcpu) = target_pc;
+ /*
+ * NOTE: We always update r0 (or x0) because for PSCI v0.1
+ * the general puspose registers are undefined upon CPU_ON.
+ */
+ *vcpu_reg(vcpu, 0) = context_id;
vcpu->arch.pause = false;
smp_mb(); /* Make sure the above is visible */
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 11/16] ARM/ARM64: KVM: Emulate PSCI v0.2 CPU_SUSPEND
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (9 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 10/16] ARM/ARM64: KVM: Fix CPU_ON emulation for PSCI v0.2 Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 12/16] ARM/ARM64: KVM: Advertise KVM_CAP_ARM_PSCI_0_2 to user space Christoffer Dall
` (4 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
This patch adds emulation of PSCI v0.2 CPU_SUSPEND function call for
KVM ARM/ARM64. This is a CPU-level function call which can suspend
current CPU or current CPU cluster. We don't have VCPU clusters in
KVM so we only suspend the current VCPU.
The CPU_SUSPEND emulation is not tested much because currently there
is no CPUIDLE driver in Linux kernel that uses PSCI CPU_SUSPEND. The
PSCI CPU_SUSPEND implementation in ARM64 kernel was tested using a
Simple CPUIDLE driver which is not published due to unstable DT-bindings
for PSCI.
(For more info, http://lwn.net/Articles/574950/)
For simplicity, we implement CPU_SUSPEND emulation similar to WFI
(Wait-for-interrupt) emulation and we also treat power-down request
to be same as stand-by request. This is consistent with section
5.4.1 and section 5.4.2 of PSCI v0.2 specification.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/kvm/psci.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 1067579..09cf377 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -37,6 +37,26 @@ static unsigned long psci_affinity_mask(unsigned long affinity_level)
return 0;
}
+static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
+{
+ /*
+ * NOTE: For simplicity, we make VCPU suspend emulation to be
+ * same-as WFI (Wait-for-interrupt) emulation.
+ *
+ * This means for KVM the wakeup events are interrupts and
+ * this is consistent with intended use of StateID as described
+ * in section 5.4.1 of PSCI v0.2 specification (ARM DEN 0022A).
+ *
+ * Further, we also treat power-down request to be same as
+ * stand-by request as-per section 5.4.2 clause 3 of PSCI v0.2
+ * specification (ARM DEN 0022A). This means all suspend states
+ * for KVM will preserve the register state.
+ */
+ kvm_vcpu_block(vcpu);
+
+ return PSCI_RET_SUCCESS;
+}
+
static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
{
vcpu->arch.pause = true;
@@ -183,6 +203,10 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
*/
val = 2;
break;
+ case PSCI_0_2_FN_CPU_SUSPEND:
+ case PSCI_0_2_FN64_CPU_SUSPEND:
+ val = kvm_psci_vcpu_suspend(vcpu);
+ break;
case PSCI_0_2_FN_CPU_OFF:
kvm_psci_vcpu_off(vcpu);
val = PSCI_RET_SUCCESS;
@@ -235,10 +259,6 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
val = PSCI_RET_INTERNAL_FAILURE;
ret = 0;
break;
- case PSCI_0_2_FN_CPU_SUSPEND:
- case PSCI_0_2_FN64_CPU_SUSPEND:
- val = PSCI_RET_NOT_SUPPORTED;
- break;
default:
return -EINVAL;
}
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 12/16] ARM/ARM64: KVM: Advertise KVM_CAP_ARM_PSCI_0_2 to user space
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (10 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 11/16] ARM/ARM64: KVM: Emulate PSCI v0.2 CPU_SUSPEND Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-25 18:18 ` [PATCH 13/16] PSCI: Add initial support for PSCIv0.2 functions Christoffer Dall
` (3 subsequent siblings)
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Anup Patel <anup.patel@linaro.org>
We have PSCI v0.2 emulation available in KVM ARM/ARM64
hence advertise this to user space (i.e. QEMU or KVMTOOL)
via KVM_CHECK_EXTENSION ioctl.
Signed-off-by: Anup Patel <anup.patel@linaro.org>
Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/kvm/arm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index f0e50a0..3c82b37 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -197,6 +197,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
case KVM_CAP_ONE_REG:
case KVM_CAP_ARM_PSCI:
+ case KVM_CAP_ARM_PSCI_0_2:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 13/16] PSCI: Add initial support for PSCIv0.2 functions
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (11 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 12/16] ARM/ARM64: KVM: Advertise KVM_CAP_ARM_PSCI_0_2 to user space Christoffer Dall
@ 2014-05-25 18:18 ` Christoffer Dall
2014-05-27 7:44 ` Shawn Guo
2014-05-25 18:19 ` [PATCH 14/16] Documentation: devicetree: Add new binding for PSCIv0.2 Christoffer Dall
` (2 subsequent siblings)
15 siblings, 1 reply; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
From: Ashwin Chaugule <ashwin.chaugule@linaro.org>
The PSCIv0.2 spec defines standard values of function IDs
and introduces a few new functions. Detect version of PSCI
and appropriately select the right PSCI functions.
Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/include/asm/psci.h | 7 +-
arch/arm/kernel/psci.c | 196 +++++++++++++++++++++++++++++++++--------
arch/arm64/include/asm/psci.h | 2 +-
arch/arm64/kernel/psci.c | 200 ++++++++++++++++++++++++++++++++++--------
4 files changed, 328 insertions(+), 77 deletions(-)
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
index c4ae171..b93e34a 100644
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -29,16 +29,19 @@ struct psci_operations {
int (*cpu_off)(struct psci_power_state state);
int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
int (*migrate)(unsigned long cpuid);
+ int (*affinity_info)(unsigned long target_affinity,
+ unsigned long lowest_affinity_level);
+ int (*migrate_info_type)(void);
};
extern struct psci_operations psci_ops;
extern struct smp_operations psci_smp_ops;
#ifdef CONFIG_ARM_PSCI
-void psci_init(void);
+int psci_init(void);
bool psci_smp_available(void);
#else
-static inline void psci_init(void) { }
+static inline int psci_init(void) { }
static inline bool psci_smp_available(void) { return false; }
#endif
diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
index 4693188..f73891b 100644
--- a/arch/arm/kernel/psci.c
+++ b/arch/arm/kernel/psci.c
@@ -17,63 +17,58 @@
#include <linux/init.h>
#include <linux/of.h>
+#include <linux/reboot.h>
+#include <linux/pm.h>
+#include <uapi/linux/psci.h>
#include <asm/compiler.h>
#include <asm/errno.h>
#include <asm/opcodes-sec.h>
#include <asm/opcodes-virt.h>
#include <asm/psci.h>
+#include <asm/system_misc.h>
struct psci_operations psci_ops;
static int (*invoke_psci_fn)(u32, u32, u32, u32);
+typedef int (*psci_initcall_t)(const struct device_node *);
enum psci_function {
PSCI_FN_CPU_SUSPEND,
PSCI_FN_CPU_ON,
PSCI_FN_CPU_OFF,
PSCI_FN_MIGRATE,
+ PSCI_FN_AFFINITY_INFO,
+ PSCI_FN_MIGRATE_INFO_TYPE,
PSCI_FN_MAX,
};
static u32 psci_function_id[PSCI_FN_MAX];
-#define PSCI_RET_SUCCESS 0
-#define PSCI_RET_EOPNOTSUPP -1
-#define PSCI_RET_EINVAL -2
-#define PSCI_RET_EPERM -3
-
static int psci_to_linux_errno(int errno)
{
switch (errno) {
case PSCI_RET_SUCCESS:
return 0;
- case PSCI_RET_EOPNOTSUPP:
+ case PSCI_RET_NOT_SUPPORTED:
return -EOPNOTSUPP;
- case PSCI_RET_EINVAL:
+ case PSCI_RET_INVALID_PARAMS:
return -EINVAL;
- case PSCI_RET_EPERM:
+ case PSCI_RET_DENIED:
return -EPERM;
};
return -EINVAL;
}
-#define PSCI_POWER_STATE_ID_MASK 0xffff
-#define PSCI_POWER_STATE_ID_SHIFT 0
-#define PSCI_POWER_STATE_TYPE_MASK 0x1
-#define PSCI_POWER_STATE_TYPE_SHIFT 16
-#define PSCI_POWER_STATE_AFFL_MASK 0x3
-#define PSCI_POWER_STATE_AFFL_SHIFT 24
-
static u32 psci_power_state_pack(struct psci_power_state state)
{
- return ((state.id & PSCI_POWER_STATE_ID_MASK)
- << PSCI_POWER_STATE_ID_SHIFT) |
- ((state.type & PSCI_POWER_STATE_TYPE_MASK)
- << PSCI_POWER_STATE_TYPE_SHIFT) |
- ((state.affinity_level & PSCI_POWER_STATE_AFFL_MASK)
- << PSCI_POWER_STATE_AFFL_SHIFT);
+ return ((state.id << PSCI_0_2_POWER_STATE_ID_SHIFT)
+ & PSCI_0_2_POWER_STATE_ID_MASK) |
+ ((state.type << PSCI_0_2_POWER_STATE_TYPE_SHIFT)
+ & PSCI_0_2_POWER_STATE_TYPE_MASK) |
+ ((state.affinity_level << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
+ & PSCI_0_2_POWER_STATE_AFFL_MASK);
}
/*
@@ -110,6 +105,14 @@ static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
return function_id;
}
+static int psci_get_version(void)
+{
+ int err;
+
+ err = invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
+ return err;
+}
+
static int psci_cpu_suspend(struct psci_power_state state,
unsigned long entry_point)
{
@@ -153,26 +156,36 @@ static int psci_migrate(unsigned long cpuid)
return psci_to_linux_errno(err);
}
-static const struct of_device_id psci_of_match[] __initconst = {
- { .compatible = "arm,psci", },
- {},
-};
+static int psci_affinity_info(unsigned long target_affinity,
+ unsigned long lowest_affinity_level)
+{
+ int err;
+ u32 fn;
+
+ fn = psci_function_id[PSCI_FN_AFFINITY_INFO];
+ err = invoke_psci_fn(fn, target_affinity, lowest_affinity_level, 0);
+ return err;
+}
-void __init psci_init(void)
+static int psci_migrate_info_type(void)
{
- struct device_node *np;
- const char *method;
- u32 id;
+ int err;
+ u32 fn;
- np = of_find_matching_node(NULL, psci_of_match);
- if (!np)
- return;
+ fn = psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE];
+ err = invoke_psci_fn(fn, 0, 0, 0);
+ return err;
+}
+
+static int get_set_conduit_method(struct device_node *np)
+{
+ const char *method;
- pr_info("probing function IDs from device-tree\n");
+ pr_info("probing for conduit method from DT.\n");
if (of_property_read_string(np, "method", &method)) {
- pr_warning("missing \"method\" property\n");
- goto out_put_node;
+ pr_warn("missing \"method\" property\n");
+ return -ENXIO;
}
if (!strcmp("hvc", method)) {
@@ -180,10 +193,99 @@ void __init psci_init(void)
} else if (!strcmp("smc", method)) {
invoke_psci_fn = __invoke_psci_fn_smc;
} else {
- pr_warning("invalid \"method\" property: %s\n", method);
+ pr_warn("invalid \"method\" property: %s\n", method);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
+{
+ invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+}
+
+static void psci_sys_poweroff(void)
+{
+ invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+}
+
+/*
+ * PSCI Function IDs for v0.2+ are well defined so use
+ * standard values.
+ */
+static int psci_0_2_init(struct device_node *np)
+{
+ int err, ver;
+
+ err = get_set_conduit_method(np);
+
+ if (err)
+ goto out_put_node;
+
+ ver = psci_get_version();
+
+ if (ver == PSCI_RET_NOT_SUPPORTED) {
+ /* PSCI v0.2 mandates implementation of PSCI_ID_VERSION. */
+ pr_err("PSCI firmware does not comply with the v0.2 spec.\n");
+ err = -EOPNOTSUPP;
goto out_put_node;
+ } else {
+ pr_info("PSCIv%d.%d detected in firmware.\n",
+ PSCI_VERSION_MAJOR(ver),
+ PSCI_VERSION_MINOR(ver));
+
+ if (PSCI_VERSION_MAJOR(ver) == 0 &&
+ PSCI_VERSION_MINOR(ver) < 2) {
+ err = -EINVAL;
+ pr_err("Conflicting PSCI version detected.\n");
+ goto out_put_node;
+ }
}
+ pr_info("Using standard PSCI v0.2 function IDs\n");
+ psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN_CPU_SUSPEND;
+ psci_ops.cpu_suspend = psci_cpu_suspend;
+
+ psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
+ psci_ops.cpu_off = psci_cpu_off;
+
+ psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN_CPU_ON;
+ psci_ops.cpu_on = psci_cpu_on;
+
+ psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN_MIGRATE;
+ psci_ops.migrate = psci_migrate;
+
+ psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN_AFFINITY_INFO;
+ psci_ops.affinity_info = psci_affinity_info;
+
+ psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
+ PSCI_0_2_FN_MIGRATE_INFO_TYPE;
+ psci_ops.migrate_info_type = psci_migrate_info_type;
+
+ arm_pm_restart = psci_sys_reset;
+
+ pm_power_off = psci_sys_poweroff;
+
+out_put_node:
+ of_node_put(np);
+ return err;
+}
+
+/*
+ * PSCI < v0.2 get PSCI Function IDs via DT.
+ */
+static int psci_0_1_init(struct device_node *np)
+{
+ u32 id;
+ int err;
+
+ err = get_set_conduit_method(np);
+
+ if (err)
+ goto out_put_node;
+
+ pr_info("Using PSCI v0.1 Function IDs from DT\n");
+
if (!of_property_read_u32(np, "cpu_suspend", &id)) {
psci_function_id[PSCI_FN_CPU_SUSPEND] = id;
psci_ops.cpu_suspend = psci_cpu_suspend;
@@ -206,5 +308,25 @@ void __init psci_init(void)
out_put_node:
of_node_put(np);
- return;
+ return err;
+}
+
+static const struct of_device_id psci_of_match[] __initconst = {
+ { .compatible = "arm,psci", .data = psci_0_1_init},
+ { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
+ {},
+};
+
+int __init psci_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *matched_np;
+ psci_initcall_t init_fn;
+
+ np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
+ if (!np)
+ return -ENODEV;
+
+ init_fn = (psci_initcall_t)matched_np->data;
+ return init_fn(np);
}
diff --git a/arch/arm64/include/asm/psci.h b/arch/arm64/include/asm/psci.h
index d15ab8b4..e5312ea 100644
--- a/arch/arm64/include/asm/psci.h
+++ b/arch/arm64/include/asm/psci.h
@@ -14,6 +14,6 @@
#ifndef __ASM_PSCI_H
#define __ASM_PSCI_H
-void psci_init(void);
+int psci_init(void);
#endif /* __ASM_PSCI_H */
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index ea4828a..90df6e6 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -18,12 +18,16 @@
#include <linux/init.h>
#include <linux/of.h>
#include <linux/smp.h>
+#include <linux/reboot.h>
+#include <linux/pm.h>
+#include <uapi/linux/psci.h>
#include <asm/compiler.h>
#include <asm/cpu_ops.h>
#include <asm/errno.h>
#include <asm/psci.h>
#include <asm/smp_plat.h>
+#include <asm/system_misc.h>
#define PSCI_POWER_STATE_TYPE_STANDBY 0
#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1
@@ -40,58 +44,52 @@ struct psci_operations {
int (*cpu_off)(struct psci_power_state state);
int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
int (*migrate)(unsigned long cpuid);
+ int (*affinity_info)(unsigned long target_affinity,
+ unsigned long lowest_affinity_level);
+ int (*migrate_info_type)(void);
};
static struct psci_operations psci_ops;
static int (*invoke_psci_fn)(u64, u64, u64, u64);
+typedef int (*psci_initcall_t)(const struct device_node *);
enum psci_function {
PSCI_FN_CPU_SUSPEND,
PSCI_FN_CPU_ON,
PSCI_FN_CPU_OFF,
PSCI_FN_MIGRATE,
+ PSCI_FN_AFFINITY_INFO,
+ PSCI_FN_MIGRATE_INFO_TYPE,
PSCI_FN_MAX,
};
static u32 psci_function_id[PSCI_FN_MAX];
-#define PSCI_RET_SUCCESS 0
-#define PSCI_RET_EOPNOTSUPP -1
-#define PSCI_RET_EINVAL -2
-#define PSCI_RET_EPERM -3
-
static int psci_to_linux_errno(int errno)
{
switch (errno) {
case PSCI_RET_SUCCESS:
return 0;
- case PSCI_RET_EOPNOTSUPP:
+ case PSCI_RET_NOT_SUPPORTED:
return -EOPNOTSUPP;
- case PSCI_RET_EINVAL:
+ case PSCI_RET_INVALID_PARAMS:
return -EINVAL;
- case PSCI_RET_EPERM:
+ case PSCI_RET_DENIED:
return -EPERM;
};
return -EINVAL;
}
-#define PSCI_POWER_STATE_ID_MASK 0xffff
-#define PSCI_POWER_STATE_ID_SHIFT 0
-#define PSCI_POWER_STATE_TYPE_MASK 0x1
-#define PSCI_POWER_STATE_TYPE_SHIFT 16
-#define PSCI_POWER_STATE_AFFL_MASK 0x3
-#define PSCI_POWER_STATE_AFFL_SHIFT 24
-
static u32 psci_power_state_pack(struct psci_power_state state)
{
- return ((state.id & PSCI_POWER_STATE_ID_MASK)
- << PSCI_POWER_STATE_ID_SHIFT) |
- ((state.type & PSCI_POWER_STATE_TYPE_MASK)
- << PSCI_POWER_STATE_TYPE_SHIFT) |
- ((state.affinity_level & PSCI_POWER_STATE_AFFL_MASK)
- << PSCI_POWER_STATE_AFFL_SHIFT);
+ return ((state.id << PSCI_0_2_POWER_STATE_ID_SHIFT)
+ & PSCI_0_2_POWER_STATE_ID_MASK) |
+ ((state.type << PSCI_0_2_POWER_STATE_TYPE_SHIFT)
+ & PSCI_0_2_POWER_STATE_TYPE_MASK) |
+ ((state.affinity_level << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
+ & PSCI_0_2_POWER_STATE_AFFL_MASK);
}
/*
@@ -128,6 +126,14 @@ static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
return function_id;
}
+static int psci_get_version(void)
+{
+ int err;
+
+ err = invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
+ return err;
+}
+
static int psci_cpu_suspend(struct psci_power_state state,
unsigned long entry_point)
{
@@ -171,26 +177,36 @@ static int psci_migrate(unsigned long cpuid)
return psci_to_linux_errno(err);
}
-static const struct of_device_id psci_of_match[] __initconst = {
- { .compatible = "arm,psci", },
- {},
-};
+static int psci_affinity_info(unsigned long target_affinity,
+ unsigned long lowest_affinity_level)
+{
+ int err;
+ u32 fn;
+
+ fn = psci_function_id[PSCI_FN_AFFINITY_INFO];
+ err = invoke_psci_fn(fn, target_affinity, lowest_affinity_level, 0);
+ return err;
+}
-void __init psci_init(void)
+static int psci_migrate_info_type(void)
{
- struct device_node *np;
- const char *method;
- u32 id;
+ int err;
+ u32 fn;
- np = of_find_matching_node(NULL, psci_of_match);
- if (!np)
- return;
+ fn = psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE];
+ err = invoke_psci_fn(fn, 0, 0, 0);
+ return err;
+}
+
+static int get_set_conduit_method(struct device_node *np)
+{
+ const char *method;
- pr_info("probing function IDs from device-tree\n");
+ pr_info("probing for conduit method from DT.\n");
if (of_property_read_string(np, "method", &method)) {
- pr_warning("missing \"method\" property\n");
- goto out_put_node;
+ pr_warn("missing \"method\" property\n");
+ return -ENXIO;
}
if (!strcmp("hvc", method)) {
@@ -198,10 +214,99 @@ void __init psci_init(void)
} else if (!strcmp("smc", method)) {
invoke_psci_fn = __invoke_psci_fn_smc;
} else {
- pr_warning("invalid \"method\" property: %s\n", method);
+ pr_warn("invalid \"method\" property: %s\n", method);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
+{
+ invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+}
+
+static void psci_sys_poweroff(void)
+{
+ invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+}
+
+/*
+ * PSCI Function IDs for v0.2+ are well defined so use
+ * standard values.
+ */
+static int psci_0_2_init(struct device_node *np)
+{
+ int err, ver;
+
+ err = get_set_conduit_method(np);
+
+ if (err)
+ goto out_put_node;
+
+ ver = psci_get_version();
+
+ if (ver == PSCI_RET_NOT_SUPPORTED) {
+ /* PSCI v0.2 mandates implementation of PSCI_ID_VERSION. */
+ pr_err("PSCI firmware does not comply with the v0.2 spec.\n");
+ err = -EOPNOTSUPP;
goto out_put_node;
+ } else {
+ pr_info("PSCIv%d.%d detected in firmware.\n",
+ PSCI_VERSION_MAJOR(ver),
+ PSCI_VERSION_MINOR(ver));
+
+ if (PSCI_VERSION_MAJOR(ver) == 0 &&
+ PSCI_VERSION_MINOR(ver) < 2) {
+ err = -EINVAL;
+ pr_err("Conflicting PSCI version detected.\n");
+ goto out_put_node;
+ }
}
+ pr_info("Using standard PSCI v0.2 function IDs\n");
+ psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN64_CPU_SUSPEND;
+ psci_ops.cpu_suspend = psci_cpu_suspend;
+
+ psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
+ psci_ops.cpu_off = psci_cpu_off;
+
+ psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN64_CPU_ON;
+ psci_ops.cpu_on = psci_cpu_on;
+
+ psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN64_MIGRATE;
+ psci_ops.migrate = psci_migrate;
+
+ psci_function_id[PSCI_FN_AFFINITY_INFO] = PSCI_0_2_FN64_AFFINITY_INFO;
+ psci_ops.affinity_info = psci_affinity_info;
+
+ psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE] =
+ PSCI_0_2_FN_MIGRATE_INFO_TYPE;
+ psci_ops.migrate_info_type = psci_migrate_info_type;
+
+ arm_pm_restart = psci_sys_reset;
+
+ pm_power_off = psci_sys_poweroff;
+
+out_put_node:
+ of_node_put(np);
+ return err;
+}
+
+/*
+ * PSCI < v0.2 get PSCI Function IDs via DT.
+ */
+static int psci_0_1_init(struct device_node *np)
+{
+ u32 id;
+ int err;
+
+ err = get_set_conduit_method(np);
+
+ if (err)
+ goto out_put_node;
+
+ pr_info("Using PSCI v0.1 Function IDs from DT\n");
+
if (!of_property_read_u32(np, "cpu_suspend", &id)) {
psci_function_id[PSCI_FN_CPU_SUSPEND] = id;
psci_ops.cpu_suspend = psci_cpu_suspend;
@@ -224,7 +329,28 @@ void __init psci_init(void)
out_put_node:
of_node_put(np);
- return;
+ return err;
+}
+
+static const struct of_device_id psci_of_match[] __initconst = {
+ { .compatible = "arm,psci", .data = psci_0_1_init},
+ { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
+ {},
+};
+
+int __init psci_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *matched_np;
+ psci_initcall_t init_fn;
+
+ np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
+
+ if (!np)
+ return -ENODEV;
+
+ init_fn = (psci_initcall_t)matched_np->data;
+ return init_fn(np);
}
#ifdef CONFIG_SMP
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 13/16] PSCI: Add initial support for PSCIv0.2 functions
2014-05-25 18:18 ` [PATCH 13/16] PSCI: Add initial support for PSCIv0.2 functions Christoffer Dall
@ 2014-05-27 7:44 ` Shawn Guo
2014-05-27 9:18 ` Christoffer Dall
0 siblings, 1 reply; 27+ messages in thread
From: Shawn Guo @ 2014-05-27 7:44 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, May 25, 2014 at 08:18:59PM +0200, Christoffer Dall wrote:
> diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
> index c4ae171..b93e34a 100644
> --- a/arch/arm/include/asm/psci.h
> +++ b/arch/arm/include/asm/psci.h
> @@ -29,16 +29,19 @@ struct psci_operations {
> int (*cpu_off)(struct psci_power_state state);
> int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
> int (*migrate)(unsigned long cpuid);
> + int (*affinity_info)(unsigned long target_affinity,
> + unsigned long lowest_affinity_level);
> + int (*migrate_info_type)(void);
> };
>
> extern struct psci_operations psci_ops;
> extern struct smp_operations psci_smp_ops;
>
> #ifdef CONFIG_ARM_PSCI
> -void psci_init(void);
> +int psci_init(void);
> bool psci_smp_available(void);
> #else
> -static inline void psci_init(void) { }
> +static inline int psci_init(void) { }
The change introduces the following compile warning on
imx_v6_v7_defconfig build.
In file included from ../arch/arm/kernel/setup.c:40:0:
../arch/arm/include/asm/psci.h: In function ?psci_init?:
../arch/arm/include/asm/psci.h:44:1: warning: no return statement in function returning non-void [-Wreturn-type]
Shawn
> static inline bool psci_smp_available(void) { return false; }
> #endif
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 13/16] PSCI: Add initial support for PSCIv0.2 functions
2014-05-27 7:44 ` Shawn Guo
@ 2014-05-27 9:18 ` Christoffer Dall
2014-05-27 9:27 ` Paolo Bonzini
0 siblings, 1 reply; 27+ messages in thread
From: Christoffer Dall @ 2014-05-27 9:18 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, May 27, 2014 at 03:44:55PM +0800, Shawn Guo wrote:
> On Sun, May 25, 2014 at 08:18:59PM +0200, Christoffer Dall wrote:
> > diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
> > index c4ae171..b93e34a 100644
> > --- a/arch/arm/include/asm/psci.h
> > +++ b/arch/arm/include/asm/psci.h
> > @@ -29,16 +29,19 @@ struct psci_operations {
> > int (*cpu_off)(struct psci_power_state state);
> > int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
> > int (*migrate)(unsigned long cpuid);
> > + int (*affinity_info)(unsigned long target_affinity,
> > + unsigned long lowest_affinity_level);
> > + int (*migrate_info_type)(void);
> > };
> >
> > extern struct psci_operations psci_ops;
> > extern struct smp_operations psci_smp_ops;
> >
> > #ifdef CONFIG_ARM_PSCI
> > -void psci_init(void);
> > +int psci_init(void);
> > bool psci_smp_available(void);
> > #else
> > -static inline void psci_init(void) { }
> > +static inline int psci_init(void) { }
>
> The change introduces the following compile warning on
> imx_v6_v7_defconfig build.
>
> In file included from ../arch/arm/kernel/setup.c:40:0:
> ../arch/arm/include/asm/psci.h: In function ?psci_init?:
> ../arch/arm/include/asm/psci.h:44:1: warning: no return statement in function returning non-void [-Wreturn-type]
>
Thanks for noticing, I just sent a fixup patch.
-Christoffer
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 13/16] PSCI: Add initial support for PSCIv0.2 functions
2014-05-27 9:18 ` Christoffer Dall
@ 2014-05-27 9:27 ` Paolo Bonzini
2014-05-27 9:46 ` Christoffer Dall
0 siblings, 1 reply; 27+ messages in thread
From: Paolo Bonzini @ 2014-05-27 9:27 UTC (permalink / raw)
To: linux-arm-kernel
Il 27/05/2014 11:18, Christoffer Dall ha scritto:
> On Tue, May 27, 2014 at 03:44:55PM +0800, Shawn Guo wrote:
>> On Sun, May 25, 2014 at 08:18:59PM +0200, Christoffer Dall wrote:
>>> diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
>>> index c4ae171..b93e34a 100644
>>> --- a/arch/arm/include/asm/psci.h
>>> +++ b/arch/arm/include/asm/psci.h
>>> @@ -29,16 +29,19 @@ struct psci_operations {
>>> int (*cpu_off)(struct psci_power_state state);
>>> int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
>>> int (*migrate)(unsigned long cpuid);
>>> + int (*affinity_info)(unsigned long target_affinity,
>>> + unsigned long lowest_affinity_level);
>>> + int (*migrate_info_type)(void);
>>> };
>>>
>>> extern struct psci_operations psci_ops;
>>> extern struct smp_operations psci_smp_ops;
>>>
>>> #ifdef CONFIG_ARM_PSCI
>>> -void psci_init(void);
>>> +int psci_init(void);
>>> bool psci_smp_available(void);
>>> #else
>>> -static inline void psci_init(void) { }
>>> +static inline int psci_init(void) { }
>>
>> The change introduces the following compile warning on
>> imx_v6_v7_defconfig build.
>>
>> In file included from ../arch/arm/kernel/setup.c:40:0:
>> ../arch/arm/include/asm/psci.h: In function ?psci_init?:
>> ../arch/arm/include/asm/psci.h:44:1: warning: no return statement in function returning non-void [-Wreturn-type]
>>
> Thanks for noticing, I just sent a fixup patch.
Since this is not a KVM file, I'd rather get a new pull request.
Paolo
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 13/16] PSCI: Add initial support for PSCIv0.2 functions
2014-05-27 9:27 ` Paolo Bonzini
@ 2014-05-27 9:46 ` Christoffer Dall
2014-05-27 9:47 ` Paolo Bonzini
0 siblings, 1 reply; 27+ messages in thread
From: Christoffer Dall @ 2014-05-27 9:46 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, May 27, 2014 at 11:27:10AM +0200, Paolo Bonzini wrote:
> Il 27/05/2014 11:18, Christoffer Dall ha scritto:
> >On Tue, May 27, 2014 at 03:44:55PM +0800, Shawn Guo wrote:
> >>On Sun, May 25, 2014 at 08:18:59PM +0200, Christoffer Dall wrote:
> >>>diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
> >>>index c4ae171..b93e34a 100644
> >>>--- a/arch/arm/include/asm/psci.h
> >>>+++ b/arch/arm/include/asm/psci.h
> >>>@@ -29,16 +29,19 @@ struct psci_operations {
> >>> int (*cpu_off)(struct psci_power_state state);
> >>> int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
> >>> int (*migrate)(unsigned long cpuid);
> >>>+ int (*affinity_info)(unsigned long target_affinity,
> >>>+ unsigned long lowest_affinity_level);
> >>>+ int (*migrate_info_type)(void);
> >>> };
> >>>
> >>> extern struct psci_operations psci_ops;
> >>> extern struct smp_operations psci_smp_ops;
> >>>
> >>> #ifdef CONFIG_ARM_PSCI
> >>>-void psci_init(void);
> >>>+int psci_init(void);
> >>> bool psci_smp_available(void);
> >>> #else
> >>>-static inline void psci_init(void) { }
> >>>+static inline int psci_init(void) { }
> >>
> >>The change introduces the following compile warning on
> >>imx_v6_v7_defconfig build.
> >>
> >>In file included from ../arch/arm/kernel/setup.c:40:0:
> >>../arch/arm/include/asm/psci.h: In function ?psci_init?:
> >>../arch/arm/include/asm/psci.h:44:1: warning: no return statement in function returning non-void [-Wreturn-type]
> >>
> >Thanks for noticing, I just sent a fixup patch.
>
> Since this is not a KVM file, I'd rather get a new pull request.
>
Not sure I see why that makes a difference for a one-line fix patch, but
ok.
You want a new pull request with just this patch or a new pull request
instead of the existing one containing all the PSCI patches + this fixup
patch?
-Christoffer
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 14/16] Documentation: devicetree: Add new binding for PSCIv0.2
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (12 preceding siblings ...)
2014-05-25 18:18 ` [PATCH 13/16] PSCI: Add initial support for PSCIv0.2 functions Christoffer Dall
@ 2014-05-25 18:19 ` Christoffer Dall
2014-05-25 18:19 ` [PATCH 15/16] ARM: Check if a CPU has gone offline Christoffer Dall
2014-05-25 18:19 ` [PATCH 16/16] arm64: KVM: Enable minimalistic support for Cortex-A53 Christoffer Dall
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:19 UTC (permalink / raw)
To: linux-arm-kernel
From: Ashwin Chaugule <ashwin.chaugule@linaro.org>
The PSCI v0.2+ spec defines standard values for PSCI function IDs.
Add a new binding entry so that pre v0.2 implementations can
use DT entries for function IDs and v0.2+ implementations use
standard entries as defined by the PSCIv0.2 specification.
Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
Documentation/devicetree/bindings/arm/psci.txt | 37 +++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/arm/psci.txt b/Documentation/devicetree/bindings/arm/psci.txt
index 433afe9..b4a58f3 100644
--- a/Documentation/devicetree/bindings/arm/psci.txt
+++ b/Documentation/devicetree/bindings/arm/psci.txt
@@ -21,7 +21,15 @@ to #0.
Main node required properties:
- - compatible : Must be "arm,psci"
+ - compatible : should contain at least one of:
+
+ * "arm,psci" : for implementations complying to PSCI versions prior to
+ 0.2. For these cases function IDs must be provided.
+
+ * "arm,psci-0.2" : for implementations complying to PSCI 0.2. Function
+ IDs are not required and should be ignored by an OS with PSCI 0.2
+ support, but are permitted to be present for compatibility with
+ existing software when "arm,psci" is later in the compatible list.
- method : The method of calling the PSCI firmware. Permitted
values are:
@@ -45,6 +53,8 @@ Main node optional properties:
Example:
+Case 1: PSCI v0.1 only.
+
psci {
compatible = "arm,psci";
method = "smc";
@@ -53,3 +63,28 @@ Example:
cpu_on = <0x95c10002>;
migrate = <0x95c10003>;
};
+
+
+Case 2: PSCI v0.2 only
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+Case 3: PSCI v0.2 and PSCI v0.1.
+
+ A DTB may provide IDs for use by kernels without PSCI 0.2 support,
+ enabling firmware and hypervisors to support existing and new kernels.
+ These IDs will be ignored by kernels with PSCI 0.2 support, which will
+ use the standard PSCI 0.2 IDs exclusively.
+
+ psci {
+ compatible = "arm,psci-0.2", "arm,psci";
+ method = "hvc";
+
+ cpu_on = < arbitrary value >;
+ cpu_off = < arbitrary value >;
+
+ ...
+ };
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 15/16] ARM: Check if a CPU has gone offline
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (13 preceding siblings ...)
2014-05-25 18:19 ` [PATCH 14/16] Documentation: devicetree: Add new binding for PSCIv0.2 Christoffer Dall
@ 2014-05-25 18:19 ` Christoffer Dall
2014-05-25 18:19 ` [PATCH 16/16] arm64: KVM: Enable minimalistic support for Cortex-A53 Christoffer Dall
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:19 UTC (permalink / raw)
To: linux-arm-kernel
From: Ashwin Chaugule <ashwin.chaugule@linaro.org>
PSCIv0.2 adds a new function called AFFINITY_INFO, which
can be used to query if a specified CPU has actually gone
offline. Calling this function via cpu_kill ensures that
a CPU has quiesced after a call to cpu_die. This helps
prevent the CPU from doing arbitrary bad things when data
or instructions are clobbered (as happens with kexec)
in the window between a CPU announcing that it is dead
and said CPU leaving the kernel.
Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/kernel/psci_smp.c | 33 +++++++++++++++++++++++++++++++++
arch/arm64/include/asm/cpu_ops.h | 2 ++
arch/arm64/kernel/psci.c | 31 +++++++++++++++++++++++++++++++
arch/arm64/kernel/smp.c | 22 ++++++++++++++++++++++
4 files changed, 88 insertions(+)
diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c
index 570a48c..28a1db4 100644
--- a/arch/arm/kernel/psci_smp.c
+++ b/arch/arm/kernel/psci_smp.c
@@ -16,6 +16,8 @@
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/of.h>
+#include <linux/delay.h>
+#include <uapi/linux/psci.h>
#include <asm/psci.h>
#include <asm/smp_plat.h>
@@ -66,6 +68,36 @@ void __ref psci_cpu_die(unsigned int cpu)
/* We should never return */
panic("psci: cpu %d failed to shutdown\n", cpu);
}
+
+int __ref psci_cpu_kill(unsigned int cpu)
+{
+ int err, i;
+
+ if (!psci_ops.affinity_info)
+ return 1;
+ /*
+ * cpu_kill could race with cpu_die and we can
+ * potentially end up declaring this cpu undead
+ * while it is dying. So, try again a few times.
+ */
+
+ for (i = 0; i < 10; i++) {
+ err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
+ if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) {
+ pr_info("CPU%d killed.\n", cpu);
+ return 1;
+ }
+
+ msleep(10);
+ pr_info("Retrying again to check for CPU kill\n");
+ }
+
+ pr_warn("CPU%d may not have shut down cleanly (AFFINITY_INFO reports %d)\n",
+ cpu, err);
+ /* Make platform_cpu_kill() fail. */
+ return 0;
+}
+
#endif
bool __init psci_smp_available(void)
@@ -78,5 +110,6 @@ struct smp_operations __initdata psci_smp_ops = {
.smp_boot_secondary = psci_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = psci_cpu_die,
+ .cpu_kill = psci_cpu_kill,
#endif
};
diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
index 1524130..d7b4b38 100644
--- a/arch/arm64/include/asm/cpu_ops.h
+++ b/arch/arm64/include/asm/cpu_ops.h
@@ -39,6 +39,7 @@ struct device_node;
* from the cpu to be killed.
* @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the
* cpu being killed.
+ * @cpu_kill: Ensures a cpu has left the kernel. Called from another cpu.
* @cpu_suspend: Suspends a cpu and saves the required context. May fail owing
* to wrong parameters or error conditions. Called from the
* CPU being suspended. Must be called with IRQs disabled.
@@ -52,6 +53,7 @@ struct cpu_operations {
#ifdef CONFIG_HOTPLUG_CPU
int (*cpu_disable)(unsigned int cpu);
void (*cpu_die)(unsigned int cpu);
+ int (*cpu_kill)(unsigned int cpu);
#endif
#ifdef CONFIG_ARM64_CPU_SUSPEND
int (*cpu_suspend)(unsigned long);
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 90df6e6..9e9798f 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -20,6 +20,7 @@
#include <linux/smp.h>
#include <linux/reboot.h>
#include <linux/pm.h>
+#include <linux/delay.h>
#include <uapi/linux/psci.h>
#include <asm/compiler.h>
@@ -403,6 +404,35 @@ static void cpu_psci_cpu_die(unsigned int cpu)
pr_crit("unable to power off CPU%u (%d)\n", cpu, ret);
}
+
+static int cpu_psci_cpu_kill(unsigned int cpu)
+{
+ int err, i;
+
+ if (!psci_ops.affinity_info)
+ return 1;
+ /*
+ * cpu_kill could race with cpu_die and we can
+ * potentially end up declaring this cpu undead
+ * while it is dying. So, try again a few times.
+ */
+
+ for (i = 0; i < 10; i++) {
+ err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
+ if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) {
+ pr_info("CPU%d killed.\n", cpu);
+ return 1;
+ }
+
+ msleep(10);
+ pr_info("Retrying again to check for CPU kill\n");
+ }
+
+ pr_warn("CPU%d may not have shut down cleanly (AFFINITY_INFO reports %d)\n",
+ cpu, err);
+ /* Make op_cpu_kill() fail. */
+ return 0;
+}
#endif
const struct cpu_operations cpu_psci_ops = {
@@ -413,6 +443,7 @@ const struct cpu_operations cpu_psci_ops = {
#ifdef CONFIG_HOTPLUG_CPU
.cpu_disable = cpu_psci_cpu_disable,
.cpu_die = cpu_psci_cpu_die,
+ .cpu_kill = cpu_psci_cpu_kill,
#endif
};
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index f0a141d..c3cb160 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -228,6 +228,19 @@ int __cpu_disable(void)
return 0;
}
+static int op_cpu_kill(unsigned int cpu)
+{
+ /*
+ * If we have no means of synchronising with the dying CPU, then assume
+ * that it is really dead. We can only wait for an arbitrary length of
+ * time and hope that it's dead, so let's skip the wait and just hope.
+ */
+ if (!cpu_ops[cpu]->cpu_kill)
+ return 1;
+
+ return cpu_ops[cpu]->cpu_kill(cpu);
+}
+
static DECLARE_COMPLETION(cpu_died);
/*
@@ -241,6 +254,15 @@ void __cpu_die(unsigned int cpu)
return;
}
pr_notice("CPU%u: shutdown\n", cpu);
+
+ /*
+ * Now that the dying CPU is beyond the point of no return w.r.t.
+ * in-kernel synchronisation, try to get the firwmare to help us to
+ * verify that it has really left the kernel before we consider
+ * clobbering anything it might still be using.
+ */
+ if (!op_cpu_kill(cpu))
+ pr_warn("CPU%d may not have shut down cleanly\n", cpu);
}
/*
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 16/16] arm64: KVM: Enable minimalistic support for Cortex-A53
2014-05-25 18:18 [GIT PULL] KVM/ARM and PSCI v0.2 Changes for 3.16 Christoffer Dall
` (14 preceding siblings ...)
2014-05-25 18:19 ` [PATCH 15/16] ARM: Check if a CPU has gone offline Christoffer Dall
@ 2014-05-25 18:19 ` Christoffer Dall
15 siblings, 0 replies; 27+ messages in thread
From: Christoffer Dall @ 2014-05-25 18:19 UTC (permalink / raw)
To: linux-arm-kernel
From: Marc Zyngier <marc.zyngier@arm.com>
In order to allow KVM to run on Cortex-A53 implementations, wire the
minimal support required.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm64/include/asm/cputype.h | 1 +
arch/arm64/include/uapi/asm/kvm.h | 3 ++-
arch/arm64/kvm/guest.c | 2 ++
arch/arm64/kvm/sys_regs_generic_v8.c | 2 ++
4 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index c404fb0..27f54a7 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -41,6 +41,7 @@
#define ARM_CPU_PART_AEM_V8 0xD0F0
#define ARM_CPU_PART_FOUNDATION 0xD000
+#define ARM_CPU_PART_CORTEX_A53 0xD030
#define ARM_CPU_PART_CORTEX_A57 0xD070
#define APM_CPU_PART_POTENZA 0x0000
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index e6471da..e633ff8 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -57,8 +57,9 @@ struct kvm_regs {
#define KVM_ARM_TARGET_FOUNDATION_V8 1
#define KVM_ARM_TARGET_CORTEX_A57 2
#define KVM_ARM_TARGET_XGENE_POTENZA 3
+#define KVM_ARM_TARGET_CORTEX_A53 4
-#define KVM_ARM_NUM_TARGETS 4
+#define KVM_ARM_NUM_TARGETS 5
/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
#define KVM_ARM_DEVICE_TYPE_SHIFT 0
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 0874557..60b5c31 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -214,6 +214,8 @@ int __attribute_const__ kvm_target_cpu(void)
return KVM_ARM_TARGET_AEM_V8;
case ARM_CPU_PART_FOUNDATION:
return KVM_ARM_TARGET_FOUNDATION_V8;
+ case ARM_CPU_PART_CORTEX_A53:
+ return KVM_ARM_TARGET_CORTEX_A53;
case ARM_CPU_PART_CORTEX_A57:
return KVM_ARM_TARGET_CORTEX_A57;
};
diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c b/arch/arm64/kvm/sys_regs_generic_v8.c
index 8fe6f76..475fd29 100644
--- a/arch/arm64/kvm/sys_regs_generic_v8.c
+++ b/arch/arm64/kvm/sys_regs_generic_v8.c
@@ -88,6 +88,8 @@ static int __init sys_reg_genericv8_init(void)
&genericv8_target_table);
kvm_register_target_sys_reg_table(KVM_ARM_TARGET_FOUNDATION_V8,
&genericv8_target_table);
+ kvm_register_target_sys_reg_table(KVM_ARM_TARGET_CORTEX_A53,
+ &genericv8_target_table);
kvm_register_target_sys_reg_table(KVM_ARM_TARGET_CORTEX_A57,
&genericv8_target_table);
kvm_register_target_sys_reg_table(KVM_ARM_TARGET_XGENE_POTENZA,
--
1.8.5.2
^ permalink raw reply related [flat|nested] 27+ messages in thread