Bug 282505 - Emulated ID_AA64DFR0_EL1 is wrong
Summary: Emulated ID_AA64DFR0_EL1 is wrong
Status: In Progress
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: 15.0-CURRENT
Hardware: arm Any
: --- Affects Only Me
Assignee: Andrew Turner
URL: https://reviews.freebsd.org/D47437
Keywords:
Depends on:
Blocks:
 
Reported: 2024-11-03 00:50 UTC by John F. Carr
Modified: 2024-11-25 05:32 UTC (History)
1 user (show)

See Also:
linimon: mfc-stable14?
linimon: mfc-stable13?


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John F. Carr 2024-11-03 00:50:14 UTC
Short version: vmm might provide a bad value for id_aa64dfr0_el1 on my hardware.

A 13.3 kernel crashes almost immediately running under bhyve on a RockPro64 running 15.0-CURRENT.  Function dbg_monitor_enter accesses an unimplemented watchpoint 4.  The hardware supported range is 0-3.  The A53 and A72 TRMs say 4 watchpoints and dbg_watchpoint_num=4 on the host.  This is all too early to enter the debugger or examine memory.  I have console output and a register dump.  Panic string is

panic: Undefined instruction: d51004e2

The instruction decodes to

msr	dbgwcr4_el1, x2

This is consistent with the register dump, which shows dbg_wb_write_reg called from this loop in dbg_monitor_enter with i==4:

		for (i = 0; i < dbg_watchpoint_num; i++) {
			dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
			dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
		}

The watchpoint count comes from

	dbg_watchpoint_num = ((READ_SPECIALREG(id_aa64dfr0_el1) >> 20) & 0xf) + 1;

I do not yet know what the mrs instruction here returns running under bhyve.

The SOC has 4 Cortex A53 and 2 Cortex A72.
Comment 1 John F. Carr 2024-11-03 19:59:44 UTC
The guest kernel reads

ID_AA64DFR0_EL1 = 0x00000000f0f0f106

That is 16 watchpoints, 16 breakpoints, PMUv3, no PE trace, ARMv8 debug without VHE.

This is tested with a 14.1 kernel in bhyve, still running on 15.0-CURRENT host.
Comment 2 Andrew Turner freebsd_committer freebsd_triage 2024-11-04 17:13:11 UTC
Can you test the patch in review D47437? I think the logic is backwards so we get the largest field value rather than smallest.
Comment 3 John F. Carr 2024-11-04 18:58:27 UTC
The patch D47437 works for me.  The kernel running in bhyve reports

Debug Features 0 = <DoubleLock,2 CTX BKPTs,4 Watchpoints,6 Breakpoints,PMUv3,Debugv8>
Comment 4 commit-hook freebsd_committer freebsd_triage 2024-11-19 17:47:30 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=ce284dded5d5db6b1bceda309dccba616f485ade

commit ce284dded5d5db6b1bceda309dccba616f485ade
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-11-19 10:20:24 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-11-19 17:31:00 +0000

    arm64: Fix comparing ID register fields

    The logic in update_special_reg_field was reversed. Fix by swapping the
    order of the arguments.

    PR:             282505
    Fixes:          f1fb1d5c9017 ("arm64: Support more ID register field types")
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D47437

 sys/arm64/arm64/identcpu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)