当前位置: 首页 > news >正文

virt基础-bar模拟调用流程

每一个virt设备都要定义vfio-pci region,标准的vfio-pci region数量为9。通过传入的offset知道要访问的是哪一个bar。

/** The VFIO-PCI bus driver makes use of the following fixed region and* IRQ index mapping.  Unimplemented regions return a size of zero.* Unimplemented IRQ types return a count of zero.*/enum {VFIO_PCI_BAR0_REGION_INDEX,VFIO_PCI_BAR1_REGION_INDEX,VFIO_PCI_BAR2_REGION_INDEX,VFIO_PCI_BAR3_REGION_INDEX,VFIO_PCI_BAR4_REGION_INDEX,VFIO_PCI_BAR5_REGION_INDEX,VFIO_PCI_ROM_REGION_INDEX,VFIO_PCI_CONFIG_REGION_INDEX,/** Expose VGA regions defined for PCI base class 03, subclass 00.* This includes I/O port ranges 0x3b0 to 0x3bb and 0x3c0 to 0x3df* as well as the MMIO range 0xa0000 to 0xbffff.  Each implemented* range is found at it's identity mapped offset from the region* offset, for example 0x3b0 is region_info.offset + 0x3b0.  Areas* between described ranges are unimplemented.*/VFIO_PCI_VGA_REGION_INDEX,VFIO_PCI_NUM_REGIONS = 9 /* Fixed user ABI, region indexes >=9 use *//* device specific cap to define content. */
};

i915中关于这一层的代码调用,这一层就是对bar的模拟

@linux5.15/drivers/gpu/drm/i915/gvt/kvmgt.c
static struct mdev_parent_ops intel_vgpu_ops = {.mdev_attr_groups       = intel_vgpu_groups,.create			= intel_vgpu_create,.remove			= intel_vgpu_remove,.open_device		= intel_vgpu_open_device,.close_device		= intel_vgpu_close_device,.read			= intel_vgpu_read,.write			= intel_vgpu_write,.mmap			= intel_vgpu_mmap,.ioctl			= intel_vgpu_ioctl,
};static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops)
{int ret;ret = intel_gvt_init_vgpu_type_groups((struct intel_gvt *)gvt);if (ret)return ret;intel_gvt_ops = ops;intel_vgpu_ops.supported_type_groups = gvt_vgpu_type_groups;ret = mdev_register_device(dev, &intel_vgpu_ops);if (ret)intel_gvt_cleanup_vgpu_type_groups((struct intel_gvt *)gvt);return ret;
}static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,size_t count, loff_t *ppos, bool is_write)
{struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);u64 pos = *ppos & VFIO_PCI_OFFSET_MASK;int ret = -EINVAL;if (index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions) {gvt_vgpu_err("invalid index: %u\n", index);return -EINVAL;}switch (index) {case VFIO_PCI_CONFIG_REGION_INDEX:if (is_write)ret = intel_gvt_ops->emulate_cfg_write(vgpu, pos,buf, count);elseret = intel_gvt_ops->emulate_cfg_read(vgpu, pos,buf, count);break;case VFIO_PCI_BAR0_REGION_INDEX:ret = intel_vgpu_bar_rw(vgpu, PCI_BASE_ADDRESS_0, pos,buf, count, is_write);break;case VFIO_PCI_BAR2_REGION_INDEX:ret = intel_vgpu_aperture_rw(vgpu, pos, buf, count, is_write);break;case VFIO_PCI_BAR1_REGION_INDEX:case VFIO_PCI_BAR3_REGION_INDEX:case VFIO_PCI_BAR4_REGION_INDEX:case VFIO_PCI_BAR5_REGION_INDEX:case VFIO_PCI_VGA_REGION_INDEX:case VFIO_PCI_ROM_REGION_INDEX:break;default:if (index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions)return -EINVAL;index -= VFIO_PCI_NUM_REGIONS;return vdev->region[index].ops->rw(vgpu, buf, count,ppos, is_write);}return ret == 0 ? count : ret;
}static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,size_t count, loff_t *ppos)
{unsigned int done = 0;int ret;while (count) {size_t filled;/* Only support GGTT entry 8 bytes read */if (count >= 8 && !(*ppos % 8) &&gtt_entry(mdev, ppos)) {u64 val;ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),ppos, false);if (ret <= 0)goto read_err;if (copy_to_user(buf, &val, sizeof(val)))goto read_err;filled = 8;} else if (count >= 4 && !(*ppos % 4)) {u32 val;ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),ppos, false);if (ret <= 0)goto read_err;if (copy_to_user(buf, &val, sizeof(val)))goto read_err;filled = 4;} else if (count >= 2 && !(*ppos % 2)) {u16 val;ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),ppos, false);if (ret <= 0)goto read_err;if (copy_to_user(buf, &val, sizeof(val)))goto read_err;filled = 2;} else {u8 val;ret = intel_vgpu_rw(mdev, &val, sizeof(val), ppos,false);if (ret <= 0)goto read_err;if (copy_to_user(buf, &val, sizeof(val)))goto read_err;filled = 1;}count -= filled;done += filled;*ppos += filled;buf += filled;}return done;read_err:return -EFAULT;
}
http://www.jsqmd.com/news/647190/

相关文章:

  • MySQL 查询:按2017年平均成绩降序列出所有学生姓名及均分
  • 全文降AI的好处你知道吗?这3款工具帮你省时省力
  • Halcon点云降噪实战:用`get_object_model_3d_params`和`select_points_object_model_3d`搞定稀疏离群点
  • Claude Code Routines:如何让AI编程助手实现全自动工作流?
  • PHP怎么使用外键映射模式_PHP关联关系处理方法【指南】
  • 从原理到实战:用Qt和C++手搓一个带容错的二维码生成器
  • static静态变量
  • 大麦网自动抢票脚本技术解决方案:告别手动抢票的低效率困境
  • Linux服务器宝塔面板故障排查:SSH可连接但面板无法访问的解决方案
  • 从Nucleo到BluePill:一份超详细的STM32F103 BSP移植实战记录(附避坑点)
  • 树莓派+SocketCAN实战:手把手教你用CanFestival控制伺服电机(保姆级避坑指南)
  • 配置操作失败数量统计
  • LVGL复选框(lv_checkbox)实战:手把手教你做个嵌入式点餐界面(附完整源码)
  • 如何避免组态王打包程序时的3个典型错误?实测经验分享
  • 别只当计算器用!深入理解ANSYS Workbench 18.2 的Units设置与Engineering Data管理
  • 畅快呼吸,从 “鼻” 守护 —— 世界爱鼻日大咖共话慢性鼻窦炎药物与手术规范化诊疗
  • 软件工程师的远程工作攻略:全球高薪机会
  • 3大技术突破:nanoMODBUS如何重塑嵌入式工业通信的轻量化标准
  • 别再乱配Shiro了!Spring Boot整合Shiro实现Token登录,这份配置清单请收好
  • Stata17新版实测:3种数据导入方法速度对比(附命令行自动化脚本)
  • Renesas MCU开发踩坑记:CS+ for CC找不到iodefine.h的3种解决方法
  • 2025届毕业生推荐的AI科研助手推荐
  • aubo i5 + realsense D435i手眼标定
  • 想把 Chrome 插件变成独立的桌面程序
  • 2025届最火的十大降AI率工具推荐
  • 音视频直播构建优化
  • 保姆级教程:用Python+Ultralytics YOLOv8实时识别你电脑屏幕上的任何物体(附完整代码)
  • 2026年4月企业微信SCRM系统TOP7实测榜单:全行业私域增长工具选购指南
  • 官宣!数数科技正式更名为 ThinkingAI
  • P1618三连击 (暴力+枚举)