Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6b7a806 authored by Marc Zyngier's avatar Marc Zyngier Committed by Christoffer Dall
Browse files

arm64: KVM: Do not corrupt registers on failed 64bit CP read



If we fail to emulate a mrrc instruction, we:
1) deliver an exception,
2) spit a nastygram on the console,
3) write back some garbage to Rt/Rt2

While 1) and 2) are perfectly acceptable, 3) is out of the scope of
the architecture... Let's mimick the code in kvm_handle_cp_32 and
be more cautious.

Reviewed-by: default avatarChristoffer Dall <cdall@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarChristoffer Dall <cdall@linaro.org>
parent e70b9522
Loading
Loading
Loading
Loading
+16 −11
Original line number Diff line number Diff line
@@ -1678,14 +1678,15 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
		params.regval |= vcpu_get_reg(vcpu, Rt2) << 32;
	}

	if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
		goto out;
	if (!emulate_cp(vcpu, &params, global, nr_global))
		goto out;

	unhandled_cp_access(vcpu, &params);

out:
	/*
	 * Try to emulate the coprocessor access using the target
	 * specific table first, and using the global table afterwards.
	 * If either of the tables contains a handler, handle the
	 * potential register operation in the case of a read and return
	 * with success.
	 */
	if (!emulate_cp(vcpu, &params, target_specific, nr_specific) ||
	    !emulate_cp(vcpu, &params, global, nr_global)) {
		/* Split up the value between registers for the read side */
		if (!params.is_write) {
			vcpu_set_reg(vcpu, Rt, lower_32_bits(params.regval));
@@ -1695,6 +1696,10 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
		return 1;
	}

	unhandled_cp_access(vcpu, &params);
	return 1;
}

/**
 * kvm_handle_cp_32 -- handles a mrc/mcr trap on a guest CP14/CP15 access
 * @vcpu: The VCPU pointer