// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2024 - Google LLC * Author: Marc Zyngier <maz@kernel.org> * * Primitive PAuth emulation for ERETAA/ERETAB. * * This code assumes that is is run from EL2, and that it is part of * the emulation of ERETAx for a guest hypervisor. That's a lot of * baked-in assumptions and shortcuts. * * Do no reuse for anything else!
*/
/* * Since we are authenticating an instruction address, we have * to take TBID into account. If E2H==0, ignore VA[55], as * TCR_EL2 only has a single TBI/TBID. If VA[55] was set in * this case, this is likely a guest bug...
*/ if (!vcpu_el2_e2h_is_set(vcpu)) {
tbi = tcr & BIT(20);
tbid = tcr & BIT(29);
} elseif (bit55) {
tbi = tcr & TCR_TBI1;
tbid = tcr & TCR_TBID1;
} else {
tbi = tcr & TCR_TBI0;
tbid = tcr & TCR_TBID0;
}
return tbi && !tbid;
}
staticint compute_bottom_pac(struct kvm_vcpu *vcpu, bool bit55)
{ staticconstint maxtxsz = 39; // Revisit these two values once staticconstint mintxsz = 16; // (if) we support TTST/LVA/LVA2
u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2); int txsz;
/* * Authenticate an ERETAA/ERETAB instruction, returning true if the * authentication succeeded and false otherwise. In all cases, *elr * contains the VA to ERET to. Potential exception injection is left * to the caller.
*/ bool kvm_auth_eretax(struct kvm_vcpu *vcpu, u64 *elr)
{
u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL2);
u64 esr = kvm_vcpu_get_esr(vcpu);
u64 ptr, cptr, pac, mask; struct ptrauth_key ikey;
*elr = ptr = vcpu_read_sys_reg(vcpu, ELR_EL2);
/* We assume we're already in the context of an ERETAx */ if (esr_iss_is_eretab(esr)) { if (!(sctlr & SCTLR_EL1_EnIB)) returntrue;
/* * Slightly deviate from the pseudocode: if we have a PAC * match with the signed pointer, then it must be good. * Anything after this point is pure error handling.
*/ if ((pac & mask) == (ptr & mask)) {
*elr = cptr; returntrue;
}
/* * Authentication failed, corrupt the canonical address if * PAuth2 isn't implemented, or some XORing if it is.
*/ if (!kvm_has_pauth(vcpu->kvm, PAuth2))
cptr = corrupt_addr(vcpu, cptr); else
cptr = ptr ^ (pac & mask);
*elr = cptr; returnfalse;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.