spapr_drc.c (fbf553971898aee18b5933d335e2fa3e74bb9be7) spapr_drc.c (b8fdd530be3450940130b63d930bb0aee1538e7e)
1/*
2 * QEMU SPAPR Dynamic Reconfiguration Connector Implementation
3 *
4 * Copyright IBM Corp. 2014
5 *
6 * Authors:
7 * Michael Roth <mdroth@linux.vnet.ibm.com>
8 *

--- 13 unchanged lines hidden (view full) ---

22#include "hw/ppc/spapr.h" /* for RTAS return codes */
23#include "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */
24#include "trace.h"
25
26#define DRC_CONTAINER_PATH "/dr-connector"
27#define DRC_INDEX_TYPE_SHIFT 28
28#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1)
29
1/*
2 * QEMU SPAPR Dynamic Reconfiguration Connector Implementation
3 *
4 * Copyright IBM Corp. 2014
5 *
6 * Authors:
7 * Michael Roth <mdroth@linux.vnet.ibm.com>
8 *

--- 13 unchanged lines hidden (view full) ---

22#include "hw/ppc/spapr.h" /* for RTAS return codes */
23#include "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */
24#include "trace.h"
25
26#define DRC_CONTAINER_PATH "/dr-connector"
27#define DRC_INDEX_TYPE_SHIFT 28
28#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1)
29
30static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPRMachineState *spapr,
31 uint32_t drc_index)
32{
33 sPAPRConfigureConnectorState *ccs = NULL;
34
35 QTAILQ_FOREACH(ccs, &spapr->ccs_list, next) {
36 if (ccs->drc_index == drc_index) {
37 break;
38 }
39 }
40
41 return ccs;
42}
43
44static void spapr_ccs_add(sPAPRMachineState *spapr,
45 sPAPRConfigureConnectorState *ccs)
46{
47 g_assert(!spapr_ccs_find(spapr, ccs->drc_index));
48 QTAILQ_INSERT_HEAD(&spapr->ccs_list, ccs, next);
49}
50
51static void spapr_ccs_remove(sPAPRMachineState *spapr,
52 sPAPRConfigureConnectorState *ccs)
53{
54 QTAILQ_REMOVE(&spapr->ccs_list, ccs, next);
55 g_free(ccs);
56}
57
58sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc)
59{
60 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
61
62 return 1 << drck->typeshift;
63}
64
65uint32_t spapr_drc_index(sPAPRDRConnector *drc)

--- 10 unchanged lines hidden (view full) ---

76
77static uint32_t set_isolation_state(sPAPRDRConnector *drc,
78 sPAPRDRIsolationState state)
79{
80 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
81
82 trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);
83
30sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc)
31{
32 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
33
34 return 1 << drck->typeshift;
35}
36
37uint32_t spapr_drc_index(sPAPRDRConnector *drc)

--- 10 unchanged lines hidden (view full) ---

48
49static uint32_t set_isolation_state(sPAPRDRConnector *drc,
50 sPAPRDRIsolationState state)
51{
52 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
53
54 trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);
55
56 /* if the guest is configuring a device attached to this DRC, we
57 * should reset the configuration state at this point since it may
58 * no longer be reliable (guest released device and needs to start
59 * over, or unplug occurred so the FDT is no longer valid)
60 */
61 if (state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
62 g_free(drc->ccs);
63 drc->ccs = NULL;
64 }
65
84 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
85 /* cannot unisolate a non-existent resource, and, or resources
86 * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5)
87 */
88 if (!drc->dev ||
89 drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
90 return RTAS_OUT_NO_SUCH_INDICATOR;
91 }

--- 388 unchanged lines hidden (view full) ---

480
481static void reset(DeviceState *d)
482{
483 sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
484 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
485 sPAPRDREntitySense state;
486
487 trace_spapr_drc_reset(spapr_drc_index(drc));
66 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
67 /* cannot unisolate a non-existent resource, and, or resources
68 * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5)
69 */
70 if (!drc->dev ||
71 drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
72 return RTAS_OUT_NO_SUCH_INDICATOR;
73 }

--- 388 unchanged lines hidden (view full) ---

462
463static void reset(DeviceState *d)
464{
465 sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
466 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
467 sPAPRDREntitySense state;
468
469 trace_spapr_drc_reset(spapr_drc_index(drc));
470
471 g_free(drc->ccs);
472 drc->ccs = NULL;
473
488 /* immediately upon reset we can safely assume DRCs whose devices
489 * are pending removal can be safely removed, and that they will
490 * subsequently be left in an ISOLATED state. move the DRC to this
491 * state in these cases (which will in turn complete any pending
492 * device removals)
493 */
494 if (drc->awaiting_release) {
495 drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_ISOLATED);

--- 518 unchanged lines hidden (view full) ---

1014 trace_spapr_rtas_set_indicator_invalid(sensor_index);
1015 ret = RTAS_OUT_PARAM_ERROR;
1016 goto out;
1017 }
1018 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
1019
1020 switch (sensor_type) {
1021 case RTAS_SENSOR_TYPE_ISOLATION_STATE:
474 /* immediately upon reset we can safely assume DRCs whose devices
475 * are pending removal can be safely removed, and that they will
476 * subsequently be left in an ISOLATED state. move the DRC to this
477 * state in these cases (which will in turn complete any pending
478 * device removals)
479 */
480 if (drc->awaiting_release) {
481 drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_ISOLATED);

--- 518 unchanged lines hidden (view full) ---

1000 trace_spapr_rtas_set_indicator_invalid(sensor_index);
1001 ret = RTAS_OUT_PARAM_ERROR;
1002 goto out;
1003 }
1004 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
1005
1006 switch (sensor_type) {
1007 case RTAS_SENSOR_TYPE_ISOLATION_STATE:
1022 /* if the guest is configuring a device attached to this
1023 * DRC, we should reset the configuration state at this
1024 * point since it may no longer be reliable (guest released
1025 * device and needs to start over, or unplug occurred so
1026 * the FDT is no longer valid)
1027 */
1028 if (sensor_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
1029 sPAPRConfigureConnectorState *ccs = spapr_ccs_find(spapr,
1030 sensor_index);
1031 if (ccs) {
1032 spapr_ccs_remove(spapr, ccs);
1033 }
1034 }
1035 ret = drck->set_isolation_state(drc, sensor_state);
1036 break;
1037 case RTAS_SENSOR_TYPE_DR:
1038 ret = drck->set_indicator_state(drc, sensor_state);
1039 break;
1040 case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
1041 ret = drck->set_allocation_state(drc, sensor_state);
1042 break;

--- 67 unchanged lines hidden (view full) ---

1110
1111static void configure_connector_st(target_ulong addr, target_ulong offset,
1112 const void *buf, size_t len)
1113{
1114 cpu_physical_memory_write(ppc64_phys_to_real(addr + offset),
1115 buf, MIN(len, CC_WA_LEN - offset));
1116}
1117
1008 ret = drck->set_isolation_state(drc, sensor_state);
1009 break;
1010 case RTAS_SENSOR_TYPE_DR:
1011 ret = drck->set_indicator_state(drc, sensor_state);
1012 break;
1013 case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
1014 ret = drck->set_allocation_state(drc, sensor_state);
1015 break;

--- 67 unchanged lines hidden (view full) ---

1083
1084static void configure_connector_st(target_ulong addr, target_ulong offset,
1085 const void *buf, size_t len)
1086{
1087 cpu_physical_memory_write(ppc64_phys_to_real(addr + offset),
1088 buf, MIN(len, CC_WA_LEN - offset));
1089}
1090
1118void spapr_ccs_reset_hook(void *opaque)
1119{
1120 sPAPRMachineState *spapr = opaque;
1121 sPAPRConfigureConnectorState *ccs, *ccs_tmp;
1122
1123 QTAILQ_FOREACH_SAFE(ccs, &spapr->ccs_list, next, ccs_tmp) {
1124 spapr_ccs_remove(spapr, ccs);
1125 }
1126}
1127
1128static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
1129 sPAPRMachineState *spapr,
1130 uint32_t token, uint32_t nargs,
1131 target_ulong args, uint32_t nret,
1132 target_ulong rets)
1133{
1134 uint64_t wa_addr;
1135 uint64_t wa_offset;

--- 19 unchanged lines hidden (view full) ---

1155 }
1156
1157 if (!drc->fdt) {
1158 trace_spapr_rtas_ibm_configure_connector_missing_fdt(drc_index);
1159 rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE;
1160 goto out;
1161 }
1162
1091static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
1092 sPAPRMachineState *spapr,
1093 uint32_t token, uint32_t nargs,
1094 target_ulong args, uint32_t nret,
1095 target_ulong rets)
1096{
1097 uint64_t wa_addr;
1098 uint64_t wa_offset;

--- 19 unchanged lines hidden (view full) ---

1118 }
1119
1120 if (!drc->fdt) {
1121 trace_spapr_rtas_ibm_configure_connector_missing_fdt(drc_index);
1122 rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE;
1123 goto out;
1124 }
1125
1163 ccs = spapr_ccs_find(spapr, drc_index);
1126 ccs = drc->ccs;
1164 if (!ccs) {
1165 ccs = g_new0(sPAPRConfigureConnectorState, 1);
1166 ccs->fdt_offset = drc->fdt_start_offset;
1127 if (!ccs) {
1128 ccs = g_new0(sPAPRConfigureConnectorState, 1);
1129 ccs->fdt_offset = drc->fdt_start_offset;
1167 ccs->drc_index = drc_index;
1168 spapr_ccs_add(spapr, ccs);
1130 drc->ccs = ccs;
1169 }
1170
1171 do {
1172 uint32_t tag;
1173 const char *name;
1174 const struct fdt_property *prop;
1175 int fdt_offset_next, prop_len;
1176

--- 20 unchanged lines hidden (view full) ---

1197 */
1198 trace_spapr_drc_set_configured(drc_index);
1199 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
1200 drc->configured = true;
1201 } else {
1202 /* guest should be not configuring an isolated device */
1203 trace_spapr_drc_set_configured_skipping(drc_index);
1204 }
1131 }
1132
1133 do {
1134 uint32_t tag;
1135 const char *name;
1136 const struct fdt_property *prop;
1137 int fdt_offset_next, prop_len;
1138

--- 20 unchanged lines hidden (view full) ---

1159 */
1160 trace_spapr_drc_set_configured(drc_index);
1161 if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
1162 drc->configured = true;
1163 } else {
1164 /* guest should be not configuring an isolated device */
1165 trace_spapr_drc_set_configured_skipping(drc_index);
1166 }
1205 spapr_ccs_remove(spapr, ccs);
1167 g_free(ccs);
1168 drc->ccs = NULL;
1206 ccs = NULL;
1207 resp = SPAPR_DR_CC_RESPONSE_SUCCESS;
1208 } else {
1209 resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT;
1210 }
1211 break;
1212 case FDT_PROP:
1213 prop = fdt_get_property_by_offset(drc->fdt, ccs->fdt_offset,

--- 51 unchanged lines hidden ---
1169 ccs = NULL;
1170 resp = SPAPR_DR_CC_RESPONSE_SUCCESS;
1171 } else {
1172 resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT;
1173 }
1174 break;
1175 case FDT_PROP:
1176 prop = fdt_get_property_by_offset(drc->fdt, ccs->fdt_offset,

--- 51 unchanged lines hidden ---