diff options
author | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2015-06-10 10:19:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-07-10 12:49:34 -0400 |
commit | 3f3587c4ff8c828aac436237aeca8694a26defd3 (patch) | |
tree | b956990186dd889c572ab634204a1faa232b5586 /arch | |
parent | c8bdf091472978ecfc884148b50be5f93761fdf9 (diff) |
ARM: kvm: psci: fix handling of unimplemented functions
commit e2d997366dc5b6c9d14035867f73957f93e7578c upstream.
According to the PSCI specification and the SMC/HVC calling
convention, PSCI function_ids that are not implemented must
return NOT_SUPPORTED as return value.
Current KVM implementation takes an unhandled PSCI function_id
as an error and injects an undefined instruction into the guest
if PSCI implementation is called with a function_id that is not
handled by the resident PSCI version (ie it is not implemented),
which is not the behaviour expected by a guest when calling a
PSCI function_id that is not implemented.
This patch fixes this issue by returning NOT_SUPPORTED whenever
the kvm PSCI call is executed for a function_id that is not
implemented by the PSCI kvm layer.
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/kvm/psci.c | 16 |
1 files changed, 3 insertions, 13 deletions
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index 02fa8eff6ae1..531e922486b2 100644 --- a/arch/arm/kvm/psci.c +++ b/arch/arm/kvm/psci.c | |||
@@ -230,10 +230,6 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) | |||
230 | case PSCI_0_2_FN64_AFFINITY_INFO: | 230 | case PSCI_0_2_FN64_AFFINITY_INFO: |
231 | val = kvm_psci_vcpu_affinity_info(vcpu); | 231 | val = kvm_psci_vcpu_affinity_info(vcpu); |
232 | break; | 232 | break; |
233 | case PSCI_0_2_FN_MIGRATE: | ||
234 | case PSCI_0_2_FN64_MIGRATE: | ||
235 | val = PSCI_RET_NOT_SUPPORTED; | ||
236 | break; | ||
237 | case PSCI_0_2_FN_MIGRATE_INFO_TYPE: | 233 | case PSCI_0_2_FN_MIGRATE_INFO_TYPE: |
238 | /* | 234 | /* |
239 | * Trusted OS is MP hence does not require migration | 235 | * Trusted OS is MP hence does not require migration |
@@ -242,10 +238,6 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) | |||
242 | */ | 238 | */ |
243 | val = PSCI_0_2_TOS_MP; | 239 | val = PSCI_0_2_TOS_MP; |
244 | break; | 240 | break; |
245 | case PSCI_0_2_FN_MIGRATE_INFO_UP_CPU: | ||
246 | case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU: | ||
247 | val = PSCI_RET_NOT_SUPPORTED; | ||
248 | break; | ||
249 | case PSCI_0_2_FN_SYSTEM_OFF: | 241 | case PSCI_0_2_FN_SYSTEM_OFF: |
250 | kvm_psci_system_off(vcpu); | 242 | kvm_psci_system_off(vcpu); |
251 | /* | 243 | /* |
@@ -271,7 +263,8 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) | |||
271 | ret = 0; | 263 | ret = 0; |
272 | break; | 264 | break; |
273 | default: | 265 | default: |
274 | return -EINVAL; | 266 | val = PSCI_RET_NOT_SUPPORTED; |
267 | break; | ||
275 | } | 268 | } |
276 | 269 | ||
277 | *vcpu_reg(vcpu, 0) = val; | 270 | *vcpu_reg(vcpu, 0) = val; |
@@ -291,12 +284,9 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu) | |||
291 | case KVM_PSCI_FN_CPU_ON: | 284 | case KVM_PSCI_FN_CPU_ON: |
292 | val = kvm_psci_vcpu_on(vcpu); | 285 | val = kvm_psci_vcpu_on(vcpu); |
293 | break; | 286 | break; |
294 | case KVM_PSCI_FN_CPU_SUSPEND: | 287 | default: |
295 | case KVM_PSCI_FN_MIGRATE: | ||
296 | val = PSCI_RET_NOT_SUPPORTED; | 288 | val = PSCI_RET_NOT_SUPPORTED; |
297 | break; | 289 | break; |
298 | default: | ||
299 | return -EINVAL; | ||
300 | } | 290 | } |
301 | 291 | ||
302 | *vcpu_reg(vcpu, 0) = val; | 292 | *vcpu_reg(vcpu, 0) = val; |