pci: Only add special VF handling for direct children in bus methods
For activate/deactivate resource, use a more standard check at the
start of the function since the addition of the PCI_IOV code made this
more complex. For the three recently added methods, just add the
typical check at the beginning that I missed.
This wasn't always fatal as if your system only had PCI device_t's as
children of PCI bus devices it would happen to work ok, but if you
have a non-PCI child device (e.g. an ATA channel) then dereferencing
ivars for non-direct-children could fault.
Reported by: Cirrus-CI (via emaste)
Reviewed by: emaste
Fixes: 871b33ad65 pci: Consistently use pci_vf_* for suballocated VF memory resources
Differential Revision: https://reviews.freebsd.org/D45499
This commit is contained in:
+21
-6
@@ -5695,6 +5695,9 @@ pci_activate_resource(device_t dev, device_t child, struct resource *r)
|
|||||||
struct pci_devinfo *dinfo;
|
struct pci_devinfo *dinfo;
|
||||||
int error, rid, type;
|
int error, rid, type;
|
||||||
|
|
||||||
|
if (device_get_parent(child) != dev)
|
||||||
|
return (bus_generic_activate_resource(dev, child, r));
|
||||||
|
|
||||||
dinfo = device_get_ivars(child);
|
dinfo = device_get_ivars(child);
|
||||||
#ifdef PCI_IOV
|
#ifdef PCI_IOV
|
||||||
if (dinfo->cfg.flags & PCICFG_VF) {
|
if (dinfo->cfg.flags & PCICFG_VF) {
|
||||||
@@ -5716,21 +5719,21 @@ pci_activate_resource(device_t dev, device_t child, struct resource *r)
|
|||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
/* Enable decoding in the command register when activating BARs. */
|
|
||||||
if (device_get_parent(child) == dev) {
|
|
||||||
/* Device ROMs need their decoding explicitly enabled. */
|
|
||||||
rid = rman_get_rid(r);
|
rid = rman_get_rid(r);
|
||||||
type = rman_get_type(r);
|
type = rman_get_type(r);
|
||||||
|
|
||||||
|
/* Device ROMs need their decoding explicitly enabled. */
|
||||||
if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid))
|
if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid))
|
||||||
pci_write_bar(child, pci_find_bar(child, rid),
|
pci_write_bar(child, pci_find_bar(child, rid),
|
||||||
rman_get_start(r) | PCIM_BIOS_ENABLE);
|
rman_get_start(r) | PCIM_BIOS_ENABLE);
|
||||||
|
|
||||||
|
/* Enable decoding in the command register when activating BARs. */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SYS_RES_IOPORT:
|
case SYS_RES_IOPORT:
|
||||||
case SYS_RES_MEMORY:
|
case SYS_RES_MEMORY:
|
||||||
error = PCI_ENABLE_IO(dev, child, type);
|
error = PCI_ENABLE_IO(dev, child, type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5740,6 +5743,9 @@ pci_deactivate_resource(device_t dev, device_t child, struct resource *r)
|
|||||||
struct pci_devinfo *dinfo;
|
struct pci_devinfo *dinfo;
|
||||||
int error, rid, type;
|
int error, rid, type;
|
||||||
|
|
||||||
|
if (device_get_parent(child) != dev)
|
||||||
|
return (bus_generic_deactivate_resource(dev, child, r));
|
||||||
|
|
||||||
dinfo = device_get_ivars(child);
|
dinfo = device_get_ivars(child);
|
||||||
#ifdef PCI_IOV
|
#ifdef PCI_IOV
|
||||||
if (dinfo->cfg.flags & PCICFG_VF) {
|
if (dinfo->cfg.flags & PCICFG_VF) {
|
||||||
@@ -5762,13 +5768,11 @@ pci_deactivate_resource(device_t dev, device_t child, struct resource *r)
|
|||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
/* Disable decoding for device ROMs. */
|
/* Disable decoding for device ROMs. */
|
||||||
if (device_get_parent(child) == dev) {
|
|
||||||
rid = rman_get_rid(r);
|
rid = rman_get_rid(r);
|
||||||
type = rman_get_type(r);
|
type = rman_get_type(r);
|
||||||
if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid))
|
if (type == SYS_RES_MEMORY && PCIR_IS_BIOS(&dinfo->cfg, rid))
|
||||||
pci_write_bar(child, pci_find_bar(child, rid),
|
pci_write_bar(child, pci_find_bar(child, rid),
|
||||||
rman_get_start(r));
|
rman_get_start(r));
|
||||||
}
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5779,6 +5783,10 @@ pci_adjust_resource(device_t dev, device_t child, struct resource *r,
|
|||||||
{
|
{
|
||||||
struct pci_devinfo *dinfo;
|
struct pci_devinfo *dinfo;
|
||||||
|
|
||||||
|
if (device_get_parent(child) != dev)
|
||||||
|
return (bus_generic_adjust_resource(dev, child, r, start,
|
||||||
|
end));
|
||||||
|
|
||||||
dinfo = device_get_ivars(child);
|
dinfo = device_get_ivars(child);
|
||||||
if (dinfo->cfg.flags & PCICFG_VF) {
|
if (dinfo->cfg.flags & PCICFG_VF) {
|
||||||
switch (rman_get_type(r)) {
|
switch (rman_get_type(r)) {
|
||||||
@@ -5802,6 +5810,10 @@ pci_map_resource(device_t dev, device_t child, struct resource *r,
|
|||||||
{
|
{
|
||||||
struct pci_devinfo *dinfo;
|
struct pci_devinfo *dinfo;
|
||||||
|
|
||||||
|
if (device_get_parent(child) != dev)
|
||||||
|
return (bus_generic_map_resource(dev, child, r, argsp,
|
||||||
|
map));
|
||||||
|
|
||||||
dinfo = device_get_ivars(child);
|
dinfo = device_get_ivars(child);
|
||||||
if (dinfo->cfg.flags & PCICFG_VF) {
|
if (dinfo->cfg.flags & PCICFG_VF) {
|
||||||
switch (rman_get_type(r)) {
|
switch (rman_get_type(r)) {
|
||||||
@@ -5825,6 +5837,9 @@ pci_unmap_resource(device_t dev, device_t child, struct resource *r,
|
|||||||
{
|
{
|
||||||
struct pci_devinfo *dinfo;
|
struct pci_devinfo *dinfo;
|
||||||
|
|
||||||
|
if (device_get_parent(child) != dev)
|
||||||
|
return (bus_generic_unmap_resource(dev, child, r, map));
|
||||||
|
|
||||||
dinfo = device_get_ivars(child);
|
dinfo = device_get_ivars(child);
|
||||||
if (dinfo->cfg.flags & PCICFG_VF) {
|
if (dinfo->cfg.flags & PCICFG_VF) {
|
||||||
switch (rman_get_type(r)) {
|
switch (rman_get_type(r)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user