Lines Matching refs:mdev_state
168 struct mdev_state *mdev_state; member
174 struct mdev_state { struct
216 static struct page *__mbochs_get_page(struct mdev_state *mdev_state,
218 static struct page *mbochs_get_page(struct mdev_state *mdev_state,
221 static void mbochs_create_config_space(struct mdev_state *mdev_state) in mbochs_create_config_space() argument
223 STORE_LE16((u16 *) &mdev_state->vconfig[PCI_VENDOR_ID], in mbochs_create_config_space()
225 STORE_LE16((u16 *) &mdev_state->vconfig[PCI_DEVICE_ID], in mbochs_create_config_space()
227 STORE_LE16((u16 *) &mdev_state->vconfig[PCI_SUBSYSTEM_VENDOR_ID], in mbochs_create_config_space()
229 STORE_LE16((u16 *) &mdev_state->vconfig[PCI_SUBSYSTEM_ID], in mbochs_create_config_space()
232 STORE_LE16((u16 *) &mdev_state->vconfig[PCI_COMMAND], in mbochs_create_config_space()
234 STORE_LE16((u16 *) &mdev_state->vconfig[PCI_CLASS_DEVICE], in mbochs_create_config_space()
236 mdev_state->vconfig[PCI_CLASS_REVISION] = 0x01; in mbochs_create_config_space()
238 STORE_LE32((u32 *) &mdev_state->vconfig[PCI_BASE_ADDRESS_0], in mbochs_create_config_space()
242 mdev_state->bar_mask[0] = ~(mdev_state->memsize) + 1; in mbochs_create_config_space()
244 STORE_LE32((u32 *) &mdev_state->vconfig[PCI_BASE_ADDRESS_2], in mbochs_create_config_space()
247 mdev_state->bar_mask[2] = ~(MBOCHS_MMIO_BAR_SIZE) + 1; in mbochs_create_config_space()
250 static int mbochs_check_framebuffer(struct mdev_state *mdev_state, in mbochs_check_framebuffer() argument
253 struct device *dev = mdev_dev(mdev_state->mdev); in mbochs_check_framebuffer()
254 u16 *vbe = mdev_state->vbe; in mbochs_check_framebuffer()
257 WARN_ON(!mutex_is_locked(&mdev_state->ops_lock)); in mbochs_check_framebuffer()
289 if (mode->offset + mode->size > mdev_state->memsize) { in mbochs_check_framebuffer()
308 static void handle_pci_cfg_write(struct mdev_state *mdev_state, u16 offset, in handle_pci_cfg_write() argument
311 struct device *dev = mdev_dev(mdev_state->mdev); in handle_pci_cfg_write()
321 cfg_addr = (cfg_addr & mdev_state->bar_mask[index]); in handle_pci_cfg_write()
329 cfg_addr |= (mdev_state->vconfig[offset] & in handle_pci_cfg_write()
331 STORE_LE32(&mdev_state->vconfig[offset], cfg_addr); in handle_pci_cfg_write()
336 static void handle_mmio_write(struct mdev_state *mdev_state, u16 offset, in handle_mmio_write() argument
339 struct device *dev = mdev_dev(mdev_state->mdev); in handle_mmio_write()
351 if (index < ARRAY_SIZE(mdev_state->vbe)) in handle_mmio_write()
352 mdev_state->vbe[index] = reg16; in handle_mmio_write()
366 static void handle_mmio_read(struct mdev_state *mdev_state, u16 offset, in handle_mmio_read() argument
369 struct device *dev = mdev_dev(mdev_state->mdev); in handle_mmio_read()
376 edid = &mdev_state->edid_regs; in handle_mmio_read()
382 memcpy(buf, mdev_state->edid_blob + offset, count); in handle_mmio_read()
388 if (index < ARRAY_SIZE(mdev_state->vbe)) in handle_mmio_read()
389 reg16 = mdev_state->vbe[index]; in handle_mmio_read()
403 static void handle_edid_regs(struct mdev_state *mdev_state, u16 offset, in handle_edid_regs() argument
406 char *regs = (void *)&mdev_state->edid_regs; in handle_edid_regs()
408 if (offset + count > sizeof(mdev_state->edid_regs)) in handle_edid_regs()
430 static void handle_edid_blob(struct mdev_state *mdev_state, u16 offset, in handle_edid_blob() argument
433 if (offset + count > mdev_state->edid_regs.edid_max_size) in handle_edid_blob()
436 memcpy(mdev_state->edid_blob + offset, buf, count); in handle_edid_blob()
438 memcpy(buf, mdev_state->edid_blob + offset, count); in handle_edid_blob()
441 static ssize_t mdev_access(struct mdev_state *mdev_state, char *buf, in mdev_access() argument
449 mutex_lock(&mdev_state->ops_lock); in mdev_access()
453 handle_pci_cfg_write(mdev_state, pos, buf, count); in mdev_access()
455 memcpy(buf, (mdev_state->vconfig + pos), count); in mdev_access()
462 handle_mmio_write(mdev_state, pos, buf, count); in mdev_access()
464 handle_mmio_read(mdev_state, pos, buf, count); in mdev_access()
471 handle_edid_regs(mdev_state, pos, buf, count, is_write); in mdev_access()
474 handle_edid_blob(mdev_state, pos, buf, count, is_write); in mdev_access()
479 MBOCHS_MEMORY_BAR_OFFSET + mdev_state->memsize) { in mdev_access()
482 pg = __mbochs_get_page(mdev_state, pos >> PAGE_SHIFT); in mdev_access()
492 dev_dbg(mdev_state->vdev.dev, "%s: %s @0x%llx (unhandled)\n", in mdev_access()
502 mutex_unlock(&mdev_state->ops_lock); in mdev_access()
507 static int mbochs_reset(struct mdev_state *mdev_state) in mbochs_reset() argument
509 u32 size64k = mdev_state->memsize / (64 * 1024); in mbochs_reset()
512 for (i = 0; i < ARRAY_SIZE(mdev_state->vbe); i++) in mbochs_reset()
513 mdev_state->vbe[i] = 0; in mbochs_reset()
514 mdev_state->vbe[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5; in mbochs_reset()
515 mdev_state->vbe[VBE_DISPI_INDEX_VIDEO_MEMORY_64K] = size64k; in mbochs_reset()
521 struct mdev_state *mdev_state = in mbochs_init_dev() local
522 container_of(vdev, struct mdev_state, vdev); in mbochs_init_dev()
535 mdev_state->vconfig = kzalloc(MBOCHS_CONFIG_SPACE_SIZE, GFP_KERNEL); in mbochs_init_dev()
536 if (!mdev_state->vconfig) in mbochs_init_dev()
539 mdev_state->memsize = type->mbytes * 1024 * 1024; in mbochs_init_dev()
540 mdev_state->pagecount = mdev_state->memsize >> PAGE_SHIFT; in mbochs_init_dev()
541 mdev_state->pages = kcalloc(mdev_state->pagecount, in mbochs_init_dev()
544 if (!mdev_state->pages) in mbochs_init_dev()
547 mutex_init(&mdev_state->ops_lock); in mbochs_init_dev()
548 mdev_state->mdev = mdev; in mbochs_init_dev()
549 INIT_LIST_HEAD(&mdev_state->dmabufs); in mbochs_init_dev()
550 mdev_state->next_id = 1; in mbochs_init_dev()
552 mdev_state->type = type; in mbochs_init_dev()
553 mdev_state->edid_regs.max_xres = type->max_x; in mbochs_init_dev()
554 mdev_state->edid_regs.max_yres = type->max_y; in mbochs_init_dev()
555 mdev_state->edid_regs.edid_offset = MBOCHS_EDID_BLOB_OFFSET; in mbochs_init_dev()
556 mdev_state->edid_regs.edid_max_size = sizeof(mdev_state->edid_blob); in mbochs_init_dev()
557 mbochs_create_config_space(mdev_state); in mbochs_init_dev()
558 mbochs_reset(mdev_state); in mbochs_init_dev()
561 type->type.pretty_name, type->mbytes, mdev_state->pagecount); in mbochs_init_dev()
565 kfree(mdev_state->vconfig); in mbochs_init_dev()
573 struct mdev_state *mdev_state; in mbochs_probe() local
576 mdev_state = vfio_alloc_device(mdev_state, vdev, &mdev->dev, in mbochs_probe()
578 if (IS_ERR(mdev_state)) in mbochs_probe()
579 return PTR_ERR(mdev_state); in mbochs_probe()
581 ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev); in mbochs_probe()
584 dev_set_drvdata(&mdev->dev, mdev_state); in mbochs_probe()
588 vfio_put_device(&mdev_state->vdev); in mbochs_probe()
594 struct mdev_state *mdev_state = in mbochs_release_dev() local
595 container_of(vdev, struct mdev_state, vdev); in mbochs_release_dev()
597 atomic_add(mdev_state->type->mbytes, &mbochs_avail_mbytes); in mbochs_release_dev()
598 kfree(mdev_state->pages); in mbochs_release_dev()
599 kfree(mdev_state->vconfig); in mbochs_release_dev()
604 struct mdev_state *mdev_state = dev_get_drvdata(&mdev->dev); in mbochs_remove() local
606 vfio_unregister_group_dev(&mdev_state->vdev); in mbochs_remove()
607 vfio_put_device(&mdev_state->vdev); in mbochs_remove()
613 struct mdev_state *mdev_state = in mbochs_read() local
614 container_of(vdev, struct mdev_state, vdev); in mbochs_read()
624 ret = mdev_access(mdev_state, (char *)&val, sizeof(val), in mbochs_read()
636 ret = mdev_access(mdev_state, (char *)&val, sizeof(val), in mbochs_read()
648 ret = mdev_access(mdev_state, (char *)&val, sizeof(val), in mbochs_read()
674 struct mdev_state *mdev_state = in mbochs_write() local
675 container_of(vdev, struct mdev_state, vdev); in mbochs_write()
688 ret = mdev_access(mdev_state, (char *)&val, sizeof(val), in mbochs_write()
700 ret = mdev_access(mdev_state, (char *)&val, sizeof(val), in mbochs_write()
712 ret = mdev_access(mdev_state, (char *)&val, sizeof(val), in mbochs_write()
730 static struct page *__mbochs_get_page(struct mdev_state *mdev_state, in __mbochs_get_page() argument
733 WARN_ON(!mutex_is_locked(&mdev_state->ops_lock)); in __mbochs_get_page()
735 if (!mdev_state->pages[pgoff]) { in __mbochs_get_page()
736 mdev_state->pages[pgoff] = in __mbochs_get_page()
738 if (!mdev_state->pages[pgoff]) in __mbochs_get_page()
742 get_page(mdev_state->pages[pgoff]); in __mbochs_get_page()
743 return mdev_state->pages[pgoff]; in __mbochs_get_page()
746 static struct page *mbochs_get_page(struct mdev_state *mdev_state, in mbochs_get_page() argument
751 if (WARN_ON(pgoff >= mdev_state->pagecount)) in mbochs_get_page()
754 mutex_lock(&mdev_state->ops_lock); in mbochs_get_page()
755 page = __mbochs_get_page(mdev_state, pgoff); in mbochs_get_page()
756 mutex_unlock(&mdev_state->ops_lock); in mbochs_get_page()
761 static void mbochs_put_pages(struct mdev_state *mdev_state) in mbochs_put_pages() argument
763 struct device *dev = mdev_dev(mdev_state->mdev); in mbochs_put_pages()
766 WARN_ON(!mutex_is_locked(&mdev_state->ops_lock)); in mbochs_put_pages()
768 for (i = 0; i < mdev_state->pagecount; i++) { in mbochs_put_pages()
769 if (!mdev_state->pages[i]) in mbochs_put_pages()
771 put_page(mdev_state->pages[i]); in mbochs_put_pages()
772 mdev_state->pages[i] = NULL; in mbochs_put_pages()
781 struct mdev_state *mdev_state = vma->vm_private_data; in mbochs_region_vm_fault() local
784 if (page_offset >= mdev_state->pagecount) in mbochs_region_vm_fault()
787 vmf->page = mbochs_get_page(mdev_state, page_offset); in mbochs_region_vm_fault()
800 struct mdev_state *mdev_state = in mbochs_mmap() local
801 container_of(vdev, struct mdev_state, vdev); in mbochs_mmap()
807 if (vma->vm_end - vma->vm_start > mdev_state->memsize) in mbochs_mmap()
813 vma->vm_private_data = mdev_state; in mbochs_mmap()
837 struct device *dev = mdev_dev(dmabuf->mdev_state->mdev); in mbochs_mmap_dmabuf()
852 struct device *dev = mdev_dev(dmabuf->mdev_state->mdev); in mbochs_print_dmabuf()
869 struct device *dev = mdev_dev(dmabuf->mdev_state->mdev); in mbochs_map_dmabuf()
898 struct device *dev = mdev_dev(dmabuf->mdev_state->mdev); in mbochs_unmap_dmabuf()
910 struct mdev_state *mdev_state = dmabuf->mdev_state; in mbochs_release_dmabuf() local
911 struct device *dev = mdev_dev(mdev_state->mdev); in mbochs_release_dmabuf()
919 mutex_lock(&mdev_state->ops_lock); in mbochs_release_dmabuf()
923 mutex_unlock(&mdev_state->ops_lock); in mbochs_release_dmabuf()
933 static struct mbochs_dmabuf *mbochs_dmabuf_alloc(struct mdev_state *mdev_state, in mbochs_dmabuf_alloc() argument
939 WARN_ON(!mutex_is_locked(&mdev_state->ops_lock)); in mbochs_dmabuf_alloc()
946 dmabuf->id = mdev_state->next_id++; in mbochs_dmabuf_alloc()
955 dmabuf->pages[pg] = __mbochs_get_page(mdev_state, in mbochs_dmabuf_alloc()
961 dmabuf->mdev_state = mdev_state; in mbochs_dmabuf_alloc()
962 list_add(&dmabuf->next, &mdev_state->dmabufs); in mbochs_dmabuf_alloc()
977 mbochs_dmabuf_find_by_mode(struct mdev_state *mdev_state, in mbochs_dmabuf_find_by_mode() argument
982 WARN_ON(!mutex_is_locked(&mdev_state->ops_lock)); in mbochs_dmabuf_find_by_mode()
984 list_for_each_entry(dmabuf, &mdev_state->dmabufs, next) in mbochs_dmabuf_find_by_mode()
992 mbochs_dmabuf_find_by_id(struct mdev_state *mdev_state, u32 id) in mbochs_dmabuf_find_by_id() argument
996 WARN_ON(!mutex_is_locked(&mdev_state->ops_lock)); in mbochs_dmabuf_find_by_id()
998 list_for_each_entry(dmabuf, &mdev_state->dmabufs, next) in mbochs_dmabuf_find_by_id()
1007 struct mdev_state *mdev_state = dmabuf->mdev_state; in mbochs_dmabuf_export() local
1008 struct device *dev = mdev_state->vdev.dev; in mbochs_dmabuf_export()
1012 WARN_ON(!mutex_is_locked(&mdev_state->ops_lock)); in mbochs_dmabuf_export()
1036 static int mbochs_get_region_info(struct mdev_state *mdev_state, in mbochs_get_region_info() argument
1053 region_info->size = mdev_state->memsize; in mbochs_get_region_info()
1101 static int mbochs_query_gfx_plane(struct mdev_state *mdev_state, in mbochs_query_gfx_plane() argument
1124 mutex_lock(&mdev_state->ops_lock); in mbochs_query_gfx_plane()
1128 ret = mbochs_check_framebuffer(mdev_state, &mode); in mbochs_query_gfx_plane()
1139 dmabuf = mbochs_dmabuf_find_by_mode(mdev_state, &mode); in mbochs_query_gfx_plane()
1141 mbochs_dmabuf_alloc(mdev_state, &mode); in mbochs_query_gfx_plane()
1143 mutex_unlock(&mdev_state->ops_lock); in mbochs_query_gfx_plane()
1156 mdev_state->active_id != plane->dmabuf_id) { in mbochs_query_gfx_plane()
1157 dev_dbg(mdev_state->vdev.dev, "%s: primary: %d => %d\n", in mbochs_query_gfx_plane()
1158 __func__, mdev_state->active_id, plane->dmabuf_id); in mbochs_query_gfx_plane()
1159 mdev_state->active_id = plane->dmabuf_id; in mbochs_query_gfx_plane()
1161 mutex_unlock(&mdev_state->ops_lock); in mbochs_query_gfx_plane()
1165 static int mbochs_get_gfx_dmabuf(struct mdev_state *mdev_state, u32 id) in mbochs_get_gfx_dmabuf() argument
1169 mutex_lock(&mdev_state->ops_lock); in mbochs_get_gfx_dmabuf()
1171 dmabuf = mbochs_dmabuf_find_by_id(mdev_state, id); in mbochs_get_gfx_dmabuf()
1173 mutex_unlock(&mdev_state->ops_lock); in mbochs_get_gfx_dmabuf()
1180 mutex_unlock(&mdev_state->ops_lock); in mbochs_get_gfx_dmabuf()
1191 struct mdev_state *mdev_state = in mbochs_ioctl() local
1192 container_of(vdev, struct mdev_state, vdev); in mbochs_ioctl()
1233 ret = mbochs_get_region_info(mdev_state, &info); in mbochs_ioctl()
1279 ret = mbochs_query_gfx_plane(mdev_state, &plane); in mbochs_ioctl()
1296 return mbochs_get_gfx_dmabuf(mdev_state, dmabuf_id); in mbochs_ioctl()
1303 return mbochs_reset(mdev_state); in mbochs_ioctl()
1310 struct mdev_state *mdev_state = in mbochs_close_device() local
1311 container_of(vdev, struct mdev_state, vdev); in mbochs_close_device()
1314 mutex_lock(&mdev_state->ops_lock); in mbochs_close_device()
1316 list_for_each_entry_safe(dmabuf, tmp, &mdev_state->dmabufs, next) { in mbochs_close_device()
1325 mbochs_put_pages(mdev_state); in mbochs_close_device()
1327 mutex_unlock(&mdev_state->ops_lock); in mbochs_close_device()
1334 struct mdev_state *mdev_state = dev_get_drvdata(dev); in memory_show() local
1336 return sprintf(buf, "%d MB\n", mdev_state->type->mbytes); in memory_show()