aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorNeel Natu <neel@FreeBSD.org>2013-12-16 19:59:31 +0000
committerNeel Natu <neel@FreeBSD.org>2013-12-16 19:59:31 +0000
commit4f8be175d57e157601e0f6a22685d4e6a64b61ad (patch)
tree8ec9e1a8b6bf2777a53d91e51e51248ba5823e74 /usr.sbin
parent926ec73fe2ee856832809aae43d1089b107341ae (diff)
downloadsrc-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.c33
-rw-r--r--usr.sbin/bhyve/pci_emul.h8
-rw-r--r--usr.sbin/bhyve/pci_passthru.c26
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);
}
}