1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2017 The FreeBSD Foundation 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the company nor the name of the author may be used to 15 * endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 #include <sys/types.h> 33 #include <sys/systm.h> 34 #include <sys/bus.h> 35 #include <sys/kernel.h> 36 #include <sys/module.h> 37 #include <sys/mutex.h> 38 #include <sys/rman.h> 39 #include <sys/sysctl.h> 40 #include <sys/time.h> 41 #include <sys/timeet.h> 42 #include <sys/timetc.h> 43 44 #include <machine/bus.h> 45 #include <machine/machdep.h> 46 #include <machine/vmm.h> 47 #include <machine/armreg.h> 48 49 #include <arm64/vmm/arm64.h> 50 51 #include "vgic.h" 52 #include "vtimer.h" 53 54 #define RES1 0xffffffffffffffffUL 55 56 #define timer_enabled(ctl) \ 57 (!((ctl) & CNTP_CTL_IMASK) && ((ctl) & CNTP_CTL_ENABLE)) 58 59 static uint32_t tmr_frq; 60 61 #define timer_condition_met(ctl) ((ctl) & CNTP_CTL_ISTATUS) 62 63 SYSCTL_DECL(_hw_vmm); 64 SYSCTL_NODE(_hw_vmm, OID_AUTO, vtimer, CTLFLAG_RW, NULL, NULL); 65 66 static bool allow_ecv_phys = false; 67 SYSCTL_BOOL(_hw_vmm_vtimer, OID_AUTO, allow_ecv_phys, CTLFLAG_RW, 68 &allow_ecv_phys, 0, 69 "Enable hardware access to the physical timer if FEAT_ECV_POFF is supported"); 70 71 static void vtimer_schedule_irq(struct hypctx *hypctx, bool phys); 72 73 static int 74 vtimer_virtual_timer_intr(void *arg) 75 { 76 struct hypctx *hypctx; 77 uint64_t cntpct_el0; 78 uint32_t cntv_ctl; 79 80 hypctx = arm64_get_active_vcpu(); 81 cntv_ctl = READ_SPECIALREG(cntv_ctl_el0); 82 83 if (!hypctx) { 84 /* vm_destroy() was called. */ 85 eprintf("No active vcpu\n"); 86 cntv_ctl = READ_SPECIALREG(cntv_ctl_el0); 87 goto out; 88 } 89 if (!timer_enabled(cntv_ctl)) { 90 eprintf("Timer not enabled\n"); 91 goto out; 92 } 93 if (!timer_condition_met(cntv_ctl)) { 94 eprintf("Timer condition not met\n"); 95 goto out; 96 } 97 98 cntpct_el0 = READ_SPECIALREG(cntpct_el0) - 99 hypctx->hyp->vtimer.cntvoff_el2; 100 if (hypctx->vtimer_cpu.virt_timer.cntx_cval_el0 < cntpct_el0) 101 vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), 102 GT_VIRT_IRQ, true); 103 104 cntv_ctl = hypctx->vtimer_cpu.virt_timer.cntx_ctl_el0; 105 106 out: 107 /* 108 * Disable the timer interrupt. This will prevent the interrupt from 109 * being reasserted as soon as we exit the handler and getting stuck 110 * in an infinite loop. 111 * 112 * This is safe to do because the guest disabled the timer, and then 113 * enables it as part of the interrupt handling routine. 114 */ 115 cntv_ctl &= ~CNTP_CTL_ENABLE; 116 WRITE_SPECIALREG(cntv_ctl_el0, cntv_ctl); 117 118 return (FILTER_HANDLED); 119 } 120 121 int 122 vtimer_init(void) 123 { 124 /* 125 * The guest *MUST* use the same timer frequency as the host. The 126 * register CNTFRQ_EL0 is accessible to the guest and a different value 127 * in the guest dts file might have unforseen consequences. 128 */ 129 tmr_frq = READ_SPECIALREG(cntfrq_el0); 130 131 return (0); 132 } 133 134 void 135 vtimer_vminit(struct hyp *hyp) 136 { 137 uint64_t now; 138 bool ecv_poff; 139 140 ecv_poff = false; 141 142 if (allow_ecv_phys && (hyp->feats & HYP_FEAT_ECV_POFF) != 0) 143 ecv_poff = true; 144 145 /* 146 * Configure the Counter-timer Hypervisor Control Register for the VM. 147 */ 148 if (in_vhe()) { 149 /* 150 * CNTHCTL_E2H_EL0PCTEN: trap EL0 access to CNTP{CT,CTSS}_EL0 151 * CNTHCTL_E2H_EL0VCTEN: don't trap EL0 access to 152 * CNTV{CT,CTXX}_EL0 153 * CNTHCTL_E2H_EL0VTEN: don't trap EL0 access to 154 * CNTV_{CTL,CVAL,TVAL}_EL0 155 * CNTHCTL_E2H_EL0PTEN: trap EL0 access to 156 * CNTP_{CTL,CVAL,TVAL}_EL0 157 * CNTHCTL_E2H_EL1PCTEN: trap access to CNTPCT_EL0 158 * CNTHCTL_E2H_EL1PTEN: trap access to 159 * CNTP_{CTL,CVAL,TVAL}_EL0 160 * CNTHCTL_E2H_EL1VCTEN: don't trap EL0 access to 161 * CNTV{CT,CTSS}_EL0 162 * CNTHCTL_E2H_EL1PCEN: trap EL1 access to 163 * CNTP_{CTL,CVAL,TVAL}_EL0 164 * 165 * TODO: Don't trap when FEAT_ECV is present 166 */ 167 hyp->vtimer.cnthctl_el2 = 168 CNTHCTL_E2H_EL0VCTEN_NOTRAP | 169 CNTHCTL_E2H_EL0VTEN_NOTRAP; 170 if (ecv_poff) { 171 hyp->vtimer.cnthctl_el2 |= 172 CNTHCTL_E2H_EL0PCTEN_NOTRAP | 173 CNTHCTL_E2H_EL0PTEN_NOTRAP | 174 CNTHCTL_E2H_EL1PCTEN_NOTRAP | 175 CNTHCTL_E2H_EL1PTEN_NOTRAP; 176 } else { 177 hyp->vtimer.cnthctl_el2 |= 178 CNTHCTL_E2H_EL0PCTEN_TRAP | 179 CNTHCTL_E2H_EL0PTEN_TRAP | 180 CNTHCTL_E2H_EL1PCTEN_TRAP | 181 CNTHCTL_E2H_EL1PTEN_TRAP; 182 } 183 } else { 184 /* 185 * CNTHCTL_EL1PCEN: trap access to CNTP_{CTL, CVAL, TVAL}_EL0 186 * from EL1 187 * CNTHCTL_EL1PCTEN: trap access to CNTPCT_EL0 188 */ 189 if (ecv_poff) { 190 hyp->vtimer.cnthctl_el2 = 191 CNTHCTL_EL1PCTEN_NOTRAP | 192 CNTHCTL_EL1PCEN_NOTRAP; 193 } else { 194 hyp->vtimer.cnthctl_el2 = 195 CNTHCTL_EL1PCTEN_TRAP | 196 CNTHCTL_EL1PCEN_TRAP; 197 } 198 } 199 200 if (ecv_poff) 201 hyp->vtimer.cnthctl_el2 |= CNTHCTL_ECV_EN; 202 203 now = READ_SPECIALREG(cntpct_el0); 204 hyp->vtimer.cntvoff_el2 = now; 205 206 return; 207 } 208 209 void 210 vtimer_cpuinit(struct hypctx *hypctx) 211 { 212 struct vtimer_cpu *vtimer_cpu; 213 214 vtimer_cpu = &hypctx->vtimer_cpu; 215 /* 216 * Configure physical timer interrupts for the VCPU. 217 * 218 * CNTP_CTL_IMASK: mask interrupts 219 * ~CNTP_CTL_ENABLE: disable the timer 220 */ 221 vtimer_cpu->phys_timer.cntx_ctl_el0 = CNTP_CTL_IMASK & ~CNTP_CTL_ENABLE; 222 223 mtx_init(&vtimer_cpu->phys_timer.mtx, "vtimer phys callout mutex", NULL, 224 MTX_DEF); 225 callout_init_mtx(&vtimer_cpu->phys_timer.callout, 226 &vtimer_cpu->phys_timer.mtx, 0); 227 vtimer_cpu->phys_timer.irqid = GT_PHYS_NS_IRQ; 228 229 mtx_init(&vtimer_cpu->virt_timer.mtx, "vtimer virt callout mutex", NULL, 230 MTX_DEF); 231 callout_init_mtx(&vtimer_cpu->virt_timer.callout, 232 &vtimer_cpu->virt_timer.mtx, 0); 233 vtimer_cpu->virt_timer.irqid = GT_VIRT_IRQ; 234 } 235 236 void 237 vtimer_cpucleanup(struct hypctx *hypctx) 238 { 239 struct vtimer_cpu *vtimer_cpu; 240 241 vtimer_cpu = &hypctx->vtimer_cpu; 242 callout_drain(&vtimer_cpu->phys_timer.callout); 243 callout_drain(&vtimer_cpu->virt_timer.callout); 244 mtx_destroy(&vtimer_cpu->phys_timer.mtx); 245 mtx_destroy(&vtimer_cpu->virt_timer.mtx); 246 } 247 248 void 249 vtimer_vmcleanup(struct hyp *hyp) 250 { 251 struct hypctx *hypctx; 252 uint32_t cntv_ctl; 253 254 hypctx = arm64_get_active_vcpu(); 255 if (!hypctx) { 256 /* The active VM was destroyed, stop the timer. */ 257 cntv_ctl = READ_SPECIALREG(cntv_ctl_el0); 258 cntv_ctl &= ~CNTP_CTL_ENABLE; 259 WRITE_SPECIALREG(cntv_ctl_el0, cntv_ctl); 260 } 261 } 262 263 void 264 vtimer_cleanup(void) 265 { 266 } 267 268 static void 269 vtime_sync_timer(struct hypctx *hypctx, struct vtimer_timer *timer, 270 uint64_t cntpct_el0) 271 { 272 if (!timer_enabled(timer->cntx_ctl_el0)) { 273 vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), 274 timer->irqid, false); 275 } else if (timer->cntx_cval_el0 < cntpct_el0) { 276 vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), 277 timer->irqid, true); 278 } else { 279 vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), 280 timer->irqid, false); 281 vtimer_schedule_irq(hypctx, false); 282 } 283 } 284 285 void 286 vtimer_sync_hwstate(struct hypctx *hypctx) 287 { 288 uint64_t cntpct_el0; 289 290 cntpct_el0 = READ_SPECIALREG(cntpct_el0) - 291 hypctx->hyp->vtimer.cntvoff_el2; 292 vtime_sync_timer(hypctx, &hypctx->vtimer_cpu.virt_timer, cntpct_el0); 293 /* If FEAT_ECV_POFF is in use then we need to sync the physical timer */ 294 if ((hypctx->hyp->vtimer.cnthctl_el2 & CNTHCTL_ECV_EN) != 0) { 295 vtime_sync_timer(hypctx, &hypctx->vtimer_cpu.phys_timer, 296 cntpct_el0); 297 } 298 } 299 300 static void 301 vtimer_inject_irq_callout_phys(void *context) 302 { 303 struct hypctx *hypctx; 304 305 hypctx = context; 306 vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), 307 hypctx->vtimer_cpu.phys_timer.irqid, true); 308 } 309 310 static void 311 vtimer_inject_irq_callout_virt(void *context) 312 { 313 struct hypctx *hypctx; 314 315 hypctx = context; 316 vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), 317 hypctx->vtimer_cpu.virt_timer.irqid, true); 318 } 319 320 static void 321 vtimer_schedule_irq(struct hypctx *hypctx, bool phys) 322 { 323 sbintime_t time; 324 struct vtimer_timer *timer; 325 uint64_t cntpct_el0; 326 uint64_t diff; 327 328 if (phys) 329 timer = &hypctx->vtimer_cpu.phys_timer; 330 else 331 timer = &hypctx->vtimer_cpu.virt_timer; 332 cntpct_el0 = READ_SPECIALREG(cntpct_el0) - 333 hypctx->hyp->vtimer.cntvoff_el2; 334 if (timer->cntx_cval_el0 < cntpct_el0) { 335 /* Timer set in the past, trigger interrupt */ 336 vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(hypctx->vcpu), 337 timer->irqid, true); 338 } else { 339 diff = timer->cntx_cval_el0 - cntpct_el0; 340 time = diff * SBT_1S / tmr_frq; 341 if (phys) 342 callout_reset_sbt(&timer->callout, time, 0, 343 vtimer_inject_irq_callout_phys, hypctx, 0); 344 else 345 callout_reset_sbt(&timer->callout, time, 0, 346 vtimer_inject_irq_callout_virt, hypctx, 0); 347 } 348 } 349 350 static void 351 vtimer_remove_irq(struct hypctx *hypctx, struct vcpu *vcpu) 352 { 353 struct vtimer_cpu *vtimer_cpu; 354 struct vtimer_timer *timer; 355 356 vtimer_cpu = &hypctx->vtimer_cpu; 357 timer = &vtimer_cpu->phys_timer; 358 359 callout_drain(&timer->callout); 360 /* 361 * The interrupt needs to be deactivated here regardless of the callout 362 * function having been executed. The timer interrupt can be masked with 363 * the CNTP_CTL_EL0.IMASK bit instead of reading the IAR register. 364 * Masking the interrupt doesn't remove it from the list registers. 365 */ 366 vgic_inject_irq(hypctx->hyp, vcpu_vcpuid(vcpu), timer->irqid, false); 367 } 368 369 /* 370 * Timer emulation functions. 371 * 372 * The guest should use the virtual timer, however some software, e.g. u-boot, 373 * used the physical timer. Emulate this in software for the guest to use. 374 * 375 * Adjust for cntvoff_el2 so the physical and virtual timers are at similar 376 * times. This simplifies interrupt handling in the virtual timer as the 377 * adjustment will have already happened. 378 */ 379 380 int 381 vtimer_phys_ctl_read(struct vcpu *vcpu, uint64_t *rval, void *arg) 382 { 383 struct hyp *hyp; 384 struct hypctx *hypctx; 385 struct vtimer_cpu *vtimer_cpu; 386 uint64_t cntpct_el0; 387 388 hypctx = vcpu_get_cookie(vcpu); 389 hyp = hypctx->hyp; 390 vtimer_cpu = &hypctx->vtimer_cpu; 391 392 cntpct_el0 = READ_SPECIALREG(cntpct_el0) - hyp->vtimer.cntvoff_el2; 393 if (vtimer_cpu->phys_timer.cntx_cval_el0 < cntpct_el0) 394 /* Timer condition met */ 395 *rval = vtimer_cpu->phys_timer.cntx_ctl_el0 | CNTP_CTL_ISTATUS; 396 else 397 *rval = vtimer_cpu->phys_timer.cntx_ctl_el0 & ~CNTP_CTL_ISTATUS; 398 399 return (0); 400 } 401 402 int 403 vtimer_phys_ctl_write(struct vcpu *vcpu, uint64_t wval, void *arg) 404 { 405 struct hypctx *hypctx; 406 struct vtimer_cpu *vtimer_cpu; 407 uint64_t ctl_el0; 408 bool timer_toggled_on; 409 410 hypctx = vcpu_get_cookie(vcpu); 411 vtimer_cpu = &hypctx->vtimer_cpu; 412 413 timer_toggled_on = false; 414 ctl_el0 = vtimer_cpu->phys_timer.cntx_ctl_el0; 415 416 if (!timer_enabled(ctl_el0) && timer_enabled(wval)) 417 timer_toggled_on = true; 418 else if (timer_enabled(ctl_el0) && !timer_enabled(wval)) 419 vtimer_remove_irq(hypctx, vcpu); 420 421 vtimer_cpu->phys_timer.cntx_ctl_el0 = wval; 422 423 if (timer_toggled_on) 424 vtimer_schedule_irq(hypctx, true); 425 426 return (0); 427 } 428 429 int 430 vtimer_phys_cnt_read(struct vcpu *vcpu, uint64_t *rval, void *arg) 431 { 432 struct vm *vm; 433 struct hyp *hyp; 434 435 vm = vcpu_vm(vcpu); 436 hyp = vm_get_cookie(vm); 437 *rval = READ_SPECIALREG(cntpct_el0) - hyp->vtimer.cntvoff_el2; 438 return (0); 439 } 440 441 int 442 vtimer_phys_cnt_write(struct vcpu *vcpu, uint64_t wval, void *arg) 443 { 444 return (0); 445 } 446 447 int 448 vtimer_phys_cval_read(struct vcpu *vcpu, uint64_t *rval, void *arg) 449 { 450 struct hypctx *hypctx; 451 struct vtimer_cpu *vtimer_cpu; 452 453 hypctx = vcpu_get_cookie(vcpu); 454 vtimer_cpu = &hypctx->vtimer_cpu; 455 456 *rval = vtimer_cpu->phys_timer.cntx_cval_el0; 457 458 return (0); 459 } 460 461 int 462 vtimer_phys_cval_write(struct vcpu *vcpu, uint64_t wval, void *arg) 463 { 464 struct hypctx *hypctx; 465 struct vtimer_cpu *vtimer_cpu; 466 467 hypctx = vcpu_get_cookie(vcpu); 468 vtimer_cpu = &hypctx->vtimer_cpu; 469 470 vtimer_cpu->phys_timer.cntx_cval_el0 = wval; 471 472 vtimer_remove_irq(hypctx, vcpu); 473 if (timer_enabled(vtimer_cpu->phys_timer.cntx_ctl_el0)) { 474 vtimer_schedule_irq(hypctx, true); 475 } 476 477 return (0); 478 } 479 480 int 481 vtimer_phys_tval_read(struct vcpu *vcpu, uint64_t *rval, void *arg) 482 { 483 struct hyp *hyp; 484 struct hypctx *hypctx; 485 struct vtimer_cpu *vtimer_cpu; 486 uint32_t cntpct_el0; 487 488 hypctx = vcpu_get_cookie(vcpu); 489 hyp = hypctx->hyp; 490 vtimer_cpu = &hypctx->vtimer_cpu; 491 492 if (!(vtimer_cpu->phys_timer.cntx_ctl_el0 & CNTP_CTL_ENABLE)) { 493 /* 494 * ARMv8 Architecture Manual, p. D7-2702: the result of reading 495 * TVAL when the timer is disabled is UNKNOWN. I have chosen to 496 * return the maximum value possible on 32 bits which means the 497 * timer will fire very far into the future. 498 */ 499 *rval = (uint32_t)RES1; 500 } else { 501 cntpct_el0 = READ_SPECIALREG(cntpct_el0) - 502 hyp->vtimer.cntvoff_el2; 503 *rval = vtimer_cpu->phys_timer.cntx_cval_el0 - cntpct_el0; 504 } 505 506 return (0); 507 } 508 509 int 510 vtimer_phys_tval_write(struct vcpu *vcpu, uint64_t wval, void *arg) 511 { 512 struct hyp *hyp; 513 struct hypctx *hypctx; 514 struct vtimer_cpu *vtimer_cpu; 515 uint64_t cntpct_el0; 516 517 hypctx = vcpu_get_cookie(vcpu); 518 hyp = hypctx->hyp; 519 vtimer_cpu = &hypctx->vtimer_cpu; 520 521 cntpct_el0 = READ_SPECIALREG(cntpct_el0) - hyp->vtimer.cntvoff_el2; 522 vtimer_cpu->phys_timer.cntx_cval_el0 = (int32_t)wval + cntpct_el0; 523 524 vtimer_remove_irq(hypctx, vcpu); 525 if (timer_enabled(vtimer_cpu->phys_timer.cntx_ctl_el0)) { 526 vtimer_schedule_irq(hypctx, true); 527 } 528 529 return (0); 530 } 531 532 struct vtimer_softc { 533 struct resource *res; 534 void *ihl; 535 int rid; 536 }; 537 538 static int 539 vtimer_probe(device_t dev) 540 { 541 device_set_desc(dev, "Virtual timer"); 542 return (BUS_PROBE_DEFAULT); 543 } 544 545 static int 546 vtimer_attach(device_t dev) 547 { 548 struct vtimer_softc *sc; 549 550 sc = device_get_softc(dev); 551 552 sc->rid = 0; 553 sc->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->rid, RF_ACTIVE); 554 if (sc->res == NULL) 555 return (ENXIO); 556 557 bus_setup_intr(dev, sc->res, INTR_TYPE_CLK, vtimer_virtual_timer_intr, 558 NULL, NULL, &sc->ihl); 559 560 return (0); 561 } 562 563 static device_method_t vtimer_methods[] = { 564 /* Device interface */ 565 DEVMETHOD(device_probe, vtimer_probe), 566 DEVMETHOD(device_attach, vtimer_attach), 567 568 /* End */ 569 DEVMETHOD_END 570 }; 571 572 DEFINE_CLASS_0(vtimer, vtimer_driver, vtimer_methods, 573 sizeof(struct vtimer_softc)); 574 575 DRIVER_MODULE(vtimer, generic_timer, vtimer_driver, 0, 0); 576