Page MenuHomeFreeBSD

D50211.diff
No OneTemporary

D50211.diff

diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -2384,48 +2384,49 @@
return (1);
}
-static int
-user_mrs_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame,
- uint32_t esr)
+static bool
+user_idreg_handler(uint64_t esr, struct trapframe *frame)
{
uint64_t value;
- int CRm, Op2, i, reg;
+ int reg;
- if ((insn & MRS_MASK) != MRS_VALUE)
- return (0);
+ if (ESR_ELx_EXCEPTION(esr) != EXCP_MSR)
+ return (false);
+
+ /* Only support reading from ID registers */
+ if ((esr & ISS_MSR_DIR) == 0)
+ return (false);
/*
- * We only emulate Op0 == 3, Op1 == 0, CRn == 0, CRm == {0, 4-7}.
- * These are in the EL1 CPU identification space.
- * CRm == 0 holds MIDR_EL1, MPIDR_EL1, and REVID_EL1.
- * CRm == {4-7} holds the ID_AA64 registers.
+ * This only handles the ID register space and a few registers that
+ * are safe to pass through to userspace.
*
- * For full details see the ARMv8 ARM (ARM DDI 0487C.a)
- * Table D9-2 System instruction encodings for non-Debug System
- * register accesses.
+ * These registers are all in the space op0 == 3, op1 == 0,
+ * CRn == 0. We support the following CRm:
+ * - CRm == 0: midr_el1, mpidr_el1, and revidr_el1.
+ * - CRm in {4-7}: sanitized ID registers.
+ *
+ * Registers in the ID register space (CRm in {4-7}) are all
+ * read-only and have either defined fields, or are read as
+ * zero (RAZ). For these we return 0 for any unknown register.
*/
- if (mrs_Op0(insn) != 3 || mrs_Op1(insn) != 0 || mrs_CRn(insn) != 0)
- return (0);
-
- CRm = mrs_CRm(insn);
- if (CRm > 7 || (CRm < 4 && CRm != 0))
- return (0);
+ if (ISS_MSR_OP0(esr) != 3 || ISS_MSR_OP1(esr) != 0 ||
+ ISS_MSR_CRn(esr) != 0)
+ return (false);
- Op2 = mrs_Op2(insn);
value = 0;
-
- for (i = 0; i < nitems(user_regs); i++) {
- if (user_regs[i].CRm == CRm && user_regs[i].Op2 == Op2) {
- if (SV_CURPROC_ABI() == SV_ABI_FREEBSD)
- value = CPU_DESC_FIELD(user_cpu_desc, i);
- else
- value = CPU_DESC_FIELD(l_user_cpu_desc, i);
- break;
+ if (ISS_MSR_CRm(esr) >= 4 && ISS_MSR_CRm(esr) <= 7) {
+ for (int i = 0; i < nitems(user_regs); i++) {
+ if (user_regs[i].iss == (esr & ISS_MSR_REG_MASK)) {
+ if (SV_CURPROC_ABI() == SV_ABI_FREEBSD)
+ value = CPU_DESC_FIELD(user_cpu_desc, i);
+ else
+ value = CPU_DESC_FIELD(l_user_cpu_desc, i);
+ break;
+ }
}
- }
-
- if (CRm == 0) {
- switch (Op2) {
+ } else if (ISS_MSR_CRm(esr) == 0) {
+ switch (ISS_MSR_OP2(esr)) {
case 0:
value = READ_SPECIALREG(midr_el1);
break;
@@ -2436,8 +2437,10 @@
value = READ_SPECIALREG(revidr_el1);
break;
default:
- return (0);
+ return (false);
}
+ } else {
+ return (false);
}
/*
@@ -2446,7 +2449,7 @@
*/
frame->tf_elr += INSN_SIZE;
- reg = MRS_REGISTER(insn);
+ reg = ISS_MSR_Rt(esr);
/* If reg is 31 then write to xzr, i.e. do nothing */
if (reg == 31)
return (1);
@@ -2456,7 +2459,7 @@
else if (reg == 30)
frame->tf_lr = value;
- return (1);
+ return (true);
}
/*
@@ -2795,7 +2798,7 @@
#endif
install_undef_handler(user_ctr_handler);
- install_undef_handler(user_mrs_handler);
+ install_sys_handler(user_idreg_handler);
}
SYSINIT(identify_cpu, SI_SUB_CPU, SI_ORDER_MIDDLE, identify_cpu_sysinit, NULL);

File Metadata

Mime Type
text/plain
Expires
Thu, Jul 2, 1:53 AM (14 h, 54 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34583541
Default Alt Text
D50211.diff (3 KB)

Event Timeline