@@ -426,7 +426,7 @@ static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
target_ulong rets)
{
sPAPRPHBState *sphb;
- sPAPRPHBClass *spc;
+ PCIDevice *pdev;
uint32_t addr, option;
uint64_t buid;
int ret;
@@ -440,16 +440,17 @@ static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
option = rtas_ld(args, 3);
sphb = spapr_pci_find_phb(spapr, buid);
- if (!sphb) {
+ if (!sphb || !sphb->has_vfio) {
goto param_error_exit;
}
- spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
- if (!spc->eeh_set_option) {
+ pdev = pci_find_device(PCI_HOST_BRIDGE(sphb)->bus,
+ (addr >> 16) & 0xFF, (addr >> 8) & 0xFF);
+ if (!pdev || !object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
goto param_error_exit;
}
- ret = spc->eeh_set_option(sphb, addr, option);
+ ret = spapr_phb_vfio_eeh_set_option(sphb, pdev, option);
rtas_st(rets, 0, ret);
return;
@@ -464,7 +465,6 @@ static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
target_ulong rets)
{
sPAPRPHBState *sphb;
- sPAPRPHBClass *spc;
PCIDevice *pdev;
uint32_t addr, option;
uint64_t buid;
@@ -475,12 +475,7 @@ static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
sphb = spapr_pci_find_phb(spapr, buid);
- if (!sphb) {
- goto param_error_exit;
- }
-
- spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
- if (!spc->eeh_set_option) {
+ if (!sphb || !sphb->has_vfio) {
goto param_error_exit;
}
@@ -520,7 +515,6 @@ static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
target_ulong rets)
{
sPAPRPHBState *sphb;
- sPAPRPHBClass *spc;
uint64_t buid;
int state, ret;
@@ -530,16 +524,11 @@ static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
sphb = spapr_pci_find_phb(spapr, buid);
- if (!sphb) {
+ if (!sphb || !sphb->has_vfio) {
goto param_error_exit;
}
- spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
- if (!spc->eeh_get_state) {
- goto param_error_exit;
- }
-
- ret = spc->eeh_get_state(sphb, &state);
+ ret = spapr_phb_vfio_eeh_get_state(sphb, &state);
rtas_st(rets, 0, ret);
if (ret != RTAS_OUT_SUCCESS) {
return;
@@ -564,7 +553,6 @@ static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
target_ulong rets)
{
sPAPRPHBState *sphb;
- sPAPRPHBClass *spc;
uint32_t option;
uint64_t buid;
int ret;
@@ -576,16 +564,11 @@ static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
option = rtas_ld(args, 3);
sphb = spapr_pci_find_phb(spapr, buid);
- if (!sphb) {
+ if (!sphb || !sphb->has_vfio) {
goto param_error_exit;
}
- spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
- if (!spc->eeh_reset) {
- goto param_error_exit;
- }
-
- ret = spc->eeh_reset(sphb, option);
+ ret = spapr_phb_vfio_eeh_reset(sphb, option);
rtas_st(rets, 0, ret);
return;
@@ -600,7 +583,6 @@ static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
target_ulong rets)
{
sPAPRPHBState *sphb;
- sPAPRPHBClass *spc;
uint64_t buid;
int ret;
@@ -610,16 +592,11 @@ static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
sphb = spapr_pci_find_phb(spapr, buid);
- if (!sphb) {
+ if (!sphb || !sphb->has_vfio) {
goto param_error_exit;
}
- spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
- if (!spc->eeh_configure) {
- goto param_error_exit;
- }
-
- ret = spc->eeh_configure(sphb);
+ ret = spapr_phb_vfio_eeh_configure(sphb);
rtas_st(rets, 0, ret);
return;
@@ -635,7 +612,6 @@ static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
target_ulong rets)
{
sPAPRPHBState *sphb;
- sPAPRPHBClass *spc;
int option;
uint64_t buid;
@@ -645,12 +621,7 @@ static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
sphb = spapr_pci_find_phb(spapr, buid);
- if (!sphb) {
- goto param_error_exit;
- }
-
- spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
- if (!spc->eeh_set_option) {
+ if (!sphb || !sphb->has_vfio) {
goto param_error_exit;
}
@@ -747,9 +718,14 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
static int spapr_phb_dma_capabilities_update(sPAPRPHBState *sphb)
{
+ int ret;
+
sphb->dma32_window_start = 0;
sphb->dma32_window_size = SPAPR_PCI_DMA32_SIZE;
+ ret = spapr_phb_vfio_dma_capabilities_update(sphb);
+ sphb->has_vfio = (ret == 0);
+
return 0;
}
@@ -762,7 +738,8 @@ static int spapr_phb_dma_init_window(sPAPRPHBState *sphb,
spapr_tce_table_enable(tcet, bus_offset, page_shift,
window_size >> page_shift,
- false);
+ sphb->has_vfio);
+
return 0;
}
@@ -790,12 +767,11 @@ static int spapr_phb_disable_dma_windows(Object *child, void *opaque)
int spapr_phb_dma_reset(sPAPRPHBState *sphb)
{
const uint32_t liobn = SPAPR_PCI_LIOBN(sphb->index, 0);
- sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
- spc->dma_capabilities_update(sphb); /* Refresh @has_vfio status */
+ spapr_phb_dma_capabilities_update(sphb); /* Refresh @has_vfio status */
object_child_foreach(OBJECT(sphb), spapr_phb_disable_dma_windows, sphb);
- spc->dma_init_window(sphb, liobn, SPAPR_TCE_PAGE_SHIFT,
- sphb->dma32_window_size);
+ spapr_phb_dma_init_window(sphb, liobn, SPAPR_TCE_PAGE_SHIFT,
+ sphb->dma32_window_size);
return 0;
}
@@ -1185,6 +1161,11 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
uint64_t msi_window_size = 4096;
sPAPRTCETable *tcet;
+ if ((sphb->iommugroupid != -1) &&
+ object_dynamic_cast(OBJECT(sphb), TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE)) {
+ error_report("Warning: iommugroupid shall not be used");
+ }
+
if (sphb->index != (uint32_t)-1) {
hwaddr windows_base;
@@ -1482,7 +1463,6 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
{
PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_CLASS(klass);
HotplugHandlerClass *hp = HOTPLUG_HANDLER_CLASS(klass);
hc->root_bus_path = spapr_phb_root_bus_path;
@@ -1494,8 +1474,6 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
dc->cannot_instantiate_with_device_add_yet = false;
hp->plug = spapr_phb_hot_plug_child;
hp->unplug = spapr_phb_hot_unplug_child;
- spc->dma_capabilities_update = spapr_phb_dma_capabilities_update;
- spc->dma_init_window = spapr_phb_dma_init_window;
}
static const TypeInfo spapr_phb_info = {
@@ -23,11 +23,11 @@
#include "hw/vfio/vfio.h"
static Property spapr_phb_vfio_properties[] = {
- DEFINE_PROP_INT32("iommu", sPAPRPHBVFIOState, iommugroupid, -1),
+ DEFINE_PROP_INT32("iommu", sPAPRPHBState, iommugroupid, -1),
DEFINE_PROP_END_OF_LIST(),
};
-static int spapr_phb_vfio_dma_capabilities_update(sPAPRPHBState *sphb)
+int spapr_phb_vfio_dma_capabilities_update(sPAPRPHBState *sphb)
{
struct vfio_iommu_spapr_tce_info info = { .argsz = sizeof(info) };
int ret;
@@ -44,22 +44,8 @@ static int spapr_phb_vfio_dma_capabilities_update(sPAPRPHBState *sphb)
return ret;
}
-static int spapr_phb_vfio_dma_init_window(sPAPRPHBState *sphb,
- uint32_t liobn, uint32_t page_shift,
- uint64_t window_size)
-{
- uint64_t bus_offset = sphb->dma32_window_start;
- sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
-
- spapr_tce_table_enable(tcet, bus_offset, page_shift,
- window_size >> page_shift,
- true);
-
- return 0;
-}
-
-static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
- unsigned int addr, int option)
+int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
+ PCIDevice *pdev, int option)
{
struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };
int ret;
@@ -68,25 +54,9 @@ static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
case RTAS_EEH_DISABLE:
op.op = VFIO_EEH_PE_DISABLE;
break;
- case RTAS_EEH_ENABLE: {
- PCIHostState *phb;
- PCIDevice *pdev;
-
- /*
- * The EEH functionality is enabled on basis of PCI device,
- * instead of PE. We need check the validity of the PCI
- * device address.
- */
- phb = PCI_HOST_BRIDGE(sphb);
- pdev = pci_find_device(phb->bus,
- (addr >> 16) & 0xFF, (addr >> 8) & 0xFF);
- if (!pdev) {
- return RTAS_OUT_PARAM_ERROR;
- }
-
+ case RTAS_EEH_ENABLE:
op.op = VFIO_EEH_PE_ENABLE;
break;
- }
case RTAS_EEH_THAW_IO:
op.op = VFIO_EEH_PE_UNFREEZE_IO;
break;
@@ -106,7 +76,7 @@ static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
return RTAS_OUT_SUCCESS;
}
-static int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state)
+int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state)
{
struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };
int ret;
@@ -122,7 +92,7 @@ static int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state)
return RTAS_OUT_SUCCESS;
}
-static int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
+int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
{
struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };
int ret;
@@ -150,7 +120,7 @@ static int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
return RTAS_OUT_SUCCESS;
}
-static int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
+int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
{
struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };
int ret;
@@ -168,21 +138,14 @@ static int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_CLASS(klass);
dc->props = spapr_phb_vfio_properties;
- spc->dma_capabilities_update = spapr_phb_vfio_dma_capabilities_update;
- spc->dma_init_window = spapr_phb_vfio_dma_init_window;
- spc->eeh_set_option = spapr_phb_vfio_eeh_set_option;
- spc->eeh_get_state = spapr_phb_vfio_eeh_get_state;
- spc->eeh_reset = spapr_phb_vfio_eeh_reset;
- spc->eeh_configure = spapr_phb_vfio_eeh_configure;
}
static const TypeInfo spapr_phb_vfio_info = {
.name = TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE,
.parent = TYPE_SPAPR_PCI_HOST_BRIDGE,
- .instance_size = sizeof(sPAPRPHBVFIOState),
+ .instance_size = sizeof(sPAPRPHBState),
.class_init = spapr_phb_vfio_class_init,
.class_size = sizeof(sPAPRPHBClass),
};
@@ -47,15 +47,6 @@ typedef struct sPAPRPHBVFIOState sPAPRPHBVFIOState;
struct sPAPRPHBClass {
PCIHostBridgeClass parent_class;
-
- int (*dma_capabilities_update)(sPAPRPHBState *sphb);
- int (*dma_init_window)(sPAPRPHBState *sphb,
- uint32_t liobn, uint32_t page_shift,
- uint64_t window_size);
- int (*eeh_set_option)(sPAPRPHBState *sphb, unsigned int addr, int option);
- int (*eeh_get_state)(sPAPRPHBState *sphb, int *state);
- int (*eeh_reset)(sPAPRPHBState *sphb, int option);
- int (*eeh_configure)(sPAPRPHBState *sphb);
};
typedef struct spapr_pci_msi {
@@ -95,16 +86,12 @@ struct sPAPRPHBState {
uint32_t dma32_window_start;
uint32_t dma32_window_size;
+ bool has_vfio;
+ int32_t iommugroupid; /* obsolete */
QLIST_ENTRY(sPAPRPHBState) list;
};
-struct sPAPRPHBVFIOState {
- sPAPRPHBState phb;
-
- int32_t iommugroupid;
-};
-
#define SPAPR_PCI_MAX_INDEX 255
#define SPAPR_PCI_BASE_BUID 0x800000020000000ULL
@@ -147,4 +134,12 @@ int spapr_phb_dma_remove_window(sPAPRPHBState *sphb,
sPAPRTCETable *tcet);
int spapr_phb_dma_reset(sPAPRPHBState *sphb);
+int spapr_phb_vfio_dma_capabilities_update(sPAPRPHBState *sphb);
+int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
+ PCIDevice *pdev, int option);
+int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state);
+int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option);
+int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb);
+
+
#endif /* __HW_SPAPR_PCI_H__ */