Page MenuHomeFreeBSD

D56554.id176276.diff
No OneTemporary

D56554.id176276.diff

diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h
--- a/sys/arm64/vmm/arm64.h
+++ b/sys/arm64/vmm/arm64.h
@@ -224,6 +224,8 @@
uint64_t hfgrtr2_el2;
uint64_t hfgwtr2_el2;
+ uint64_t vttbr_el2;
+
/* Storage for *host* timer registers */
struct {
uint64_t cnthctl_el2;
@@ -237,6 +239,7 @@
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. */
@@ -293,9 +296,7 @@
struct hyp {
struct vm *vm;
- struct vtimer vtimer;
uint64_t vmid_generation;
- uint64_t vttbr_el2;
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.h b/sys/arm64/vmm/io/vtimer.h
--- a/sys/arm64/vmm/io/vtimer.h
+++ b/sys/arm64/vmm/io/vtimer.h
@@ -67,7 +67,6 @@
};
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/io/vtimer.c b/sys/arm64/vmm/io/vtimer.c
--- a/sys/arm64/vmm/io/vtimer.c
+++ b/sys/arm64/vmm/io/vtimer.c
@@ -97,7 +97,7 @@
}
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 @@
}
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 @@
*
* 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 @@
* 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 = READ_SPECIALREG(cntpct_el0);;
}
void
@@ -289,10 +280,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
*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 @@
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/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c
--- a/sys/arm64/vmm/vmm_arm64.c
+++ b/sys/arm64/vmm/vmm_arm64.c
@@ -540,7 +540,6 @@
if (ID_AA64MMFR1_HCX_VAL(idreg) >= ID_AA64MMFR1_HCX_IMPL)
hyp->feats |= HYP_FEAT_HCX;
- vtimer_vminit(hyp);
vgic_vminit(hyp);
if (!in_vhe())
@@ -1160,7 +1159,7 @@
/* 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
--- a/sys/arm64/vmm/vmm_hyp.c
+++ b/sys/arm64/vmm/vmm_hyp.c
@@ -218,7 +218,7 @@
vmm_hyp_reg_store_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;
if (guest) {
/* Store the timer registers */
@@ -231,9 +231,9 @@
} 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);
}
if (guest_or_nonvhe(guest) && ecv_poff) {
@@ -519,13 +519,13 @@
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(EL1_REG(CNTKCTL), hypctx->vtimer_cpu.cntkctl_el1);
+ 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(EL0_REG(CNTV_CVAL),
hypctx->vtimer_cpu.virt_timer.cntx_cval_el0);
WRITE_SPECIALREG(EL0_REG(CNTV_CTL),
@@ -537,12 +537,9 @@
* 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);
}
if (guest_or_nonvhe(guest) && ecv_poff) {
/*
@@ -688,7 +685,7 @@
__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);
@@ -711,14 +708,14 @@
host_hypctx.el2_vncr_addr = hypctx->el2_host_vncr_addr;
#endif
- vmm_hyp_reg_store(&host_hypctx, hyp, false);
+ vmm_hyp_reg_store(&host_hypctx, NULL, false);
vmm_hyp_reg_restore(hypctx, hyp, true);
ret = __vmm_hyp_call_guest(hypctx, &host_hypctx);
vmm_hyp_reg_store(hypctx, hyp, true);
vmm_hyp_handle_guest_exit(hypctx, &host_hypctx, &ret);
- vmm_hyp_reg_restore(&host_hypctx, hyp, false);
+ vmm_hyp_reg_restore(&host_hypctx, NULL, false);
return (ret);
}

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 27, 5:40 AM (17 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32210475
Default Alt Text
D56554.id176276.diff (10 KB)

Event Timeline