Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Mar 2023 17:02:44 GMT
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: d2ae03bae2ad - main - arm64: disable the physical timer for now if HCR_EL2.E2H is set
Message-ID:  <202303031702.323H2ig9082913@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kevans:

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

commit d2ae03bae2add82124973876dec95eb126ff34c8
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2023-03-03 17:02:19 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2023-03-03 17:02:34 +0000

    arm64: disable the physical timer for now if HCR_EL2.E2H is set
    
    On some hardware, we can't clear HCR_EL2.E2H so accesses to the physical
    timer hopelessly trap to EL2.  Stash off the value of HCR_EL2 and use it
    in has_hyp() to avoid this.
    
    Reviewed by:    andrew
    Differential Revision:  https://reviews.freebsd.org/D38884
---
 sys/arm64/arm64/genassym.c  | 1 +
 sys/arm64/arm64/locore.S    | 5 +++--
 sys/arm64/arm64/machdep.c   | 9 ++++++++-
 sys/arm64/include/machdep.h | 1 +
 4 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/sys/arm64/arm64/genassym.c b/sys/arm64/arm64/genassym.c
index bd359699eca9..e444d0166360 100644
--- a/sys/arm64/arm64/genassym.c
+++ b/sys/arm64/arm64/genassym.c
@@ -45,6 +45,7 @@ ASSYM(BP_KERN_DELTA, offsetof(struct arm64_bootparams, kern_delta));
 ASSYM(BP_KERN_STACK, offsetof(struct arm64_bootparams, kern_stack));
 ASSYM(BP_KERN_TTBR0, offsetof(struct arm64_bootparams, kern_ttbr0));
 ASSYM(BP_BOOT_EL, offsetof(struct arm64_bootparams, boot_el));
+ASSYM(BP_HCR_EL2, offsetof(struct arm64_bootparams, hcr_el2));
 
 ASSYM(PCPU_SIZE, sizeof(struct pcpu));
 ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S
index da3001711955..1080ebc6217e 100644
--- a/sys/arm64/arm64/locore.S
+++ b/sys/arm64/arm64/locore.S
@@ -146,6 +146,7 @@ virtdone:
 	str	x25, [x0, #BP_KERN_STACK]
 	str	x27, [x0, #BP_KERN_TTBR0]
 	str	x23, [x0, #BP_BOOT_EL]
+	str	x4,  [x0, #BP_HCR_EL2]
 
 	/* trace back starts here */
 	mov	fp, #0
@@ -286,8 +287,8 @@ LENTRY(drop_to_el1)
 	 */
 	tst	x4, #HCR_E2H
 	mov	x3, #CPTR_RES1	/* HCR_E2H == 0 */
-	mov	x4, #CPTR_FPEN	/* HCR_E2H == 1 */
-	csel	x2, x3, x4, eq
+	mov	x5, #CPTR_FPEN	/* HCR_E2H == 1 */
+	csel	x2, x3, x5, eq
 	msr	cptr_el2, x2
 
 	/* Don't trap to EL2 for CP15 traps */
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index 19fa7cd913a0..a076bd0a046a 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/armreg.h>
 #include <machine/cpu.h>
 #include <machine/debug_monitor.h>
+#include <machine/hypervisor.h>
 #include <machine/kdb.h>
 #include <machine/machdep.h>
 #include <machine/metadata.h>
@@ -124,6 +125,7 @@ static struct trapframe proc0_tf;
 int early_boot = 1;
 int cold = 1;
 static int boot_el;
+static uint64_t hcr_el2;
 
 struct kva_md_info kmi;
 
@@ -191,7 +193,11 @@ bool
 has_hyp(void)
 {
 
-	return (boot_el == 2);
+	/*
+	 * XXX The E2H check is wrong, but it's close enough for now.  Needs to
+	 * be re-evaluated once we're running regularly in EL2.
+	 */
+	return (boot_el == 2 && (hcr_el2 & HCR_E2H) == 0);
 }
 
 static void
@@ -865,6 +871,7 @@ initarm(struct arm64_bootparams *abp)
 	TSRAW(&thread0, TS_ENTER, __func__, NULL);
 
 	boot_el = abp->boot_el;
+	hcr_el2 = abp->hcr_el2;
 
 	/* Parse loader or FDT boot parametes. Determine last used address. */
 	lastaddr = parse_boot_param(abp);
diff --git a/sys/arm64/include/machdep.h b/sys/arm64/include/machdep.h
index 112390bb27ef..69babfff8467 100644
--- a/sys/arm64/include/machdep.h
+++ b/sys/arm64/include/machdep.h
@@ -36,6 +36,7 @@ struct arm64_bootparams {
 	uint64_t	kern_delta;
 	vm_offset_t	kern_stack;
 	vm_paddr_t	kern_ttbr0;
+	uint64_t	hcr_el2;
 	int		boot_el;	/* EL the kernel booted from */
 	int		pad;
 };



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202303031702.323H2ig9082913>