qw1w2 = xive_tctx_get_os_cam(tctx, &nvt_blk, &nvt_idx, &vo);
+ if (!vo) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: pulling invalid NVT %x/%x !?\n",
+ nvt_blk, nvt_idx);
+ }
+
/* Invalidate CAM line */
qw1w2_new = xive_set_field32(TM_QW1W2_VO, qw1w2, 0);
xive_tctx_set_os_cam(tctx, qw1w2_new);
/*
* The thread context register words are in big-endian format.
*/
-static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
- uint8_t nvt_blk, uint32_t nvt_idx,
- bool cam_ignore, uint32_t logic_serv)
+int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
+ uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool cam_ignore, uint32_t logic_serv)
{
uint32_t cam = xive_nvt_cam_line(nvt_blk, nvt_idx);
uint32_t qw3w2 = xive_tctx_word2(&tctx->regs[TM_QW3_HV_PHYS]);
return -1;
}
-typedef struct XiveTCTXMatch {
- XiveTCTX *tctx;
- uint8_t ring;
-} XiveTCTXMatch;
-
static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
uint8_t nvt_blk, uint32_t nvt_idx,
bool cam_ignore, uint8_t priority,
uint32_t logic_serv, XiveTCTXMatch *match)
{
- CPUState *cs;
-
- /*
- * TODO (PowerNV): handle chip_id overwrite of block field for
- * hardwired CAM compares
- */
+ XivePresenter *xptr = XIVE_PRESENTER(xrtr);
+ XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+ int count;
- CPU_FOREACH(cs) {
- XiveTCTX *tctx = xive_router_get_tctx(xrtr, cs);
- int ring;
-
- /*
- * Skip partially initialized vCPUs. This can happen when
- * vCPUs are hotplugged.
- */
- if (!tctx) {
- continue;
- }
-
- /*
- * HW checks that the CPU is enabled in the Physical Thread
- * Enable Register (PTER).
- */
-
- /*
- * Check the thread context CAM lines and record matches. We
- * will handle CPU exception delivery later
- */
- ring = xive_presenter_tctx_match(tctx, format, nvt_blk, nvt_idx,
- cam_ignore, logic_serv);
- /*
- * Save the context and follow on to catch duplicates, that we
- * don't support yet.
- */
- if (ring != -1) {
- if (match->tctx) {
- qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a thread "
- "context NVT %x/%x\n", nvt_blk, nvt_idx);
- return false;
- }
-
- match->ring = ring;
- match->tctx = tctx;
- }
+ count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
+ priority, logic_serv, match);
+ if (count < 0) {
+ return false;
}
if (!match->tctx) {
.class_init = xive_router_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_XIVE_NOTIFIER },
+ { TYPE_XIVE_PRESENTER },
{ }
}
};
.class_size = sizeof(XiveNotifierClass),
};
+/*
+ * XIVE Presenter
+ */
+static const TypeInfo xive_presenter_info = {
+ .name = TYPE_XIVE_PRESENTER,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(XivePresenterClass),
+};
+
static void xive_register_types(void)
{
type_register_static(&xive_source_info);
type_register_static(&xive_notifier_info);
+ type_register_static(&xive_presenter_info);
type_register_static(&xive_router_info);
type_register_static(&xive_end_source_info);
type_register_static(&xive_tctx_info);