spapr_pci: Eliminate class callbacks
The EEH operations in the spapr-vfio-pci-host-bridge no longer rely on the special groupid field in sPAPRPHBVFIOState. So we can simplify, removing the class specific callbacks with direct calls based on a simple spapr_phb_eeh_enabled() helper. For now we implement that in terms of a boolean in the class, but we'll continue to clean that up later. On its own this is a rather strange way of doing things, but it's a useful intermediate step to further cleanups. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
This commit is contained in:
parent
76a9e9f680
commit
fbb4e98341
@ -92,6 +92,13 @@ PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
|
|||||||
return pci_find_device(phb->bus, bus_num, devfn);
|
return pci_find_device(phb->bus, bus_num, devfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool spapr_phb_eeh_available(sPAPRPHBState *sphb)
|
||||||
|
{
|
||||||
|
sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
|
||||||
|
|
||||||
|
return spc->eeh_available;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t rtas_pci_cfgaddr(uint32_t arg)
|
static uint32_t rtas_pci_cfgaddr(uint32_t arg)
|
||||||
{
|
{
|
||||||
/* This handles the encoding of extended config space addresses */
|
/* This handles the encoding of extended config space addresses */
|
||||||
@ -440,7 +447,6 @@ static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
|
|||||||
target_ulong rets)
|
target_ulong rets)
|
||||||
{
|
{
|
||||||
sPAPRPHBState *sphb;
|
sPAPRPHBState *sphb;
|
||||||
sPAPRPHBClass *spc;
|
|
||||||
uint32_t addr, option;
|
uint32_t addr, option;
|
||||||
uint64_t buid;
|
uint64_t buid;
|
||||||
int ret;
|
int ret;
|
||||||
@ -458,12 +464,11 @@ static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
|
|||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
|
if (!spapr_phb_eeh_available(sphb)) {
|
||||||
if (!spc->eeh_set_option) {
|
|
||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spc->eeh_set_option(sphb, addr, option);
|
ret = spapr_phb_vfio_eeh_set_option(sphb, addr, option);
|
||||||
rtas_st(rets, 0, ret);
|
rtas_st(rets, 0, ret);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -478,7 +483,6 @@ static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
|
|||||||
target_ulong rets)
|
target_ulong rets)
|
||||||
{
|
{
|
||||||
sPAPRPHBState *sphb;
|
sPAPRPHBState *sphb;
|
||||||
sPAPRPHBClass *spc;
|
|
||||||
PCIDevice *pdev;
|
PCIDevice *pdev;
|
||||||
uint32_t addr, option;
|
uint32_t addr, option;
|
||||||
uint64_t buid;
|
uint64_t buid;
|
||||||
@ -493,8 +497,7 @@ static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
|
|||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
|
if (!spapr_phb_eeh_available(sphb)) {
|
||||||
if (!spc->eeh_set_option) {
|
|
||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +537,6 @@ static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
|
|||||||
target_ulong rets)
|
target_ulong rets)
|
||||||
{
|
{
|
||||||
sPAPRPHBState *sphb;
|
sPAPRPHBState *sphb;
|
||||||
sPAPRPHBClass *spc;
|
|
||||||
uint64_t buid;
|
uint64_t buid;
|
||||||
int state, ret;
|
int state, ret;
|
||||||
|
|
||||||
@ -548,12 +550,11 @@ static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
|
|||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
|
if (!spapr_phb_eeh_available(sphb)) {
|
||||||
if (!spc->eeh_get_state) {
|
|
||||||
goto param_error_exit;
|
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);
|
rtas_st(rets, 0, ret);
|
||||||
if (ret != RTAS_OUT_SUCCESS) {
|
if (ret != RTAS_OUT_SUCCESS) {
|
||||||
return;
|
return;
|
||||||
@ -578,7 +579,6 @@ static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
|
|||||||
target_ulong rets)
|
target_ulong rets)
|
||||||
{
|
{
|
||||||
sPAPRPHBState *sphb;
|
sPAPRPHBState *sphb;
|
||||||
sPAPRPHBClass *spc;
|
|
||||||
uint32_t option;
|
uint32_t option;
|
||||||
uint64_t buid;
|
uint64_t buid;
|
||||||
int ret;
|
int ret;
|
||||||
@ -594,12 +594,11 @@ static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
|
|||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
|
if (!spapr_phb_eeh_available(sphb)) {
|
||||||
if (!spc->eeh_reset) {
|
|
||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spc->eeh_reset(sphb, option);
|
ret = spapr_phb_vfio_eeh_reset(sphb, option);
|
||||||
rtas_st(rets, 0, ret);
|
rtas_st(rets, 0, ret);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -614,7 +613,6 @@ static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
|
|||||||
target_ulong rets)
|
target_ulong rets)
|
||||||
{
|
{
|
||||||
sPAPRPHBState *sphb;
|
sPAPRPHBState *sphb;
|
||||||
sPAPRPHBClass *spc;
|
|
||||||
uint64_t buid;
|
uint64_t buid;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -628,12 +626,11 @@ static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
|
|||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
|
if (!spapr_phb_eeh_available(sphb)) {
|
||||||
if (!spc->eeh_configure) {
|
|
||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spc->eeh_configure(sphb);
|
ret = spapr_phb_vfio_eeh_configure(sphb);
|
||||||
rtas_st(rets, 0, ret);
|
rtas_st(rets, 0, ret);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -649,7 +646,6 @@ static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
|
|||||||
target_ulong rets)
|
target_ulong rets)
|
||||||
{
|
{
|
||||||
sPAPRPHBState *sphb;
|
sPAPRPHBState *sphb;
|
||||||
sPAPRPHBClass *spc;
|
|
||||||
int option;
|
int option;
|
||||||
uint64_t buid;
|
uint64_t buid;
|
||||||
|
|
||||||
@ -663,8 +659,7 @@ static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
|
|||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
|
if (!spapr_phb_eeh_available(sphb)) {
|
||||||
if (!spc->eeh_set_option) {
|
|
||||||
goto param_error_exit;
|
goto param_error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1513,6 +1508,10 @@ static void spapr_phb_reset(DeviceState *qdev)
|
|||||||
{
|
{
|
||||||
/* Reset the IOMMU state */
|
/* Reset the IOMMU state */
|
||||||
object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL);
|
object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL);
|
||||||
|
|
||||||
|
if (spapr_phb_eeh_available(SPAPR_PCI_HOST_BRIDGE(qdev))) {
|
||||||
|
spapr_phb_vfio_reset(qdev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property spapr_phb_properties[] = {
|
static Property spapr_phb_properties[] = {
|
||||||
@ -1643,6 +1642,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
|
|||||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||||
dc->cannot_instantiate_with_device_add_yet = false;
|
dc->cannot_instantiate_with_device_add_yet = false;
|
||||||
spc->finish_realize = spapr_phb_finish_realize;
|
spc->finish_realize = spapr_phb_finish_realize;
|
||||||
|
spc->eeh_available = false;
|
||||||
hp->plug = spapr_phb_hot_plug_child;
|
hp->plug = spapr_phb_hot_plug_child;
|
||||||
hp->unplug = spapr_phb_hot_unplug_child;
|
hp->unplug = spapr_phb_hot_unplug_child;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ static void spapr_phb_vfio_eeh_reenable(sPAPRPHBState *sphb)
|
|||||||
vfio_eeh_as_op(&sphb->iommu_as, VFIO_EEH_PE_ENABLE);
|
vfio_eeh_as_op(&sphb->iommu_as, VFIO_EEH_PE_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spapr_phb_vfio_reset(DeviceState *qdev)
|
void spapr_phb_vfio_reset(DeviceState *qdev)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The PE might be in frozen state. To reenable the EEH
|
* The PE might be in frozen state. To reenable the EEH
|
||||||
@ -89,8 +89,8 @@ static void spapr_phb_vfio_reset(DeviceState *qdev)
|
|||||||
spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
|
spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
||||||
unsigned int addr, int option)
|
unsigned int addr, int option)
|
||||||
{
|
{
|
||||||
uint32_t op;
|
uint32_t op;
|
||||||
int ret;
|
int ret;
|
||||||
@ -136,7 +136,7 @@ static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
|||||||
return RTAS_OUT_SUCCESS;
|
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)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ static void spapr_phb_vfio_eeh_pre_reset(sPAPRPHBState *sphb)
|
|||||||
pci_for_each_bus(phb->bus, spapr_phb_vfio_eeh_clear_bus_msix, NULL);
|
pci_for_each_bus(phb->bus, spapr_phb_vfio_eeh_clear_bus_msix, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
|
int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
|
||||||
{
|
{
|
||||||
uint32_t op;
|
uint32_t op;
|
||||||
int ret;
|
int ret;
|
||||||
@ -221,7 +221,7 @@ static int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
|
|||||||
return RTAS_OUT_SUCCESS;
|
return RTAS_OUT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
|
int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -239,12 +239,8 @@ static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
|
|||||||
sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_CLASS(klass);
|
sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_CLASS(klass);
|
||||||
|
|
||||||
dc->props = spapr_phb_vfio_properties;
|
dc->props = spapr_phb_vfio_properties;
|
||||||
dc->reset = spapr_phb_vfio_reset;
|
|
||||||
spc->finish_realize = spapr_phb_vfio_finish_realize;
|
spc->finish_realize = spapr_phb_vfio_finish_realize;
|
||||||
spc->eeh_set_option = spapr_phb_vfio_eeh_set_option;
|
spc->eeh_available = true;
|
||||||
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 = {
|
static const TypeInfo spapr_phb_vfio_info = {
|
||||||
|
@ -49,10 +49,7 @@ struct sPAPRPHBClass {
|
|||||||
PCIHostBridgeClass parent_class;
|
PCIHostBridgeClass parent_class;
|
||||||
|
|
||||||
void (*finish_realize)(sPAPRPHBState *sphb, Error **errp);
|
void (*finish_realize)(sPAPRPHBState *sphb, Error **errp);
|
||||||
int (*eeh_set_option)(sPAPRPHBState *sphb, unsigned int addr, int option);
|
bool eeh_available;
|
||||||
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 {
|
typedef struct spapr_pci_msi {
|
||||||
@ -137,4 +134,36 @@ sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid);
|
|||||||
PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
|
PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
|
||||||
uint32_t config_addr);
|
uint32_t config_addr);
|
||||||
|
|
||||||
|
/* VFIO EEH hooks */
|
||||||
|
#ifdef CONFIG_LINUX
|
||||||
|
int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
||||||
|
unsigned int addr, 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);
|
||||||
|
void spapr_phb_vfio_reset(DeviceState *qdev);
|
||||||
|
#else
|
||||||
|
static inline int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
||||||
|
unsigned int addr, int option)
|
||||||
|
{
|
||||||
|
return RTAS_OUT_HW_ERROR;
|
||||||
|
}
|
||||||
|
static inline int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb,
|
||||||
|
int *state)
|
||||||
|
{
|
||||||
|
return RTAS_OUT_HW_ERROR;
|
||||||
|
}
|
||||||
|
static inline int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
|
||||||
|
{
|
||||||
|
return RTAS_OUT_HW_ERROR;
|
||||||
|
}
|
||||||
|
static inline int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
|
||||||
|
{
|
||||||
|
return RTAS_OUT_HW_ERROR;
|
||||||
|
}
|
||||||
|
static inline void spapr_phb_vfio_reset(DeviceState *qdev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __HW_SPAPR_PCI_H__ */
|
#endif /* __HW_SPAPR_PCI_H__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user