diff options
author | Anup Patel <anup.patel@linaro.org> | 2014-04-29 01:54:23 -0400 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2014-04-30 07:18:58 -0400 |
commit | aa8aeefe5e567637bbec7d7a3031cc057e3af303 (patch) | |
tree | 456989d612026d8cc55aa2171143e29b1cfbe08a /arch/arm/kvm | |
parent | bab0b43012a8ad64877fa46134370a7f5c6ce861 (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.c | 15 |
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 | ||