diff options
Diffstat (limited to 'tools/proxyclient/experiments/hacr_trap_bits.py')
| -rwxr-xr-x | tools/proxyclient/experiments/hacr_trap_bits.py | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/tools/proxyclient/experiments/hacr_trap_bits.py b/tools/proxyclient/experiments/hacr_trap_bits.py new file mode 100755 index 0000000..7982c33 --- /dev/null +++ b/tools/proxyclient/experiments/hacr_trap_bits.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: MIT +import sys, pathlib +sys.path.append(str(pathlib.Path(__file__).resolve().parents[1])) + +from m1n1.setup import * +from m1n1 import asm + +code_len = 12 * 16 * 8 + 4 +data_len = 8 * 16 * 8 + +if u.mrs(SPRR_CONFIG_EL1): + u.msr(GXF_CONFIG_EL12, 0) + u.msr(SPRR_CONFIG_EL12, 0) + u.msr(GXF_CONFIG_EL1, 0) + u.msr(SPRR_CONFIG_EL1, 0) + +u.msr(HACR_EL2, 0) + +hcr = HCR(u.mrs(HCR_EL2)) +hcr.TIDCP = 0 +hcr.TGE = 0 +u.msr(HCR_EL2, hcr.value) +u.inst(0xd5033fdf) # isb + +ACTLR_DEFAULT = 0xc00 +ACTLR_AFP = 1 << 5 +u.msr(ACTLR_EL1, ACTLR_DEFAULT | ACTLR_AFP) + +code_buffer = p.malloc(code_len) +data_buffer = p.malloc(data_len) + +template = asm.ARMAsm(""" + mov x2, x0 + mrs x2, s3_0_c0_c0_0 + str x2, [x1], #8 + ret +""", code_buffer) + +mov, mrs, st, ret = struct.unpack("4I", template.data) + +data = [] + +BAD = 0xacce5515abad1dea + +AUX = [ + ACTLR_EL1, + ACTLR_EL2, + AFSR0_EL1, + AFSR0_EL2, + AFSR1_EL1, + AFSR1_EL2, + AIDR_EL1, + AIDR2_EL1, + AMAIR_EL1, + AMAIR_EL2, + APCTL_EL1, + APSTS_EL1, +] + +def test(): + u.msr(SPRR_CONFIG_EL1, 1) + u.msr(GXF_CONFIG_EL1, 1) + u.msr(SPRR_CONFIG_EL12, 1) + u.msr(GXF_CONFIG_EL12, 1) + + for op1 in range(1 << 3): + for CRn in (0b1011, 0b1111): + mrs0 = mrs | (op1 << 16) | (CRn << 12) + insns = [] + for CRm in range(1 << 4): + for op2 in range(1 << 3): + insns.extend((mov, mrs0 | (CRm << 8) | (op2 << 5), st)) + insns.append(ret) + iface.writemem(code_buffer, struct.pack("<385I", *insns)) + p.dc_cvau(code_buffer, code_len) + p.ic_ivau(code_buffer, code_len) + + p.set_exc_guard(GUARD.SILENT | GUARD.SKIP) + p.el1_call(code_buffer, BAD, data_buffer) + cnt = p.get_exc_count() + + data = iface.readmem(data_buffer, data_len) + d = struct.unpack("<128Q", data) + i = 0 + for CRm in range(1 << 4): + for op2 in range(1 << 3): + v = d[i] + if v != BAD: + yield (3, op1, CRn, CRm, op2) + i += 1 + for enc in AUX: + try: + v = u.mrs(enc, call="el1", silent=True) + if v != BAD: + yield enc + except: + continue + + u.msr(GXF_CONFIG_EL12, 0) + u.msr(SPRR_CONFIG_EL12, 0) + u.msr(GXF_CONFIG_EL1, 0) + u.msr(SPRR_CONFIG_EL1, 0) + +baseline = set(test()) + +for bit in range(64): + print() + print ("## HACR_EL2[%d]" % bit) + u.msr(HACR_EL2, 1<<bit) + u.inst(0xd5033fdf) # isb + + new = set(test()) + + added = new - baseline + removed = baseline - new + + if added: + print("Untraps:") + for enc in sorted(added): + print(f"{sysreg_name(enc)} ({', '.join(str(i) for i in enc)})") + + if removed: + print("Traps:") + for enc in sorted(removed): + print(f"{sysreg_name(enc)} ({', '.join(str(i) for i in enc)})") + +p.set_exc_guard(GUARD.OFF) |
