diff options
author | Neel Natu <neel@FreeBSD.org> | 2013-12-16 19:59:31 +0000 |
---|---|---|
committer | Neel Natu <neel@FreeBSD.org> | 2013-12-16 19:59:31 +0000 |
commit | 4f8be175d57e157601e0f6a22685d4e6a64b61ad (patch) | |
tree | 8ec9e1a8b6bf2777a53d91e51e51248ba5823e74 /usr.sbin | |
parent | 926ec73fe2ee856832809aae43d1089b107341ae (diff) | |
download | src-4f8be175d57e157601e0f6a22685d4e6a64b61ad.tar.gz src-4f8be175d57e157601e0f6a22685d4e6a64b61ad.zip |
Add an API to deliver message signalled interrupts to vcpus. This allows
callers treat the MSI 'addr' and 'data' fields as opaque and also lets
bhyve implement multiple destination modes: physical, flat and clustered.
Submitted by: Tycho Nightingale (tycho.nightingale@pluribusnetworks.com)
Reviewed by: grehan@
Notes
Notes:
svn path=/head/; revision=259482
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bhyve/pci_emul.c | 33 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.h | 8 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_passthru.c | 26 |
3 files changed, 31 insertions, 36 deletions
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c index c7086ddcbcf5..d22873fbb46e 100644 --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -850,19 +850,14 @@ msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, else msgdata = pci_get_cfgdata16(pi, capoff + 8); - /* - * XXX check delivery mode, destination mode etc - */ mme = msgctrl & PCIM_MSICTRL_MME_MASK; pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0; if (pi->pi_msi.enabled) { - pi->pi_msi.cpu = (addrlo >> 12) & 0xff; - pi->pi_msi.vector = msgdata & 0xff; - pi->pi_msi.msgnum = 1 << (mme >> 4); + pi->pi_msi.addr = addrlo; + pi->pi_msi.msg_data = msgdata; + pi->pi_msi.maxmsgnum = 1 << (mme >> 4); } else { - pi->pi_msi.cpu = 0; - pi->pi_msi.vector = 0; - pi->pi_msi.msgnum = 0; + pi->pi_msi.maxmsgnum = 0; } } @@ -1060,10 +1055,10 @@ pci_msi_enabled(struct pci_devinst *pi) } int -pci_msi_msgnum(struct pci_devinst *pi) +pci_msi_maxmsgnum(struct pci_devinst *pi) { if (pi->pi_msi.enabled) - return (pi->pi_msi.msgnum); + return (pi->pi_msi.maxmsgnum); else return (0); } @@ -1092,19 +1087,17 @@ pci_generate_msix(struct pci_devinst *pi, int index) mte = &pi->pi_msix.table[index]; if ((mte->vector_control & PCIM_MSIX_VCTRL_MASK) == 0) { /* XXX Set PBA bit if interrupt is disabled */ - vm_lapic_irq(pi->pi_vmctx, - (mte->addr >> 12) & 0xff, mte->msg_data & 0xff); + vm_lapic_msi(pi->pi_vmctx, mte->addr, mte->msg_data); } } void -pci_generate_msi(struct pci_devinst *pi, int msg) +pci_generate_msi(struct pci_devinst *pi, int index) { - if (pci_msi_enabled(pi) && msg < pci_msi_msgnum(pi)) { - vm_lapic_irq(pi->pi_vmctx, - pi->pi_msi.cpu, - pi->pi_msi.vector + msg); + if (pci_msi_enabled(pi) && index < pci_msi_maxmsgnum(pi)) { + vm_lapic_msi(pi->pi_vmctx, pi->pi_msi.addr, + pi->pi_msi.msg_data + index); } } @@ -1511,10 +1504,10 @@ pci_emul_diow(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, * Special magic value to generate an interrupt */ if (offset == 4 && size == 4 && pci_msi_enabled(pi)) - pci_generate_msi(pi, value % pci_msi_msgnum(pi)); + pci_generate_msi(pi, value % pci_msi_maxmsgnum(pi)); if (value == 0xabcdef) { - for (i = 0; i < pci_msi_msgnum(pi); i++) + for (i = 0; i < pci_msi_maxmsgnum(pi); i++) pci_generate_msi(pi, i); } } diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h index 6a1d7575b44c..09fad073c55a 100644 --- a/usr.sbin/bhyve/pci_emul.h +++ b/usr.sbin/bhyve/pci_emul.h @@ -109,10 +109,10 @@ struct pci_devinst { int pi_bar_getsize; struct { - int enabled; - int cpu; - int vector; - int msgnum; + int enabled; + uint64_t addr; + uint64_t msg_data; + int maxmsgnum; } pi_msi; struct { diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c index 43c542d3c18b..25654750938b 100644 --- a/usr.sbin/bhyve/pci_passthru.c +++ b/usr.sbin/bhyve/pci_passthru.c @@ -348,9 +348,9 @@ msix_table_write(struct vmctx *ctx, int vcpu, struct passthru_softc *sc, error = vm_setup_msix(ctx, vcpu, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, - index, entry->msg_data, - entry->vector_control, - entry->addr); + index, entry->addr, + entry->msg_data, + entry->vector_control); } } } @@ -653,8 +653,9 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, msicap_cfgwrite(pi, sc->psc_msi.capoff, coff, bytes, val); error = vm_setup_msi(ctx, vcpu, sc->psc_sel.pc_bus, - sc->psc_sel.pc_dev, sc->psc_sel.pc_func, pi->pi_msi.cpu, - pi->pi_msi.vector, pi->pi_msi.msgnum); + sc->psc_sel.pc_dev, sc->psc_sel.pc_func, + pi->pi_msi.addr, pi->pi_msi.msg_data, + pi->pi_msi.maxmsgnum); if (error != 0) { printf("vm_setup_msi returned error %d\r\n", errno); exit(1); @@ -667,15 +668,16 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, if (pi->pi_msix.enabled) { msix_table_entries = pi->pi_msix.table_count; for (i = 0; i < msix_table_entries; i++) { - error = vm_setup_msix(ctx, vcpu, sc->psc_sel.pc_bus, - sc->psc_sel.pc_dev, - sc->psc_sel.pc_func, i, - pi->pi_msix.table[i].msg_data, - pi->pi_msix.table[i].vector_control, - pi->pi_msix.table[i].addr); + error = vm_setup_msix(ctx, vcpu, + sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, + sc->psc_sel.pc_func, i, + pi->pi_msix.table[i].addr, + pi->pi_msix.table[i].msg_data, + pi->pi_msix.table[i].vector_control); if (error) { - printf("vm_setup_msix returned error %d\r\n", errno); + printf("vm_setup_msix error %d\r\n", + errno); exit(1); } } |