Skip to content

Commit 66f6347

Browse files
author
Marc Zyngier
committed
Merge branch 'kvm-arm64/psci-fixes-5.7' into kvmarm-master/master
2 parents 8f3d9f3 + fdc9999 commit 66f6347

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

virt/kvm/arm/psci.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,44 @@ static void kvm_psci_system_reset(struct kvm_vcpu *vcpu)
186186
kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET);
187187
}
188188

189+
static void kvm_psci_narrow_to_32bit(struct kvm_vcpu *vcpu)
190+
{
191+
int i;
192+
193+
/*
194+
* Zero the input registers' upper 32 bits. They will be fully
195+
* zeroed on exit, so we're fine changing them in place.
196+
*/
197+
for (i = 1; i < 4; i++)
198+
vcpu_set_reg(vcpu, i, lower_32_bits(vcpu_get_reg(vcpu, i)));
199+
}
200+
201+
static unsigned long kvm_psci_check_allowed_function(struct kvm_vcpu *vcpu, u32 fn)
202+
{
203+
switch(fn) {
204+
case PSCI_0_2_FN64_CPU_SUSPEND:
205+
case PSCI_0_2_FN64_CPU_ON:
206+
case PSCI_0_2_FN64_AFFINITY_INFO:
207+
/* Disallow these functions for 32bit guests */
208+
if (vcpu_mode_is_32bit(vcpu))
209+
return PSCI_RET_NOT_SUPPORTED;
210+
break;
211+
}
212+
213+
return 0;
214+
}
215+
189216
static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
190217
{
191218
struct kvm *kvm = vcpu->kvm;
192219
u32 psci_fn = smccc_get_function(vcpu);
193220
unsigned long val;
194221
int ret = 1;
195222

223+
val = kvm_psci_check_allowed_function(vcpu, psci_fn);
224+
if (val)
225+
goto out;
226+
196227
switch (psci_fn) {
197228
case PSCI_0_2_FN_PSCI_VERSION:
198229
/*
@@ -210,12 +241,16 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
210241
val = PSCI_RET_SUCCESS;
211242
break;
212243
case PSCI_0_2_FN_CPU_ON:
244+
kvm_psci_narrow_to_32bit(vcpu);
245+
fallthrough;
213246
case PSCI_0_2_FN64_CPU_ON:
214247
mutex_lock(&kvm->lock);
215248
val = kvm_psci_vcpu_on(vcpu);
216249
mutex_unlock(&kvm->lock);
217250
break;
218251
case PSCI_0_2_FN_AFFINITY_INFO:
252+
kvm_psci_narrow_to_32bit(vcpu);
253+
fallthrough;
219254
case PSCI_0_2_FN64_AFFINITY_INFO:
220255
val = kvm_psci_vcpu_affinity_info(vcpu);
221256
break;
@@ -256,6 +291,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
256291
break;
257292
}
258293

294+
out:
259295
smccc_set_retval(vcpu, val, 0, 0, 0);
260296
return ret;
261297
}
@@ -273,6 +309,10 @@ static int kvm_psci_1_0_call(struct kvm_vcpu *vcpu)
273309
break;
274310
case PSCI_1_0_FN_PSCI_FEATURES:
275311
feature = smccc_get_arg1(vcpu);
312+
val = kvm_psci_check_allowed_function(vcpu, feature);
313+
if (val)
314+
break;
315+
276316
switch(feature) {
277317
case PSCI_0_2_FN_PSCI_VERSION:
278318
case PSCI_0_2_FN_CPU_SUSPEND:

0 commit comments

Comments
 (0)