vioapic
vioapic_send_intr(struct vioapic *vioapic, int pin)
ASSERT(VIOAPIC_LOCKED(vioapic));
low = vioapic->rtbl[pin].reg;
high = vioapic->rtbl[pin].reg >> 32;
vioapic->rtbl[pin].reg |= IOART_REM_IRR;
vlapic_deliver_intr(vioapic->vm, level, dest, phys, delmode, vector);
vioapic->stats.is_interrupts++;
vioapic_set_pinstate(struct vioapic *vioapic, int pin, bool newstate)
ASSERT(VIOAPIC_LOCKED(vioapic));
oldcnt = newcnt = vioapic->rtbl[pin].acnt;
struct vioapic *, vioapic, int, pin);
vioapic->stats.is_saturate_high++;
struct vioapic *, vioapic, int, pin);
vioapic->stats.is_saturate_low++;
vioapic->rtbl[pin].acnt = newcnt;
DTRACE_PROBE2(vioapic__assert, struct vioapic *, vioapic,
DTRACE_PROBE2(vioapic__deassert, struct vioapic *, vioapic,
vioapic_send_intr(vioapic, pin);
struct vioapic *vioapic;
vioapic = vm_ioapic(vm);
VIOAPIC_LOCK(vioapic);
err = vioapic_set_pinstate(vioapic, irq, true);
err = vioapic_set_pinstate(vioapic, irq, false);
err = vioapic_set_pinstate(vioapic, irq, true);
err = vioapic_set_pinstate(vioapic, irq, false);
VIOAPIC_UNLOCK(vioapic);
vioapic_read(struct vioapic *vioapic, int vcpuid, uint32_t addr)
return (vioapic->id);
return (vioapic->id);
return (vioapic->rtbl[pin].reg >> rshift);
vioapic_write(struct vioapic *vioapic, int vcpuid, uint32_t addr, uint32_t data)
vioapic->id = data & APIC_ID_MASK;
vioapic->rtbl[pin].reg &= ~mask64 | RTBL_RO_BITS;
vioapic->rtbl[pin].reg |= data64 & ~RTBL_RO_BITS;
if ((vioapic->rtbl[pin].reg & IOART_TRGRMOD) == IOART_TRGREDG &&
(vioapic->rtbl[pin].reg & IOART_REM_IRR) != 0)
vioapic->rtbl[pin].reg &= ~IOART_REM_IRR;
if ((vioapic->rtbl[pin].reg & IOART_TRGRMOD) == IOART_TRGRLVL &&
(vioapic->rtbl[pin].acnt > 0)) {
vioapic_send_intr(vioapic, pin);
vioapic_mmio_rw(struct vioapic *vioapic, int vcpuid, uint64_t gpa,
VIOAPIC_LOCK(vioapic);
*data = vioapic->ioregsel;
vioapic->ioregsel = *data;
*data = vioapic_read(vioapic, vcpuid,
vioapic->ioregsel);
vioapic_write(vioapic, vcpuid, vioapic->ioregsel,
VIOAPIC_UNLOCK(vioapic);
struct vioapic *vioapic;
vioapic = vm_ioapic(vm);
error = vioapic_mmio_rw(vioapic, vcpuid, gpa, rval, size, true);
struct vioapic *vioapic;
vioapic = vm_ioapic(vm);
error = vioapic_mmio_rw(vioapic, vcpuid, gpa, &wval, size, false);
struct vioapic *vioapic;
vioapic = vm_ioapic(vm);
VIOAPIC_LOCK(vioapic);
if ((vioapic->rtbl[pin].reg & IOART_REM_IRR) == 0)
if ((vioapic->rtbl[pin].reg & IOART_INTVEC) != vector)
vioapic->rtbl[pin].reg &= ~IOART_REM_IRR;
if (vioapic->rtbl[pin].acnt > 0) {
vioapic_send_intr(vioapic, pin);
VIOAPIC_UNLOCK(vioapic);
struct vioapic *
struct vioapic *vioapic;
vioapic = kmem_zalloc(sizeof (struct vioapic), KM_SLEEP);
vioapic->vm = vm;
mutex_init(&vioapic->lock, NULL, MUTEX_ADAPTIVE, NULL);
vioapic->rtbl[i].reg = 0x0001000000010000UL;
return (vioapic);
vioapic_cleanup(struct vioapic *vioapic)
mutex_destroy(&vioapic->lock);
kmem_free(vioapic, sizeof (*vioapic));
struct vioapic *vioapic = datap;
VIOAPIC_LOCK(vioapic);
out->vi_id = vioapic->id;
out->vi_reg_sel = vioapic->ioregsel;
out->vi_pin_reg[i] = vioapic->rtbl[i].reg;
out->vi_pin_level[i] = vioapic->rtbl[i].acnt;
VIOAPIC_UNLOCK(vioapic);
struct vioapic *vioapic = datap;
VIOAPIC_LOCK(vioapic);
vioapic->id = src->vi_id;
vioapic->ioregsel = src->vi_reg_sel;
vioapic->rtbl[i].reg = src->vi_pin_reg[i] & ~RTBL_RO_BITS;
vioapic->rtbl[i].acnt = src->vi_pin_level[i];
VIOAPIC_UNLOCK(vioapic);
#define VIOAPIC_LOCK(vioapic) mutex_enter(&((vioapic)->lock))
#define VIOAPIC_UNLOCK(vioapic) mutex_exit(&((vioapic)->lock))
#define VIOAPIC_LOCKED(vioapic) MUTEX_HELD(&((vioapic)->lock))
struct vioapic *vioapic_init(struct vm *vm);
void vioapic_cleanup(struct vioapic *vioapic);
struct vioapic *vm_ioapic(struct vm *vm);
struct vioapic;
struct vioapic *vioapic; /* (i) virtual ioapic */
struct vioapic *
return (vm->vioapic);
return (vm->vioapic);
vm->vioapic = vioapic_init(vm);
vioapic_cleanup(vm->vioapic);