static void ivshmem_receive(void *opaque, const uint8_t *buf, int size) { IVShmemState *s = opaque; ivshmem_IntrStatus_write(s, *buf); IVSHMEM_DPRINTF("ivshmem_receive 0x%02x\n", *buf); }
static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr, uint32_t val) { IVShmemState *s = opaque; uint64_t write_one = 1; uint16_t dest = val >> 16; uint16_t vector = val & 0xff; addr &= 0xfc; IVSHMEM_DPRINTF("writing to addr " TARGET_FMT_plx "\n", addr); switch (addr) { case INTRMASK: ivshmem_IntrMask_write(s, val); break; case INTRSTATUS: ivshmem_IntrStatus_write(s, val); break; case DOORBELL: /* check that dest VM ID is reasonable */ if ((dest < 0) || (dest > s->max_peer)) { IVSHMEM_DPRINTF("Invalid destination VM ID (%d)\n", dest); break; } /* check doorbell range */ if ((vector >= 0) && (vector < s->peers[dest].nb_eventfds)) { IVSHMEM_DPRINTF("Writing %" PRId64 " to VM %d on vector %d\n", write_one, dest, vector); if (write(s->peers[dest].eventfds[vector], &(write_one), 8) != 8) { IVSHMEM_DPRINTF("error writing to eventfd\n"); } } break; default: IVSHMEM_DPRINTF("Invalid VM Doorbell VM %d\n", dest); } }
static void ivshmem_vector_notify(void *opaque) { MSIVector *entry = opaque; PCIDevice *pdev = entry->pdev; IVShmemState *s = IVSHMEM(pdev); int vector = entry - s->msi_vectors; EventNotifier *n = &s->peers[s->vm_id].eventfds[vector]; if (!event_notifier_test_and_clear(n)) { return; } IVSHMEM_DPRINTF("interrupt on vector %p %d\n", pdev, vector); if (ivshmem_has_feature(s, IVSHMEM_MSI)) { msix_notify(pdev, vector); } else { ivshmem_IntrStatus_write(s, 1); } }
static void ivshmem_io_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { IVShmemState *s = opaque; uint16_t dest = val >> 16; uint16_t vector = val & 0xff; addr &= 0xfc; IVSHMEM_DPRINTF("writing to addr " TARGET_FMT_plx "\n", addr); switch (addr) { case INTRMASK: ivshmem_IntrMask_write(s, val); break; case INTRSTATUS: ivshmem_IntrStatus_write(s, val); break; case DOORBELL: /* check that dest VM ID is reasonable */ if (dest >= s->nb_peers) { IVSHMEM_DPRINTF("Invalid destination VM ID (%d)\n", dest); break; } /* check doorbell range */ if (vector < s->peers[dest].nb_eventfds) { IVSHMEM_DPRINTF("Notifying VM %d on vector %d\n", dest, vector); event_notifier_set(&s->peers[dest].eventfds[vector]); } else { IVSHMEM_DPRINTF("Invalid destination vector %d on VM %d\n", vector, dest); } break; default: IVSHMEM_DPRINTF("Unhandled write " TARGET_FMT_plx "\n", addr); } }