Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148602117
D24549.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D24549.diff
View Options
Index: usr.sbin/bhyve/pci_emul.h
===================================================================
--- usr.sbin/bhyve/pci_emul.h
+++ usr.sbin/bhyve/pci_emul.h
@@ -124,7 +124,6 @@
enum lintr_stat state;
int pirq_pin;
int ioapic_irq;
- pthread_mutex_t lock;
} pi_lintr;
struct {
@@ -147,6 +146,8 @@
void *pba_page;
int pba_page_offset;
} pi_msix;
+
+ pthread_mutex_t pi_intr_lock;
void *pi_arg; /* devemu-private data */
Index: usr.sbin/bhyve/pci_emul.c
===================================================================
--- usr.sbin/bhyve/pci_emul.c
+++ usr.sbin/bhyve/pci_emul.c
@@ -37,6 +37,7 @@
#include <ctype.h>
#include <errno.h>
#include <pthread.h>
+#include <pthread_np.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -278,15 +279,20 @@
/*
* Return if table index is beyond what device supports
*/
+ //pthread_mutex_lock(&pi->pi_intr_lock);
tab_index = offset / MSIX_TABLE_ENTRY_SIZE;
- if (tab_index >= pi->pi_msix.table_count)
+ if (tab_index >= pi->pi_msix.table_count) {
+ //pthread_mutex_unlock(&pi->pi_intr_lock);
return (-1);
+ }
msix_entry_offset = offset % MSIX_TABLE_ENTRY_SIZE;
/* support only aligned writes */
- if ((msix_entry_offset % size) != 0)
+ if ((msix_entry_offset % size) != 0) {
+ //pthread_mutex_unlock(&pi->pi_intr_lock);
return (-1);
+ }
dest = (char *)(pi->pi_msix.table + tab_index);
dest += msix_entry_offset;
@@ -295,6 +301,7 @@
*((uint32_t *)dest) = value;
else
*((uint64_t *)dest) = value;
+ //pthread_mutex_unlock(&pi->pi_intr_lock);
return (0);
}
@@ -315,10 +322,12 @@
if (size != 1 && size != 4 && size != 8)
return (retval);
+ //pthread_mutex_lock(&pi->pi_intr_lock);
msix_entry_offset = offset % MSIX_TABLE_ENTRY_SIZE;
/* support only aligned reads */
if ((msix_entry_offset % size) != 0) {
+ //pthread_mutex_unlock(&pi->pi_intr_lock);
return (retval);
}
@@ -339,6 +348,7 @@
/* return 0 for PBA access */
retval = 0;
}
+ //pthread_mutex_unlock(&pi->pi_intr_lock);
return (retval);
}
@@ -751,7 +761,7 @@
pdi->pi_bus = bus;
pdi->pi_slot = slot;
pdi->pi_func = func;
- pthread_mutex_init(&pdi->pi_lintr.lock, NULL);
+ pthread_mutex_init(&pdi->pi_intr_lock, NULL);
pdi->pi_lintr.pin = 0;
pdi->pi_lintr.state = IDLE;
pdi->pi_lintr.pirq_pin = 0;
@@ -881,6 +891,7 @@
uint16_t msgctrl, rwmask;
int off;
+ pthread_mutex_lock(&pi->pi_intr_lock);
off = offset - capoff;
/* Message Control Register */
if (off == 2 && bytes == 2) {
@@ -896,6 +907,7 @@
}
CFGWRITE(pi, offset, val, bytes);
+ pthread_mutex_unlock(&pi->pi_intr_lock);
}
void
@@ -905,6 +917,8 @@
uint16_t msgctrl, rwmask, msgdata, mme;
uint32_t addrlo;
+ pthread_mutex_lock(&pi->pi_intr_lock);
+
/*
* If guest is writing to the message control register make sure
* we do not overwrite read-only fields.
@@ -915,26 +929,28 @@
msgctrl &= ~rwmask;
msgctrl |= val & rwmask;
val = msgctrl;
+ }
+ CFGWRITE(pi, offset, val, bytes);
- addrlo = pci_get_cfgdata32(pi, capoff + 4);
- if (msgctrl & PCIM_MSICTRL_64BIT)
- msgdata = pci_get_cfgdata16(pi, capoff + 12);
- else
- msgdata = pci_get_cfgdata16(pi, capoff + 8);
+ msgctrl = pci_get_cfgdata16(pi, capoff + 2);
+ addrlo = pci_get_cfgdata32(pi, capoff + 4);
+ if (msgctrl & PCIM_MSICTRL_64BIT)
+ msgdata = pci_get_cfgdata16(pi, capoff + 12);
+ else
+ msgdata = pci_get_cfgdata16(pi, capoff + 8);
- 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.addr = addrlo;
- pi->pi_msi.msg_data = msgdata;
- pi->pi_msi.maxmsgnum = 1 << (mme >> 4);
- } else {
- pi->pi_msi.maxmsgnum = 0;
- }
- pci_lintr_update(pi);
+ 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.addr = addrlo;
+ pi->pi_msi.msg_data = msgdata;
+ pi->pi_msi.maxmsgnum = 1 << (mme >> 4);
+ } else {
+ pi->pi_msi.maxmsgnum = 0;
}
+ pci_lintr_update(pi);
- CFGWRITE(pi, offset, val, bytes);
+ pthread_mutex_unlock(&pi->pi_intr_lock);
}
void
@@ -1447,30 +1463,40 @@
{
struct msix_table_entry *mte;
- if (!pci_msix_enabled(pi))
+ pthread_mutex_lock(&pi->pi_intr_lock);
+ if (!pci_msix_enabled(pi)) {
+ pthread_mutex_unlock(&pi->pi_intr_lock);
return;
+ }
- if (pi->pi_msix.function_mask)
+ if (pi->pi_msix.function_mask) {
+ pthread_mutex_unlock(&pi->pi_intr_lock);
return;
+ }
- if (index >= pi->pi_msix.table_count)
+ if (index >= pi->pi_msix.table_count) {
+ pthread_mutex_unlock(&pi->pi_intr_lock);
return;
+ }
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_msi(pi->pi_vmctx, mte->addr, mte->msg_data);
}
+ pthread_mutex_unlock(&pi->pi_intr_lock);
}
void
pci_generate_msi(struct pci_devinst *pi, int index)
{
+ pthread_mutex_lock(&pi->pi_intr_lock);
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);
}
+ pthread_mutex_unlock(&pi->pi_intr_lock);
}
static bool
@@ -1552,7 +1578,7 @@
assert(pi->pi_lintr.pin > 0);
- pthread_mutex_lock(&pi->pi_lintr.lock);
+ pthread_mutex_lock(&pi->pi_intr_lock);
if (pi->pi_lintr.state == IDLE) {
if (pci_lintr_permitted(pi)) {
pi->pi_lintr.state = ASSERTED;
@@ -1560,7 +1586,7 @@
} else
pi->pi_lintr.state = PENDING;
}
- pthread_mutex_unlock(&pi->pi_lintr.lock);
+ pthread_mutex_unlock(&pi->pi_intr_lock);
}
void
@@ -1569,20 +1595,20 @@
assert(pi->pi_lintr.pin > 0);
- pthread_mutex_lock(&pi->pi_lintr.lock);
+ pthread_mutex_lock(&pi->pi_intr_lock);
if (pi->pi_lintr.state == ASSERTED) {
pi->pi_lintr.state = IDLE;
pci_irq_deassert(pi);
} else if (pi->pi_lintr.state == PENDING)
pi->pi_lintr.state = IDLE;
- pthread_mutex_unlock(&pi->pi_lintr.lock);
+ pthread_mutex_unlock(&pi->pi_intr_lock);
}
static void
pci_lintr_update(struct pci_devinst *pi)
{
- pthread_mutex_lock(&pi->pi_lintr.lock);
+ assert(pthread_mutex_isowned_np(&pi->pi_intr_lock));
if (pi->pi_lintr.state == ASSERTED && !pci_lintr_permitted(pi)) {
pci_irq_deassert(pi);
pi->pi_lintr.state = PENDING;
@@ -1590,7 +1616,6 @@
pi->pi_lintr.state = ASSERTED;
pci_irq_assert(pi);
}
- pthread_mutex_unlock(&pi->pi_lintr.lock);
}
int
@@ -1736,7 +1761,9 @@
* If INTx has been unmasked and is pending, assert the
* interrupt.
*/
+ pthread_mutex_lock(&pi->pi_intr_lock);
pci_lintr_update(pi);
+ pthread_mutex_unlock(&pi->pi_intr_lock);
}
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 20, 2:07 AM (4 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29991810
Default Alt Text
D24549.diff (6 KB)
Attached To
Mode
D24549: Use a pthread mutex to protect the MSI and MSI-X state.
Attached
Detach File
Event Timeline
Log In to Comment