Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167029285
D58892.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D58892.diff
View Options
Index: usr.sbin/bhyve/pci_passthru.c
===================================================================
--- usr.sbin/bhyve/pci_passthru.c
+++ usr.sbin/bhyve/pci_passthru.c
@@ -101,6 +101,11 @@
struct {
int capoff;
} psc_msix;
+ struct {
+ int capoff;
+ uint16_t pmcsr;
+ uint16_t reset_pmcsr;
+ } psc_pm;
struct {
int capoff;
uint16_t devctl;
@@ -332,6 +337,8 @@
capptr += 4;
msixcap_ptr += 4;
}
+ } else if (cap == PCIY_PMG) {
+ sc->psc_pm.capoff = ptr;
} else if (cap == PCIY_EXPRESS) {
sc->psc_pcie.capoff = ptr;
}
@@ -339,6 +346,13 @@
1);
}
}
+ if (sc->psc_pm.capoff != 0) {
+ sc->psc_pm.pmcsr = passthru_read_config(&sel,
+ sc->psc_pm.capoff + PCIR_POWER_STATUS, 2);
+ /* The physical function remains in its host-owned power state. */
+ sc->psc_pm.pmcsr |= PCIM_PSTAT_NOSOFTRESET;
+ sc->psc_pm.reset_pmcsr = sc->psc_pm.pmcsr;
+ }
if (sc->psc_pcie.capoff != 0) {
sc->psc_pcie.devctl = passthru_read_config(&sel,
sc->psc_pcie.capoff + PCIER_DEVICE_CTL, 2);
@@ -1122,6 +1136,8 @@
#define PASSTHRU_DEVCTL_NO_WRITE PCIEM_CTL_PHANTHOM_FUNCS
#define PASSTHRU_DEVCTL2_VIRT (PCIEM_CTL2_COMP_TIMO_VAL | \
PCIEM_CTL2_COMP_TIMO_DISABLE)
+#define PASSTHRU_PMCSR_VIRT (PCIM_PSTAT_DMASK | \
+ PCIM_PSTAT_NOSOFTRESET)
static uint32_t
passthru_cfg_field_mask(int coff, int bytes, int fieldoff, uint16_t mask)
@@ -1227,6 +1243,8 @@
(sc->psc_pcie.reset_devctl & ~PCIEM_CTL_MAX_PAYLOAD) | guest_mps;
if (sc->psc_pcie.has_devctl2)
sc->psc_pcie.devctl2 = sc->psc_pcie.reset_devctl2;
+ if (sc->psc_pm.capoff != 0)
+ sc->psc_pm.pmcsr = sc->psc_pm.reset_pmcsr;
}
static int
@@ -1301,22 +1319,30 @@
/* Everything else just read from the device's config space. */
*rv = passthru_read_config(&sc->psc_sel, coff, bytes);
+ /* The physical Vendor ID, not virtual capability fields, reports removal. */
+ if (sc->psc_pm.capoff != 0) {
+ uint32_t mask;
+ int pmcsr;
+
+ pmcsr = sc->psc_pm.capoff + PCIR_POWER_STATUS;
+ mask = passthru_cfg_field_mask(coff, bytes, pmcsr,
+ PASSTHRU_PMCSR_VIRT);
+ if (mask != 0)
+ *rv = (*rv & ~mask) |
+ (passthru_cfg_field_value(coff, bytes, pmcsr,
+ sc->psc_pm.pmcsr) & mask);
+ }
if (sc->psc_pcie.capoff != 0) {
uint32_t mask;
- uint16_t physical_devctl;
int devctl;
devctl = sc->psc_pcie.capoff + PCIER_DEVICE_CTL;
mask = passthru_cfg_field_mask(coff, bytes, devctl,
PASSTHRU_DEVCTL_VIRT);
- if (mask != 0) {
- physical_devctl = passthru_read_config(&sc->psc_sel,
- devctl, 2);
- if (physical_devctl != 0xffff)
- *rv = (*rv & ~mask) |
- (passthru_cfg_field_value(coff, bytes,
- devctl, sc->psc_pcie.devctl) & mask);
- }
+ if (mask != 0)
+ *rv = (*rv & ~mask) |
+ (passthru_cfg_field_value(coff, bytes, devctl,
+ sc->psc_pcie.devctl) & mask);
if (sc->psc_pcie.has_devctl2) {
devctl = sc->psc_pcie.capoff + PCIER_DEVICE_CTL2;
mask = passthru_cfg_field_mask(coff, bytes, devctl,
@@ -1357,8 +1383,8 @@
int coff, int bytes, uint32_t val)
{
uint32_t flr_mask, host_mask, transport_mask;
- uint16_t physical_devctl;
- int devctl, devctl2, host_mps, guest_mrrs;
+ uint16_t physical_devctl, physical_pmcsr;
+ int devctl, devctl2, host_mps, guest_mrrs, pmcsr;
int error, msix_table_entries, i;
uint16_t cmd_old;
@@ -1403,6 +1429,33 @@
return (0);
}
+ /*
+ * A physical D3hot-to-D0 transition may reset the function and clear
+ * Command behind bhyve's emulated copy. Keep the physical D-state
+ * host-owned, emulate the guest D-state, and advertise No_Soft_Reset so
+ * the guest does not rely on this cycle as a function reset.
+ */
+ pmcsr = sc->psc_pm.capoff + PCIR_POWER_STATUS;
+ if (sc->psc_pm.capoff != 0 && coff < pmcsr + 2 &&
+ coff + bytes > pmcsr) {
+ physical_pmcsr = passthru_read_config(&sc->psc_sel, pmcsr, 2);
+ if (physical_pmcsr == 0xffff) {
+ warnx("configuration space unavailable for passthru "
+ "device %d/%d/%d", sc->psc_sel.pc_bus,
+ sc->psc_sel.pc_dev, sc->psc_sel.pc_func);
+ return (0);
+ }
+ passthru_cfg_update_field(coff, bytes, val, pmcsr,
+ PCIM_PSTAT_DMASK, &sc->psc_pm.pmcsr);
+ host_mask = passthru_cfg_field_mask(coff, bytes, pmcsr,
+ PASSTHRU_PMCSR_VIRT);
+ val = (val & ~host_mask) |
+ (passthru_cfg_field_value(coff, bytes, pmcsr,
+ physical_pmcsr) & host_mask);
+ passthru_write_config(&sc->psc_sel, coff, bytes, val);
+ return (0);
+ }
+
/*
* A direct FLR would clear physical Command while the guest sees its
* emulated copy remain enabled. Route FLR through ppt so it restores
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Aug 19, 4:13 PM (2 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36916832
Default Alt Text
D58892.diff (4 KB)
Attached To
Mode
D58892: bhyve: Keep passthrough PCI power state virtual
Attached
Detach File
Event Timeline
Log In to Comment