From nobody Mon Jul 6 15:24:42 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gv7Sw2XTfz6kDM0 for ; Mon, 06 Jul 2026 15:24:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gv7Sp6TNfz3D6r for ; Mon, 06 Jul 2026 15:24:42 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1783351482; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=xkWEkvtyuSP1Tm3UT92evDoOi2+ahXIc5XW5rvxopt8=; b=ckam3GQFsivwedjPy1tXg9+P0kMiK40VWAqeP/TvmBd+fMiyjVJlTA5E/+w31HKNnv8SuS iB37BxnrlJQC3lffQuXMNe2iKylAimpO88kzmMaXLsarVKAa3M0IxWw47baITsIPqzd6R3 Fa8BJZvDi35+igSWnAkSA/FbhippTMxk0lD/v24vsB3nJibruc4PSD7EWqSJsztMBwplTr QgZndc/DCmmmrq39KSF7K3zlEEEoj6rg5gfhe+90pVYRfnYAbN+MDp5uNoDuzrWsoMnrns hPiWcOtFygs7H8zVVAJI9/81Slq3jBFQ+2f6hSJHJ4Q+E3T1JMKocQH5ELnpzQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1783351482; a=rsa-sha256; cv=none; b=edByH8KglKgwBE3R+YtTxjAz2cWYnBTCDv50zGUBas9lwCpkYn9tXr8LzlYQDvqLauZL0h wF24DwmaM9oTZQye/ehaHs3toO3pqa8+xCNzPO20XjkjBgebsmfCyBmeMawZf/0leFgR4C 9lPqTqhssaVPNXo5Gh99K5C+PSVX3Ry1UQFcWKMfeuNS1Aj9f1dV0hGsLIT4Lpns0Xtsja 7jIhUWeC71OtAcO5iRUfiX8NEZW6Btll90CabrNLYBAv+ybirf6NuwSloAl8AgZ/OidaQI G9bLmICmAsDswOnyluzQti7ZKYYc75HvNAcnufitZD38R165K3BgHOfCAQ+xtQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1783351482; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=xkWEkvtyuSP1Tm3UT92evDoOi2+ahXIc5XW5rvxopt8=; b=dIkLW/C0WldDDnihL+78NoXSzzmD4oHjv3o+RLzfO6bE/IOLTKl9W02KYcLhb7mX41MHiO AjxPqt1I088odIqRIeKES4weLcWesgtybhNj9SH8sa1mQpQc6AHv+WV2LNzv2jng+L81ft av421sj4ZGa/972qofQS29ljSuryuMcZ66DSdv6GWgA1bDb7N7cL1NgboeiWsY0KwbouVP /sI5l17jTUBRd9jUc9f1WszpFLiLsQ0h2MGR8hNHBQQ9UpyQG69zheh9VbNVwIZmklYSCP OExkv7bRAUGpqzCUOJygyaUoaB36NA6whJjFWfhDPowudHeLlxEqFsTGiIxvYw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gv7Sp5Mzkz194V for ; Mon, 06 Jul 2026 15:24:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1dd46 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 06 Jul 2026 15:24:42 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Kajetan Puchalski From: Andrew Turner Subject: git: f4c3458ab3ce - main - arm64/vmm: Move vttbr_el2 & vtimer into struct hypctx List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f4c3458ab3ce52ba9b234bee7711d0cb9a0745ac Auto-Submitted: auto-generated Date: Mon, 06 Jul 2026 15:24:42 +0000 Message-Id: <6a4bc8ba.1dd46.19bb853a@gitrepo.freebsd.org> The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=f4c3458ab3ce52ba9b234bee7711d0cb9a0745ac commit f4c3458ab3ce52ba9b234bee7711d0cb9a0745ac Author: Kajetan Puchalski AuthorDate: 2026-07-06 14:17:58 +0000 Commit: Andrew Turner CommitDate: 2026-07-06 15:18:30 +0000 arm64/vmm: Move vttbr_el2 & vtimer into struct hypctx Move vttbr_el2 & vtimer from struct hyp into struct hypctx to streamline the logic and handle them in the same way as other *_el2 registers are already being handled. Signed-off-by: Kajetan Puchalski Reviewed by: andrew Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D56554 --- sys/arm64/vmm/arm64.h | 6 ++- sys/arm64/vmm/io/vtimer.c | 99 ++++++++++++++++++++--------------------------- sys/arm64/vmm/io/vtimer.h | 1 - sys/arm64/vmm/vmm_arm64.c | 4 +- sys/arm64/vmm/vmm_hyp.c | 21 +++++----- 5 files changed, 56 insertions(+), 75 deletions(-) diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h index 2b69f86da321..c43034454808 100644 --- a/sys/arm64/vmm/arm64.h +++ b/sys/arm64/vmm/arm64.h @@ -229,6 +229,8 @@ struct hypctx { uint64_t hfgrtr2_el2; uint64_t hfgwtr2_el2; + uint64_t vttbr_el2; + /* Storage for *host* timer registers */ struct { uint64_t cnthctl_el2; @@ -242,6 +244,7 @@ struct hypctx { uint64_t hpfar_el2; /* Hypervisor IPA Fault Address Register */ } exit_info; + struct vtimer vtimer; struct vtimer_cpu vtimer_cpu; uint64_t setcaps; /* Currently enabled capabilities. */ @@ -307,9 +310,8 @@ hypctx_read_sys_reg(struct hypctx *hypctx, enum hypctx_sysreg reg) struct hyp { struct vm *vm; - struct vtimer vtimer; uint64_t vmid_generation; - uint64_t vttbr_el2; + uint64_t cntvoff_el2; /* VM-wide virtual timer offset */ uint64_t el2_addr; /* The address of this in el2 space */ uint64_t feats; /* Which features are enabled */ #define HYP_FEAT_HCX (0x1ul << 0) diff --git a/sys/arm64/vmm/io/vtimer.c b/sys/arm64/vmm/io/vtimer.c index d1c489463882..ff29a06751e0 100644 --- a/sys/arm64/vmm/io/vtimer.c +++ b/sys/arm64/vmm/io/vtimer.c @@ -97,7 +97,7 @@ vtimer_virtual_timer_intr(void *arg) } cntpct_el0 = READ_SPECIALREG(cntpct_el0) - - hypctx->hyp->vtimer.cntvoff_el2; + hypctx->vtimer.cntvoff_el2; if (hypctx->vtimer_cpu.virt_timer.cntx_cval_el0 < cntpct_el0) vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), GT_VIRT_IRQ, true); @@ -133,14 +133,35 @@ vtimer_init(void) } void -vtimer_vminit(struct hyp *hyp) +vtimer_cpuinit(struct hypctx *hypctx) { - uint64_t now; + struct vtimer_cpu *vtimer_cpu; bool ecv_poff; + vtimer_cpu = &hypctx->vtimer_cpu; + /* + * Configure physical timer interrupts for the VCPU. + * + * CNTP_CTL_IMASK: mask interrupts + * ~CNTP_CTL_ENABLE: disable the timer + */ + vtimer_cpu->phys_timer.cntx_ctl_el0 = CNTP_CTL_IMASK & ~CNTP_CTL_ENABLE; + + mtx_init(&vtimer_cpu->phys_timer.mtx, "vtimer phys callout mutex", NULL, + MTX_DEF); + callout_init_mtx(&vtimer_cpu->phys_timer.callout, + &vtimer_cpu->phys_timer.mtx, 0); + vtimer_cpu->phys_timer.irqid = GT_PHYS_NS_IRQ; + + mtx_init(&vtimer_cpu->virt_timer.mtx, "vtimer virt callout mutex", NULL, + MTX_DEF); + callout_init_mtx(&vtimer_cpu->virt_timer.callout, + &vtimer_cpu->virt_timer.mtx, 0); + vtimer_cpu->virt_timer.irqid = GT_VIRT_IRQ; + ecv_poff = false; - if (allow_ecv_phys && (hyp->feats & HYP_FEAT_ECV_POFF) != 0) + if (allow_ecv_phys && (hypctx->hyp->feats & HYP_FEAT_ECV_POFF) != 0) ecv_poff = true; /* @@ -165,17 +186,17 @@ vtimer_vminit(struct hyp *hyp) * * TODO: Don't trap when FEAT_ECV is present */ - hyp->vtimer.cnthctl_el2 = + hypctx->vtimer.cnthctl_el2 = CNTHCTL_E2H_EL0VCTEN_NOTRAP | CNTHCTL_E2H_EL0VTEN_NOTRAP; if (ecv_poff) { - hyp->vtimer.cnthctl_el2 |= + hypctx->vtimer.cnthctl_el2 |= CNTHCTL_E2H_EL0PCTEN_NOTRAP | CNTHCTL_E2H_EL0PTEN_NOTRAP | CNTHCTL_E2H_EL1PCTEN_NOTRAP | CNTHCTL_E2H_EL1PTEN_NOTRAP; } else { - hyp->vtimer.cnthctl_el2 |= + hypctx->vtimer.cnthctl_el2 |= CNTHCTL_E2H_EL0PCTEN_TRAP | CNTHCTL_E2H_EL0PTEN_TRAP | CNTHCTL_E2H_EL1PCTEN_TRAP | @@ -188,50 +209,20 @@ vtimer_vminit(struct hyp *hyp) * CNTHCTL_EL1PCTEN: trap access to CNTPCT_EL0 */ if (ecv_poff) { - hyp->vtimer.cnthctl_el2 = + hypctx->vtimer.cnthctl_el2 = CNTHCTL_EL1PCTEN_NOTRAP | CNTHCTL_EL1PCEN_NOTRAP; } else { - hyp->vtimer.cnthctl_el2 = + hypctx->vtimer.cnthctl_el2 = CNTHCTL_EL1PCTEN_TRAP | CNTHCTL_EL1PCEN_TRAP; } } if (ecv_poff) - hyp->vtimer.cnthctl_el2 |= CNTHCTL_ECV_EN; - - now = READ_SPECIALREG(cntpct_el0); - hyp->vtimer.cntvoff_el2 = now; + hypctx->vtimer.cnthctl_el2 |= CNTHCTL_ECV_EN; - return; -} - -void -vtimer_cpuinit(struct hypctx *hypctx) -{ - struct vtimer_cpu *vtimer_cpu; - - vtimer_cpu = &hypctx->vtimer_cpu; - /* - * Configure physical timer interrupts for the VCPU. - * - * CNTP_CTL_IMASK: mask interrupts - * ~CNTP_CTL_ENABLE: disable the timer - */ - vtimer_cpu->phys_timer.cntx_ctl_el0 = CNTP_CTL_IMASK & ~CNTP_CTL_ENABLE; - - mtx_init(&vtimer_cpu->phys_timer.mtx, "vtimer phys callout mutex", NULL, - MTX_DEF); - callout_init_mtx(&vtimer_cpu->phys_timer.callout, - &vtimer_cpu->phys_timer.mtx, 0); - vtimer_cpu->phys_timer.irqid = GT_PHYS_NS_IRQ; - - mtx_init(&vtimer_cpu->virt_timer.mtx, "vtimer virt callout mutex", NULL, - MTX_DEF); - callout_init_mtx(&vtimer_cpu->virt_timer.callout, - &vtimer_cpu->virt_timer.mtx, 0); - vtimer_cpu->virt_timer.irqid = GT_VIRT_IRQ; + hypctx->vtimer.cntvoff_el2 = hypctx->hyp->cntvoff_el2; } void @@ -289,10 +280,10 @@ vtimer_sync_hwstate(struct hypctx *hypctx) uint64_t cntpct_el0; cntpct_el0 = READ_SPECIALREG(cntpct_el0) - - hypctx->hyp->vtimer.cntvoff_el2; + hypctx->vtimer.cntvoff_el2; vtime_sync_timer(hypctx, &hypctx->vtimer_cpu.virt_timer, cntpct_el0); /* If FEAT_ECV_POFF is in use then we need to sync the physical timer */ - if ((hypctx->hyp->vtimer.cnthctl_el2 & CNTHCTL_ECV_EN) != 0) { + if ((hypctx->vtimer.cnthctl_el2 & CNTHCTL_ECV_EN) != 0) { vtime_sync_timer(hypctx, &hypctx->vtimer_cpu.phys_timer, cntpct_el0); } @@ -331,7 +322,7 @@ vtimer_schedule_irq(struct hypctx *hypctx, bool phys) else timer = &hypctx->vtimer_cpu.virt_timer; cntpct_el0 = READ_SPECIALREG(cntpct_el0) - - hypctx->hyp->vtimer.cntvoff_el2; + hypctx->vtimer.cntvoff_el2; if (timer->cntx_cval_el0 < cntpct_el0) { /* Timer set in the past, trigger interrupt */ vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), @@ -381,16 +372,14 @@ vtimer_remove_irq(struct hypctx *hypctx, struct vcpu *vcpu) int vtimer_phys_ctl_read(struct vcpu *vcpu, uint64_t *rval, void *arg) { - struct hyp *hyp; struct hypctx *hypctx; struct vtimer_cpu *vtimer_cpu; uint64_t cntpct_el0; hypctx = vcpu_get_cookie(vcpu); - hyp = hypctx->hyp; vtimer_cpu = &hypctx->vtimer_cpu; - cntpct_el0 = READ_SPECIALREG(cntpct_el0) - hyp->vtimer.cntvoff_el2; + cntpct_el0 = READ_SPECIALREG(cntpct_el0) - hypctx->vtimer.cntvoff_el2; if (vtimer_cpu->phys_timer.cntx_cval_el0 < cntpct_el0) /* Timer condition met */ *rval = vtimer_cpu->phys_timer.cntx_ctl_el0 | CNTP_CTL_ISTATUS; @@ -430,12 +419,10 @@ vtimer_phys_ctl_write(struct vcpu *vcpu, uint64_t wval, void *arg) int vtimer_phys_cnt_read(struct vcpu *vcpu, uint64_t *rval, void *arg) { - struct vm *vm; - struct hyp *hyp; + struct hypctx *hypctx; - vm = vcpu_vm(vcpu); - hyp = vm_get_cookie(vm); - *rval = READ_SPECIALREG(cntpct_el0) - hyp->vtimer.cntvoff_el2; + hypctx = vcpu_get_cookie(vcpu); + *rval = READ_SPECIALREG(cntpct_el0) - hypctx->vtimer.cntvoff_el2; return (0); } @@ -481,13 +468,11 @@ vtimer_phys_cval_write(struct vcpu *vcpu, uint64_t wval, void *arg) int vtimer_phys_tval_read(struct vcpu *vcpu, uint64_t *rval, void *arg) { - struct hyp *hyp; struct hypctx *hypctx; struct vtimer_cpu *vtimer_cpu; uint32_t cntpct_el0; hypctx = vcpu_get_cookie(vcpu); - hyp = hypctx->hyp; vtimer_cpu = &hypctx->vtimer_cpu; if (!(vtimer_cpu->phys_timer.cntx_ctl_el0 & CNTP_CTL_ENABLE)) { @@ -500,7 +485,7 @@ vtimer_phys_tval_read(struct vcpu *vcpu, uint64_t *rval, void *arg) *rval = (uint32_t)RES1; } else { cntpct_el0 = READ_SPECIALREG(cntpct_el0) - - hyp->vtimer.cntvoff_el2; + hypctx->vtimer.cntvoff_el2; *rval = vtimer_cpu->phys_timer.cntx_cval_el0 - cntpct_el0; } @@ -510,16 +495,14 @@ vtimer_phys_tval_read(struct vcpu *vcpu, uint64_t *rval, void *arg) int vtimer_phys_tval_write(struct vcpu *vcpu, uint64_t wval, void *arg) { - struct hyp *hyp; struct hypctx *hypctx; struct vtimer_cpu *vtimer_cpu; uint64_t cntpct_el0; hypctx = vcpu_get_cookie(vcpu); - hyp = hypctx->hyp; vtimer_cpu = &hypctx->vtimer_cpu; - cntpct_el0 = READ_SPECIALREG(cntpct_el0) - hyp->vtimer.cntvoff_el2; + cntpct_el0 = READ_SPECIALREG(cntpct_el0) - hypctx->vtimer.cntvoff_el2; vtimer_cpu->phys_timer.cntx_cval_el0 = (int32_t)wval + cntpct_el0; vtimer_remove_irq(hypctx, vcpu); diff --git a/sys/arm64/vmm/io/vtimer.h b/sys/arm64/vmm/io/vtimer.h index 92ce025968d2..d415afa47acc 100644 --- a/sys/arm64/vmm/io/vtimer.h +++ b/sys/arm64/vmm/io/vtimer.h @@ -67,7 +67,6 @@ struct vtimer_cpu { }; int vtimer_init(void); -void vtimer_vminit(struct hyp *); void vtimer_cpuinit(struct hypctx *); void vtimer_cpucleanup(struct hypctx *); void vtimer_vmcleanup(struct hyp *); diff --git a/sys/arm64/vmm/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c index 3615d2da66cc..43f45dc596c9 100644 --- a/sys/arm64/vmm/vmm_arm64.c +++ b/sys/arm64/vmm/vmm_arm64.c @@ -542,7 +542,7 @@ vmmops_init(struct vm *vm, pmap_t pmap) if (ID_AA64MMFR1_HCX_VAL(idreg) >= ID_AA64MMFR1_HCX_IMPL) hyp->feats |= HYP_FEAT_HCX; - vtimer_vminit(hyp); + hyp->cntvoff_el2 = READ_SPECIALREG(cntpct_el0); vgic_vminit(hyp); if (!in_vhe()) @@ -1170,7 +1170,7 @@ vmmops_run(void *vcpui, register_t pc, pmap_t pmap, struct vm_eventinfo *evinfo) /* Activate the stage2 pmap so the vmid is valid */ pmap_activate_vm(pmap); - hyp->vttbr_el2 = pmap_to_ttbr0(pmap); + hypctx->vttbr_el2 = pmap_to_ttbr0(pmap); /* * TODO: What happens if a timer interrupt is asserted exactly diff --git a/sys/arm64/vmm/vmm_hyp.c b/sys/arm64/vmm/vmm_hyp.c index 25b04d14dca8..070142199c44 100644 --- a/sys/arm64/vmm/vmm_hyp.c +++ b/sys/arm64/vmm/vmm_hyp.c @@ -241,13 +241,13 @@ vmm_hyp_reg_store_timer(struct hypctx *hypctx, struct hyp *hyp, bool guest) } else { hypctx->vtimer_cpu.cntkctl_el1 = READ_SPECIALREG(cntkctl_el1); - hypctx->host_timer_regs.cnthctl_el2 = + hypctx->vtimer.cnthctl_el2 = READ_SPECIALREG(cnthctl_el2); - hypctx->host_timer_regs.cntvoff_el2 = + hypctx->vtimer.cntvoff_el2 = READ_SPECIALREG(cntvoff_el2); } - ecv_poff = (hyp->vtimer.cnthctl_el2 & CNTHCTL_ECV_EN) != 0; + ecv_poff = (hypctx->vtimer.cnthctl_el2 & CNTHCTL_ECV_EN) != 0; if (guest_or_nonvhe(guest) && ecv_poff) { /* @@ -565,11 +565,12 @@ static void vmm_hyp_reg_restore_timer(struct hypctx *hypctx, struct hyp *hyp, bool guest) { bool ecv_poff; - ecv_poff = (hyp->vtimer.cnthctl_el2 & CNTHCTL_ECV_EN) != 0; + ecv_poff = (hypctx->vtimer.cnthctl_el2 & CNTHCTL_ECV_EN) != 0; + + WRITE_SPECIALREG(cnthctl_el2, hypctx->vtimer.cnthctl_el2); + WRITE_SPECIALREG(cntvoff_el2, hypctx->vtimer.cntvoff_el2); if (guest) { - WRITE_SPECIALREG(cnthctl_el2, hyp->vtimer.cnthctl_el2); - WRITE_SPECIALREG(cntvoff_el2, hyp->vtimer.cntvoff_el2); WRITE_SPECIALREG(EL1_REG(CNTKCTL), hypctx->vtimer_cpu.cntkctl_el1); WRITE_SPECIALREG(EL0_REG(CNTV_CVAL), @@ -583,14 +584,10 @@ vmm_hyp_reg_restore_timer(struct hypctx *hypctx, struct hyp *hyp, bool guest) * to keep in sync. */ WRITE_SPECIALREG(CNTPOFF_EL2_REG, - hyp->vtimer.cntvoff_el2); + hypctx->vtimer.cntvoff_el2); isb(); } } else { - WRITE_SPECIALREG(cnthctl_el2, - hypctx->host_timer_regs.cnthctl_el2); - WRITE_SPECIALREG(cntvoff_el2, - hypctx->host_timer_regs.cntvoff_el2); WRITE_SPECIALREG(cntkctl_el1, hypctx->vtimer_cpu.cntkctl_el1); } if (guest_or_nonvhe(guest) && ecv_poff) { @@ -736,7 +733,7 @@ static uint64_t __vmm_hyp_call_guest(struct hypctx *hypctx, struct hypctx *host_hypctx) { uint64_t ret; - WRITE_SPECIALREG(vttbr_el2, hypctx->hyp->vttbr_el2); + WRITE_SPECIALREG(vttbr_el2, hypctx->vttbr_el2); WRITE_SPECIALREG(mdcr_el2, hypctx->mdcr_el2); /* Call into the guest */ ret = VMM_HYP_FUNC(do_call_guest)(hypctx);