Skip to content

Commit 3c0ce14

Browse files
committed
Merge tag 'powerpc-5.14-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: - Fix guest to host memory corruption in H_RTAS due to missing nargs check. - Fix guest triggerable host crashes due to bad handling of nested guest TM state. - Fix possible crashes due to incorrect reference counting in kvm_arch_vcpu_ioctl(). - Two commits fixing some regressions in KVM transactional memory handling introduced by the recent rework of the KVM code. Thanks to Nicholas Piggin, Alexey Kardashevskiy, and Michael Neuling. * tag 'powerpc-5.14-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: KVM: PPC: Book3S HV Nested: Sanitise H_ENTER_NESTED TM state KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow KVM: PPC: Fix kvm_arch_vcpu_ioctl vcpu_load leak KVM: PPC: Book3S: Fix CONFIG_TRANSACTIONAL_MEM=n crash KVM: PPC: Book3S HV P9: Fix guest TM support
2 parents 12e9bd1 + d9c57d3 commit 3c0ce14

File tree

5 files changed

+68
-8
lines changed

5 files changed

+68
-8
lines changed

arch/powerpc/kvm/book3s_hv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,8 +2697,10 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu)
26972697
HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP | HFSCR_PREFIX;
26982698
if (cpu_has_feature(CPU_FTR_HVMODE)) {
26992699
vcpu->arch.hfscr &= mfspr(SPRN_HFSCR);
2700+
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
27002701
if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST))
27012702
vcpu->arch.hfscr |= HFSCR_TM;
2703+
#endif
27022704
}
27032705
if (cpu_has_feature(CPU_FTR_TM_COMP))
27042706
vcpu->arch.hfscr |= HFSCR_TM;

arch/powerpc/kvm/book3s_hv_nested.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
302302
if (vcpu->kvm->arch.l1_ptcr == 0)
303303
return H_NOT_AVAILABLE;
304304

305+
if (MSR_TM_TRANSACTIONAL(vcpu->arch.shregs.msr))
306+
return H_BAD_MODE;
307+
305308
/* copy parameters in */
306309
hv_ptr = kvmppc_get_gpr(vcpu, 4);
307310
regs_ptr = kvmppc_get_gpr(vcpu, 5);
@@ -322,6 +325,23 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
322325
if (l2_hv.vcpu_token >= NR_CPUS)
323326
return H_PARAMETER;
324327

328+
/*
329+
* L1 must have set up a suspended state to enter the L2 in a
330+
* transactional state, and only in that case. These have to be
331+
* filtered out here to prevent causing a TM Bad Thing in the
332+
* host HRFID. We could synthesize a TM Bad Thing back to the L1
333+
* here but there doesn't seem like much point.
334+
*/
335+
if (MSR_TM_SUSPENDED(vcpu->arch.shregs.msr)) {
336+
if (!MSR_TM_ACTIVE(l2_regs.msr))
337+
return H_BAD_MODE;
338+
} else {
339+
if (l2_regs.msr & MSR_TS_MASK)
340+
return H_BAD_MODE;
341+
if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_TS_MASK))
342+
return H_BAD_MODE;
343+
}
344+
325345
/* translate lpid */
326346
l2 = kvmhv_get_nested(vcpu->kvm, l2_hv.lpid, true);
327347
if (!l2)

arch/powerpc/kvm/book3s_hv_p9_entry.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
317317
*/
318318
mtspr(SPRN_HDEC, hdec);
319319

320+
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
321+
tm_return_to_guest:
322+
#endif
320323
mtspr(SPRN_DAR, vcpu->arch.shregs.dar);
321324
mtspr(SPRN_DSISR, vcpu->arch.shregs.dsisr);
322325
mtspr(SPRN_SRR0, vcpu->arch.shregs.srr0);
@@ -415,11 +418,23 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
415418
* is in real suspend mode and is trying to transition to
416419
* transactional mode.
417420
*/
418-
if (local_paca->kvm_hstate.fake_suspend &&
421+
if (!local_paca->kvm_hstate.fake_suspend &&
419422
(vcpu->arch.shregs.msr & MSR_TS_S)) {
420423
if (kvmhv_p9_tm_emulation_early(vcpu)) {
421-
/* Prevent it being handled again. */
422-
trap = 0;
424+
/*
425+
* Go straight back into the guest with the
426+
* new NIP/MSR as set by TM emulation.
427+
*/
428+
mtspr(SPRN_HSRR0, vcpu->arch.regs.nip);
429+
mtspr(SPRN_HSRR1, vcpu->arch.shregs.msr);
430+
431+
/*
432+
* tm_return_to_guest re-loads SRR0/1, DAR,
433+
* DSISR after RI is cleared, in case they had
434+
* been clobbered by a MCE.
435+
*/
436+
__mtmsrd(0, 1); /* clear RI */
437+
goto tm_return_to_guest;
423438
}
424439
}
425440
#endif
@@ -499,6 +514,10 @@ int kvmhv_vcpu_entry_p9(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpc
499514
* If we are in real mode, only switch MMU on after the MMU is
500515
* switched to host, to avoid the P9_RADIX_PREFETCH_BUG.
501516
*/
517+
if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
518+
vcpu->arch.shregs.msr & MSR_TS_MASK)
519+
msr |= MSR_TS_S;
520+
502521
__mtmsrd(msr, 0);
503522

504523
end_timing(vcpu);

arch/powerpc/kvm/book3s_rtas.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
242242
* value so we can restore it on the way out.
243243
*/
244244
orig_rets = args.rets;
245+
if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) {
246+
/*
247+
* Don't overflow our args array: ensure there is room for
248+
* at least rets[0] (even if the call specifies 0 nret).
249+
*
250+
* Each handler must then check for the correct nargs and nret
251+
* values, but they may always return failure in rets[0].
252+
*/
253+
rc = -EINVAL;
254+
goto fail;
255+
}
245256
args.rets = &args.args[be32_to_cpu(args.nargs)];
246257

247258
mutex_lock(&vcpu->kvm->arch.rtas_token_lock);
@@ -269,9 +280,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
269280
fail:
270281
/*
271282
* We only get here if the guest has called RTAS with a bogus
272-
* args pointer. That means we can't get to the args, and so we
273-
* can't fail the RTAS call. So fail right out to userspace,
274-
* which should kill the guest.
283+
* args pointer or nargs/nret values that would overflow the
284+
* array. That means we can't get to the args, and so we can't
285+
* fail the RTAS call. So fail right out to userspace, which
286+
* should kill the guest.
287+
*
288+
* SLOF should actually pass the hcall return value from the
289+
* rtas handler call in r3, so enter_rtas could be modified to
290+
* return a failure indication in r3 and we could return such
291+
* errors to the guest rather than failing to host userspace.
292+
* However old guests that don't test for failure could then
293+
* continue silently after errors, so for now we won't do this.
275294
*/
276295
return rc;
277296
}

arch/powerpc/kvm/powerpc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,9 +2048,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
20482048
{
20492049
struct kvm_enable_cap cap;
20502050
r = -EFAULT;
2051-
vcpu_load(vcpu);
20522051
if (copy_from_user(&cap, argp, sizeof(cap)))
20532052
goto out;
2053+
vcpu_load(vcpu);
20542054
r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
20552055
vcpu_put(vcpu);
20562056
break;
@@ -2074,9 +2074,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
20742074
case KVM_DIRTY_TLB: {
20752075
struct kvm_dirty_tlb dirty;
20762076
r = -EFAULT;
2077-
vcpu_load(vcpu);
20782077
if (copy_from_user(&dirty, argp, sizeof(dirty)))
20792078
goto out;
2079+
vcpu_load(vcpu);
20802080
r = kvm_vcpu_ioctl_dirty_tlb(vcpu, &dirty);
20812081
vcpu_put(vcpu);
20822082
break;

0 commit comments

Comments
 (0)