QEMU源码全解析 —— virtio(9)
接前一篇文章:
上两回讲解了virtio balloon相关类所涉及的realize函数以及大致流程,如下表所示:
realize函数 | parent_dc_realize函数 | |
DeviceClass | virtio_pci_dc_realize | |
PCIDeviceClass | virtio_pci_realize | |
VirtioPCIClass | virtio_balloon_pci_realize | pci_qdev_realize |
本回对于流程进行深入解析。
综合前文书所讲,当具现化TYPE_VIRTIO_BALLOON的时候,device_set_realized函数中会首先调用DeciceClass->realize即virtio_pci_dc_realize函数。再次贴出该函数源码,在hw/virtio/virtio-pci.c中,如下:
static void virtio_pci_dc_realize(DeviceState *qdev, Error **errp)
{VirtioPCIClass *vpciklass = VIRTIO_PCI_GET_CLASS(qdev);VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev);PCIDevice *pci_dev = &proxy->pci_dev;if (!(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_PCIE) &&virtio_pci_modern(proxy)) {pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;}vpciklass->parent_dc_realize(qdev, errp);
}
virtio_pci_dc_realize函数首先判断virtio PCI代理设备是否具有VIRTIO_PCI_FLAG_DISABLE_PCIE特性,该特性使得virtio PCI代理展现出PCIe的的接口。
之后调用了vpciklass->parent_dc_realize函数,由前文分析可知,该回调函数是pci_qdev_realize()。再次贴出pci_qdev_realize函数源码,在hw/virtio/virtio-pci.c中,如下:
static void pci_qdev_realize(DeviceState *qdev, Error **errp)
{PCIDevice *pci_dev = (PCIDevice *)qdev;PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);ObjectClass *klass = OBJECT_CLASS(pc);Error *local_err = NULL;bool is_default_rom;uint16_t class_id;/** capped by systemd (see: udev-builtin-net_id.c)* as it's the only known user honor it to avoid users* misconfigure QEMU and then wonder why acpi-index doesn't work*/if (pci_dev->acpi_index > ONBOARD_INDEX_MAX) {error_setg(errp, "acpi-index should be less or equal to %u",ONBOARD_INDEX_MAX);return;}/** make sure that acpi-index is unique across all present PCI devices*/if (pci_dev->acpi_index) {GSequence *used_indexes = pci_acpi_index_list();if (g_sequence_lookup(used_indexes,GINT_TO_POINTER(pci_dev->acpi_index),g_cmp_uint32, NULL)) {error_setg(errp, "a PCI device with acpi-index = %" PRIu32" already exist", pci_dev->acpi_index);return;}g_sequence_insert_sorted(used_indexes,GINT_TO_POINTER(pci_dev->acpi_index),g_cmp_uint32, NULL);}if (pci_dev->romsize != -1 && !is_power_of_2(pci_dev->romsize)) {error_setg(errp, "ROM size %u is not a power of two", pci_dev->romsize);return;}/* initialize cap_present for pci_is_express() and pci_config_size(),* Note that hybrid PCIs are not set automatically and need to manage* QEMU_PCI_CAP_EXPRESS manually */if (object_class_dynamic_cast(klass, INTERFACE_PCIE_DEVICE) &&!object_class_dynamic_cast(klass, INTERFACE_CONVENTIONAL_PCI_DEVICE)) {pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;}if (object_class_dynamic_cast(klass, INTERFACE_CXL_DEVICE)) {pci_dev->cap_present |= QEMU_PCIE_CAP_CXL;}pci_dev = do_pci_register_device(pci_dev,object_get_typename(OBJECT(qdev)),pci_dev->devfn, errp);if (pci_dev == NULL)return;if (pc->realize) {pc->realize(pci_dev, &local_err);if (local_err) {error_propagate(errp, local_err);do_pci_unregister_device(pci_dev);return;}}/** A PCIe Downstream Port that do not have ARI Forwarding enabled must* associate only Device 0 with the device attached to the bus* representing the Link from the Port (PCIe base spec rev 4.0 ver 0.3,* sec 7.3.1).* With ARI, PCI_SLOT() can return non-zero value as the traditional* 5-bit Device Number and 3-bit Function Number fields in its associated* Routing IDs, Requester IDs and Completer IDs are interpreted as a* single 8-bit Function Number. Hence, ignore ARI capable devices.*/if (pci_is_express(pci_dev) &&!pcie_find_capability(pci_dev, PCI_EXT_CAP_ID_ARI) &&pcie_has_upstream_port(pci_dev) &&PCI_SLOT(pci_dev->devfn)) {warn_report("PCI: slot %d is not valid for %s,"" parent device only allows plugging into slot 0.",PCI_SLOT(pci_dev->devfn), pci_dev->name);}if (pci_dev->failover_pair_id) {if (!pci_bus_is_express(pci_get_bus(pci_dev))) {error_setg(errp, "failover primary device must be on ""PCIExpress bus");pci_qdev_unrealize(DEVICE(pci_dev));return;}class_id = pci_get_word(pci_dev->config + PCI_CLASS_DEVICE);if (class_id != PCI_CLASS_NETWORK_ETHERNET) {error_setg(errp, "failover primary device is not an ""Ethernet device");pci_qdev_unrealize(DEVICE(pci_dev));return;}if ((pci_dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)|| (PCI_FUNC(pci_dev->devfn) != 0)) {error_setg(errp, "failover: primary device must be in its own ""PCI slot");pci_qdev_unrealize(DEVICE(pci_dev));return;}qdev->allow_unplug_during_migration = true;}/* rom loading */is_default_rom = false;if (pci_dev->romfile == NULL && pc->romfile != NULL) {pci_dev->romfile = g_strdup(pc->romfile);is_default_rom = true;}pci_add_option_rom(pci_dev, is_default_rom, &local_err);if (local_err) {error_propagate(errp, local_err);pci_qdev_unrealize(DEVICE(pci_dev));return;}pci_set_power(pci_dev, true);pci_dev->msi_trigger = pci_msi_trigger;
}
相关文章:
QEMU源码全解析 —— virtio(9)
接前一篇文章: 上两回讲解了virtio balloon相关类所涉及的realize函数以及大致流程,如下表所示: realize函数parent_dc_realize函数DeviceClassvirtio_pci_dc_realizePCIDeviceClassvirtio_pci_realizeVirtioPCIClassvirtio_balloon_pci_rea…...

金蝶云星空协同开发环境应用内执行单据类型脚本
文章目录 金蝶云星空协同开发环境应用内执行单据类型脚本业务界面查询单据类型表数据导出数据执行数据库脚本单据类型xml检验是否执行成功检查数据库检查业务数据 金蝶云星空协同开发环境应用内执行单据类型脚本 业务界面 查询单据类型表数据 先使用类型中文在单据类型多语言…...
矩阵理论及其应用邱启荣习题3.5题解
(1) P ( − 1 0 1 − 1 − 1 2 1 1 − 1 ) \begin{pmatrix} -1 & 0&1 \\ -1 & -1&2\\1&1&-1 \end{pmatrix} −1−110−1112−1 A ( 1 0 1 1 1 0 − 1 2 1 ) \begin{pmatrix} 1 & 0&1 \\ 1 & 1&0\\-1&2&1 \end{pmat…...
Java面试题(每天10题)-------连载(49)
目录 Tomcat篇 1、Tomcat的缺省端口是多少?怎么修改? 2、Tomcat有哪几种Connector运行模式(优化)? 3、Tomcat有几种部署方式? 4、Tomcat容器时如何创建servlet类实例?用到了什么原理&…...
python——数据类型
数据类型目录 前言一、Number(数字)数字类型转换:二、String(字符串)常用字符串运算符:字符串格式化:三、Tuple(元组)常用运算符四、List(列表)嵌套列表:常用列表操作:五、Dictionary(字典)六、Set(集合)...
hive中如何求取中位数?
目录 中位数的概念代码实现准备数据实现 中位数的概念 中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本、种群或概率分布中的一个数值,其可将数值集合…...
在C#中异步编程
在C#中,异步编程是一种编写并发和响应式代码的技术,通过将耗时的操作放在后台线程中执行,以避免阻塞主线程,提高程序的性能和响应性。异步编程使用async和await关键字,结合任务(Task)和异步操作…...

微服务保护--Feign整合Sentinel
限流是一种预防措施,虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了。 线程隔离之前讲到…...
二进制to十六进制
输入小于等于十六位的二进制数据,输出十六进制数据; #include <stdio.h> #include <stdlib.h> #include <math.h>int main(void) {char arr[16] { 0 }; int array[16] { 0 }; int hex[4] { 0 };int i 0; int num 0;scanf("…...

Logistic 回归算法
Logistic 回归 Logistic 回归算法Logistic 回归简述Sigmoid 函数Logistic 回归模型表达式求解参数 $\theta $梯度上升优化算法 Logistic 回归简单实现使用 sklearn 构建 Logistic 回归分类器Logistic 回归算法的优缺点 Logistic 回归算法 Logistic 回归简述 Logistic 回归是一…...

ubuntu安装详细步骤
一,先下载vmware 1,第一步打开上面链接 下载网址 : https://www.vmware.com/products/workstation-pro/wo rkstation-pro-evaluation.html 许可证 JU090-6039P-08409-8J0QH-2YR7F ZF3R0-FHED2-M80TY-8QYGC-NPKYF FC7D0-D1YDL-M8DXZ-CYPZE-P2AY6 ZC3T…...
力扣5. 最长回文子串
动态规划 思路: 假设 dp[i][j] 为字符串 (i, j) 子串是否为回文的结果;那么 dp[i][j] dp[i 1][j - 1] 且 (s[i] s[j]);长度为1的字符串都是回文; 原字符串长度为1,是回文;原字符串子串长度为1ÿ…...
肆[4],函数VectorToHomMat2d/AffineTransPoint2d
函数VectorToHomMat2d C形式 LIntExport void VectorToHomMat2d( const HTuple& Px, const HTuple& Py, const HTuple& Qx, const HTuple& Qy, HTuple* HomMat2D);//参数1:图像坐标X数组 //参数2:图像坐标Y数组 //参数3:世界坐标X数组 //参数4:世界坐标Y…...
下载文件 后端返回给前端 response header 响应头
当浏览器在请求资源时,会通过http返回头中的content-type决定如何显示/处理将要加载的数据,如果这个类型浏览器能够支持阅览,浏览器就会直接展示该资源,比如png、jpeg、video等格式。在某些下载文件的场景中,服务端可能…...

lvs负载均集群
目录 NAT模式 LVS负载均衡群集部署 1.部署共享存储 2.配置节点服务器 192.168.17.130 编辑 192.168.17.133 3.配置负载调度器 4.测试效果 NAT模式 LVS负载均衡群集部署 负载调度器:内网关 ens33:192.168.17.70,外网关 ens36&#x…...

luttuce(RedisTempate)实现hash expire lua脚本
话不多说先放脚本: local argv ARGV local length #argv if length > 0 then local unpackArgs {} for i 1, length - 1 dotable.insert(unpackArgs, argv[i]) end if redis.call(exists, KEYS[1]) 1 thenredis.call(del, KEYS[1])redis.call(hset, KEYS[…...
【Xamarin】WebView连接局域网自动跳转外部浏览器问题的解决
xamarin在中国用的很少,但也有一些独到之处。例如用惯了Visual Studio的就很合适。而且类Java开发,几乎没什么障碍。 protected override void OnCreate(Bundle savedInstanceState) {base.OnCreate(savedInstanceState);Xamarin.Essentials.Platform.I…...

【Unity动画】实现不同的肢体动作自由搭配播放Layer+Avatar Mask
这个教程教你学会使用Unity 动画层配合布偶遮罩(AvaterMask) 实现从2个动画身上只保留部分肢体动作,然后搭配播放 例如:一个正常跑的动画片段,我只保留腿部动作,形成一个层叫Run_leg 然后在从一个攻击动作…...
将0x06(16进制)转换为二进制
将0x06(16进制)转换为二进制,可以按照如下步骤进行: 1. 将0x06中的字母"0x"去除。 2. 将数字"06"中的数字"0"去除。 3. 将数字"06"转换为二进制。 根据步骤1和步骤2,去除&q…...

考PRINCE2有用么?有PMP证书了还需要考PRINCE2吗?
有用的,PMP相当于是理论,PRINCE2是实践,对小白来说pmp考后再考一个prince2是很好的选择,对项目管理的小白来说更好入门。 先来说下 prince 2 和 pmp 的区别 一、prince 2 是什么?跟PMP有什么区别? prince…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...