aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@linaro.org>2014-04-29 01:54:23 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2014-04-30 07:18:58 -0400
commitaa8aeefe5e567637bbec7d7a3031cc057e3af303 (patch)
tree456989d612026d8cc55aa2171143e29b1cfbe08a /arch/arm/kvm
parentbab0b43012a8ad64877fa46134370a7f5c6ce861 (diff)
ARM/ARM64: KVM: Fix CPU_ON emulation for PSCI v0.2
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>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r--arch/arm/kvm/psci.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index cce901a510fa..1067579c7336 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)
48 struct kvm_vcpu *vcpu = NULL, *tmp; 48 struct kvm_vcpu *vcpu = NULL, *tmp;
49 wait_queue_head_t *wq; 49 wait_queue_head_t *wq;
50 unsigned long cpu_id; 50 unsigned long cpu_id;
51 unsigned long context_id;
51 unsigned long mpidr; 52 unsigned long mpidr;
52 phys_addr_t target_pc; 53 phys_addr_t target_pc;
53 int i; 54 int i;
@@ -68,10 +69,17 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
68 * Make sure the caller requested a valid CPU and that the CPU is 69 * Make sure the caller requested a valid CPU and that the CPU is
69 * turned off. 70 * turned off.
70 */ 71 */
71 if (!vcpu || !vcpu->arch.pause) 72 if (!vcpu)
72 return PSCI_RET_INVALID_PARAMS; 73 return PSCI_RET_INVALID_PARAMS;
74 if (!vcpu->arch.pause) {
75 if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1)
76 return PSCI_RET_ALREADY_ON;
77 else
78 return PSCI_RET_INVALID_PARAMS;
79 }
73 80
74 target_pc = *vcpu_reg(source_vcpu, 2); 81 target_pc = *vcpu_reg(source_vcpu, 2);
82 context_id = *vcpu_reg(source_vcpu, 3);
75 83
76 kvm_reset_vcpu(vcpu); 84 kvm_reset_vcpu(vcpu);
77 85
@@ -86,6 +94,11 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
86 kvm_vcpu_set_be(vcpu); 94 kvm_vcpu_set_be(vcpu);
87 95
88 *vcpu_pc(vcpu) = target_pc; 96 *vcpu_pc(vcpu) = target_pc;
97 /*
98 * NOTE: We always update r0 (or x0) because for PSCI v0.1
99 * the general puspose registers are undefined upon CPU_ON.
100 */
101 *vcpu_reg(vcpu, 0) = context_id;
89 vcpu->arch.pause = false; 102 vcpu->arch.pause = false;
90 smp_mb(); /* Make sure the above is visible */ 103 smp_mb(); /* Make sure the above is visible */
91 104